fillTeamInfo.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <template>
  2. <view class="default_page" :style="{'min-height':h+'px', 'padding-top':mt+'px'}">
  3. <cus-header title='填写所在团队信息'></cus-header>
  4. <cus-team-info-fill ref="teamRef" :submitting="creationState.submitting || creationState.completed" @handleConfirm="handleConfirm" :confirmText="confirmText" :qtype="qtype"></cus-team-info-fill>
  5. </view>
  6. </template>
  7. <script>
  8. import CusTeamInfoFill from '@/components/CusTeamInfoFill/index.vue'
  9. import teamBackgroundRules from '@/utils/teamBackgroundFile.js'
  10. const {
  11. beginTeamSubmission,
  12. createTeamCreationState,
  13. createTeamPayloadSnapshot,
  14. createTeamSubmitPayload,
  15. finishTeamSubmission,
  16. rememberCreatedTeam,
  17. setTeamSubmissionStage
  18. } = teamBackgroundRules
  19. export default {
  20. components:{ CusTeamInfoFill },
  21. data(){
  22. return {
  23. title:'',
  24. type:'',
  25. next:'',
  26. questionnaireId:'',
  27. confirmText:'下一步',
  28. qtype:'',
  29. creationState:createTeamCreationState(),
  30. navigationTimer:null,
  31. navigationReject:null,
  32. pageUnloaded:false
  33. }
  34. },
  35. onLoad(options) {
  36. this.pageUnloaded = false;
  37. this.title = options.title||'';
  38. this.type = options.type;
  39. this.qtype = options.qtype||'';
  40. this.questionnaireId = options.questionnaireId||'';
  41. this.confirmText = options.type?'确定':'下一步';
  42. this.next = options.next;
  43. if(this.next) this.confirmText = '下一步';
  44. },
  45. onUnload() {
  46. this.pageUnloaded = true
  47. this.cancelPendingNavigation(new Error('页面已离开'))
  48. },
  49. methods:{
  50. async handleConfirm(team){
  51. if(!beginTeamSubmission(this.creationState)) return
  52. const payload = createTeamSubmitPayload(Object.assign({}, team, {
  53. questionnaireId:this.questionnaireId
  54. }))
  55. const payloadSnapshot = createTeamPayloadSnapshot(payload)
  56. try {
  57. let teamId = this.creationState.createdTeamId
  58. const resumeStage = this.creationState.stage === 'update'
  59. ? this.creationState.resumeStage
  60. : this.creationState.stage
  61. const resumeNavigation = resumeStage === 'navigate'
  62. if(!teamId){
  63. setTeamSubmissionStage(this.creationState, 'save')
  64. const { data:res } = await this.$api.post('/core/user/team',payload)
  65. if(res.code!==0){
  66. this.$showToast(res.msg || '团队保存失败,请重试')
  67. return
  68. }
  69. teamId = res.data && res.data.teamId
  70. if(!teamId){
  71. this.$showToast('团队保存未返回团队ID,请重试')
  72. return
  73. }
  74. rememberCreatedTeam(this.creationState, teamId)
  75. this.creationState.teamPayloadSnapshot = payloadSnapshot
  76. } else if(this.creationState.teamPayloadSnapshot !== payloadSnapshot) {
  77. this.creationState.resumeStage = resumeStage
  78. setTeamSubmissionStage(this.creationState, 'update')
  79. const response = await this.$api.put('/core/user/team', Object.assign({}, payload, {
  80. id:teamId
  81. }))
  82. const res = response.data
  83. if(res.code!==0) throw new Error(res.msg || '团队更新请求失败')
  84. this.creationState.teamPayloadSnapshot = payloadSnapshot
  85. setTeamSubmissionStage(this.creationState, resumeStage)
  86. this.creationState.resumeStage = ''
  87. } else if(this.creationState.stage === 'update') {
  88. setTeamSubmissionStage(this.creationState, resumeStage)
  89. this.creationState.resumeStage = ''
  90. }
  91. if(resumeNavigation) {
  92. setTeamSubmissionStage(this.creationState, 'navigate')
  93. await this.continueAfterTeamCreated(teamId)
  94. finishTeamSubmission(this.creationState, true)
  95. return
  96. }
  97. setTeamSubmissionStage(this.creationState, 'upload')
  98. const uploadResult = await this.$refs.teamRef.flushBackgroundFiles(teamId)
  99. if(uploadResult.failed > 0 || this.$refs.teamRef.hasUnresolvedBackgroundFiles()){
  100. await this.$showModal('仍有背景资料未上传成功,请重试后继续;团队已保存,无需再次创建')
  101. return
  102. }
  103. if(this.$refs.teamRef.hasDeferredPcUpload()){
  104. setTeamSubmissionStage(this.creationState, 'pcSession')
  105. await this.$refs.teamRef.waitForDeferredPcUpload(teamId)
  106. }
  107. if(this.next && !this.creationState.teamQuestionnaireId) {
  108. setTeamSubmissionStage(this.creationState, 'publish')
  109. const publishResult = await this.publishQuestionnaire(teamId)
  110. this.creationState.publishResult = publishResult
  111. this.creationState.teamQuestionnaireId = publishResult.data
  112. }
  113. setTeamSubmissionStage(this.creationState, 'navigate')
  114. await this.continueAfterTeamCreated(teamId)
  115. finishTeamSubmission(this.creationState, true)
  116. } catch(error) {
  117. this.showStageError(error)
  118. } finally {
  119. finishTeamSubmission(this.creationState)
  120. }
  121. },
  122. showStageError(error) {
  123. if(this.pageUnloaded) return
  124. const prefix = {
  125. save:'团队保存失败',
  126. update:'团队更新失败',
  127. upload:'背景资料处理失败',
  128. pcSession:'电脑上传流程失败',
  129. publish:'问卷发布失败',
  130. navigate:'页面跳转失败'
  131. }[this.creationState.stage] || '操作失败'
  132. const message = error && (error.message || error.msg)
  133. this.$showToast(message ? `${prefix}:${message}` : `${prefix},请重试`)
  134. },
  135. async publishQuestionnaire(teamId) {
  136. const response = await this.$api.post('/core/team/questionnaire/publish',{
  137. answerSetting:1,
  138. coachId:JSON.parse(uni.getStorageSync('userInfo')).id,
  139. startTime:new Date().Format('yyyy-MM-dd hh:mm:ss'),
  140. endTime:new Date(new Date().setDate(new Date().getDate()+30)).Format('yyyy-MM-dd hh:mm:ss'),
  141. questionnaireId:this.questionnaireId,
  142. teamId,
  143. type:1
  144. })
  145. const result = response.data
  146. if(result.code!==0) throw new Error(result.msg || '发布请求失败')
  147. return result
  148. },
  149. async continueAfterTeamCreated(teamId) {
  150. if(this.next){
  151. this.$showToast('保存成功,即将填写问卷')
  152. await this.runDelayedNavigation(({ success, fail }) => {
  153. uni.navigateTo({
  154. url:`/pagesPublish/questionnaireFill?teamQuestionnaireId=${this.creationState.teamQuestionnaireId}&teamId=${teamId}&type=${this.type}&title=${this.title}`,
  155. success,
  156. fail
  157. })
  158. })
  159. uni.removeStorageSync('newUser')
  160. return
  161. }
  162. this.$showToast('团队新增成功')
  163. await this.runDelayedNavigation(({ success, fail }) => {
  164. uni.navigateBack({ success, fail })
  165. })
  166. const eventChannel = this.getOpenerEventChannel()
  167. if(eventChannel) eventChannel.emit('saveTeamInfo')
  168. },
  169. runDelayedNavigation(invokeNavigation) {
  170. return new Promise((resolve, reject) => {
  171. if(this.pageUnloaded) {
  172. reject(new Error('页面已离开'))
  173. return
  174. }
  175. let settled = false
  176. const settle = (callback, value) => {
  177. if(settled) return
  178. settled = true
  179. this.navigationTimer = null
  180. this.navigationReject = null
  181. callback(value)
  182. }
  183. this.navigationReject = error => settle(reject, error)
  184. this.navigationTimer = setTimeout(() => {
  185. this.navigationTimer = null
  186. if(this.pageUnloaded) {
  187. settle(reject, new Error('页面已离开'))
  188. return
  189. }
  190. try {
  191. invokeNavigation({
  192. success: result => {
  193. if(this.pageUnloaded) settle(reject, new Error('页面已离开'))
  194. else settle(resolve, result)
  195. },
  196. fail: error => settle(reject, new Error(error && (error.errMsg || error.message) || '跳转失败'))
  197. })
  198. } catch(error) {
  199. settle(reject, error)
  200. }
  201. },1500)
  202. })
  203. },
  204. cancelPendingNavigation(error) {
  205. if(this.navigationTimer) clearTimeout(this.navigationTimer)
  206. this.navigationTimer = null
  207. const reject = this.navigationReject
  208. this.navigationReject = null
  209. if(reject) reject(error || new Error('跳转已取消'))
  210. }
  211. }
  212. }
  213. </script>
  214. <style scoped lang="scss">
  215. .default_page{
  216. box-sizing: border-box;
  217. }
  218. </style>