| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- <template>
- <view class="default_page" :style="{'height':h+'px', 'padding-top':mt+'px'}">
- <cus-header title='生成报告' bgColor="transparent"></cus-header>
- <div class="box adffcac">
- <image class="box-loading" src="https://gitee.com/hw_0302/chuang-heng-wechat-images/raw/e6d5bea9491a14aafd3f955d332e62d08e521229/report_success.png" v-if="generation.imageKey==='success'"></image>
- <image class="box-loading" src="https://gitee.com/hw_0302/chuang-heng-wechat-images/raw/e6d5bea9491a14aafd3f955d332e62d08e521229/report_fail.png" v-else></image>
- <div class="box-p1">{{generation.title}}</div>
- <div class="box-p2" v-if="generation.subtitle">{{generation.subtitle}}</div>
- <div class="box-p3">{{generation.state===-1 ? '失败原因:'+generation.errorMessage : generation.description}}</div>
- </div>
- <div class="form">
- <div class="form-item adfacjb">
- <div class="form-item-left">问卷名称</div>
- <div class="form-item-right">{{info.title||''}}</div>
- </div>
- <div class="form-item adfacjb">
- <div class="form-item-left">团队名称</div>
- <div class="form-item-right">{{info.teamName||''}}</div>
- </div>
- <div class="form-item adfacjb">
- <div class="form-item-left">创建时间</div>
- <div class="form-item-right">{{info.startTime||info.createDate||''}}</div>
- </div>
- </div>
- <div class="btn">
- <div class="zt_btn" @click="handleAction">{{generation.actionText}}</div>
- </div>
- </view>
- </template>
- <script>
- function toNumber(value) {
- if (value === '' || value === null || value === undefined) return undefined
- const numeric = Number(value)
- return Number.isNaN(numeric) ? undefined : numeric
- }
- function extractReportId(payload) {
- if (payload === null || payload === undefined) return undefined
- if (typeof payload === 'number') return payload
- if (typeof payload === 'string') return toNumber(payload)
- if (typeof payload !== 'object') return undefined
- const direct = toNumber(payload.reportId ?? payload.id)
- if (direct !== undefined) return direct
- for (const key of ['data', 'dto', 'info']) {
- const nested = extractReportId(payload[key])
- if (nested !== undefined) return nested
- }
- return undefined
- }
- function normalizeGenerationStatus(payload = {}) {
- const source = payload && typeof payload === 'object' ? payload : {}
- const state = toNumber(source.state)
- return {
- reportId: extractReportId(source) || '',
- state: state === undefined ? 0 : state,
- status: source.status || '',
- errorMessage: source.errorMessage || ''
- }
- }
- function applyGenerationStatus(payload = {}) {
- const generation = normalizeGenerationStatus(payload)
- if (generation.state === -1) {
- return {
- ...generation,
- title: '报告生成失败',
- subtitle: '',
- description: generation.errorMessage || '失败原因:网络延迟',
- errorMessage: generation.errorMessage || '网络延迟',
- polling: false,
- actionText: '重新生成',
- imageKey: 'fail'
- }
- }
- if (generation.state === 1) {
- return {
- ...generation,
- title: '报告生成成功',
- subtitle: '',
- description: '报告已生成完成,你可以去我的PREILL报告查阅报告结果。',
- errorMessage: '',
- polling: false,
- actionText: '返回',
- imageKey: 'success'
- }
- }
- return {
- ...generation,
- title: '报告正在生成中~',
- subtitle: '预计所需时间1小时左右',
- description: '我们会在报告生成完成后提示你,你可以去我的PREILL报告查阅报告结果。',
- errorMessage: '',
- polling: true,
- actionText: '返回',
- imageKey: 'success'
- }
- }
- function shouldResumePolling(reportId, generation = {}) {
- return Boolean(reportId && normalizeGenerationStatus(generation).state === 0)
- }
- function setStatusPageVisible(vm, visible) {
- if(vm.isPageVisible === visible) return vm.statusVisibilityToken
- vm.isPageVisible = visible
- if(!visible){
- vm.statusVisibilityToken++
- vm.statusActiveRequestId = 0
- vm.statusRequestInFlight = false
- }
- return vm.statusVisibilityToken
- }
- function beginStatusRequest(vm) {
- if(!vm.isPageVisible || vm.statusRequestInFlight) return null
- vm.statusRequestSeq++
- vm.statusActiveRequestId = vm.statusRequestSeq
- vm.statusRequestInFlight = true
- return {
- requestId: vm.statusActiveRequestId,
- visibilityToken: vm.statusVisibilityToken
- }
- }
- function shouldApplyStatusResponse(vm, meta) {
- return Boolean(
- meta
- && vm.isPageVisible
- && vm.statusRequestInFlight
- && vm.statusActiveRequestId === meta.requestId
- && vm.statusVisibilityToken === meta.visibilityToken
- )
- }
- function finishStatusRequest(vm, meta) {
- if(!meta) return
- if(vm.statusActiveRequestId === meta.requestId){
- vm.statusActiveRequestId = 0
- vm.statusRequestInFlight = false
- }
- }
- export default {
- data(){
- return {
- reportId:'',
- info:{},
- generation:applyGenerationStatus(),
- pollTimer:null,
- hasStatusErrorToastShown:false,
- isPageVisible:false,
- statusVisibilityToken:0,
- statusRequestSeq:0,
- statusActiveRequestId:0,
- statusRequestInFlight:false
- }
- },
- onLoad(options) {
- this.info = options.info&&JSON.parse(decodeURIComponent(options.info)) || {}
- this.reportId = extractReportId({ reportId:options.reportId, dto:options, info:this.info }) || ''
- if(!this.reportId){
- this.stopPolling('报告编号缺失')
- return
- }
- },
- onShow() {
- setStatusPageVisible(this, true)
- if(shouldResumePolling(this.reportId, this.generation)){
- this.startPolling()
- this.fetchGenerationStatus(false)
- }
- },
- onHide() {
- setStatusPageVisible(this, false)
- this.clearPolling()
- },
- onUnload() {
- setStatusPageVisible(this, false)
- this.clearPolling()
- },
- methods:{
- startPolling(){
- if(!this.isPageVisible || !shouldResumePolling(this.reportId, this.generation) || this.pollTimer) return
- this.pollTimer = setInterval(() => {
- this.fetchGenerationStatus(false)
- }, 5000)
- },
- clearPolling(){
- if(this.pollTimer){
- clearInterval(this.pollTimer)
- this.pollTimer = null
- }
- },
- reconcileGeneration(status){
- this.generation = applyGenerationStatus(status)
- this.hasStatusErrorToastShown = false
- if(this.generation.polling && this.reportId) return this.startPolling()
- this.clearPolling()
- },
- stopPolling(errorMessage){
- this.clearPolling()
- this.generation = applyGenerationStatus({
- reportId:this.reportId,
- state:-1,
- errorMessage:errorMessage || this.generation.errorMessage || '网络延迟'
- })
- },
- fetchGenerationStatus(showErrorToast = true){
- if(!this.reportId){
- this.stopPolling('报告编号缺失')
- return Promise.resolve()
- }
- const requestMeta = beginStatusRequest(this)
- if(!requestMeta) return Promise.resolve()
- return this.$api.get(`/core/report/generationStatus/${this.reportId}`, {}, false).then(({data:res})=>{
- if(!shouldApplyStatusResponse(this, requestMeta)) return
- if(res.code!==0){
- if(showErrorToast && !this.hasStatusErrorToastShown){
- this.$showToast(res.msg || '报告状态获取失败')
- this.hasStatusErrorToastShown = true
- }
- this.startPolling()
- return
- }
- this.reconcileGeneration({ ...(res.data || {}), reportId:this.reportId })
- }).catch(error => {
- if(!shouldApplyStatusResponse(this, requestMeta)) return
- const message = error && (error.message || error.msg) || '报告状态获取失败'
- if(showErrorToast && !this.hasStatusErrorToastShown){
- this.$showToast(message)
- this.hasStatusErrorToastShown = true
- }
- this.startPolling()
- }).finally(() => {
- finishStatusRequest(this, requestMeta)
- })
- },
- handleAction(){
- if(this.generation.state===-1){
- this.handleReCreate()
- return
- }
- uni.navigateBack()
- },
- handleReCreate(){
- this.$api.get(`/core/team/questionnaire/genReport/${this.info.teamQuestionnaireId}`).then(({data:res})=>{
- if(res.code!==0) return this.$showToast(res.msg)
- const nextReportId = extractReportId(res.data)
- if(!nextReportId) return this.$showToast('未获取到报告编号')
- this.$showToast('重新生成成功')
- uni.redirectTo({
- url:'/pagesHome/reportResult?reportId='+nextReportId+'&info='+encodeURIComponent(JSON.stringify(this.info))
- })
- })
- }
- }
- }
- </script>
- <style scoped lang="scss">
- .default_page{
- background: #F7F7F7;
- .box{
- width: 100%;
- background: #FFFFFF;
- border-radius: 36rpx 36rpx 0rpx 0rpx;
- padding: 54rpx 0 64rpx;
- &-loading{
- width: 340rpx;
- height: 340rpx;
- }
- &-p1{
- font-family: PingFang-SC, PingFang-SC;
- font-weight: bold;
- font-size: 32rpx;
- color: #002846;
- line-height: 40rpx;
- text-align: center;
- margin-top: 41rpx;
- }
- &-p2{
- font-family: PingFang-SC, PingFang-SC;
- font-weight: bold;
- font-size: 28rpx;
- color: #002846;
- line-height: 28rpx;
- text-align: center;
- margin-top: 23rpx;
- }
- &-p3{
- padding: 0 100rpx;
- font-family: PingFangSC, PingFang SC;
- font-weight: 400;
- font-size: 28rpx;
- color: #667E90;
- line-height: 42rpx;
- text-align: center;
- margin-top: 24rpx;
- }
- }
-
- .form{
- width: 100%;
- margin-top: 20rpx;
- &-item{
- padding: 28rpx 24rpx;
- background: #FFFFFF;
- box-shadow: inset 0rpx -1rpx 0rpx 0rpx #EFEFEF;
- &-left{
- width: 140rpx;
- font-family: PingFangSC, PingFang SC;
- font-weight: 400;
- font-size: 30rpx;
- color: #002846;
- line-height: 42rpx;
- }
- &-right{
- width: calc(100% - 140rpx);
- padding-left: 20rpx;
- box-sizing: border-box;
- font-family: PingFangSC, PingFang SC;
- font-weight: 400;
- font-size: 30rpx;
- color: #667E90;
- line-height: 32rpx;
- text-align: right;
- }
- }
- }
-
- .btn{
- width: calc(100% -100rpx);
- margin: 120rpx 50rpx 0;
- }
- }
- </style>
|