工作任务代码迁移
This commit is contained in:
		
							
								
								
									
										222
									
								
								src/project/pingchang/AppWorkTask/AppWorkTask.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								src/project/pingchang/AppWorkTask/AppWorkTask.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,222 @@ | ||||
| <template> | ||||
|   <div class="work-task"> | ||||
|     <ai-top-fixed> | ||||
|       <u-tabs :list="tabs" height="88" bar-width="136" :current="index" @change="change"></u-tabs> | ||||
|     </ai-top-fixed> | ||||
|     <div class="list" v-if="list.length"> | ||||
|       <div class="card" v-for="(item,index) in list" :key="index" @click="handleClick(item)"> | ||||
|         <header>{{item.taskTitle}}</header> | ||||
|         <u-gap height="24"></u-gap> | ||||
|         <u-row> | ||||
|           <text>任务类型:</text> | ||||
|           <text>{{$dict.getLabel("workTaskType",item.type)}}</text> | ||||
|         </u-row> | ||||
|         <u-gap height="8"></u-gap> | ||||
|         <u-row> | ||||
|           <text>截止时间:</text> | ||||
|           <text>{{item.lastTime}}</text> | ||||
|         </u-row> | ||||
|         <u-gap height="8"></u-gap> | ||||
|         <u-row> | ||||
|           <text>剩余时间:</text> | ||||
|           <text :style="{color:item.isOverTime==1?'#FF4466':'#1365DD'}">{{item.overTimeStatus}}</text> | ||||
|         </u-row> | ||||
|         <u-gap height="24"></u-gap> | ||||
|         <span>已完成{{item.percent}}%</span> | ||||
|         <u-gap height="16"></u-gap> | ||||
|         <div class="progress"> | ||||
|           <div class="active" :style="{width: item.percent + '%'}"></div> | ||||
|         </div> | ||||
|         <img :src="$cdn + tag(item.status)" alt=""> | ||||
|       </div> | ||||
|     </div> | ||||
|     <AiEmpty v-else></AiEmpty> | ||||
|     <u-loadmore :status="status" v-if="list.length"/> | ||||
|     <ai-add @add="add"></ai-add> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   // import AiTopFixed from "../../components/AiTopFixed"; | ||||
|   // import AiAdd from "../../components/AiAdd"; | ||||
|   // import AiEmpty from "../../components/AiEmpty/AiEmpty"; | ||||
|  | ||||
|   export default { | ||||
|     appName: '工作任务', | ||||
|     // components: {AiTopFixed, AiAdd, AiEmpty}, | ||||
|     data() { | ||||
|       return { | ||||
|         index: 0, | ||||
|         current: 1, | ||||
|         list: [], | ||||
|         status: "加载更多", | ||||
|         userSelect: false, | ||||
|       } | ||||
|     }, | ||||
|     computed: { | ||||
|       tabs() { | ||||
|         return [ | ||||
|           {name: "我执行的"}, | ||||
|           {name: "我完成的"}, | ||||
|           {name: "我发起的"}, | ||||
|           {name: "我督办的"}, | ||||
|           {name: "抄送我的"}, | ||||
|         ] | ||||
|       }, | ||||
|     }, | ||||
|  | ||||
|     onLoad() { | ||||
|       this.$dict.load("workTaskType") | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       tag(status) { | ||||
|         return { | ||||
|           "0": "common/1jxz.png", | ||||
|           "1": "common/1ywc.png", | ||||
|           "2": "common/1ygb.png" | ||||
|         }[status] | ||||
|       }, | ||||
|       handleClick(item) { | ||||
|         uni.navigateTo({ | ||||
|           url: "/pages/workTask/components/detail?id=" + item.id + "&taskCode=" + item.taskCode + "&isMine=" + this.index | ||||
|         }) | ||||
|       }, | ||||
|       add() { | ||||
|         uni.navigateTo({ | ||||
|           url: "/pages/workTask/components/create" | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       change(e) { | ||||
|         this.index = e | ||||
|         this.current = 1 | ||||
|         this.getList() | ||||
|  | ||||
|       }, | ||||
|  | ||||
|       map(index) { | ||||
|         return { | ||||
|           "0": { | ||||
|             taskRole: 1, | ||||
|             status: 0, | ||||
|           }, | ||||
|           "1": { | ||||
|             taskRole: 1, | ||||
|             status: 1, | ||||
|           }, | ||||
|           "2": { | ||||
|             taskRole: 0, | ||||
|           }, | ||||
|           "3": { | ||||
|             taskRole: 2, | ||||
|           }, | ||||
|           "4": { | ||||
|             taskRole: 3, | ||||
|           } | ||||
|         }[index] | ||||
|       }, | ||||
|  | ||||
|       getList() { | ||||
|         this.$http.post("/app/appworktaskinfo/list", null, { | ||||
|           params: { | ||||
|             ...this.map(this.index), | ||||
|             size: 10, | ||||
|             current: this.current | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res && res.data) { | ||||
|             if (this.current > 1 && this.current > res.data.pages) { | ||||
|               this.status = "已经到底啦" | ||||
|             } | ||||
|             this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     onReachBottom() { | ||||
|       this.current = this.current + 1; | ||||
|       this.getList() | ||||
|     }, | ||||
|  | ||||
|     onShow() { | ||||
|       uni.pageScrollTo({ | ||||
|         duration: 0, | ||||
|         scrollTop: 0 | ||||
|       }) | ||||
|       this.current = 1 | ||||
|       this.getList() | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .work-task { | ||||
|     min-height: 100%; | ||||
|     background-color: #F5F5F5; | ||||
|     padding-bottom: 32px; | ||||
|  | ||||
|     ::v-deep .content { | ||||
|       padding: 0; | ||||
|     } | ||||
|  | ||||
|     .list { | ||||
|       box-sizing: border-box; | ||||
|       padding: 32px 32px 0 32px; | ||||
|  | ||||
|       .card { | ||||
|         background: #FFFFFF; | ||||
|         border-radius: 8px; | ||||
|         box-sizing: border-box; | ||||
|         padding: 32px; | ||||
|         position: relative; | ||||
|         margin-bottom: 32px; | ||||
|  | ||||
|         & > header { | ||||
|           font-size: 32px; | ||||
|           font-weight: 600; | ||||
|           color: #333333; | ||||
|         } | ||||
|  | ||||
|         & > .u-row { | ||||
|           text { | ||||
|             font-size: 30px; | ||||
|             color: #999999; | ||||
|             line-height: 42px; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         & > span { | ||||
|           font-size: 26px; | ||||
|           color: #649EFD; | ||||
|         } | ||||
|  | ||||
|         .progress { | ||||
|           width: 100%; | ||||
|           height: 4px; | ||||
|           background: #F0F1F2; | ||||
|           border-radius: 2px; | ||||
|           position: relative; | ||||
|  | ||||
|           .active { | ||||
|             position: absolute; | ||||
|             left: 0; | ||||
|             top: 0; | ||||
|             height: 4px; | ||||
|             background: #639EFD; | ||||
|             border-radius: 2px; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         & > img { | ||||
|           width: 112px; | ||||
|           height: 112px; | ||||
|           position: absolute; | ||||
|           top: 0; | ||||
|           right: 0; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										325
									
								
								src/project/pingchang/AppWorkTask/components/create.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										325
									
								
								src/project/pingchang/AppWorkTask/components/create.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,325 @@ | ||||
| <template> | ||||
|   <div class="create-sub-task"> | ||||
|     <template v-if="!userSelect"> | ||||
|       <div class="card"> | ||||
|         <u-row justify="between"> | ||||
|           <div class="left"> | ||||
|             <em>*</em>任务类型 | ||||
|           </div> | ||||
|           <picker @change="change" :value="form.type" range-key="dictName" :range="$dict.getDict('workTaskType')"> | ||||
|             <u-row> | ||||
|               <div v-if="form.type!=null" class="value">{{$dict.getDict('workTaskType')[form.type]["dictName"]}}</div> | ||||
|               <div v-else class="placeholder">请选择</div> | ||||
|               <div class="arrow"></div> | ||||
|             </u-row> | ||||
|           </picker> | ||||
|         </u-row> | ||||
|       </div> | ||||
|       <div class="card"> | ||||
|         <u-row justify="between"> | ||||
|           <div class="left"> | ||||
|             <em>*</em>任务标题 | ||||
|           </div> | ||||
|         </u-row> | ||||
|         <u-gap height="16"></u-gap> | ||||
|         <input maxlength="30" v-model.trim="form.taskTitle" placeholder="限30字"> | ||||
|         <u-gap height="32"></u-gap> | ||||
|       </div> | ||||
|       <div class="card"> | ||||
|         <u-row justify="between"> | ||||
|           <div class="left"> | ||||
|             <em>*</em>任务说明 | ||||
|           </div> | ||||
|         </u-row> | ||||
|         <u-gap height="16"></u-gap> | ||||
|         <textarea maxlength="1000" v-model.trim="form.taskDescription" placeholder="请输入任务内容,限1000字"/> | ||||
|       </div> | ||||
|       <div class="card"> | ||||
|         <u-row justify="between"> | ||||
|           <div class="left"> | ||||
|             <em>*</em>截止日期 | ||||
|           </div> | ||||
|           <picker @change="dateChange" mode="date" :value="form.lastTime" :start="startDate" :end="endDate"> | ||||
|             <u-row> | ||||
|               <div v-if="form.lastTime!=null" class="value">{{form.lastTime}}</div> | ||||
|               <div v-else class="placeholder">请选择</div> | ||||
|               <div class="arrow" v-if="form.lastTime==null"></div> | ||||
|               <div class="clear" v-else @click.stop="form.lastTime = null"></div> | ||||
|             </u-row> | ||||
|           </picker> | ||||
|         </u-row> | ||||
|       </div> | ||||
|       <div class="card" style="padding: 13px 17px;margin-bottom: 0"> | ||||
|         <u-row justify="between"> | ||||
|           <div class="left" style="line-height: 22px;"> | ||||
|             <em>*</em>执行人 | ||||
|           </div> | ||||
|           <u-row @click="handleSelectUser(0)" style="justify-content: flex-end"> | ||||
|             <div v-if="form.userInfoList.length" class="value"> | ||||
|               已选择<em>{{form.userInfoList.slice(0,2).map(e=>e.name).join("、")}}</em>等 | ||||
|               <em>{{form.userInfoList.length}}</em>人 | ||||
|             </div> | ||||
|             <div v-else class="placeholder">请选择</div> | ||||
|             <div class="arrow"></div> | ||||
|           </u-row> | ||||
|         </u-row> | ||||
|       </div> | ||||
|       <div class="card border" style="padding: 13px 17px;margin-bottom: 0"> | ||||
|         <u-row justify="between"> | ||||
|           <div class="left" style="line-height: 22px;">督办人</div> | ||||
|           <u-row @click="handleSelectUser(1)" style="justify-content: flex-end"> | ||||
|             <div v-if="form.checkUserList.length" class="value"> | ||||
|               已选择<em>{{form.checkUserList.slice(0,2).map(e=>e.name).join("、")}}</em>等 | ||||
|               <em>{{form.checkUserList.length}}</em>人 | ||||
|             </div> | ||||
|             <div v-else class="placeholder">请选择</div> | ||||
|             <div class="arrow"></div> | ||||
|           </u-row> | ||||
|         </u-row> | ||||
|       </div> | ||||
|       <div class="card" style="padding: 13px 17px"> | ||||
|         <u-row justify="between"> | ||||
|           <div class="left" style="line-height: 22px;">抄送人</div> | ||||
|           <u-row @click="handleSelectUser(2)" style="justify-content: flex-end"> | ||||
|             <div v-if="form.sendUserList.length" class="value"> | ||||
|               已选择<em>{{form.sendUserList.slice(0,2).map(e=>e.name).join("、")}}</em>等 | ||||
|               <em>{{form.sendUserList.length}}</em>人 | ||||
|             </div> | ||||
|             <div v-else class="placeholder">请选择</div> | ||||
|             <div class="arrow"></div> | ||||
|           </u-row> | ||||
|         </u-row> | ||||
|       </div> | ||||
|       <div class="card" style="padding: 12px 17px;"> | ||||
|         <u-row justify="between"> | ||||
|           <div class="left"> 发送任务通知</div> | ||||
|           <switch :checked="!!form.isNofity" @change="(e)=>form.isNofity=Number(e.detail.value)"/> | ||||
|         </u-row> | ||||
|       </div> | ||||
|       <div class="footer" @click="handleCreate">创建</div> | ||||
|     </template> | ||||
|  | ||||
|     <AiSelectEnterprise :visible.sync="userSelect" :value="selectList" v-if="userSelect" | ||||
|                         @change="userChange"></AiSelectEnterprise> | ||||
|     <ai-back ref="aiBack" v-if="!userSelect"/> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import AiBack from "../../../components/AiBack"; | ||||
|   import AiSelectEnterprise from "../../../components/AiSelectEnterprise/AiSelectEnterprise"; | ||||
|  | ||||
|   export default { | ||||
|     name: "create", | ||||
|     components: {AiBack, AiSelectEnterprise}, | ||||
|     data() { | ||||
|       return { | ||||
|         index: null, | ||||
|         userSelect: false, | ||||
|         selectList: [], | ||||
|         form: { | ||||
|           parentTaskCode: null, | ||||
|           type: null, | ||||
|           taskTitle: "", | ||||
|           taskDescription: "", | ||||
|           lastTime: null, | ||||
|           userInfoList: [], | ||||
|           checkUserList: [], | ||||
|           sendUserList: [], | ||||
|           isNofity: 0 | ||||
|         }, | ||||
|         currentClick: null, | ||||
|       } | ||||
|     }, | ||||
|     onLoad(opt) { | ||||
|       if (opt.taskCode) { | ||||
|         this.form.parentTaskCode = opt.taskCode | ||||
|       } | ||||
|       this.$dict.load("workTaskType") | ||||
|     }, | ||||
|     computed: { | ||||
|       startDate() { | ||||
|         return this.getDate('start'); | ||||
|       }, | ||||
|       endDate() { | ||||
|         return this.getDate('end'); | ||||
|       } | ||||
|     }, | ||||
|     methods: { | ||||
|       handleCreate() { | ||||
|         if (this.form.type==null) return this.$u.toast("请选择任务类型") | ||||
|         if (!this.form.taskTitle) return this.$u.toast("请输入任务标题") | ||||
|         if (!this.form.taskDescription) return this.$u.toast("请输入任务说明") | ||||
|         if (this.form.lastTime==null) return this.$u.toast("请选择截止日期") | ||||
|         if (!this.form.userInfoList.length) return this.$u.toast("请选择执行人") | ||||
|  | ||||
|         this.$http.post("/app/appworktaskinfo/addOrUpdate", { | ||||
|           ...this.form, | ||||
|           lastTime:this.form.lastTime + " 23:59:59" | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.$u.toast("创建成功") | ||||
|             this.$refs["aiBack"].back() | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       handleSelectUser(status) { | ||||
|         this.currentClick = status | ||||
|         if (this.currentClick == 0 && this.form.userInfoList.length) { | ||||
|           this.selectList = this.form.userInfoList | ||||
|         } else if (this.currentClick == 1 && this.form.checkUserList.length) { | ||||
|           this.selectList = this.form.checkUserList | ||||
|         } else if (this.currentClick == 2 && this.form.sendUserList.length) { | ||||
|           this.selectList = this.form.sendUserList | ||||
|         } | ||||
|         this.userSelect = true | ||||
|       }, | ||||
|       dateChange(e) { | ||||
|         let date = this.getDate({format: true}); | ||||
|         if (new Date(date).getTime() > new Date(e.target.value).getTime()) { | ||||
|           this.form.lastTime = null | ||||
|           return this.$u.toast("截止时间不能小于当前时间") | ||||
|         } | ||||
|         this.form.lastTime = e.target.value | ||||
|       }, | ||||
|       getDate(type) { | ||||
|         const date = new Date(); | ||||
|         let year = date.getFullYear(); | ||||
|         let month = date.getMonth() + 1; | ||||
|         let day = date.getDate(); | ||||
|  | ||||
|         if (type === 'start') { | ||||
|           year = year - 60; | ||||
|         } else if (type === 'end') { | ||||
|           year = year + 2; | ||||
|         } | ||||
|         month = month > 9 ? month : '0' + month; | ||||
|         day = day > 9 ? day : '0' + day; | ||||
|         return `${year}-${month}-${day}`; | ||||
|       }, | ||||
|       change(e) { | ||||
|         this.form.type = e.detail.value | ||||
|       }, | ||||
|       userChange(e) { | ||||
|         if (this.currentClick == 0) { | ||||
|           this.form.userInfoList = e | ||||
|         } else if (this.currentClick == 1) { | ||||
|           this.form.checkUserList = e | ||||
|         } else if (this.currentClick == 2) { | ||||
|           this.form.sendUserList = e | ||||
|         } | ||||
|         this.selectList = [] | ||||
|       } | ||||
|     }, | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .create-sub-task { | ||||
|     min-height: 100%; | ||||
|     background-color: #F5F5F5; | ||||
|     box-sizing: border-box; | ||||
|     padding: 16px 0 140px 0; | ||||
|  | ||||
|     .card { | ||||
|       background-color: #FFFFFF; | ||||
|       box-sizing: border-box; | ||||
|       padding: 32px 34px; | ||||
|       margin-bottom: 16px; | ||||
|  | ||||
|       .left { | ||||
|         font-size: 32px; | ||||
|         color: #333333; | ||||
|         font-weight: 400; | ||||
|         line-height: 48px; | ||||
|  | ||||
|         & > em { | ||||
|           font-style: normal; | ||||
|           font-size: 32px; | ||||
|           color: #FF4466; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .value { | ||||
|         font-size: 32px; | ||||
|         color: #333333; | ||||
|  | ||||
|         & > em { | ||||
|           font-style: normal; | ||||
|           font-size: 28px; | ||||
|           color: #1365DD; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .placeholder { | ||||
|         font-size: 28px; | ||||
|         color: #999999; | ||||
|       } | ||||
|  | ||||
|       .arrow { | ||||
|         width: 16px; | ||||
|         height: 16px; | ||||
|         border-top: 5px solid #CCCCCC; | ||||
|         border-right: 5px solid #CCCCCC; | ||||
|         transform: rotate(45deg); | ||||
|         margin-left: 8px; | ||||
|       } | ||||
|  | ||||
|       .clear { | ||||
|         width: 32px; | ||||
|         height: 32px; | ||||
|         border-radius: 50%; | ||||
|         background-color: #CCCCCC; | ||||
|         margin-left: 8px; | ||||
|         position: relative; | ||||
|  | ||||
|         &:before { | ||||
|           content: ""; | ||||
|           width: 4px; | ||||
|           height: 24px; | ||||
|           position: absolute; | ||||
|           left: 50%; | ||||
|           top: 50%; | ||||
|           transform: translate(-50%, -50%) rotate(-45deg); | ||||
|           background-color: #FFFFFF; | ||||
|           border-radius: 4px; | ||||
|         } | ||||
|  | ||||
|         &:after { | ||||
|           content: ""; | ||||
|           width: 4px; | ||||
|           height: 24px; | ||||
|           position: absolute; | ||||
|           left: 50%; | ||||
|           top: 50%; | ||||
|           transform: translate(-50%, -50%) rotate(45deg); | ||||
|           background-color: #FFFFFF; | ||||
|           border-radius: 4px; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       textarea { | ||||
|         width: 100%; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .border { | ||||
|       border-top: 1px solid rgba(216, 221, 230, 0.5); | ||||
|       border-bottom: 1px solid rgba(216, 221, 230, 0.5); | ||||
|     } | ||||
|  | ||||
|     .footer { | ||||
|       height: 112px; | ||||
|       width: 100%; | ||||
|       position: fixed; | ||||
|       left: 0; | ||||
|       bottom: 0; | ||||
|       background: #1365DD; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|       font-size: 36px; | ||||
|       color: #FFFFFF; | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										444
									
								
								src/project/pingchang/AppWorkTask/components/detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										444
									
								
								src/project/pingchang/AppWorkTask/components/detail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,444 @@ | ||||
| <template> | ||||
|   <div class="detail"> | ||||
|     <ai-top-fixed> | ||||
|       <u-tabs :list="tabs" height="96" :is-scroll="false" item-width="33.33%" bar-width="250" :current="index" | ||||
|               @change="change"></u-tabs> | ||||
|     </ai-top-fixed> | ||||
|     <template v-if="index==0"> | ||||
|       <div class="card"> | ||||
|         <header>{{detail.taskTitle}}</header> | ||||
|         <u-gap height="16"></u-gap> | ||||
|         <u-row> | ||||
|           <span>任务类型:</span> | ||||
|           <span>{{$dict.getLabel("workTaskType",detail.type)}}</span> | ||||
|         </u-row> | ||||
|         <u-gap height="8"></u-gap> | ||||
|         <u-row> | ||||
|           <span>开始时间:</span> | ||||
|           <span>{{detail.createTime}}</span> | ||||
|         </u-row> | ||||
|         <u-gap height="8"></u-gap> | ||||
|         <u-row> | ||||
|           <span>截止时间:</span> | ||||
|           <span style="color:#1365DD">{{detail.lastTime}}</span> | ||||
|         </u-row> | ||||
|         <u-gap height="8"></u-gap> | ||||
|         <u-row> | ||||
|           <span>剩余时间:</span> | ||||
|           <span style="color:#1365DD">{{detail.overTimeStatus}}</span> | ||||
|         </u-row> | ||||
|         <u-gap height="8"></u-gap> | ||||
|         <u-row> | ||||
|           <span>任务状态:</span> | ||||
|           <span>{{$dict.getLabel("workTaskDoStatus",detail.status)}}</span> | ||||
|         </u-row> | ||||
|         <u-gap height="8"></u-gap> | ||||
|         <u-row> | ||||
|           <span>执行说明:</span> | ||||
|           <span>{{detail.doDescription}}</span> | ||||
|         </u-row> | ||||
|         <u-gap height="16"></u-gap> | ||||
|       </div> | ||||
|       <div class="card" style="padding-top: 0"> | ||||
|         <div class="label">任务说明</div> | ||||
|         <u-read-more close-text="展开" color="#999999" show-height="300"> | ||||
|           <span>{{detail.taskDescription}}</span> | ||||
|         </u-read-more> | ||||
|       </div> | ||||
|       <div class="card" style="padding-top: 0" v-if="detail.fileList && detail.fileList.length"> | ||||
|         <div class="label">相关附件</div> | ||||
|         <div class="file" v-for="(item,index) in detail.fileList" :key="index" @click="preFile(item)"> | ||||
|           <u-row justify="between"> | ||||
|             <label class="left"> | ||||
|               <img :src="$cdn + 'common/appendix.png'" alt=""> | ||||
|               <span>{{item.name}}.{{item.postfix}}</span> | ||||
|             </label> | ||||
|             <span>{{(item.size/1024).toFixed(2)}}KB</span> | ||||
|           </u-row> | ||||
|         </div> | ||||
|       </div> | ||||
|     </template> | ||||
|  | ||||
|     <template v-if="index==1"> | ||||
|       <template v-if="['0','1'].includes(isMine)"> | ||||
|         <div class="card"> | ||||
|           <div class="label">我的进度</div> | ||||
|           <text>已完成{{detail.myUserInfo.percent}}%</text> | ||||
|           <div class="progress"> | ||||
|             <div class="pro-active" :style="{width:detail.myUserInfo.percent + '%'}"></div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="card" v-if="detail.processList.length"> | ||||
|           <u-collapse> | ||||
|             <u-collapse-item :title="item.createDate && item.createDate.split(' ')[0]" v-for="(item, index) in detail.processList" :key="index"> | ||||
|               <template slot="info"> | ||||
|                 完成到<em>{{item.percent}}%</em> | ||||
|               </template> | ||||
|               {{item.remarks}} | ||||
|             </u-collapse-item> | ||||
|           </u-collapse> | ||||
|         </div> | ||||
|       </template> | ||||
|       <template v-else> | ||||
|         <div class="card" v-for="(item,index) in detail.userInfoList" :key="index"> | ||||
|           <div class="label">{{item.userName}}</div> | ||||
|           <text>已完成{{item.percent}}%</text> | ||||
|           <div class="progress"> | ||||
|             <div class="pro-active" :style="{width:item.percent + '%'}"></div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </template> | ||||
|     </template> | ||||
|  | ||||
|     <template v-if="index==2"> | ||||
|       <div class="card" v-if="list.length"> | ||||
|         <u-row justify="between" v-for="(item,index) in list" :key="index" class="item" @click="subDetail(item)"> | ||||
|           <label class="title">{{item.taskTitle}}</label> | ||||
|           <label class="right">{{item.percent}}% | ||||
|             <div class="arrow"></div> | ||||
|           </label> | ||||
|         </u-row> | ||||
|       </div> | ||||
|       <AiEmpty v-else></AiEmpty> | ||||
|     </template> | ||||
|  | ||||
|     <ai-back></ai-back> | ||||
|     <div class="footer" v-if="index==1 && detail.myUserInfo.taskRole == 1 &&  detail.myUserInfo.doStatus==0" @click="handleClick">去完成</div> | ||||
|     <div class="footer" v-if="index==2" @click="createSubTask">创建子任务</div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import AiTopFixed from "../../../components/AiTopFixed"; | ||||
|   import AiBack from "../../../components/AiBack"; | ||||
|   import AiEmpty from "../../../components/AiEmpty/AiEmpty"; | ||||
|   import {mapActions} from "vuex"; | ||||
|  | ||||
|   export default { | ||||
|     name: "detail", | ||||
|     components: {AiTopFixed, AiBack,AiEmpty}, | ||||
|     data() { | ||||
|       return { | ||||
|         current: 1, | ||||
|         index: 0, | ||||
|         id: null, | ||||
|         taskCode: null, | ||||
|         isMine: null, | ||||
|         detail: {}, | ||||
|         list: [], | ||||
|       } | ||||
|     }, | ||||
|     onLoad(opt) { | ||||
|       this.id = opt.id | ||||
|       this.taskCode = opt.taskCode | ||||
|       this.isMine = opt.isMine | ||||
|       this.$dict.load("workTaskType", "workTaskDoStatus") | ||||
|     }, | ||||
|     computed: { | ||||
|       tabs() { | ||||
|         return [ | ||||
|           {name: "信息"}, | ||||
|           {name: "进度"}, | ||||
|           {name: "子任务"}, | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|     methods: { | ||||
|       ...mapActions(['previewFile', 'injectJWeixin']), | ||||
|       preFile(e) { | ||||
|         if([".jpg",".png",".gif"].includes(e.postfix.toLowerCase())){ | ||||
|           uni.previewImage({ | ||||
|             current: e.url, | ||||
|             urls: [e.url] | ||||
|           }) | ||||
|         }else { | ||||
|           this.previewFile({ ...e}) | ||||
|         } | ||||
|       }, | ||||
|       getDetail() { | ||||
|         this.$http.post("/app/appworktaskinfo/queryDetailById", null, { | ||||
|           params: { | ||||
|             id: this.id | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res && res.data) { | ||||
|             this.detail = res.data | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       getList(){ | ||||
|         this.$http.post("/app/appworktaskinfo/list", null, { | ||||
|           params: { | ||||
|             parentTaskCode: this.detail.taskCode, | ||||
|             size: 999, | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res && res.data) { | ||||
|             this.list = res.data.records | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       createSubTask() { | ||||
|         uni.navigateTo({ | ||||
|           url: "/pages/workTask/components/create?taskCode=" + this.taskCode | ||||
|         }) | ||||
|       }, | ||||
|       subDetail({id}) { | ||||
|         uni.navigateTo({ | ||||
|           url: "/pages/workTask/components/subDetail?id=" + id | ||||
|         }) | ||||
|       }, | ||||
|       handleClick() { | ||||
|         uni.navigateTo({ | ||||
|           url: "/pages/workTask/components/finish?taskCode=" + this.detail.taskCode + "&percent=" + this.detail.myUserInfo.percent | ||||
|         }) | ||||
|       }, | ||||
|       change(e) { | ||||
|         this.index = e | ||||
|         if (e == 2) { | ||||
|           this.getList() | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     onShow(){ | ||||
|       this.getDetail() | ||||
|       this.getList() | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .detail { | ||||
|     min-height: 100%; | ||||
|     background-color: #F5F5F5; | ||||
|     padding-bottom: 140px; | ||||
|  | ||||
|     ::v-deep .content { | ||||
|       padding: 0; | ||||
|     } | ||||
|  | ||||
|     .card { | ||||
|       background-color: #FFFFFF; | ||||
|       margin-bottom: 8px; | ||||
|       box-sizing: border-box; | ||||
|       padding: 16px 32px; | ||||
|  | ||||
|       header { | ||||
|         font-size: 40px; | ||||
|         font-weight: 600; | ||||
|         color: #333333; | ||||
|         line-height: 64px; | ||||
|         letter-spacing: 1px; | ||||
|       } | ||||
|  | ||||
|       .u-row { | ||||
|         & > div { | ||||
|           background-color: #2266FF; | ||||
|           border-radius: 50%; | ||||
|           text-align: center; | ||||
|           font-size: 22px; | ||||
|           font-weight: bold; | ||||
|           color: #FFFFFF; | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           justify-content: center; | ||||
|         } | ||||
|  | ||||
|         & > span:first-child { | ||||
|           font-size: 30px; | ||||
|           color: #999999;; | ||||
|           line-height: 48px; | ||||
|         } | ||||
|  | ||||
|         & > span:last-child { | ||||
|           font-size: 30px; | ||||
|           color: #343D65; | ||||
|           margin-left: 16px; | ||||
|           line-height: 48px; | ||||
|         } | ||||
|  | ||||
|         .title { | ||||
|           width: 490px; | ||||
|           height: 112px; | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           font-size: 32px; | ||||
|           color: #333333; | ||||
|           overflow: hidden; | ||||
|           text-overflow: ellipsis; | ||||
|           white-space: nowrap; | ||||
|         } | ||||
|  | ||||
|         .right { | ||||
|           font-size: 28px; | ||||
|           color: #1365DD; | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|  | ||||
|           .arrow { | ||||
|             width: 16px; | ||||
|             height: 16px; | ||||
|             border-top: 3px solid #CCCCCC; | ||||
|             border-right: 3px solid #CCCCCC; | ||||
|             transform: rotate(45deg); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .item { | ||||
|         position: relative; | ||||
|  | ||||
|         &:after { | ||||
|           width: 100%; | ||||
|           height: 1px; | ||||
|           background-color: rgba(216, 221, 230, 0.5); | ||||
|           content: ""; | ||||
|           position: absolute; | ||||
|           left: 0; | ||||
|           bottom: 0; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       & > span { | ||||
|         font-size: 32px; | ||||
|         color: #333333; | ||||
|         line-height: 48px; | ||||
|         letter-spacing: 1px; | ||||
|         display: inline-block; | ||||
|       } | ||||
|  | ||||
|       .label { | ||||
|         height: 80px; | ||||
|         font-size: 32px; | ||||
|         color: #333333; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         margin-bottom: 16px; | ||||
|  | ||||
|         & > em { | ||||
|           font-style: normal; | ||||
|           font-size: 32px; | ||||
|           color: #1365DD; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .file { | ||||
|         height: 128px; | ||||
|         background: #FFFFFF; | ||||
|         border-radius: 8px; | ||||
|         border: 1px solid #CCCCCC; | ||||
|         box-sizing: border-box; | ||||
|         padding: 0 16px; | ||||
|         margin-bottom: 32px; | ||||
|  | ||||
|         & > .u-row { | ||||
|           height: 100%; | ||||
|  | ||||
|           .left { | ||||
|             width: 476px; | ||||
|             display: flex; | ||||
|             align-items: center; | ||||
|  | ||||
|             & > img { | ||||
|               flex-shrink: 0; | ||||
|               width: 96px; | ||||
|               height: 96px; | ||||
|             } | ||||
|  | ||||
|             & > span { | ||||
|               font-size: 32px; | ||||
|               color: #333333; | ||||
|               display: inline-block; | ||||
|               line-height: 44px; | ||||
|               overflow: hidden; | ||||
|               text-overflow: ellipsis; | ||||
|               display:-webkit-box; | ||||
|               -webkit-box-orient:vertical; | ||||
|               -webkit-line-clamp:2; | ||||
|             } | ||||
|           } | ||||
|  | ||||
|           & > span { | ||||
|             font-size: 28px; | ||||
|             color: #999999; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .active { | ||||
|         background-color: #F3F6F9; | ||||
|       } | ||||
|  | ||||
|       & > text { | ||||
|         width: 100%; | ||||
|         display: inline-block; | ||||
|         font-size: 30px; | ||||
|         color: #649EFD; | ||||
|         text-align: center; | ||||
|       } | ||||
|  | ||||
|       .progress { | ||||
|         height: 12px; | ||||
|         background: #F2F4FC; | ||||
|         border-radius: 12px; | ||||
|         position: relative; | ||||
|         margin: 16px 0 64px 0; | ||||
|  | ||||
|         .pro-active { | ||||
|           height: 12px; | ||||
|           background: #639EFD; | ||||
|           border-radius: 12px; | ||||
|           position: absolute; | ||||
|           left: 0; | ||||
|           top: 0; | ||||
|         } | ||||
|  | ||||
|       } | ||||
|  | ||||
|       em { | ||||
|         font-style: normal; | ||||
|         font-size: 28px; | ||||
|         color: #1365DD; | ||||
|       } | ||||
|  | ||||
|       ::v-deep .u-collapse { | ||||
|         position: relative; | ||||
|  | ||||
|         &:after { | ||||
|           content: ""; | ||||
|           width: 718px; | ||||
|           height: 1px; | ||||
|           background-color: rgba(216, 221, 230, 0.5); | ||||
|           position: absolute; | ||||
|           left: 0; | ||||
|           bottom: 0; | ||||
|         } | ||||
|  | ||||
|         .u-collapse-head { | ||||
|           padding: 40px 0; | ||||
|         } | ||||
|  | ||||
|         .u-collapse-content { | ||||
|           font-size: 32px; | ||||
|           color: #333333; | ||||
|           line-height: 48px; | ||||
|           letter-spacing: 1px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .footer { | ||||
|       height: 112px; | ||||
|       width: 100%; | ||||
|       position: fixed; | ||||
|       left: 0; | ||||
|       bottom: 0; | ||||
|       background: #1365DD; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|       font-size: 36px; | ||||
|       color: #FFFFFF; | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										179
									
								
								src/project/pingchang/AppWorkTask/components/finish.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								src/project/pingchang/AppWorkTask/components/finish.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,179 @@ | ||||
| <template> | ||||
|   <div class="finish"> | ||||
|     <div class="card"> | ||||
|       <header>设置进度</header> | ||||
|       <u-gap height="120"></u-gap> | ||||
|       <u-slider v-model="form.percent" min="0" max="100" :use-slot="true"> | ||||
|         <div class="wrap"> | ||||
|           <div class="value" :style="{right:form.percent<30?'-50px':''}">{{ form.percent }}%</div> | ||||
|           <div class="btn" :style="{background:'url('+$cdn+ 'common/yuan.png)'}"></div> | ||||
|         </div> | ||||
|       </u-slider> | ||||
|       <u-gap height="70"></u-gap> | ||||
|     </div> | ||||
|     <div class="card"> | ||||
|       <div class="label"> | ||||
|         <em>*</em> | ||||
|         完成说明 | ||||
|       </div> | ||||
|       <textarea placeholder="请输入说明" v-model.trim="form.remarks" :maxlength="1000"></textarea> | ||||
|       <u-gap height="28"></u-gap> | ||||
|       <u-row justify="between"> | ||||
|         <text @click="form.remarks=''">清空内容</text> | ||||
|         <text>{{ form.remarks.length }}/1000</text> | ||||
|       </u-row> | ||||
|       <u-gap height="48"></u-gap> | ||||
|     </div> | ||||
|     <div class="footer" @click="submit">提交</div> | ||||
|     <u-modal v-model="show" content="提交后将无法撤回,您确定要执行此操作?" @confirm="handleConfirm"></u-modal> | ||||
|     <ai-back ref="aiBack"></ai-back> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import AiBack from "../../../components/AiBack"; | ||||
|  | ||||
| export default { | ||||
|   name: "finish", | ||||
|   components: {AiBack}, | ||||
|   data() { | ||||
|     return { | ||||
|       value: 0, | ||||
|       show: false, | ||||
|       form: { | ||||
|         percent: 0, | ||||
|         remarks: "", | ||||
|         taskCode: null, | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   onLoad(opt) { | ||||
|     this.form.taskCode = opt.taskCode | ||||
|     this.form.percent = opt.percent | ||||
|   }, | ||||
|   methods: { | ||||
|     submit() { | ||||
|       if (!this.form.remarks) return this.$u.toast("请输入完成说明") | ||||
|       this.show = true | ||||
|     }, | ||||
|     handleConfirm() { | ||||
|       this.$http.post("/app/appworktaskprocess/addOrUpdate", { | ||||
|         ...this.form | ||||
|       }).then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.$u.toast("提交成功") | ||||
|           this.$refs["aiBack"].back() | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .finish { | ||||
|   min-height: 100%; | ||||
|   background-color: #F5F5F5; | ||||
|   padding-bottom: 140px; | ||||
|  | ||||
|   .card { | ||||
|     background-color: #FFFFFF; | ||||
|     margin-bottom: 8px; | ||||
|     box-sizing: border-box; | ||||
|     padding: 16px 32px; | ||||
|  | ||||
|     header { | ||||
|       font-size: 32px; | ||||
|       font-weight: 600; | ||||
|       color: #333333; | ||||
|       line-height: 44px; | ||||
|       padding: 10px 0; | ||||
|     } | ||||
|  | ||||
|     ::v-deep .u-slider { | ||||
|       background: #F2F4FC !important; | ||||
|       border-radius: 12px !important; | ||||
|  | ||||
|       .u-slider__gap { | ||||
|         height: 12px !important; | ||||
|  | ||||
|         .u-slider__button-wrap { | ||||
|           top: 100% !important; | ||||
|  | ||||
|           .wrap { | ||||
|             display: flex; | ||||
|             align-items: center; | ||||
|  | ||||
|             .value { | ||||
|               width: 136px; | ||||
|               height: 64px; | ||||
|               background: #4F8DE7; | ||||
|               border-radius: 6px; | ||||
|               position: absolute; | ||||
|               top: -80px; | ||||
|               right: 50px; | ||||
|               font-size: 32px; | ||||
|               font-weight: 600; | ||||
|               color: #FFFFFF; | ||||
|               display: flex; | ||||
|               align-items: center; | ||||
|               justify-content: center; | ||||
|             } | ||||
|  | ||||
|             .btn { | ||||
|               width: 80px; | ||||
|               height: 80px; | ||||
|               background-size: 100% 100% !important; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .label { | ||||
|       height: 80px; | ||||
|       font-size: 32px; | ||||
|       color: #333333; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|  | ||||
|       & > em { | ||||
|         font-style: normal; | ||||
|         font-size: 32px; | ||||
|         color: #FF4466; | ||||
|         line-height: 44px; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     textarea { | ||||
|       width: 100%; | ||||
|     } | ||||
|  | ||||
|     .u-row { | ||||
|       & > text:first-child { | ||||
|         font-size: 28px; | ||||
|         color: #1365DD; | ||||
|       } | ||||
|  | ||||
|       & > text:last-child { | ||||
|         font-size: 24px; | ||||
|         color: #999999; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .footer { | ||||
|     height: 112px; | ||||
|     width: 100%; | ||||
|     position: fixed; | ||||
|     left: 0; | ||||
|     bottom: 0; | ||||
|     background: #1365DD; | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     justify-content: center; | ||||
|     font-size: 36px; | ||||
|     color: #FFFFFF; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										186
									
								
								src/project/pingchang/AppWorkTask/components/finishDetail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								src/project/pingchang/AppWorkTask/components/finishDetail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,186 @@ | ||||
| <template> | ||||
|   <div class="finish-detail"> | ||||
|     <div class="card"> | ||||
|       <u-row justify="between"> | ||||
|         <div class="left"> | ||||
|           <u-avatar :src="detail.avatar" v-if="detail.avatar"></u-avatar> | ||||
|           <div class="avatar" v-else>{{detail.name && detail.name.substr(-2)}}</div> | ||||
|           <div class="info"> | ||||
|             <div class="name">{{detail.name}}</div> | ||||
|             <div class="status">{{$dict.getLabel("workTaskRole",detail.taskRole)}}</div> | ||||
|           </div> | ||||
|         </div> | ||||
| <!--        <div class="btn">--> | ||||
| <!--          <img src="../static/tx.png" alt="">催办提醒--> | ||||
| <!--        </div>--> | ||||
|       </u-row> | ||||
|       <u-gap height="32"></u-gap> | ||||
|       <u-row> | ||||
|         <div class="label">完成时间:</div> | ||||
|         <div class="value">{{detail.finishTime}}</div> | ||||
|       </u-row> | ||||
|       <u-gap height="16"></u-gap> | ||||
|       <u-row> | ||||
|         <div class="label">逾期时间:</div> | ||||
|         <div class="value" style="color: #FF4466">{{detail.overTimeStatus}}</div> | ||||
|       </u-row> | ||||
|       <u-gap height="30"></u-gap> | ||||
|     </div> | ||||
|  | ||||
|     <div class="card" v-if="detail.processList && detail.processList.length"> | ||||
|       <u-collapse v-for="(item,index) in detail.processList" :key="index"> | ||||
|         <u-collapse-item :title="item.createDate && item.createDate.split(' ')[0]"> | ||||
|           <template slot="info"> | ||||
|             完成到<em>{{item.percent}}%</em> | ||||
|           </template> | ||||
|           {{item.remarks}} | ||||
|         </u-collapse-item> | ||||
|       </u-collapse> | ||||
|     </div> | ||||
|     <ai-back></ai-back> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import AiBack from "../../../components/AiBack"; | ||||
|  | ||||
|   export default { | ||||
|     name: "finishDetail", | ||||
|     components: {AiBack}, | ||||
|     data() { | ||||
|       return { | ||||
|         id: null, | ||||
|         detail: {}, | ||||
|       } | ||||
|     }, | ||||
|     onLoad(opt) { | ||||
|       this.id = opt.id | ||||
|       this.$dict.load("workTaskRole").then(_=>this.getDetail()) | ||||
|     }, | ||||
|     methods: { | ||||
|       getDetail() { | ||||
|         this.$http.post("/app/appworktaskuserinfo/queryDetailById", null, { | ||||
|           params: { | ||||
|             id: this.id | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res && res.data) { | ||||
|             this.detail = res.data; | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .finish-detail { | ||||
|     min-height: 100%; | ||||
|     background-color: #F5F5F5; | ||||
|  | ||||
|     .card { | ||||
|       box-sizing: border-box; | ||||
|       padding: 18px 32px; | ||||
|       background-color: #FFFFFF; | ||||
|       margin-bottom: 8px; | ||||
|  | ||||
|       .left { | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|  | ||||
|         .avatar { | ||||
|           width: 80px; | ||||
|           height: 80px; | ||||
|           border-radius: 50%; | ||||
|           font-size: 28px; | ||||
|           font-weight: 500; | ||||
|           color: #FFFFFF; | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           justify-content: center; | ||||
|           background: #2266FF; | ||||
|         } | ||||
|  | ||||
|         .info { | ||||
|           display: flex; | ||||
|           flex-direction: column; | ||||
|           margin-left: 16px; | ||||
|  | ||||
|           .name { | ||||
|             font-size: 32px; | ||||
|             font-weight: 400; | ||||
|             color: #333333; | ||||
|             line-height: 44px; | ||||
|           } | ||||
|  | ||||
|           .status { | ||||
|             font-size: 24px; | ||||
|             font-weight: 400; | ||||
|             color: #999999; | ||||
|             line-height: 34px; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .btn { | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         justify-content: center; | ||||
|         font-size: 28px; | ||||
|         font-weight: 400; | ||||
|         color: #1365DD; | ||||
|  | ||||
|         & > img { | ||||
|           width: 40px; | ||||
|           height: 40px; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .label { | ||||
|         font-size: 30px; | ||||
|         font-family: PingFangSC-Regular, PingFang SC; | ||||
|         color: #999999; | ||||
|         line-height: 42px; | ||||
|       } | ||||
|  | ||||
|       .value { | ||||
|         font-size: 30px; | ||||
|         font-weight: 400; | ||||
|         color: #343D65; | ||||
|         line-height: 48px; | ||||
|       } | ||||
|  | ||||
|       em { | ||||
|         font-style: normal; | ||||
|         font-size: 28px; | ||||
|         color: #1365DD; | ||||
|       } | ||||
|  | ||||
|       ::v-deep .u-collapse { | ||||
|         position: relative; | ||||
|  | ||||
|         &:after { | ||||
|           content: ""; | ||||
|           width: 718px; | ||||
|           height: 1px; | ||||
|           background-color: rgba(216, 221, 230, 0.5); | ||||
|           position: absolute; | ||||
|           left: 0; | ||||
|           bottom: 0; | ||||
|         } | ||||
|  | ||||
|         .u-collapse-head { | ||||
|           padding: 40px 0; | ||||
|         } | ||||
|  | ||||
|         .u-collapse-content { | ||||
|           font-size: 32px; | ||||
|           color: #333333; | ||||
|           line-height: 48px; | ||||
|           letter-spacing: 1px; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										341
									
								
								src/project/pingchang/AppWorkTask/components/subDetail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								src/project/pingchang/AppWorkTask/components/subDetail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,341 @@ | ||||
| <template> | ||||
|   <div class="sub-detail"> | ||||
|     <div class="card"> | ||||
|       <header> | ||||
|         <em>[子任务]</em> | ||||
|         {{detail.taskTitle}} | ||||
|       </header> | ||||
|       <u-gap height="16"></u-gap> | ||||
|       <u-row> | ||||
|         <span>任务类型:</span> | ||||
|         <span>{{$dict.getLabel("workTaskType",detail.type)}}</span> | ||||
|       </u-row> | ||||
|       <u-gap height="8"></u-gap> | ||||
|       <u-row> | ||||
|         <span>开始时间:</span> | ||||
|         <span>{{detail.createTime}}</span> | ||||
|       </u-row> | ||||
|       <u-gap height="8"></u-gap> | ||||
|       <u-row> | ||||
|         <span>截止时间:</span> | ||||
|         <span>{{detail.lastTime}}</span> | ||||
|       </u-row> | ||||
|       <u-gap height="8"></u-gap> | ||||
|       <u-row> | ||||
|         <span>剩余时间:</span> | ||||
|         <span style="color:#1365DD">{{detail.overTimeStatus}}</span> | ||||
|       </u-row> | ||||
|       <u-gap height="8"></u-gap> | ||||
|       <u-row> | ||||
|         <span>任务状态:</span> | ||||
|         <span style="color:#1365DD">{{$dict.getLabel("workTaskDoStatus",detail.status)}}</span> | ||||
|       </u-row> | ||||
|       <u-gap height="16"></u-gap> | ||||
|     </div> | ||||
|     <div class="card" style="padding-top: 0"> | ||||
|       <div class="label">任务说明</div> | ||||
|       <u-read-more close-text="展开" color="#999999" show-height="300"> | ||||
|         <span>{{detail.taskDescription}}</span> | ||||
|       </u-read-more> | ||||
|     </div> | ||||
|  | ||||
|     <div class="card"> | ||||
|       <div class="label">当前进度</div> | ||||
|       <text>已完成{{detail.percent}}%</text> | ||||
|       <div class="progress"> | ||||
|         <div class="pro-active" :style="{width:detail.percent + '%'}"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="card" style="padding-top: 0" v-if="detail.userInfoList && detail.userInfoList.length"> | ||||
|       <div class="label title">任务完成进度(<i>{{count}}</i>/{{detail.userInfoList.length}})</div> | ||||
|       <u-row justify="between" v-for="(item,index) in detail.userInfoList" :key="index" @click="finishDetail(item)"> | ||||
|         <div>{{item.userName && item.userName.substr(-2)}}</div> | ||||
|         <u-row justify="between" class="item"> | ||||
|           <text class="name">{{item.userName}}</text> | ||||
|           <label class="right"> | ||||
|             <span>已完成{{item.percent}}%</span> | ||||
|             <label class="arrow"></label> | ||||
|           </label> | ||||
|         </u-row> | ||||
|       </u-row> | ||||
|     </div> | ||||
|  | ||||
|     <div class="footer" v-if="detail.status==0"> | ||||
|       <div> | ||||
|         <img :src="$cdn + 'common/gb.png'" alt="" @click="show=true,content='确定是否要关闭任务?',idx=0">关闭任务 | ||||
|       </div> | ||||
|       <div> | ||||
|         <img :src="$cdn + 'common/tx.png'" alt="" @click="show=true,content='该操作会向所有执行人发送提醒,您确定发送吗?',idx=1">一键催办 | ||||
|       </div> | ||||
|     </div> | ||||
|     <u-modal v-model="show" :content="content" @confirm="confirm"></u-modal> | ||||
|     <ai-back></ai-back> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import AiBack from "../../../components/AiBack"; | ||||
|  | ||||
|   export default { | ||||
|     name: "subDetail", | ||||
|     components: {AiBack}, | ||||
|     data() { | ||||
|       return { | ||||
|         id: null, | ||||
|         detail: {}, | ||||
|         show: false, | ||||
|         content: "", | ||||
|         idx: null, | ||||
|         count: 0, | ||||
|       } | ||||
|     }, | ||||
|     onLoad(opt) { | ||||
|       this.id = opt.id | ||||
|       this.$dict.load("workTaskType", "workTaskDoStatus").then(_ => this.getDetail()) | ||||
|     }, | ||||
|     methods: { | ||||
|       finishDetail({id}){ | ||||
|         uni.navigateTo({ | ||||
|           url:"/pages/workTask/components/finishDetail?id=" + id | ||||
|         }) | ||||
|       }, | ||||
|       confirm() { | ||||
|         this.$http.post(this.idx == 0 ? "/app/appworktaskinfo/stopOrFinish" : "/app/appworktaskuserinfo/sendMesage", null, { | ||||
|           params: { | ||||
|             id: this.id, | ||||
|             status: this.idx == 0 ? 2 : null | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.$u.toast(this.idx == 0 ? "关闭成功" : "催办成功") | ||||
|             this.getDetail() | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       getDetail() { | ||||
|         this.$http.post("/app/appworktaskinfo/queryDetailById", null, { | ||||
|           params: { | ||||
|             id: this.id | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res && res.data) { | ||||
|             this.detail = res.data | ||||
|             this.count = res.data?.userInfoList?.reduce((pre,cur)=>{ | ||||
|               return pre + (cur.percent==100 ? 1 : 0) | ||||
|             },0) | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .sub-detail { | ||||
|     min-height: 100%; | ||||
|     overflow-x: hidden; | ||||
|     background-color: #F5F5F5; | ||||
|     padding-bottom: 140px; | ||||
|  | ||||
|     .card { | ||||
|       background-color: #FFFFFF; | ||||
|       margin-bottom: 8px; | ||||
|       box-sizing: border-box; | ||||
|       padding: 16px 32px; | ||||
|  | ||||
|       header { | ||||
|         font-size: 40px; | ||||
|         font-weight: 600; | ||||
|         color: #333333; | ||||
|         line-height: 64px; | ||||
|         letter-spacing: 1px; | ||||
|  | ||||
|         & > em { | ||||
|           font-style: normal; | ||||
|           color: #1365DD; | ||||
|           font-size: 40px; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .u-row { | ||||
|         flex: 1; | ||||
|         margin-left: 16px; | ||||
|         position: relative; | ||||
|  | ||||
|  | ||||
|         .item { | ||||
|           height: 112px; | ||||
|  | ||||
|           &:after { | ||||
|             width: 622px; | ||||
|             height: 2px; | ||||
|             content: ""; | ||||
|             position: absolute; | ||||
|             left: 0; | ||||
|             bottom: 0; | ||||
|             background-color: rgba(216, 221, 230, 0.5); | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         & > div { | ||||
|           width: 80px; | ||||
|           height: 80px; | ||||
|           background-color: #4E8EEE; | ||||
|           border-radius: 50%; | ||||
|           text-align: center; | ||||
|           font-size: 28px; | ||||
|           font-weight: bold; | ||||
|           color: #FFFFFF; | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           justify-content: center; | ||||
|         } | ||||
|  | ||||
|         & > span:first-child { | ||||
|           font-size: 30px; | ||||
|           color: #999999;; | ||||
|           line-height: 48px; | ||||
|         } | ||||
|  | ||||
|         & > span:last-child { | ||||
|           font-size: 30px; | ||||
|           color: #343D65; | ||||
|           margin-left: 16px; | ||||
|           line-height: 48px; | ||||
|         } | ||||
|  | ||||
|         .name { | ||||
|           font-size: 32px; | ||||
|           font-weight: 400; | ||||
|           color: #333333; | ||||
|         } | ||||
|  | ||||
|         .title { | ||||
|           width: 490px; | ||||
|           height: 112px; | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           font-size: 32px; | ||||
|           color: #333333; | ||||
|           overflow: hidden; | ||||
|           text-overflow: ellipsis; | ||||
|           white-space: nowrap; | ||||
|         } | ||||
|  | ||||
|         .right { | ||||
|           font-size: 28px; | ||||
|           color: #1365DD; | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|  | ||||
|           .arrow { | ||||
|             width: 16px; | ||||
|             height: 16px; | ||||
|             border-top: 3px solid #CCCCCC; | ||||
|             border-right: 3px solid #CCCCCC; | ||||
|             transform: rotate(45deg); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       & > text { | ||||
|         width: 100%; | ||||
|         display: inline-block; | ||||
|         font-size: 30px; | ||||
|         color: #649EFD; | ||||
|         text-align: center; | ||||
|       } | ||||
|  | ||||
|       .progress { | ||||
|         height: 12px; | ||||
|         background: #F2F4FC; | ||||
|         border-radius: 12px; | ||||
|         position: relative; | ||||
|         margin: 16px 0 80px 0; | ||||
|  | ||||
|         .pro-active { | ||||
|           height: 12px; | ||||
|           background: #639EFD; | ||||
|           border-radius: 12px; | ||||
|           position: absolute; | ||||
|           left: 0; | ||||
|           top: 0; | ||||
|         } | ||||
|  | ||||
|       } | ||||
|  | ||||
|       & > span { | ||||
|         font-size: 32px; | ||||
|         color: #333333; | ||||
|         line-height: 48px; | ||||
|         letter-spacing: 1px; | ||||
|         display: inline-block; | ||||
|       } | ||||
|  | ||||
|       .label { | ||||
|         height: 80px; | ||||
|         font-size: 32px; | ||||
|         color: #333333; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         margin-bottom: 16px; | ||||
|  | ||||
|         & > em { | ||||
|           font-style: normal; | ||||
|           font-size: 32px; | ||||
|           color: #1365DD; | ||||
|         } | ||||
|  | ||||
|         & > i { | ||||
|           font-style: normal; | ||||
|           font-size: 32px; | ||||
|           color: #2EA222; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .title { | ||||
|         font-weight: bold; | ||||
|         height: 96px; | ||||
|         border-bottom: 1px solid rgba(216, 221, 230, 0.5); | ||||
|       } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     .footer { | ||||
|       height: 112px; | ||||
|       width: 100%; | ||||
|       position: fixed; | ||||
|       left: 0; | ||||
|       bottom: 0; | ||||
|       background: #FFFFFF; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|       font-size: 36px; | ||||
|       color: #FFFFFF; | ||||
|  | ||||
|       img { | ||||
|         width: 48px; | ||||
|         height: 48px; | ||||
|         margin-right: 8px; | ||||
|       } | ||||
|  | ||||
|       & > div:first-child, div:last-child { | ||||
|         width: 50%; | ||||
|         height: 100%; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         justify-content: center; | ||||
|       } | ||||
|  | ||||
|       & > div:first-child { | ||||
|         color: #666666; | ||||
|       } | ||||
|  | ||||
|       & > div:last-child { | ||||
|         background: #1365DD; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
		Reference in New Issue
	
	Block a user