fillTeamInfo.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  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. import backgroundSurveyRules from '@/utils/backgroundSurvey.js'
  11. const {
  12. beginTeamSubmission,
  13. createTeamCreationState,
  14. createTeamPayloadSnapshot,
  15. createTeamSubmitPayload,
  16. finishTeamSubmission,
  17. rememberCreatedTeam,
  18. setTeamSubmissionStage
  19. } = teamBackgroundRules
  20. const { backgroundIntroUrl } = backgroundSurveyRules
  21. export default {
  22. components:{ CusTeamInfoFill },
  23. data(){
  24. return {
  25. title:'',
  26. type:'',
  27. next:'',
  28. questionnaireId:'',
  29. confirmText:'下一步',
  30. qtype:'',
  31. creationState:createTeamCreationState(),
  32. navigationTimer:null,
  33. navigationReject:null,
  34. pageUnloaded:false,
  35. resumeAfterSurveyPending:false
  36. }
  37. },
  38. onLoad(options) {
  39. this.pageUnloaded = false;
  40. this.title = options.title||'';
  41. this.type = options.type;
  42. this.qtype = options.qtype||'';
  43. this.questionnaireId = options.questionnaireId||'';
  44. this.confirmText = options.type?'确定':'下一步';
  45. this.next = options.next;
  46. if(this.next) this.confirmText = '下一步';
  47. },
  48. onShow() {
  49. if(!this.resumeAfterSurveyPending || this.pageUnloaded) return
  50. this.resumeAfterSurveyPending = false
  51. this.resumeAfterCoachSurvey()
  52. },
  53. onUnload() {
  54. this.pageUnloaded = true
  55. this.cancelPendingNavigation(new Error('页面已离开'))
  56. },
  57. methods:{
  58. async handleConfirm(team){
  59. if(!beginTeamSubmission(this.creationState)) return
  60. const payload = createTeamSubmitPayload(Object.assign({}, team, {
  61. questionnaireId:this.questionnaireId
  62. }))
  63. const payloadSnapshot = createTeamPayloadSnapshot(payload)
  64. try {
  65. let teamId = this.creationState.createdTeamId
  66. const resumeStage = this.creationState.stage === 'update'
  67. ? this.creationState.resumeStage
  68. : this.creationState.stage
  69. const resumeNavigation = resumeStage === 'navigate'
  70. if(!teamId){
  71. setTeamSubmissionStage(this.creationState, 'save')
  72. const { data:res } = await this.$api.post('/core/user/team',payload)
  73. if(res.code!==0){
  74. this.$showToast(res.msg || '团队保存失败,请重试')
  75. return
  76. }
  77. teamId = res.data && res.data.teamId
  78. if(!teamId){
  79. this.$showToast('团队保存未返回团队ID,请重试')
  80. return
  81. }
  82. rememberCreatedTeam(this.creationState, teamId)
  83. this.creationState.teamPayloadSnapshot = payloadSnapshot
  84. } else if(this.creationState.teamPayloadSnapshot !== payloadSnapshot) {
  85. this.creationState.resumeStage = resumeStage
  86. setTeamSubmissionStage(this.creationState, 'update')
  87. const response = await this.$api.put('/core/user/team', Object.assign({}, payload, {
  88. id:teamId
  89. }))
  90. const res = response.data
  91. if(res.code!==0) throw new Error(res.msg || '团队更新请求失败')
  92. this.creationState.teamPayloadSnapshot = payloadSnapshot
  93. setTeamSubmissionStage(this.creationState, resumeStage)
  94. this.creationState.resumeStage = ''
  95. } else if(this.creationState.stage === 'update') {
  96. setTeamSubmissionStage(this.creationState, resumeStage)
  97. this.creationState.resumeStage = ''
  98. }
  99. if(resumeNavigation) {
  100. setTeamSubmissionStage(this.creationState, 'navigate')
  101. await this.continueAfterTeamCreated(teamId)
  102. finishTeamSubmission(this.creationState, true)
  103. return
  104. }
  105. setTeamSubmissionStage(this.creationState, 'upload')
  106. const uploadResult = await this.$refs.teamRef.flushBackgroundFiles(teamId)
  107. if(uploadResult.failed > 0 || this.$refs.teamRef.hasUnresolvedBackgroundFiles()){
  108. await this.$showModal('仍有背景资料未上传成功,请重试后继续;团队已保存,无需再次创建')
  109. return
  110. }
  111. if(this.$refs.teamRef.hasDeferredPcUpload()){
  112. setTeamSubmissionStage(this.creationState, 'pcSession')
  113. await this.$refs.teamRef.waitForDeferredPcUpload(teamId)
  114. }
  115. if(this.next && this.creationState.backgroundSurveyStatus !== 'COMPLETED'){
  116. setTeamSubmissionStage(this.creationState, 'coachSurvey')
  117. this.openCoachBackgroundSurvey(teamId)
  118. return
  119. }
  120. if(this.next && !this.creationState.teamQuestionnaireId) {
  121. setTeamSubmissionStage(this.creationState, 'publish')
  122. const publishResult = await this.publishQuestionnaire(teamId)
  123. this.creationState.publishResult = publishResult
  124. this.creationState.teamQuestionnaireId = publishResult.data
  125. }
  126. setTeamSubmissionStage(this.creationState, 'navigate')
  127. await this.continueAfterTeamCreated(teamId)
  128. finishTeamSubmission(this.creationState, true)
  129. } catch(error) {
  130. this.showStageError(error)
  131. } finally {
  132. finishTeamSubmission(this.creationState)
  133. }
  134. },
  135. showStageError(error) {
  136. if(this.pageUnloaded) return
  137. const prefix = {
  138. save:'团队保存失败',
  139. update:'团队更新失败',
  140. upload:'背景资料处理失败',
  141. pcSession:'电脑上传流程失败',
  142. coachSurvey:'团队背景调研失败',
  143. publish:'问卷发布失败',
  144. navigate:'页面跳转失败'
  145. }[this.creationState.stage] || '操作失败'
  146. const message = error && (error.message || error.msg)
  147. this.$showToast(message ? `${prefix}:${message}` : `${prefix},请重试`)
  148. },
  149. openCoachBackgroundSurvey(teamId) {
  150. const surveyId = this.creationState.backgroundSurveyId || ''
  151. uni.navigateTo({
  152. url:`/pagesPublish/backgroundSurvey?mode=coach&teamId=${encodeURIComponent(teamId)}&surveyId=${encodeURIComponent(surveyId)}`,
  153. events:{
  154. backgroundSurveyReady:data=>{
  155. this.creationState.backgroundSurveyId = data.surveyId
  156. this.creationState.backgroundSurveyStatus = data.status
  157. },
  158. backgroundSurveyCompleted:data=>{
  159. this.creationState.backgroundSurveyId = data.surveyId
  160. this.creationState.backgroundSurveyStatus = data.status
  161. this.resumeAfterSurveyPending = data.status === 'COMPLETED'
  162. }
  163. },
  164. fail:error=>{
  165. this.showStageError(new Error(error && error.errMsg || '背景调研页面打开失败'))
  166. }
  167. })
  168. },
  169. async resumeAfterCoachSurvey() {
  170. if(this.creationState.backgroundSurveyStatus !== 'COMPLETED'
  171. || this.creationState.teamQuestionnaireId
  172. || !beginTeamSubmission(this.creationState)) return
  173. const teamId = this.creationState.createdTeamId
  174. try {
  175. setTeamSubmissionStage(this.creationState, 'publish')
  176. const publishResult = await this.publishQuestionnaire(teamId)
  177. this.creationState.publishResult = publishResult
  178. this.creationState.teamQuestionnaireId = publishResult.data
  179. setTeamSubmissionStage(this.creationState, 'navigate')
  180. await this.continueAfterTeamCreated(teamId)
  181. finishTeamSubmission(this.creationState, true)
  182. } catch(error) {
  183. this.showStageError(error)
  184. } finally {
  185. finishTeamSubmission(this.creationState)
  186. }
  187. },
  188. async publishQuestionnaire(teamId) {
  189. const response = await this.$api.post('/core/team/questionnaire/publish',{
  190. answerSetting:1,
  191. coachId:JSON.parse(uni.getStorageSync('userInfo')).id,
  192. startTime:new Date().Format('yyyy-MM-dd hh:mm:ss'),
  193. endTime:new Date(new Date().setDate(new Date().getDate()+30)).Format('yyyy-MM-dd hh:mm:ss'),
  194. questionnaireId:this.questionnaireId,
  195. backgroundSurveyId:this.creationState.backgroundSurveyId,
  196. teamId,
  197. type:1
  198. })
  199. const result = response.data
  200. if(result.code!==0) throw new Error(result.msg || '发布请求失败')
  201. return result
  202. },
  203. async continueAfterTeamCreated(teamId) {
  204. if(this.next){
  205. this.$showToast('保存成功,即将填写问卷')
  206. await this.runDelayedNavigation(({ success, fail }) => {
  207. uni.navigateTo({
  208. url:backgroundIntroUrl({
  209. teamQuestionnaireId:this.creationState.teamQuestionnaireId,
  210. teamId,
  211. type:this.type,
  212. title:this.title
  213. }),
  214. success,
  215. fail
  216. })
  217. })
  218. uni.removeStorageSync('newUser')
  219. return
  220. }
  221. this.$showToast('团队新增成功')
  222. const eventChannel = this.getOpenerEventChannel()
  223. if(eventChannel) eventChannel.emit('saveTeamInfo',{
  224. teamId,
  225. teamName:this.$refs.teamRef && this.$refs.teamRef.teamInfo
  226. ? this.$refs.teamRef.teamInfo.teamName
  227. : ''
  228. })
  229. await this.runDelayedNavigation(({ success, fail }) => {
  230. uni.navigateBack({ success, fail })
  231. })
  232. },
  233. runDelayedNavigation(invokeNavigation) {
  234. return new Promise((resolve, reject) => {
  235. if(this.pageUnloaded) {
  236. reject(new Error('页面已离开'))
  237. return
  238. }
  239. let settled = false
  240. const settle = (callback, value) => {
  241. if(settled) return
  242. settled = true
  243. this.navigationTimer = null
  244. this.navigationReject = null
  245. callback(value)
  246. }
  247. this.navigationReject = error => settle(reject, error)
  248. this.navigationTimer = setTimeout(() => {
  249. this.navigationTimer = null
  250. if(this.pageUnloaded) {
  251. settle(reject, new Error('页面已离开'))
  252. return
  253. }
  254. try {
  255. invokeNavigation({
  256. success: result => {
  257. if(this.pageUnloaded) settle(reject, new Error('页面已离开'))
  258. else settle(resolve, result)
  259. },
  260. fail: error => settle(reject, new Error(error && (error.errMsg || error.message) || '跳转失败'))
  261. })
  262. } catch(error) {
  263. settle(reject, error)
  264. }
  265. },1500)
  266. })
  267. },
  268. cancelPendingNavigation(error) {
  269. if(this.navigationTimer) clearTimeout(this.navigationTimer)
  270. this.navigationTimer = null
  271. const reject = this.navigationReject
  272. this.navigationReject = null
  273. if(reject) reject(error || new Error('跳转已取消'))
  274. }
  275. }
  276. }
  277. </script>
  278. <style scoped lang="scss">
  279. .default_page{
  280. box-sizing: border-box;
  281. }
  282. </style>