目录代码整合
This commit is contained in:
		
							
								
								
									
										66
									
								
								packages/work/AppApprover/AppApprover.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								packages/work/AppApprover/AppApprover.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| <template> | ||||
|   <div class="doc-circulation ailist-wrapper"> | ||||
|     <keep-alive :include="['List']"> | ||||
|       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> | ||||
|     </keep-alive> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import List from './components/List' | ||||
|   import Add from './components/Add' | ||||
|  | ||||
|   export default { | ||||
|     name: 'AppApprover', | ||||
|     label: '审批负责人', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         component: 'List', | ||||
|         params: {}, | ||||
|         include: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     components: { | ||||
|       List, | ||||
|       Add | ||||
|     }, | ||||
|  | ||||
|     mounted () { | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       onChange (data) { | ||||
|         if (data.type === 'Add') { | ||||
|           this.component = 'Add' | ||||
|           this.params = data.params | ||||
|         } | ||||
|  | ||||
|         if (data.type === 'List') { | ||||
|           this.component = 'List' | ||||
|           this.params = data.params | ||||
|  | ||||
|           this.$nextTick(() => { | ||||
|             if (data.isRefresh) { | ||||
|               this.$refs.component.getList() | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss"> | ||||
|   .doc-circulation { | ||||
|     height: 100%; | ||||
|     background: #F3F6F9; | ||||
|     overflow: auto; | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										125
									
								
								packages/work/AppApprover/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								packages/work/AppApprover/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,125 @@ | ||||
| <template> | ||||
|   <ai-detail> | ||||
|     <template slot="title"> | ||||
|       <ai-title :title="params.id ? '编辑审批负责人' : '添加审批负责人'" isShowBack isShowBottomBorder @onBackClick="cancel(false)"> | ||||
|       </ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-card title="基本信息"> | ||||
|         <template #content> | ||||
|           <el-form ref="form" class="ai-form" :model="form" label-width="110px" label-position="right"> | ||||
|             <el-form-item label="角色说明" style="width: 100%;" prop=""> | ||||
|               <p style="color: red">网格员上报疑似风险/建议解除风险对象信息后,需管理员确认纳入监测对象或解除风险。</p> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="姓名" prop="name" :rules="[{ required: true, message: '请选择人员', trigger: 'blur' }]"> | ||||
|               <el-input disabled :value="form.name" size="small" placeholder="请选择人员"> | ||||
|                 <template slot="append"> | ||||
|                   <ai-wechat-selecter refs="addTags" :instance="instance" v-model="users" @change="onChooseUser"> | ||||
|                     <el-button size="small">选择人员</el-button> | ||||
|                   </ai-wechat-selecter> | ||||
|                 </template> | ||||
|               </el-input> | ||||
|             </el-form-item> | ||||
|             <el-form-item style="width: 100%!important;" label="所在地区" prop="areaId" :rules="[{ required: true, message: '请选择所在地区', trigger: 'change' }]"> | ||||
|               <ai-area-select | ||||
|                 v-model="form.areaId" | ||||
|                 always-show | ||||
|                 :instance="instance" | ||||
|                 clearable | ||||
|                 @fullname="v=>form.areaName = v" | ||||
|                 :disabledLevel="disabledLevel"/> | ||||
|             </el-form-item> | ||||
|           </el-form> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|     </template> | ||||
|     <template #footer> | ||||
|       <el-button @click="cancel">取消</el-button> | ||||
|       <el-button type="primary" @click="confirm">提交</el-button> | ||||
|     </template> | ||||
|   </ai-detail> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import { mapState } from 'vuex' | ||||
|   export default { | ||||
|     name: 'Add', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       params: Object | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         info: {}, | ||||
|         users: [], | ||||
|         form: { | ||||
|           name: '', | ||||
|           areaName: '', | ||||
|           areaId: '' | ||||
|         }, | ||||
|         id: '', | ||||
|         disabledLevel: 3 | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       ...mapState(['user']) | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       this.form.areaName = this.user.info.areaName | ||||
|       this.form.areaId = this.user.info.areaId | ||||
|       this.disabledLevel = this.user.info.areaList.length | ||||
|       if (this.params && this.params.id) { | ||||
|         this.id = this.params.id | ||||
|         this.getInfo(this.params.id) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getInfo (id) { | ||||
|         this.instance.post(`/app/apppreventionreturntopovertyriskperson/queryDetailById?id=${id}`).then(res => { | ||||
|           if (res.code === 0) { | ||||
|             this.form = { | ||||
|               ...res.data | ||||
|             } | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       onChooseUser (v) { | ||||
|  | ||||
|       }, | ||||
|  | ||||
|       confirm () { | ||||
|         this.$refs.form.validate((valid) => { | ||||
|           if (valid) { | ||||
|             this.instance.post(`/app/apppreventionreturntopovertyriskperson/addOrUpdate`, { | ||||
|               ...this.form | ||||
|             }).then(res => { | ||||
|               if (res.code == 0) { | ||||
|                 this.$message.success('提交成功') | ||||
|                 setTimeout(() => { | ||||
|                   this.cancel(true) | ||||
|                 }, 600) | ||||
|               } | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       cancel (isRefresh) { | ||||
|         this.$emit('change', { | ||||
|           type: 'List', | ||||
|           isRefresh: !!isRefresh | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| </style> | ||||
							
								
								
									
										140
									
								
								packages/work/AppApprover/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								packages/work/AppApprover/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,140 @@ | ||||
| <template> | ||||
|   <ai-list class="notice"> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="审批负责人" isShowBottomBorder :isShowArea="true" v-model="search.areaId" :instance="instance" @change="getList"></ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-search-bar> | ||||
|         <template #left> | ||||
|           <el-button icon="iconfont iconAdd" type="primary" size="small" @click="toAdd('')">添加 </el-button> | ||||
|         </template> | ||||
|         <template #right> | ||||
|           <el-input | ||||
|             v-model="search.name" | ||||
|             size="small" | ||||
|             placeholder="审批负责人" | ||||
|             clearable | ||||
|             v-throttle="() => {search.current = 1, getList()}" | ||||
|             @clear="search.current = 1, search.name = '', getList()" | ||||
|             suffix-icon="iconfont iconSearch"> | ||||
|           </el-input> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <ai-table | ||||
|         :tableData="tableData" | ||||
|         :col-configs="colConfigs" | ||||
|         :total="total" | ||||
|         style="margin-top: 12px;" | ||||
|         :current.sync="search.current" | ||||
|         :size.sync="search.size" | ||||
|         @selection-change="(v) => (ids = v.map((e) => e.id))" | ||||
|         @getList="getList"> | ||||
|         <el-table-column slot="options" width="90px" fixed="right" label="操作" align="center"> | ||||
|           <div class="table-options" slot-scope="{ row }"> | ||||
|             <el-button type="text" @click="toAdd(row.id)">编辑</el-button> | ||||
|             <el-button type="text" @click="remove(row.id)">删除</el-button> | ||||
|           </div> | ||||
|         </el-table-column> | ||||
|       </ai-table> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import { mapState } from 'vuex' | ||||
|   export default { | ||||
|     name: 'List', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object | ||||
|     }, | ||||
|  | ||||
|     data() { | ||||
|       return { | ||||
|         search: { | ||||
|           current: 1, | ||||
|           size: 10, | ||||
|           title: '', | ||||
|           areaId: '' | ||||
|         }, | ||||
|         ids: [], | ||||
|         total: 10, | ||||
|         tableData: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       ...mapState(['user']), | ||||
|  | ||||
|       colConfigs () { | ||||
|         return [ | ||||
|           { prop: 'title', label: '审批负责人', align: 'left' }, | ||||
|           { prop: 'createUserName', label: '所属地区', align: 'center' }, | ||||
|           { prop: 'createTime', label: '操作时间', align: 'center' }, | ||||
|           { prop: 'createTime', label: '操作人', align: 'center' }, | ||||
|           { slot: 'options', label: '操作' } | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       this.search.areaId = this.user.info.areaId | ||||
|       this.dict.load('epidemicRecentTestResult').then(() => { | ||||
|         this.getList() | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getList() { | ||||
|         this.instance.post(`/app/appmininotice/list`, null, { | ||||
|           params: { | ||||
|             ...this.search | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.tableData = res.data.records | ||||
|             this.total = res.data.total | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       removeAll () { | ||||
|         var id = this.ids.join(',') | ||||
|         this.remove(id) | ||||
|       }, | ||||
|  | ||||
|       remove(id) { | ||||
|         this.$confirm('确定删除该数据?').then(() => { | ||||
|           this.instance.post(`/app/appmininotice/delete?ids=${id}`).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.$message.success('删除成功!') | ||||
|               this.getList() | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       toDetail (id) { | ||||
|         this.$emit('change', { | ||||
|           type: 'Detail', | ||||
|           params: { | ||||
|             id: id || '' | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       toAdd(id) { | ||||
|         this.$emit('change', { | ||||
|           type: 'Add', | ||||
|           params: { | ||||
|             id: id || '' | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| </style> | ||||
							
								
								
									
										113
									
								
								packages/work/AppAskForm/AppAskForm.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								packages/work/AppAskForm/AppAskForm.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | ||||
| <template> | ||||
|   <ai-list v-if="!isShowDetail"> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="问卷表单" :isShowBottomBorder="false" :instance="instance" :isShowArea="currIndex === '0'" v-model="areaId" @change="changeArea"></ai-title> | ||||
|     </template> | ||||
|     <template slot="tabs"> | ||||
|       <el-tabs v-model="currIndex"> | ||||
|         <el-tab-pane v-for="(tab,i) in tabs" :key="i" :label="tab.label"> | ||||
|           <component :areaId="areaId" :ref="tab.name" v-if="currIndex == i" :is="tab.comp" @change="onChange" lazy :instance="instance" :dict="dict" :permissions="permissions"/> | ||||
|         </el-tab-pane> | ||||
|       </el-tabs> | ||||
|     </template> | ||||
|   </ai-list> | ||||
|   <Add v-else-if="componentName === 'Add'" :areaId="areaId" :params="params" :instance="instance" :dict="dict" :permissions="permissions" @change="onChange"></Add> | ||||
|   <Statistics v-else-if="componentName === 'Statistics'" :areaId="areaId" :params="params" :instance="instance" :dict="dict" :permissions="permissions" @change="onChange"></Statistics> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import FormList from './components/FormList.vue' | ||||
|   import Template from './components/Template' | ||||
|   import Add from './components/Add' | ||||
|   import Statistics from './components/Statistics' | ||||
|   import { mapState } from 'vuex' | ||||
|  | ||||
|   export default { | ||||
|     name: 'AppAskForm', | ||||
|     label: '问卷表单', | ||||
|  | ||||
|     components: { | ||||
|       FormList, | ||||
|       Add, | ||||
|       Statistics, | ||||
|       Template | ||||
|     }, | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       permissions: Function | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       ...mapState(['user']), | ||||
|  | ||||
|       tabs () { | ||||
|         const tabList = [ | ||||
|           {label: '表单列表', name: 'FormList', comp: FormList, permission: ''}, | ||||
|           {label: '共享模板', name: 'Template', comp: Template, permission: ''} | ||||
|         ].filter(item => { | ||||
|           return true | ||||
|         }) | ||||
|  | ||||
|         return tabList | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         activeName: 'JoinEvent', | ||||
|         currIndex: '0', | ||||
|         componentName: '', | ||||
|         params: {}, | ||||
|         areaId: '', | ||||
|         isShowDetail: false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     created() { | ||||
|       this.areaId = this.user.info.areaId | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       changeArea () { | ||||
|         this.$nextTick(() => { | ||||
|           this.$refs[this.tabs[Number(this.currIndex)].name][0].getList() | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       onChange (data) { | ||||
|         if (data.type === 'list') { | ||||
|           this.componentName = 'List' | ||||
|           this.isShowDetail = false | ||||
|           this.params = data.params | ||||
|  | ||||
|           if (data.isQuote) { | ||||
|             this.currIndex = 0 | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         if (data.type === 'detail') { | ||||
|           this.componentName = 'Detail' | ||||
|           this.isShowDetail = true | ||||
|           this.params = data.params | ||||
|         } | ||||
|  | ||||
|         if (data.type === 'Statistics') { | ||||
|           this.componentName = 'Statistics' | ||||
|           this.isShowDetail = true | ||||
|           this.params = data.params | ||||
|         } | ||||
|  | ||||
|         if (data.type === 'add') { | ||||
|           this.componentName = 'Add' | ||||
|           this.isShowDetail = true | ||||
|           this.params = data.params | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| </style> | ||||
							
								
								
									
										1739
									
								
								packages/work/AppAskForm/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1739
									
								
								packages/work/AppAskForm/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1089
									
								
								packages/work/AppAskForm/components/FormList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1089
									
								
								packages/work/AppAskForm/components/FormList.vue
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										761
									
								
								packages/work/AppAskForm/components/Statistics.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										761
									
								
								packages/work/AppAskForm/components/Statistics.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,761 @@ | ||||
| <template> | ||||
|   <ai-detail class="statistics"> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="数据统计" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-card title="表单信息"> | ||||
|         <template #content> | ||||
|           <ai-wrapper label-width="90px"> | ||||
|             <ai-info-item label="表单名称" :value="info.title" isLine></ai-info-item> | ||||
|             <ai-info-item label="发布状态"><span | ||||
|                 :style="{color: dict.getColor('questionnaireStatus', info.status)}">已发布</span></ai-info-item> | ||||
|             <ai-info-item label="创建人" :value="info.createUserName"></ai-info-item> | ||||
|             <ai-info-item label="创建时间" :value="info.createTime"></ai-info-item> | ||||
|             <ai-info-item label="截止时间" | ||||
|                           :value="info.periodValidityEndTime ? info.periodValidityEndTime : '永久有效'"></ai-info-item> | ||||
|             <ai-info-item label="提交次数限制" :value="info.commitType === '1' ? '限提交一次' : '不限次数' "></ai-info-item> | ||||
|           </ai-wrapper> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|       <div class="statistics-wrapper"> | ||||
|         <div class="statistics-wrapper__title"> | ||||
|           <span :class="[currIndex === 0 ? 'active' : '']" @click="currIndex = 0">表单统计</span> | ||||
|           <span :class="[currIndex === 1 ? 'active' : '']" @click="currIndex = 1">居民统计</span> | ||||
|         </div> | ||||
|         <div class="statistics-wrapper__body"> | ||||
|           <div v-show="currIndex === 0"> | ||||
|             <div class="statistics-wrapper__body--info"> | ||||
|               <span>共</span> | ||||
|               <i>{{ subjectList.length }}</i> | ||||
|               <span>题,其中</span> | ||||
|               <span v-for="(item, index) in fieldTypeCount" :key="index"> | ||||
|                 {{ mapType(item.field_type) }}<i>{{ item.c }}</i>道{{ fieldTypeCount.length - 1 === index ? '' : ',' }} | ||||
|               </span> | ||||
|             </div> | ||||
|             <div class="statistics-wrapper__body--list"> | ||||
|               <div class="statistics-wrapper__body--item" v-for="(item, index) in subjectList" :key="index"> | ||||
|                 <div class="statistics-wrapper__body--top" | ||||
|                      :style="{borderBottom: ['input', 'textarea', 'upload'].indexOf(item.type) > -1 ? 'none' : '1px solid #DDDDDD'}"> | ||||
|                   <div class="left"> | ||||
|                     <h2>{{ item.fieldName }}({{ item.fixedLabel }})</h2> | ||||
|                   </div> | ||||
|                   <div class="right"> | ||||
|                     <span>共</span> | ||||
|                     <i>{{ fieldDataCount[`field_${index}`] }}</i> | ||||
|                     <span>条数据</span> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="statistics-wrapper__body--bottom" | ||||
|                      v-if="['radio', 'checkbox', 'select'].indexOf(item.type) > -1"> | ||||
|                   <div class="statistics-wrapper__body--select" v-for="(item, i) in item.options" :key="i"> | ||||
|                     <div class="left"> | ||||
|                       <h2>{{ item.label }}</h2> | ||||
|                       <span>{{ item.c || 0 }}人</span> | ||||
|                     </div> | ||||
|                     <div class="right"> | ||||
|                       <div class="progress"> | ||||
|                         <div | ||||
|                             :style="{width: `${(((item.c || 0) / fieldDataCount[`field_${index}`]) * 100).toFixed(2)}%`}"></div> | ||||
|                       </div> | ||||
|                       <i>{{ (((item.c || 0) / fieldDataCount[`field_${index}`]) * 100).toFixed(2) }}%</i> | ||||
|                     </div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div v-show="currIndex === 1" style="padding: 16px;"> | ||||
|             <ai-search-bar> | ||||
|               <template #right> | ||||
|                 <el-input | ||||
|                     v-model="search.name" | ||||
|                     size="small" | ||||
|                     placeholder="请输入居民名称或真实姓名" | ||||
|                     clearable | ||||
|                     v-throttle="() => {search.current = 1, getList()}" | ||||
|                     @clear="search.current = 1, search.name = '', getList()" | ||||
|                     suffix-icon="iconfont iconSearch"> | ||||
|                 </el-input> | ||||
|               </template> | ||||
|             </ai-search-bar> | ||||
|             <ai-table | ||||
|                 class="detail-table__table" | ||||
|                 :border="true" | ||||
|                 style="margin-top: 4px;" | ||||
|                 :tableData="tableData" | ||||
|                 :col-configs="colConfigs" | ||||
|                 :total="total" | ||||
|                 :stripe="false" | ||||
|                 :current.sync="search.current" | ||||
|                 :size.sync="search.size" | ||||
|                 @getList="getList"> | ||||
|               <el-table-column slot="userinfo" label="居民" width="260px" align="left"> | ||||
|                 <template slot-scope="{ row }"> | ||||
|                   <div class="userinfo"> | ||||
|                     <img :src="row.avatarUrl || 'https://cdn.cunwuyun.cn/dvcp/h5/defaultAvatar.png'"> | ||||
|                     <!-- <h3>{{ row.nickName }}</h3> --> | ||||
|                     <el-tooltip effect="dark" | ||||
|                                 :content="row.corpName ? row.nickName + '@' + row.corpFullName : row.nickName + ''" | ||||
|                                 placement="top"> | ||||
|                       <div class="userinfo-right__top"> | ||||
|                         <h3>{{ row.corpName ? row.nickName : row.nickName }}</h3> | ||||
|                         <span class="ellipsis">{{ row.corpName ? '@' + row.corpName : '' }}</span> | ||||
|                       </div> | ||||
|                     </el-tooltip> | ||||
|                   </div> | ||||
|                 </template> | ||||
|               </el-table-column> | ||||
|               <el-table-column slot="tags" label="标签" align="center" width="240px"> | ||||
|                 <template slot-scope="{ row }"> | ||||
|                   <div class="table-tags" v-if="row.tagNames"> | ||||
|                     <el-tag type="info" v-for="(item, index) in row.tagNames.split(',')" size="medium" :key="index"> | ||||
|                       {{ item }} | ||||
|                     </el-tag> | ||||
|                   </div> | ||||
|                   <span v-else></span> | ||||
|                 </template> | ||||
|               </el-table-column> | ||||
|               <el-table-column slot="options" label="操作" align="center"> | ||||
|                 <template slot-scope="{ row }"> | ||||
|                   <div class="table-options"> | ||||
|                     <el-button type="text" @click="showForm(row.id)">查看表单</el-button> | ||||
|                   </div> | ||||
|                 </template> | ||||
|               </el-table-column> | ||||
|             </ai-table> | ||||
|           </div> | ||||
|         </div> | ||||
|         <ai-dialog | ||||
|             customFooter | ||||
|             :visible.sync="isShowForm" | ||||
|             @onConfirm="isShowForm = false" | ||||
|             width="800px" | ||||
|             title="表单"> | ||||
|             <div class="middle-content form"> | ||||
|               <div class="middle-content__wrapper"> | ||||
|                 <div> | ||||
|                   <div class="left-item__item left-item__item--banner" key="banner" v-if="info.headPicture"> | ||||
|                     <img :src="info.headPicture"> | ||||
|                   </div> | ||||
|                   <div class="left-item__item left-item__item--formname" key="title"> | ||||
|                     <h2>{{ info.title }}</h2> | ||||
|                   </div> | ||||
|                   <div class="left-item__item left-item__item--text" key="text"> | ||||
|                     <p>{{ info.tableExplain }}</p> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div | ||||
|                   class="left-item__item components-item" | ||||
|                   v-for="(item, i) in targetList" | ||||
|                   :key="i"> | ||||
|                 <div class="left-item__item--title"> | ||||
|                   <i :style="{opacity: item.required ? 1 : 0}">*</i> | ||||
|                   <span>{{ i + 1 }}.</span> | ||||
|                   <h2>{{ item.label }}</h2> | ||||
|                 </div> | ||||
|                 <div class="left-item__item--wrapper"> | ||||
|                   <template v-if="(item.type === 'radio')"> | ||||
|                     <div class="radio-item" v-for="(field, index) in item.options" :key="index"> | ||||
|                       <input type="radio" disabled :value="field.label" v-model="formInfo[`field_${i}`]"/> | ||||
|                       <img :src="field.img[0].url" v-if="field.img.length"> | ||||
|                       <label>{{ field.label }}</label> | ||||
|                     </div> | ||||
|                   </template> | ||||
|                   <template v-if="item.type === 'upload'"> | ||||
|                     <img style="width: 100%; height: 100%;" :src="formInfo[`field_${i}`]" v-if="formInfo[`field_${i}`]"> | ||||
|                     <div class="left-item__item--upload" v-else> | ||||
|                       <span>图片</span> | ||||
|                     </div> | ||||
|                   </template> | ||||
|                   <template v-if="item.type === 'select'"> | ||||
|                     <el-input resize="none" class="preview" type="textarea" style="color: #333" :placeholder="item.placeholder" v-model="formInfo[`field_${i}`]" disabled></el-input> | ||||
|                     <!-- <span>{{ formInfo[`field_${i}`] }}</span> --> | ||||
|                     <!-- <textarea :placeholder="item.placeholder" v-model="formInfo[`field_${i}`]" disabled></textarea> --> | ||||
|                     <!-- <el-select placeholder="请选择" disabled v-model="formInfo[`field_${i}`]" style="width: 100%;"> | ||||
|                       <el-option | ||||
|                         v-for="(item, index) in item.options" | ||||
|                         :key="index" | ||||
|                         :label="item.label" | ||||
|                         :value="item.label"> | ||||
|                       </el-option> | ||||
|                     </el-select> --> | ||||
|                   </template> | ||||
|                   <template v-if="(item.type === 'checkbox')"> | ||||
|                     <div class="radio-item" v-for="(field, index) in item.options" :key="index"> | ||||
|                       <input type="checkbox" disabled :value="field.label" v-model="formInfo[`field_${i}`]"/> | ||||
|                       <img :src="field.img[0].url" v-if="field.img.length"> | ||||
|                       <label>{{ field.label }}</label> | ||||
|                     </div> | ||||
|                   </template> | ||||
|                   <template v-if="(item.type === 'input')"> | ||||
|                     <div class="text-item"> | ||||
|                       <input :placeholder="item.placeholder" v-model="formInfo[`field_${i}`]" disabled> | ||||
|                     </div> | ||||
|                   </template> | ||||
|                   <template v-if="(item.type === 'textarea')"> | ||||
|                     <div class="textarea-item" resize="none"> | ||||
|                       <textarea :placeholder="item.placeholder" v-model="formInfo[`field_${i}`]" disabled></textarea> | ||||
|                     </div> | ||||
|                   </template> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|           <template #footer> | ||||
|             <el-button @click="isShowForm = false">关闭</el-button> | ||||
|           </template> | ||||
|         </ai-dialog> | ||||
|       </div> | ||||
|     </template> | ||||
|   </ai-detail> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: 'Statistics', | ||||
|  | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     params: Object | ||||
|   }, | ||||
|  | ||||
|   data() { | ||||
|     return { | ||||
|       currIndex: 0, | ||||
|       search: { | ||||
|         name: '', | ||||
|         size: 10, | ||||
|         current: 1 | ||||
|       }, | ||||
|       info: {}, | ||||
|       subjectList: [], | ||||
|       tableData: [], | ||||
|       total: 0, | ||||
|       form: {}, | ||||
|       fieldTypeCount: [], | ||||
|       fieldValueDistribution: [], | ||||
|       fieldDataCount: {}, | ||||
|       isShowForm: false, | ||||
|       targetList: [], | ||||
|       formInfo: {}, | ||||
|       colConfigs: [ | ||||
|         {slot: 'userinfo'}, | ||||
|         {prop: 'residentName', label: '真实姓名', align: 'center', width: '100px'}, | ||||
|         {prop: 'commitTime', label: '提交时间', align: 'center', width: '160px'}, | ||||
|         { | ||||
|           prop: 'userType', | ||||
|           label: '微信类型', | ||||
|           align: 'center', | ||||
|           width: '100px', | ||||
|           formart: v => this.dict.getLabel('wxUserType', v) | ||||
|         }, | ||||
|         {prop: 'wxUserNames', label: '所属员工', align: 'center', width: '100px'}, | ||||
|         {slot: 'tags', label: '标签', align: 'center', width: '268px'}, | ||||
|         {prop: 'totalScore', label: '分值', align: 'center'} | ||||
|       ] | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   mounted() { | ||||
|     this.getInfo() | ||||
|     this.getFormInfo() | ||||
|  | ||||
|     this.dict.load(['wxUserType']).then(() => { | ||||
|       this.getList() | ||||
|     }) | ||||
|   }, | ||||
|   methods: { | ||||
|     getList() { | ||||
|       this.instance.post(`/app/appquestionnairetemplate/statisticsResident?id=${this.params.id}`, null, { | ||||
|         params: { | ||||
|           ...this.search | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.tableData = res.data.records | ||||
|           this.total = res.data.total | ||||
|  | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     showForm(id) { | ||||
|       this.instance.post(`/app/appquestionnairetemplate/queryDataInfoById?id=${this.params.id}&dataId=${id}`).then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.formInfo = res.data | ||||
|  | ||||
|           this.targetList.forEach((item, index) => { | ||||
|             if (item.type === 'checkbox' && this.formInfo[`field_${index}`]) { | ||||
|               this.formInfo[`field_${index}`] = this.formInfo[`field_${index}`].split(',') | ||||
|             } | ||||
|           }) | ||||
|  | ||||
|           this.isShowForm = true | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     mapType(type) { | ||||
|       return { | ||||
|         upload: '上传图片', | ||||
|         input: '单行填空', | ||||
|         textarea: '多行填空', | ||||
|         radio: '单选', | ||||
|         checkbox: '多选', | ||||
|         select: '单下拉框' | ||||
|       }[type] | ||||
|     }, | ||||
|  | ||||
|     getFormInfo() { | ||||
|       this.instance.post(`/app/appquestionnairetemplate/statisticsTable?id=${this.params.id}`, null, { | ||||
|         params: { | ||||
|           ...this.search | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.fieldDataCount = res.data.fieldDataCount | ||||
|           this.fieldTypeCount = res.data.fieldTypeCount | ||||
|           this.fieldValueDistribution = res.data.fieldValueDistribution | ||||
|           this.subjectList = res.data.appQuestionnaireTemplate.fields.map((item, index) => { | ||||
|             const fieldInfo = JSON.parse(item.fieldInfo) | ||||
|             let options = fieldInfo.options | ||||
|             if (['radio', 'checkbox', 'select'].indexOf(item.fieldType) > -1) { | ||||
|               options = fieldInfo.options.map(v => { | ||||
|                 res.data.fieldValueDistribution[`field_${index}`].forEach(info => { | ||||
|                   if (info.fieldValue === v.label) { | ||||
|                     v.c = info.c | ||||
|                   } | ||||
|                 }) | ||||
|  | ||||
|                 return v | ||||
|               }) | ||||
|  | ||||
|             } | ||||
|  | ||||
|             return { | ||||
|               ...item, | ||||
|               ...fieldInfo, | ||||
|               options | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     getInfo() { | ||||
|       this.instance.post(`/app/appquestionnairetemplate/queryDetailById?id=${this.params.id}`).then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.info = res.data | ||||
|           this.targetList = res.data.fields.map(item => { | ||||
|             return JSON.parse(item.fieldInfo) | ||||
|           }) | ||||
|  | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     cancel(isRefresh) { | ||||
|       this.$emit('change', { | ||||
|         type: 'list', | ||||
|         isRefresh: !!isRefresh | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| .statistics { | ||||
|   * { | ||||
|     box-sizing: border-box; | ||||
|     font-weight: normal; | ||||
|     font-style: normal; | ||||
|   } | ||||
|  | ||||
|   .preview { | ||||
|     ::v-deep .el-textarea.is-disabled, ::v-deep .el-textarea__inner { | ||||
|       color: #666 !important; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .form { | ||||
|     .left-item__item--banner { | ||||
|       img { | ||||
|         width: 100%; | ||||
|         height: 235px; | ||||
|       } | ||||
|  | ||||
|       .config-item__banner { | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         justify-content: center; | ||||
|         flex-direction: column; | ||||
|         width: 100%; | ||||
|         height: 235px; | ||||
|         line-height: 1; | ||||
|         border: 1px dashed #bbb; | ||||
|  | ||||
|         span { | ||||
|           margin-top: 4px; | ||||
|           color: #555555; | ||||
|           font-size: 14px; | ||||
|         } | ||||
|  | ||||
|         i { | ||||
|           font-size: 30px; | ||||
|           color: #8899bb; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .left-item__item--formname { | ||||
|       margin: 16px 0 32px; | ||||
|       padding: 0 12px; | ||||
|       color: #333333; | ||||
|       font-size: 15px; | ||||
|       font-weight: normal; | ||||
|       text-align: center; | ||||
|       word-break: break-all; | ||||
|     } | ||||
|  | ||||
|     .left-item__item--text { | ||||
|       line-height: 20px; | ||||
|       // margin-bottom: 48px; | ||||
|       padding: 0 12px 20px; | ||||
|       text-align: justify; | ||||
|       color: #666; | ||||
|       font-size: 14px; | ||||
|       word-break: break-all; | ||||
|     } | ||||
|  | ||||
|     .components-item { | ||||
|       position: relative; | ||||
|       padding: 16px 16px; | ||||
|  | ||||
|       .left-item__item--wrapper { | ||||
|         & > img { | ||||
|           max-width: 300px; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .left-item__item--upload { | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         justify-content: center; | ||||
|         flex-direction: column; | ||||
|         width: 120px; | ||||
|         height: 120px; | ||||
|         border-radius: 6px; | ||||
|         border: 1px dashed #bbb; | ||||
|  | ||||
|         i { | ||||
|           font-size: 24px; | ||||
|           color: #8899bb; | ||||
|         } | ||||
|  | ||||
|         span { | ||||
|           margin-top: 4px; | ||||
|           font-size: 12px; | ||||
|           color: #555; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .text-item { | ||||
|         input { | ||||
|           display: block; | ||||
|           width: 100%; | ||||
|           height: 40px; | ||||
|           border: none; | ||||
|           border-bottom: 1px solid #ddd; | ||||
|  | ||||
|           &:focus { | ||||
|             outline: none; | ||||
|           } | ||||
|  | ||||
|           &:disabled { | ||||
|             background: #fff; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .textarea-item { | ||||
|         textarea { | ||||
|           width: 100%; | ||||
|           height: 120px; | ||||
|           resize: none; | ||||
|           border: 1px solid #ddd; | ||||
|           padding: 10px; | ||||
|  | ||||
|           &:focus { | ||||
|             outline: none; | ||||
|           } | ||||
|  | ||||
|           &:disabled { | ||||
|             background: #fff; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .radio-item { | ||||
|         display: flex; | ||||
|         margin-bottom: 10px; | ||||
|  | ||||
|         input { | ||||
|           position: relative; | ||||
|           top: 2px; | ||||
|         } | ||||
|  | ||||
|         &:last-child { | ||||
|           margin-bottom: 0; | ||||
|         } | ||||
|  | ||||
|         label { | ||||
|           margin-left: 10px; | ||||
|         } | ||||
|  | ||||
|         img { | ||||
|           width: 60px; | ||||
|           margin-left: 10px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .left-item__item--title { | ||||
|       display: flex; | ||||
|       margin-bottom: 10px; | ||||
|  | ||||
|       i { | ||||
|         position: relative; | ||||
|         top: 3px; | ||||
|         margin-right: 5px; | ||||
|         color: #E22120; | ||||
|       } | ||||
|  | ||||
|       span { | ||||
|         position: relative; | ||||
|         top: 3px; | ||||
|       } | ||||
|  | ||||
|       h2 { | ||||
|         color: #333333; | ||||
|         font-size: 15px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .table-tags { | ||||
|     .el-tag { | ||||
|       margin-right: 8px; | ||||
|       margin-bottom: 8px; | ||||
|       border: 1px solid #D0D4DC; | ||||
|       background: #F3F4F7; | ||||
|       border-radius: 4px; | ||||
|       font-size: 13px; | ||||
|       color: #222222; | ||||
|  | ||||
|       &:last-child { | ||||
|         margin-right: 0; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   h2, h3 { | ||||
|     margin: 0; | ||||
|   } | ||||
|  | ||||
|   .userinfo { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|  | ||||
|     img { | ||||
|       width: 40px; | ||||
|       height: 40px; | ||||
|       margin-right: 8px; | ||||
|       border-radius: 2px; | ||||
|     } | ||||
|  | ||||
|     h3 { | ||||
|       font-size: 14px; | ||||
|       font-weight: normal; | ||||
|       color: #222222; | ||||
|     } | ||||
|  | ||||
|     .userinfo-right__top { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       margin-bottom: 10px; | ||||
|       cursor: pointer; | ||||
|       white-space: nowrap; | ||||
|     } | ||||
|  | ||||
|     span { | ||||
|       padding-left: 8px; | ||||
|       color: #2EA222; | ||||
|       font-size: 14px; | ||||
|       white-space: nowrap; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .statistics-wrapper { | ||||
|     background: #FFFFFF; | ||||
|     box-shadow: 0 4px 6px -2px rgba(15, 15, 21, 0.15); | ||||
|     border-radius: 2px; | ||||
|  | ||||
|     .statistics-wrapper__title { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       height: 56px; | ||||
|       padding: 0 16px; | ||||
|       border-bottom: 1px solid #EEEEEE; | ||||
|  | ||||
|       span { | ||||
|         height: 56px; | ||||
|         line-height: 56px; | ||||
|         color: #888888; | ||||
|         font-size: 16px; | ||||
|         font-weight: 600; | ||||
|         cursor: pointer; | ||||
|         user-select: none; | ||||
|         border-bottom: 3px solid transparent; | ||||
|  | ||||
|         &:first-child { | ||||
|           margin-right: 32px; | ||||
|         } | ||||
|  | ||||
|         &.active { | ||||
|           color: #222222; | ||||
|           border-color: #2266FF; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .statistics-wrapper__body--list { | ||||
|       padding: 0 40px 20px; | ||||
|  | ||||
|       .statistics-wrapper__body--item { | ||||
|         margin-bottom: 20px; | ||||
|         background: #FFFFFF; | ||||
|         border-radius: 4px; | ||||
|         border: 1px solid #DDDDDD; | ||||
|       } | ||||
|  | ||||
|       .statistics-wrapper__body--bottom { | ||||
|         padding: 20px; | ||||
|  | ||||
|         .statistics-wrapper__body--select { | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           justify-content: space-between; | ||||
|           height: 48px; | ||||
|  | ||||
|           & > div { | ||||
|             display: flex; | ||||
|             align-items: center; | ||||
|           } | ||||
|  | ||||
|           .left { | ||||
|             h2 { | ||||
|               max-width: 384px; | ||||
|               margin-right: 10px; | ||||
|               overflow: hidden; | ||||
|               text-overflow: ellipsis; | ||||
|               white-space: nowrap; | ||||
|               font-size: 12px; | ||||
|               color: #222222; | ||||
|             } | ||||
|  | ||||
|             span { | ||||
|               color: #888888; | ||||
|               font-size: 12px; | ||||
|             } | ||||
|           } | ||||
|  | ||||
|           .right { | ||||
|             i { | ||||
|               width: 50px; | ||||
|               text-align: right; | ||||
|               color: #2266FF; | ||||
|               font-size: 12px; | ||||
|             } | ||||
|  | ||||
|             .progress { | ||||
|               position: relative; | ||||
|               width: 500px; | ||||
|               height: 8px; | ||||
|               margin-right: 10px; | ||||
|               background: #EEEEEE; | ||||
|               border-radius: 5px; | ||||
|  | ||||
|               div { | ||||
|                 position: absolute; | ||||
|                 top: 0; | ||||
|                 left: 0; | ||||
|                 height: 8px; | ||||
|                 background: #2266FF; | ||||
|                 border-radius: 5px; | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .statistics-wrapper__body--top { | ||||
|         display: flex; | ||||
|         justify-content: space-between; | ||||
|         align-items: center; | ||||
|         height: 70px; | ||||
|         padding: 0 20px; | ||||
|         background: #FFFFFF; | ||||
|         border-radius: 4px 4px 0 0; | ||||
|         border-bottom: 1px solid #DDDDDD; | ||||
|  | ||||
|         & > div { | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           font-size: 14px; | ||||
|         } | ||||
|  | ||||
|         .left { | ||||
|           flex: 1; | ||||
|  | ||||
|           h2 { | ||||
|             color: #222222; | ||||
|             font-size: 14px; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .right { | ||||
|           span { | ||||
|             color: #888888; | ||||
|           } | ||||
|  | ||||
|           i { | ||||
|             color: #2266FF; | ||||
|             padding: 0 4px; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .statistics-wrapper__body--info { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       height: 70px; | ||||
|       line-height: 1; | ||||
|       padding: 0 40px; | ||||
|       color: #555555; | ||||
|       font-size: 14px; | ||||
|  | ||||
|       i { | ||||
|         padding: 0 4px; | ||||
|         font-weight: 600; | ||||
|         font-style: normal; | ||||
|         color: #2266FF; | ||||
|         font-size: 14px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										282
									
								
								packages/work/AppAskForm/components/Template.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										282
									
								
								packages/work/AppAskForm/components/Template.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,282 @@ | ||||
| <template> | ||||
|   <ai-list class="template" isTabs> | ||||
|     <template slot="content"> | ||||
|       <ai-search-bar bottomBorder> | ||||
|         <template #left> | ||||
|           <ai-select | ||||
|               v-model="search.type" | ||||
|               @change="search.current = 1, getList()" | ||||
|               placeholder="项目类型" | ||||
|               :selectList="$dict.getDict('questionnaireType')"> | ||||
|           </ai-select> | ||||
|         </template> | ||||
|         <template #right> | ||||
|           <el-input | ||||
|               v-model="search.title" | ||||
|               size="small" | ||||
|               placeholder="请输入模板名称或创建人" | ||||
|               clearable | ||||
|               v-throttle="() => {search.current = 1, getList()}" | ||||
|               @clear="search.current = 1, search.title = '', getList()" | ||||
|               suffix-icon="iconfont iconSearch"> | ||||
|           </el-input> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <ai-search-bar style="margin-top: 12px;"> | ||||
|         <template #left> | ||||
|           <el-button type="primary" @click="isShow = true">新建模板</el-button> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <ai-table | ||||
|           :tableData="tableData" | ||||
|           :col-configs="colConfigs" | ||||
|           :total="total" | ||||
|           style="margin-top: 6px;" | ||||
|           :current.sync="search.current" | ||||
|           :size.sync="search.size" | ||||
|           @getList="getList"> | ||||
|         <el-table-column slot="type" width="120px" label="项目类型" align="center"> | ||||
|           <template slot-scope="{ row }"> | ||||
|             <div class="tags-wrapper"> | ||||
|               <span class="tags" :class="'type-' + row.type">{{ dict.getLabel('questionnaireType', row.type) }}</span> | ||||
|             </div> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column slot="options" width="160px" fixed="right" label="操作" align="center"> | ||||
|           <template slot-scope="{ row }"> | ||||
|             <div class="table-options"> | ||||
|               <el-button type="text" @click="toEdit(row.id, row.type)">编辑</el-button> | ||||
|               <el-button type="text" @click="quote(row.id, row.type)">引用</el-button> | ||||
|               <el-button type="text" @click="remove(row.id)">删除</el-button> | ||||
|             </div> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </ai-table> | ||||
|       <ai-dialog | ||||
|           :visible.sync="isShow" | ||||
|           width="800px" | ||||
|           title="请选择新建模板类型" | ||||
|           @onConfirm="onConfirm"> | ||||
|         <div class="type-list"> | ||||
|           <div class="type-item" @click="currIndex = 0" :class="[currIndex === 0 ? 'active' : '']"> | ||||
|             <svg class="icon" aria-hidden="true"> | ||||
|               <use xlink:href="#iconwenjuandiaocha"></use> | ||||
|             </svg> | ||||
|             <span>问卷调查</span> | ||||
|           </div> | ||||
|           <div class="type-item" @click="currIndex = 1" :class="[currIndex === 1 ? 'active' : '']"> | ||||
|             <svg class="icon" aria-hidden="true"> | ||||
|               <use xlink:href="#iconkaoshiceping"></use> | ||||
|             </svg> | ||||
|             <span>考试测评</span> | ||||
|           </div> | ||||
|           <div class="type-item" @click="currIndex = 2" :class="[currIndex === 2 ? 'active' : '']"> | ||||
|             <svg class="icon" aria-hidden="true"> | ||||
|               <use xlink:href="#iconbaomingdengji"></use> | ||||
|             </svg> | ||||
|             <span>报名登记</span> | ||||
|           </div> | ||||
|           <div class="type-item" @click="currIndex = 3" :class="[currIndex === 3 ? 'active' : '']"> | ||||
|             <svg class="icon" aria-hidden="true"> | ||||
|               <use xlink:href="#iconmanyidiaocha"></use> | ||||
|             </svg> | ||||
|             <span>满意调查</span> | ||||
|           </div> | ||||
|           <div class="type-item" @click="currIndex = 4" :class="[currIndex === 4 ? 'active' : '']"> | ||||
|             <svg class="icon" aria-hidden="true"> | ||||
|               <use xlink:href="#icontoupiaopingxuan"></use> | ||||
|             </svg> | ||||
|             <span>投票评选</span> | ||||
|           </div> | ||||
|         </div> | ||||
|       </ai-dialog> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: 'Template', | ||||
|  | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object | ||||
|   }, | ||||
|  | ||||
|   data() { | ||||
|     return { | ||||
|       search: { | ||||
|         current: 1, | ||||
|         status: '', | ||||
|         type: '', | ||||
|         size: 10, | ||||
|         templateType: 1, | ||||
|         title: '' | ||||
|       }, | ||||
|       currIndex: 0, | ||||
|       isShow: false, | ||||
|       total: 10, | ||||
|       colConfigs: [ | ||||
|         {prop: 'title', label: '模板名称', align: 'left'}, | ||||
|         {slot: 'type', label: '项目类型', align: 'center'}, | ||||
|         {prop: 'quoteCount', label: '引用次数', align: 'center'}, | ||||
|         {prop: 'createUserName', label: '创建人', align: 'center'}, | ||||
|         {prop: 'createUnitName', label: '创建单位', align: 'center'}, | ||||
|         {prop: 'createTime', label: '创建时间', align: 'center'} | ||||
|       ], | ||||
|       tableData: [] | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   mounted() { | ||||
|     this.getList() | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     getList() { | ||||
|       this.instance.post(`/app/appquestionnairetemplate/list`, null, { | ||||
|         params: { | ||||
|           ...this.search | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.tableData = res.data.records | ||||
|           this.total = res.data.total | ||||
|  | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     quote(id, type) { | ||||
|       this.$emit('change', { | ||||
|         type: 'add', | ||||
|         params: { | ||||
|           id, | ||||
|           type, | ||||
|           isQuote: true, | ||||
|           templateType: 0 | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     remove(id) { | ||||
|       this.$confirm('确定删除该数据?').then(() => { | ||||
|         this.instance.post(`/app/appquestionnairetemplate/deleteShareTemplate?ids=${id}`).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.$message.success('删除成功!') | ||||
|             this.getList() | ||||
|           } | ||||
|         }) | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     toAdd(id) { | ||||
|       this.$emit('change', { | ||||
|         type: 'Add', | ||||
|         params: { | ||||
|           id | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     toEdit(id, type) { | ||||
|       this.$emit('change', { | ||||
|         type: 'add', | ||||
|         params: { | ||||
|           id, | ||||
|           type, | ||||
|           templateType: 1 | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     onConfirm() { | ||||
|       this.$emit('change', { | ||||
|         type: 'add', | ||||
|         params: { | ||||
|           id: '', | ||||
|           templateType: 1, | ||||
|           type: this.currIndex | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .template { | ||||
|   .tags-wrapper { | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|   } | ||||
|  | ||||
|   .type-list { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|  | ||||
|     .type-item { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|       width: 128px; | ||||
|       height: 64px; | ||||
|       margin-right: 20px; | ||||
|       background: #FFFFFF; | ||||
|       // box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.08); | ||||
|       border-radius: 2px; | ||||
|       cursor: pointer; | ||||
|       border: 1px solid #E4E8EF; | ||||
|  | ||||
|       svg { | ||||
|         width: 24px; | ||||
|         height: 24px; | ||||
|         margin-right: 8px; | ||||
|       } | ||||
|  | ||||
|       &.active { | ||||
|         border: 1px solid #2266FF; | ||||
|       } | ||||
|  | ||||
|       &:last-child { | ||||
|         margin-right: 0; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .tags { | ||||
|     display: block; | ||||
|     width: 64px; | ||||
|     height: 24px; | ||||
|     line-height: 24px; | ||||
|     text-align: center; | ||||
|     border-radius: 4px; | ||||
|     font-size: 12px; | ||||
|   } | ||||
|  | ||||
|   .type-0 { | ||||
|     color: #2266FF; | ||||
|     background: rgba(34, 102, 255, 0.1); | ||||
|   } | ||||
|  | ||||
|   .type-1 { | ||||
|     color: rgba(34, 170, 153, 1); | ||||
|     background: rgba(34, 170, 153, 0.1); | ||||
|   } | ||||
|  | ||||
|   .type-2 { | ||||
|     color: rgba(248, 180, 37, 1); | ||||
|     background: rgba(248, 180, 37, 0.1); | ||||
|   } | ||||
|  | ||||
|   .type-3 { | ||||
|     color: rgba(102, 119, 187, 1); | ||||
|     background: rgba(102, 119, 187, 0.1); | ||||
|   } | ||||
|  | ||||
|   .type-4 { | ||||
|     color: rgba(236, 68, 97, 1); | ||||
|     background: rgba(236, 68, 97, 0.1); | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										181
									
								
								packages/work/AppAskForm/components/config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								packages/work/AppAskForm/components/config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,181 @@ | ||||
| export const components = [ | ||||
| 	{ | ||||
| 		type: 'options', | ||||
| 		tips: '(可重复添加)', | ||||
| 		label: '选项', | ||||
| 		children: [ | ||||
| 			{ | ||||
| 				type: 'radio', | ||||
| 				label: '单选', | ||||
| 				fixedLabel: '单选', | ||||
| 				value: '', | ||||
| 				points: '', | ||||
| 				icon: 'iconradio', | ||||
| 				isShowPoints: false, | ||||
| 				required: true, | ||||
| 				hasAnswer: false, | ||||
| 				answer: '', | ||||
| 				pointType: '0', | ||||
| 				pointDict: [ | ||||
| 					{ | ||||
| 						dictName: '此题有唯一答案和分值', | ||||
| 						dictValue: '0' | ||||
| 					}, | ||||
| 					{ | ||||
| 						dictName: '每个选项都有对应分值', | ||||
| 						dictValue: '1' | ||||
| 					} | ||||
| 				], | ||||
| 				options: [ | ||||
| 					{ | ||||
| 						label: '选项1', | ||||
| 						value: '', | ||||
| 						point: '', | ||||
| 						img: [] | ||||
| 					}, | ||||
| 					{ | ||||
| 						label: '选项2', | ||||
| 						value: '', | ||||
| 						point: '', | ||||
| 						img: [] | ||||
| 					} | ||||
| 				], | ||||
| 				title: '' | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'checkbox', | ||||
| 				label: '多选', | ||||
| 				fixedLabel: '多选', | ||||
| 				points: '', | ||||
| 				icon: 'iconcheck_box', | ||||
| 				isShowPoints: false, | ||||
| 				required: true, | ||||
| 				hasAnswer: false, | ||||
| 				answer: [], | ||||
| 				value: [], | ||||
| 				pointType: '0', | ||||
| 				pointDict: [ | ||||
| 					{ | ||||
| 						dictName: '此题有唯一答案和分值', | ||||
| 						dictValue: '0' | ||||
| 					}, | ||||
| 					{ | ||||
| 						dictName: '每个选项都有对应分值', | ||||
| 						dictValue: '1' | ||||
| 					}, | ||||
| 					{ | ||||
| 						dictName: '答对几项得几分,答错不得分', | ||||
| 						dictValue: '2' | ||||
| 					} | ||||
| 				], | ||||
| 				options: [ | ||||
| 					{ | ||||
| 						label: '选项1', | ||||
| 						value: '', | ||||
| 						point: '', | ||||
| 						img: [] | ||||
| 					}, | ||||
| 					{ | ||||
| 						label: '选项2', | ||||
| 						point: '', | ||||
| 						value: '', | ||||
| 						img: [] | ||||
| 					} | ||||
| 				], | ||||
| 				title: '' | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'select', | ||||
| 				label: '单下拉框', | ||||
| 				fixedLabel: '单下拉框', | ||||
| 				value: '', | ||||
| 				points: '', | ||||
| 				icon: 'iconSelect', | ||||
| 				isShowPoints: false, | ||||
| 				required: true, | ||||
| 				hasAnswer: false, | ||||
| 				answer: '', | ||||
| 				pointType: '0', | ||||
| 				pointDict: [ | ||||
| 					{ | ||||
| 						dictName: '此题有唯一答案和分值', | ||||
| 						dictValue: '0' | ||||
| 					}, | ||||
| 					{ | ||||
| 						dictName: '每个选项都有对应分值', | ||||
| 						dictValue: '1' | ||||
| 					} | ||||
| 				], | ||||
| 				options: [ | ||||
| 					{ | ||||
| 						label: '选项1', | ||||
| 						value: '', | ||||
| 						point: '', | ||||
| 						img: [] | ||||
| 					}, | ||||
| 					{ | ||||
| 						label: '选项2', | ||||
| 						value: '', | ||||
| 						point: '', | ||||
| 						img: [] | ||||
| 					} | ||||
| 				], | ||||
| 				title: '' | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	{ | ||||
| 		type: 'input', | ||||
| 		tips: '(可重复添加)', | ||||
| 		label: '填空', | ||||
| 		children: [ | ||||
| 			{ | ||||
| 				type: 'input', | ||||
| 				label: '单行填空', | ||||
| 				fixedLabel: '单行填空', | ||||
| 				value: '', | ||||
| 				pointType: '0', | ||||
| 				icon: 'icontext_box', | ||||
| 				isShowPoints: false, | ||||
| 				points: '', | ||||
| 				required: true, | ||||
| 				hasAnswer: false, | ||||
| 				placeholder: '请输入...', | ||||
| 				answer: '' | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'textarea', | ||||
| 				label: '多行填空', | ||||
| 				fixedLabel: '多行填空', | ||||
| 				pointType: '0', | ||||
| 				icon: 'icontext_area', | ||||
| 				points: '', | ||||
| 				isShowPoints: false, | ||||
| 				required: true, | ||||
| 				hasAnswer: false, | ||||
| 				answer: '', | ||||
| 				placeholder: '请输入...', | ||||
| 				value: '' | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	{ | ||||
| 		type: 'annex', | ||||
| 		tips: '(可重复添加)', | ||||
| 		label: '附件', | ||||
| 		children: [ | ||||
| 			{ | ||||
| 				type: 'upload', | ||||
| 				label: '上传图片', | ||||
| 				fixedLabel: '上传图片', | ||||
| 				value: '', | ||||
| 				icon: 'iconpic', | ||||
| 				isShowPoints: false, | ||||
| 				points: '', | ||||
| 				required: true, | ||||
| 				hasAnswer: false, | ||||
| 				answer: '' | ||||
| 			} | ||||
| 		] | ||||
| 	} | ||||
| ]; | ||||
							
								
								
									
										66
									
								
								packages/work/AppAssessment/AppAssessment.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								packages/work/AppAssessment/AppAssessment.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| <template> | ||||
|   <div class="doc-circulation ailist-wrapper"> | ||||
|     <keep-alive :include="['List']"> | ||||
|       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> | ||||
|     </keep-alive> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import Statistics from './components/Statistics' | ||||
|   import List from './components/List' | ||||
|  | ||||
|   export default { | ||||
|     name: 'AppAssessment', | ||||
|     label: '工作考核', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         component: 'Statistics', | ||||
|         params: {}, | ||||
|         include: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     components: { | ||||
|       Statistics, | ||||
|       List | ||||
|     }, | ||||
|  | ||||
|     mounted () { | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       onChange (data) { | ||||
|         if (data.type === 'List') { | ||||
|           this.component = 'List' | ||||
|           this.params = data.params | ||||
|         } | ||||
|  | ||||
|         if (data.type === 'Statistics') { | ||||
|           this.component = 'Statistics' | ||||
|           this.params = data.params | ||||
|  | ||||
|           this.$nextTick(() => { | ||||
|             if (data.isRefresh) { | ||||
|               this.$refs.component.getList() | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss"> | ||||
|   .doc-circulation { | ||||
|     height: 100%; | ||||
|     background: #F3F6F9; | ||||
|     overflow: auto; | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										120
									
								
								packages/work/AppAssessment/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								packages/work/AppAssessment/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | ||||
| <template> | ||||
|   <ai-list class="notice"> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="走访排查情况统计" isShowBottomBorder isShowBack @onBackClick="back"></ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-search-bar> | ||||
|         <template #left> | ||||
|           <el-date-picker | ||||
|             value-format="yyyy-MM" | ||||
|             v-model="search.startDate" | ||||
|             type="month" | ||||
|             size="small" | ||||
|             unlink-panels | ||||
|             placeholder="请选择考核开始月份" | ||||
|             @change="search.current = 1, getList()" /> | ||||
|           <el-date-picker | ||||
|             value-format="yyyy-MM" | ||||
|             v-model="search.endDate" | ||||
|             type="month" | ||||
|             size="small" | ||||
|             unlink-panels | ||||
|             placeholder="请选择考核结束月份" | ||||
|             @change="search.current = 1, getList()" /> | ||||
|         </template> | ||||
|         <template #right> | ||||
|           <el-input | ||||
|             v-model="search.createUserName" | ||||
|             size="small" | ||||
|             placeholder="网格员姓名" | ||||
|             clearable | ||||
|             v-throttle="() => {search.current = 1, getList()}" | ||||
|             @clear="search.current = 1, search.createUserName = '', getList()" | ||||
|             suffix-icon="iconfont iconSearch"> | ||||
|           </el-input> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <ai-table | ||||
|         :tableData="tableData" | ||||
|         :col-configs="colConfigs" | ||||
|         :total="total" | ||||
|         style="margin-top: 12px;" | ||||
|         :current.sync="search.current" | ||||
|         :size.sync="search.size" | ||||
|         @selection-change="(v) => (ids = v.map((e) => e.id))" | ||||
|         @getList="getList"> | ||||
|       </ai-table> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import { mapState } from 'vuex' | ||||
|   export default { | ||||
|     name: 'List', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object | ||||
|     }, | ||||
|  | ||||
|     data() { | ||||
|       return { | ||||
|         search: { | ||||
|           current: 1, | ||||
|           size: 10, | ||||
|           createUserName: '', | ||||
|           endDate: '', | ||||
|           startDate: '' | ||||
|         }, | ||||
|         total: 10, | ||||
|         tableData: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       ...mapState(['user']), | ||||
|  | ||||
|       colConfigs () { | ||||
|         return [ | ||||
|           { prop: 'month', label: '考核月份', align: 'left' }, | ||||
|           { prop: 'createUserName', label: '网格员姓名', align: 'center' }, | ||||
|           { prop: 'phone', label: '网格员联系方式', align: 'center' }, | ||||
|           { prop: 'povertyNumber', label: '监测家庭数量', align: 'center' }, | ||||
|           { prop: 'logNumber', label: '开展走访次数', align: 'center' }, | ||||
|           { prop: 'povertyHouseholdNumber', label: '已走访家庭数量', align: 'center' }, | ||||
|           { prop: 'finishRate', label: '走访进度', align: 'center', formart: v => (v * 100).toFixed(1) + '%' } | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       this.getList() | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getList() { | ||||
|         this.instance.post(`/app/apppreventionreturntopovertylogstatistic/list`, null, { | ||||
|           params: { | ||||
|             ...this.search | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.tableData = res.data.records | ||||
|             this.total = res.data.total | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       back () { | ||||
|         this.$emit('change', { | ||||
|           type: 'Statistics' | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| </style> | ||||
							
								
								
									
										369
									
								
								packages/work/AppAssessment/components/Statistics.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										369
									
								
								packages/work/AppAssessment/components/Statistics.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,369 @@ | ||||
| <template> | ||||
|   <ai-list class="AppAssessment"> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="工作考核" isShowBottomBorder :hideLevel="hideLevel" :isShowArea="true" v-model="search.areaId" :instance="instance" @change="onChange"></ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <div class="statistics-top"> | ||||
|         <div class="statistics-top__item"> | ||||
|           <span>监测家庭户数</span> | ||||
|           <h2 style="color: #2266FF;">{{ totalInfo['监测家庭户数'] }}</h2> | ||||
|         </div> | ||||
|         <div class="statistics-top__item"> | ||||
|           <span>监测对象总数</span> | ||||
|           <h2 style="color: #22AA99;">{{ totalInfo['监测对象总数'] }}</h2> | ||||
|         </div> | ||||
|         <div class="statistics-top__item"> | ||||
|           <span>解除风险人数</span> | ||||
|           <h2 style="color: #F8B425">{{ totalInfo['解除风险人数'] }}</h2> | ||||
|         </div> | ||||
|         <div class="statistics-top__item"> | ||||
|           <span>解除风险户数</span> | ||||
|           <h2 style="color: red">{{ totalInfo['解除风险户数'] }}</h2> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="info"> | ||||
|         <ai-card title="饮用水和三保障情况"> | ||||
|           <template #content> | ||||
|             <ai-wrapper label-width="120px"> | ||||
|               <ai-info-item label="住房安全" :value="info['住房安全']"></ai-info-item> | ||||
|               <ai-info-item label="饮水安全" :value="info['饮水安全']"></ai-info-item> | ||||
|               <ai-info-item label="失学辍学" :value="info['失学辍学']"></ai-info-item> | ||||
|               <ai-info-item label="未参加医疗保险" :value="info['未参加医疗保险']"></ai-info-item> | ||||
|               <ai-info-item label="低收入家庭" :value="info['低收入家庭']"></ai-info-item> | ||||
|               <ai-info-item label="低于人均收入" :value="info['低于人均收入']"></ai-info-item> | ||||
|             </ai-wrapper> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|         <ai-card title="本月网格员走访进度"> | ||||
|           <template #right> | ||||
|             <el-button type="text" @click="toList">全部</el-button> | ||||
|           </template> | ||||
|           <template #content> | ||||
|             <div class="progress-wrapper"> | ||||
|               <div class="progress"> | ||||
|                 <div class="item" v-for="(item, index) in logList" :key="index"> | ||||
|                   <h2>{{ item.createUserName }}</h2> | ||||
|                   <el-progress :percentage="item.finishRate"></el-progress> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|       </div> | ||||
|       <ai-card title="帮扶走访情况"> | ||||
|         <template #content> | ||||
|           <ai-search-bar bottomBorder> | ||||
|             <template #left> | ||||
|               <el-date-picker | ||||
|                 value-format="yyyy-MM-dd" | ||||
|                 v-model="search.beginDate" | ||||
|                 type="date" | ||||
|                 size="small" | ||||
|                 unlink-panels | ||||
|                 placeholder="请选择开始日期" | ||||
|                 @change="search.current = 1, getList()" /> | ||||
|               <el-date-picker | ||||
|                 value-format="yyyy-MM-dd" | ||||
|                 v-model="search.endDate" | ||||
|                 type="date" | ||||
|                 size="small" | ||||
|                 unlink-panels | ||||
|                 placeholder="请选择结束日期" | ||||
|                 @change="search.current = 1, getLogCount()" /> | ||||
|               <ai-select | ||||
|                 v-model="search.isGird" | ||||
|                 clearable | ||||
|                 placeholder="请选择是否关联网格" | ||||
|                 :selectList="visitDict" | ||||
|                 @change="search.current = 1, getLogCount()"> | ||||
|               </ai-select> | ||||
|               <ai-select | ||||
|                 v-model="search.isVisit" | ||||
|                 clearable | ||||
|                 placeholder="请选择走访次数" | ||||
|                 :selectList="girdDict" | ||||
|                 @change="search.current = 1, getLogCount()"> | ||||
|               </ai-select> | ||||
|               <!-- <ai-download :instance="instance" url="/app/apppreventionreturntopovertyriskperson/export" :params="search" fileName="帮扶走访" :disabled="tableData.length == 0"> | ||||
|                 <el-button icon="iconfont iconExported" :disabled="tableData.length == 0">导出</el-button> | ||||
|               </ai-download> --> | ||||
|             </template> | ||||
|             <template #right> | ||||
|               <el-input | ||||
|                 v-model="search.name" | ||||
|                 size="small" | ||||
|                 placeholder="户主姓名/身份证号/网格员" | ||||
|                 clearable | ||||
|                 v-throttle="() => {search.current = 1, getLogCount()}" | ||||
|                 @clear="search.current = 1, search.name = '', getLogCount()" | ||||
|                 suffix-icon="iconfont iconSearch"> | ||||
|               </el-input> | ||||
|             </template> | ||||
|           </ai-search-bar> | ||||
|           <ai-table | ||||
|             :tableData="tableData" | ||||
|             :col-configs="colConfigs" | ||||
|             :total="total" | ||||
|             tableSize="small" | ||||
|             border | ||||
|             style="margin-top: 12px;" | ||||
|             :current.sync="search.current" | ||||
|             :size.sync="search.size" | ||||
|             @selection-change="(v) => (ids = v.map((e) => e.id))" | ||||
|             @getList="getLogCount"> | ||||
|           </ai-table> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import { mapState } from 'vuex' | ||||
|   export default { | ||||
|     name: 'Statistics', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object | ||||
|     }, | ||||
|  | ||||
|     data() { | ||||
|       return { | ||||
|         search: { | ||||
|           current: 1, | ||||
|           size: 10, | ||||
|           name: '', | ||||
|           areaId: '', | ||||
|           beginDate: '', | ||||
|           endDate: '', | ||||
|           isVisit: '', | ||||
|           isGird: '' | ||||
|         }, | ||||
|         visitDict: [{ | ||||
|           dictName: '否', | ||||
|           dictValue: '0' | ||||
|         }, { | ||||
|           dictName: '是', | ||||
|           dictValue: '1' | ||||
|         }], | ||||
|         girdDict: [{ | ||||
|           dictName: '等于0次', | ||||
|           dictValue: '0' | ||||
|         }, { | ||||
|           dictName: '大于0次', | ||||
|           dictValue: '1' | ||||
|         }], | ||||
|         logList: [], | ||||
|         info: {}, | ||||
|         ids: [], | ||||
|         total: 10, | ||||
|         hideLevel: 3, | ||||
|         totalInfo: {}, | ||||
|         tableData: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       ...mapState(['user']), | ||||
|  | ||||
|       colConfigs () { | ||||
|         return [ | ||||
|           { prop: 'name', label: '户主姓名', align: 'left' }, | ||||
|           { prop: 'sex', label: '性别', align: 'center', formart: v => this.dict.getLabel('sex', v) }, | ||||
|           { prop: 'idNumber', label: '身份证号', align: 'center' }, | ||||
|           { prop: 'householdPhone', label: '户主联系方式', align: 'center' }, | ||||
|           { prop: 'address', label: '家庭住址', align: 'center' }, | ||||
|           { prop: 'status', label: '状态', align: 'center', formart: v => this.dict.getLabel('fpRiskPersonStatus', v) }, | ||||
|           { prop: 'girdMemberName', label: '网格员', align: 'center' }, | ||||
|           { prop: 'girdMemberPhone', label: '网格员电话', align: 'center' }, | ||||
|           { prop: 'visitCount', label: '走访次数', align: 'center' } | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       this.search.areaId = this.user.info.areaId | ||||
|       this.hideLevel = this.user.info.areaList.length - 1 | ||||
|  | ||||
|       this.dict.load('fpRiskPersonStatus', 'sex').then(() => { | ||||
|         this.getLogCount() | ||||
|       }) | ||||
|       this.getTotal() | ||||
|       this.getList() | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getList() { | ||||
|         this.instance.post(`/app/apppreventionreturntopovertylogstatistic/list`, null, { | ||||
|           params: { | ||||
|             size: 15, | ||||
|             current: 1 | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.logList = res.data.records.map(v => { | ||||
|               return { | ||||
|                 ...v, | ||||
|                 finishRate: Number((v.finishRate * 100).toFixed(1)) | ||||
|               } | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       getLogCount() { | ||||
|         this.instance.post(`/app/apppreventionreturntopovertylog/service-rating-list`, null, { | ||||
|           params: { | ||||
|             ...this.search | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.tableData = res.data.records | ||||
|             this.total = res.data.total | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       onChange () { | ||||
|         this.getTotal() | ||||
|         this.getLogCount() | ||||
|       }, | ||||
|  | ||||
|       getTotal() { | ||||
|         this.instance.post(`/app/statistics/preventionreturntopoverty/povertyReportNumber`, null, { | ||||
|           params: { | ||||
|             ...this.search | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.totalInfo = res.data | ||||
|           } | ||||
|         }) | ||||
|  | ||||
|         this.instance.post(`/app/statistics/preventionreturntopoverty/drinkingWaterCount`, null, { | ||||
|           params: { | ||||
|             ...this.search | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.info = res.data | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       removeAll () { | ||||
|         var id = this.ids.join(',') | ||||
|         this.remove(id) | ||||
|       }, | ||||
|  | ||||
|       remove(id) { | ||||
|         this.$confirm('确定删除该数据?').then(() => { | ||||
|           this.instance.post(`/app/appmininotice/delete?ids=${id}`).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.$message.success('删除成功!') | ||||
|               this.getList() | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       toList () { | ||||
|         this.$emit('change', { | ||||
|           type: 'List', | ||||
|           params: { | ||||
|             id: '' | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .AppAssessment { | ||||
|     .info { | ||||
|       display: flex; | ||||
|       justify-content: space-between; | ||||
|  | ||||
|       .ai-card { | ||||
|         flex: 1; | ||||
|         height: 300px; | ||||
|         overflow-y: auto; | ||||
|  | ||||
|         &:first-child { | ||||
|           margin-right: 20px; | ||||
|         } | ||||
|  | ||||
|         .progress { | ||||
|           overflow-y: auto; | ||||
|           height: 190px; | ||||
|  | ||||
|           .item { | ||||
|             display: flex; | ||||
|             align-items: center; | ||||
|             margin-bottom: 12px; | ||||
|  | ||||
|             .el-progress { | ||||
|               flex: 1; | ||||
|             } | ||||
|  | ||||
|             h2 { | ||||
|               width: 90px; | ||||
|               margin-right: 30px; | ||||
|               font-size: 14px; | ||||
|               text-align: right; | ||||
|               color: #333; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .statistics-top { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       margin-bottom: 20px; | ||||
|  | ||||
|       & > div { | ||||
|         flex: 1; | ||||
|         height: 96px; | ||||
|         line-height: 1; | ||||
|         margin-right: 20px; | ||||
|         padding: 16px 24px; | ||||
|         background: #FFFFFF; | ||||
|         box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.15); | ||||
|         border-radius: 4px; | ||||
|  | ||||
|         &:last-child { | ||||
|           margin-right: 0; | ||||
|         } | ||||
|  | ||||
|         h3 { | ||||
|           font-size: 24px; | ||||
|         } | ||||
|  | ||||
|         span { | ||||
|           display: block; | ||||
|           margin-bottom: 16px; | ||||
|           color: #888888; | ||||
|           font-size: 16px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     ::v-deep .ai-list__content { | ||||
|       width: 100%; | ||||
|       .ai-list__content--right { | ||||
|         width: 100%!important; | ||||
|  | ||||
|         .ai-list__content--right-wrapper { | ||||
|           padding: 0!important; | ||||
|           background: transparent!important; | ||||
|           box-shadow: none!important; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										101
									
								
								packages/work/AppConference/AppConference.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								packages/work/AppConference/AppConference.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| <template> | ||||
|   <section class="conference"> | ||||
|     <ai-list v-if="!showDetail"> | ||||
|       <template slot="title"> | ||||
|         <ai-title title="会议管理"></ai-title> | ||||
|       </template> | ||||
|       <template slot="tabs"> | ||||
|         <el-tabs v-model="currIndex" @tab-click="handleClick"> | ||||
|           <el-tab-pane v-for="(tab,i) in tabs" :key="i" :label="tab.label" :name="String(i)"> | ||||
|             <component :is="tab.comp" v-if="currIndex==i" :ref="currIndex" :instance="instance" :dict="dict" | ||||
|                        :permissions="permissions" @goPage="goPage" :listType="listType" /> | ||||
|           </el-tab-pane> | ||||
|         </el-tabs> | ||||
|       </template> | ||||
|     </ai-list> | ||||
|  | ||||
|     <component v-else :is="currentComp" :instance="instance" :dict="dict" :detail="detailRow" :listType="listType" @gotoEdit="gotoAdd" ></component> | ||||
|  | ||||
|   </section> | ||||
| </template> | ||||
| <script> | ||||
| import addMeeting from './addMeeting'; | ||||
| import detail from './detail' | ||||
| import list from './list' | ||||
|  | ||||
| export default { | ||||
|   name: 'AppConference', | ||||
|   label: "会议管理", | ||||
|   components: {addMeeting, detail, list}, | ||||
|   provide() { | ||||
|     return { | ||||
|       top: this | ||||
|     } | ||||
|   }, | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       //会议状态,0、草稿;1、未开始;2、进行中;3、已取消;4、已结束 | ||||
|       //参会状态,0、未确认;1、已确认;2、缺席 | ||||
|       currIndex: "0", | ||||
|       currentComp: "", | ||||
|       showDetail: false, | ||||
|       detailRow: {}, | ||||
|       listType: '1', | ||||
|     } | ||||
|   }, | ||||
|   computed:{ | ||||
|     tabs() { | ||||
|       return [ | ||||
|         {label: "我参与的会议", name: "addMeeting", comp: list, detail: detail, permission: ""}, | ||||
|         {label: "我发起的会议", name: "addMeeting",  comp: list, detail: detail, permission: ""}, | ||||
|       ] | ||||
|     }, | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     goPage(params) { | ||||
|       this.detailRow = params.row | ||||
|       this.currentComp = params.comp | ||||
|        | ||||
|       if(params.comp == 'detail' || params.comp == 'addMeeting') { | ||||
|         this.showDetail = true | ||||
|       } | ||||
|     }, | ||||
|     handleClick() { | ||||
|       if (this.currIndex == 0) { | ||||
|         this.listType = '1' | ||||
|       } else { | ||||
|         this.listType = '0' | ||||
|       } | ||||
|     }, | ||||
|     goBack() { | ||||
|       this.showDetail = false; | ||||
|       if (this.currIndex == '0') { | ||||
|         this.listType = '1' | ||||
|       } else { | ||||
|         this.listType = '0' | ||||
|       } | ||||
|     }, | ||||
|     gotoAdd(obj) { | ||||
|       this.showDetail = true | ||||
|       this.detailRow = obj | ||||
|       this.currentComp = 'addMeeting' | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
| <style lang="scss" scoped> | ||||
|   .conference { | ||||
|     height: 100%; | ||||
|  | ||||
|     ::v-deep .ai-list__content--right-wrapper { | ||||
|       background-color: transparent !important; | ||||
|       box-shadow: none !important; | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										244
									
								
								packages/work/AppConference/addMeeting.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								packages/work/AppConference/addMeeting.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | ||||
| <template> | ||||
|   <ai-detail class="addMeeting"> | ||||
|     <ai-title slot="title" title="发起会议" isShowBack isShowBottomBorder @onBackClick="$parent.goBack"/> | ||||
|     <template #content> | ||||
|       <ai-card title="会议信息"> | ||||
|         <template #content> | ||||
|           <el-form :model="saveData" status-icon ref="ruleForm" :rules="rules" label-width="100px" | ||||
|                    label-position="right"> | ||||
|             <el-form-item label="会议标题:" prop="title"> | ||||
|               <el-input v-model="saveData.title" size="small" placeholder="请输入..." | ||||
|                         :maxlength="30" show-word-limit></el-input> | ||||
|             </el-form-item> | ||||
|             <el-row type="flex" justify="space-between"> | ||||
|               <el-form-item label="开始时间:" prop="startTime"> | ||||
|                 <el-date-picker | ||||
|                     :editable="false" | ||||
|                     value-format="yyyy-MM-dd HH:mm:ss" | ||||
|                     v-model="saveData.startTime" | ||||
|                     :picker-options="pickerOptions" | ||||
|                     type="datetime" | ||||
|                     size="small" | ||||
|                     placeholder="选择开始时间"> | ||||
|                 </el-date-picker> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="结束时间:" prop="endTime"> | ||||
|                 <el-date-picker | ||||
|                     :editable="false" | ||||
|                     value-format="yyyy-MM-dd HH:mm:ss" | ||||
|                     v-model="saveData.endTime" | ||||
|                     :picker-options="pickerOptions" | ||||
|                     type="datetime" | ||||
|                     :disabled="!Boolean(saveData.startTime)" | ||||
|                     size="small" | ||||
|                     placeholder="选择结束时间"> | ||||
|                 </el-date-picker> | ||||
|               </el-form-item> | ||||
|             </el-row> | ||||
|             <el-form-item label="会议地点:" prop="address"> | ||||
|               <el-input v-model="saveData.address" size="small" placeholder="请输入..." | ||||
|                         :maxlength="30" show-word-limit></el-input> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="会议内容:" prop="content"> | ||||
|               <el-input v-model="saveData.content" size="small" placeholder="请输入..." | ||||
|                         type="textarea" :rows="8" :maxlength="500" show-word-limit></el-input> | ||||
|             </el-form-item> | ||||
|             <el-row type="flex" justify="space-between"> | ||||
|               <el-form-item label="参会提醒:" prop="noticeBefore"> | ||||
|                 <ai-select v-model="saveData.noticeBefore" | ||||
|                            placeholder="请选择" | ||||
|                            :selectList="dict.getDict('meetingNoticeBefore')" | ||||
|                 ></ai-select> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="确认提醒:" prop="noticeAfter"> | ||||
|                 <ai-select v-model="saveData.noticeAfter" | ||||
|                            placeholder="请选择" | ||||
|                            :selectList="dict.getDict('meetingNoticeAfter')" | ||||
|                 ></ai-select> | ||||
|               </el-form-item> | ||||
|             </el-row> | ||||
|             <el-form-item label="会议资料:" prop="files"> | ||||
|               <ai-uploader :instance="instance" @change="handleChange" isShowTip fileType="file" | ||||
|                            v-model="saveData.fileList" | ||||
|                            acceptType=".zip,.rar,.doc,.docx,.xls,.ppt,.pptx,.pdf,.txt,.jpg,.png,.xlsx" | ||||
|                            :limit="9"></ai-uploader> | ||||
|             </el-form-item> | ||||
|           </el-form> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|       <ai-card title="参会人员信息"> | ||||
|         <template #right> | ||||
|           <ai-wechat-selecter slot="append" :instance="instance" v-model="saveData.attendees"> | ||||
|             <el-button type="text" icon="iconfont iconAdd">选择参会人员</el-button> | ||||
|           </ai-wechat-selecter> | ||||
|         </template> | ||||
|         <template #content> | ||||
|           <ai-table | ||||
|               border | ||||
|               :tableData="saveData.attendees" | ||||
|               :colConfigs="colConfigs" | ||||
|               :isShowPagination="false"> | ||||
|             <el-table-column label="操作" slot="option" align="center"> | ||||
|               <template v-slot="{row}"> | ||||
|                 <el-button type="text" title="删除" @click="deletePer(row)">删除</el-button> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|           </ai-table> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|     </template> | ||||
|     <template #footer> | ||||
|       <el-button @click="$parent.goBack">取消</el-button> | ||||
|       <el-button type="primary" @click="saveFrom(0)">保存草稿</el-button> | ||||
|       <el-button type="primary" @click="saveFrom(1)">保存并发布</el-button> | ||||
|     </template> | ||||
|   </ai-detail> | ||||
| </template> | ||||
| <script> | ||||
| import {mapState} from "vuex"; | ||||
| import moment from 'dayjs' | ||||
|  | ||||
| export default { | ||||
|   name: "addMeeting", | ||||
|   inject: ['top'], | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function, | ||||
|     detail: Object | ||||
|   }, | ||||
|   data() { | ||||
|     let endTimePass = (rule, value, callback) => { | ||||
|       if (value) { | ||||
|         if (moment(value).unix() - moment(this.saveData.startTime).unix() > 0) { | ||||
|           callback() | ||||
|         } else { | ||||
|           callback(new Error('结束时间要大于开始时间')); | ||||
|         } | ||||
|       } else { | ||||
|         callback(new Error('请选择结束时间')); | ||||
|       } | ||||
|     } | ||||
|     return { | ||||
|       saveData: { | ||||
|         noticeBefore: '4', | ||||
|         noticeAfter: '0', | ||||
|         attendees: [], | ||||
|         fileList: [] | ||||
|       }, | ||||
|       rules: { | ||||
|         title: [{required: true, message: '请填写会议标题', trigger: 'blur'}], | ||||
|         startTime: [{required: true, message: '请选择开始时间', trigger: 'blur'}], | ||||
|         endTime: [{required: true, validator: endTimePass, trigger: 'change'}], | ||||
|         address: [{required: true, message: '请填写会议地点', trigger: 'blur'}], | ||||
|         // content: [{required: true, message: '请填写会议内容', trigger: 'blur'}], | ||||
|         noticeBefore: [{required: true, message: '请选择参会提醒', trigger: 'blur'}], | ||||
|         noticeAfter: [{required: true, message: '请选择确认提醒', trigger: 'blur'}], | ||||
|       }, | ||||
|       pickerOptions: { | ||||
|         disabledDate(time) { | ||||
|           return time.getTime() < Date.now() - 8.64e7; | ||||
|         } | ||||
|       }, | ||||
|       showEdit: false, | ||||
|       total: 0, | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     handleChange(e) { | ||||
|       this.saveData.fileList = e | ||||
|     }, | ||||
|     deletePer(scope) { | ||||
|       this.$confirm('确认删除此参会人?') | ||||
|       .then(_ => { | ||||
|         if (this.detail.id) { //编辑 | ||||
|  | ||||
|         } else { //新增 | ||||
|           this.saveData.attendees.map((item, index) => { | ||||
|             if (item.id == scope.id) { | ||||
|               this.saveData.attendees.splice(index, 1) | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     saveFrom(status) { | ||||
|       this.$refs["ruleForm"].validate((valid) => { | ||||
|         if (this.saveData.attendees.length == 0) { | ||||
|           return this.$message.error("参会人不能为空!") | ||||
|         } | ||||
|         if (moment(this.saveData.startTime).unix() - moment(Date.now()).unix() < 0) { | ||||
|           return this.$message.error("会议开始时间已过期,请重新选择!"); | ||||
|         } | ||||
|         if (valid) { | ||||
|  | ||||
|           this.saveData.files = [] | ||||
|           this.saveData.fileList.map((item) => { | ||||
|             this.saveData.files.push(item.id) | ||||
|           }) | ||||
|           this.instance.post(`/app/appmeetinginfo/add-update`, { | ||||
|             ...this.saveData, | ||||
|             status: status, | ||||
|           }).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               if (status != 1) { | ||||
|                 this.$message.success("保存草稿成功") | ||||
|               } else { | ||||
|                 this.$message.success("发布成功") | ||||
|               } | ||||
|               this.$parent.goBack(); | ||||
|             } | ||||
|           }); | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     getDetail() { | ||||
|       this.instance.post(`/app/appmeetinginfo/info-id?id=${this.detail.id}`).then(res => { | ||||
|         if (res?.data) { | ||||
|           this.saveData = { | ||||
|             ...res.data, | ||||
|           }; | ||||
|           this.saveData.fileList = res.data.files || [] | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.dict.load("meetingNoticeAfter", "meetingNoticeBefore").then( | ||||
|         this.$nextTick(() => { | ||||
|           if (JSON.stringify(this.detail) == '{}') { | ||||
|             this.showEdit = false; | ||||
|           } else { | ||||
|             this.showEdit = true; | ||||
|             // this.saveData = {...this.detail}; | ||||
|             // this.compereList = this.saveData.hosts; | ||||
|             // this.saveData.attendees = this.saveData.attendees || []; | ||||
|             this.getDetail() | ||||
|           } | ||||
|         }) | ||||
|     ) | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|     headerTitle() { | ||||
|       return this.showEdit ? '修改会议' : '发起会议' | ||||
|     }, | ||||
|     colConfigs() { | ||||
|       return [ | ||||
|         {prop: 'name', align: 'center', label: '姓名'}, | ||||
|         {prop: 'departName', align: 'center', label: '所属单位'}, | ||||
|         {slot: 'option'} | ||||
|       ] | ||||
|     }, | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| <style lang="scss" scoped> | ||||
| .addMeeting { | ||||
|   ::v-deep .el-button--text { | ||||
|     .iconfont { | ||||
|       color: inherit; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										597
									
								
								packages/work/AppConference/detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										597
									
								
								packages/work/AppConference/detail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,597 @@ | ||||
| <template> | ||||
|   <section class="meetingDetail detail-content"> | ||||
|     <ai-detail> | ||||
|       <template #title> | ||||
|         <ai-title title="会议详情" isShowBottomBorder isShowBack @onBackClick="$parent.goBack"> | ||||
|           <template #rightBtn> | ||||
|             <p class="conference_top_area" v-if="listType==0"> | ||||
|               <!-- <el-button type="primary" v-if="detail.status==0" @click="changeMeeting('是否立即发布会议?')">立即发布</el-button> --> | ||||
|               <el-button type="primary" v-if="detail.status==1" @click="noticeMetting()">参会提醒</el-button> | ||||
|               <el-button type="primary" v-if="detail.status==0" @click="editMeeting()">修改会议</el-button> | ||||
|               <el-button class="del-btn-list" v-if="detail.status==1" @click="changeMeeting('是否取消会议?')">取消会议</el-button> | ||||
|               <el-button class="iconfont iconDelete del-btn-list" v-if="detail.status==0||detail.status==3" | ||||
|                          @click="changeMeeting('是否删除会议?')">删除会议 | ||||
|               </el-button> | ||||
|             </p> | ||||
|             <!-- v-if="detail.status==0||detail.status==3" --> | ||||
|             <p class="conference_top_area" v-if="listType==1&&info.status==1"> | ||||
|               <el-button @click="toDo" style="width:80px;" class="del-btn-list">待定</el-button> | ||||
|               <el-button @click="innerVisible=true" v-if="info.joinStatus!=2" style="width:80px;" class="del-btn-list"> | ||||
|                 请假 | ||||
|               </el-button> | ||||
|               <el-button type="primary" @click="changeMeeting('是否确认参会?')" v-if="info.joinStatus!=1" style="width:80px;"> | ||||
|                 确认参会 | ||||
|               </el-button> | ||||
|             </p> | ||||
|           </template> | ||||
|         </ai-title> | ||||
|       </template> | ||||
|       <template #content> | ||||
|         <ai-dialog | ||||
|             title="确认请假" | ||||
|             :visible.sync="innerVisible" | ||||
|             @onConfirm="queMeeting('writeInfo')" | ||||
|             @onCancel="innerVisible=false;" @close="$refs.writeInfo.resetFields()" | ||||
|             width="520px"> | ||||
|           <div class="addother_main" style="width:400px;margin:auto;"> | ||||
|             <el-form :model="writeInfo" status-icon ref="writeInfo" label-width="100px" class="demo-ruleForm"> | ||||
|               <el-form-item label="请假原因:" prop="reason" autocomplete="off" | ||||
|                             :rules="{ | ||||
|                                         required: true, message: '请假原因不能为空', trigger: 'blur' | ||||
|                                     }" | ||||
|               > | ||||
|                 <el-input v-model.trim="writeInfo.reason" autocomplete="off" size="mini" placeholder="请输入..." | ||||
|                           type="textarea" :rows="4" :maxlength="100" show-word-limit></el-input> | ||||
|               </el-form-item> | ||||
|  | ||||
|             </el-form> | ||||
|           </div> | ||||
|         </ai-dialog> | ||||
|         <ai-card title="会议说明"> | ||||
|           <template slot="content"> | ||||
|             <ai-wrapper class="mar-t16" label-width="70px" :columnsNumber="1"> | ||||
|               <ai-info-item label="会议标题:"><span>{{ info.title }}</span></ai-info-item> | ||||
|             </ai-wrapper> | ||||
|             <ai-wrapper class="mar-t16" label-width="70px" :columnsNumber="2"> | ||||
|               <ai-info-item label="发起单位:" :value="info.unitName"> | ||||
|               </ai-info-item> | ||||
|               <ai-info-item label="发起人:" :value="info.userName"> | ||||
|               </ai-info-item> | ||||
|             </ai-wrapper> | ||||
|             <ai-wrapper class="mar-t16" label-width="70px" :columnsNumber="1"> | ||||
|               <!-- <ai-info-item label="会议状态:" v-if="xq.joinStatus==1&&listType==1"><span>{{ xq.joinStatus }}</span> | ||||
|               </ai-info-item> --> | ||||
|               <ai-info-item label="发起时间:"><span>{{ info.createTime }}</span></ai-info-item> | ||||
|             </ai-wrapper> | ||||
|             <ai-wrapper class="mar-t16" label-width="70px" :columnsNumber="2"> | ||||
|               <ai-info-item label="开始时间:"><span>{{ info.startTime }}</span></ai-info-item> | ||||
|               <ai-info-item label="结束时间:"><span>{{ info.endTime }}</span></ai-info-item> | ||||
|             </ai-wrapper> | ||||
|             <ai-wrapper class="mar-t16" label-width="70px" :columnsNumber="2"> | ||||
|               <ai-info-item label="参会提醒:"><span>{{ | ||||
|                   dict.getLabel("meetingNoticeBefore", info.noticeBefore) || "-" | ||||
|                 }}</span></ai-info-item> | ||||
|               <ai-info-item label="确认提醒:"><span>{{ | ||||
|                   dict.getLabel("meetingNoticeAfter", info.noticeAfter) || "-" | ||||
|                 }}</span> | ||||
|               </ai-info-item> | ||||
|             </ai-wrapper> | ||||
|             <ai-wrapper class="mar-t16" label-width="70px" :columnsNumber="1"> | ||||
|               <ai-info-item label="会议地点:"><span>{{ info.address }}</span></ai-info-item> | ||||
|             </ai-wrapper> | ||||
|             <ai-wrapper class="mar-t16" label-width="70px" :columnsNumber="1"> | ||||
|               <ai-info-item label="会议内容:"><span v-html="info.content"></span></ai-info-item> | ||||
|             </ai-wrapper> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|         <ai-card title="会议资料"> | ||||
|           <template slot="content"> | ||||
|             <ai-file-list :fileList="info.files" :fileOps="{name: 'name', size: 'fileSizeStr'}"></ai-file-list> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|         <ai-card title="参会名单"> | ||||
|           <template slot="content"> | ||||
|             <ai-search-bar bottomBorder> | ||||
|               <template #left> | ||||
|                 <el-select v-model="search.joinStatus" placeholder="确认状态" size="small" clearable class="vc-input-160" @change="searchMeetinguser"> | ||||
|                   <el-option | ||||
|                     v-for="(item,k) in confirmStatus" | ||||
|                     :key="k" | ||||
|                     :label="item.label" | ||||
|                     :value="k"> | ||||
|                   </el-option> | ||||
|                 </el-select> | ||||
|               </template> | ||||
|               <template #right> | ||||
|                 <!-- <ai-download :instance="instance" url="/app/appepidemicbackhomerecord/export" fileName="参会名单"> | ||||
|                   <el-button icon="iconfont iconExported">导出</el-button> | ||||
|                 </ai-download> --> | ||||
|               </template> | ||||
|             </ai-search-bar> | ||||
|             <ai-table | ||||
|               :tableData="info.attendees" | ||||
|               :colConfigs="colConfigs" | ||||
|               style="margin-top: 12px;" | ||||
|               :isShowPagination="false"> | ||||
|               <el-table-column slot="meetingUserName" | ||||
|                                label="姓名" | ||||
|                                align="center" | ||||
|                                show-overflow-tooltip> | ||||
|                 <div slot-scope="{row}"> | ||||
|                   <span>{{ row.meetingUserName }}</span> | ||||
|                 </div> | ||||
|               </el-table-column> | ||||
|  | ||||
|               <el-table-column slot="meetingUnitName" | ||||
|                                label="所属部门" | ||||
|                                align="center" | ||||
|                                show-overflow-tooltip> | ||||
|                 <div slot-scope="{row}"> | ||||
|                   <span>{{ row.meetingUnitName }}</span> | ||||
|                 </div> | ||||
|               </el-table-column> | ||||
|  | ||||
|               <el-table-column slot="joinStatus" | ||||
|                                prop="joinStatus" | ||||
|                                label="确认状态" | ||||
|                                align="center" | ||||
|                                show-overflow-tooltip> | ||||
|                 <div slot-scope="{row}"> | ||||
|                   <p style="color:rgba(255,68,102,1);display:flex;justify-content:center;" v-if="row.joinStatus==2"> | ||||
|                     请假<i class="el-icon-warning" :title="row.absence" style="cursor: pointer;"></i> | ||||
|                   </p> | ||||
|                   <span v-else :style="{color:confirmStatus[row.joinStatus].color}" | ||||
|                         v-text="confirmStatus[row.joinStatus].label"/> | ||||
|                 </div> | ||||
|               </el-table-column> | ||||
|               <el-table-column slot="option" | ||||
|                                label="操作" | ||||
|                                align="center" | ||||
|                                v-if="listType==0" | ||||
|                                show-overflow-tooltip> | ||||
|                 <div slot-scope="{row}" v-if="row.joinStatus==0"> | ||||
|                   <span class="el-icon-message-solid" style="cursor: pointer;" title="参会提醒" | ||||
|                         @click="noticeMetting(row.meetingUserId)" v-if="detail.status==1"></span> | ||||
|                 </div> | ||||
|               </el-table-column> | ||||
|             </ai-table> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|       </template> | ||||
|     </ai-detail> | ||||
|   </section> | ||||
| </template> | ||||
| <script> | ||||
| import {mapState} from "vuex"; | ||||
|  | ||||
| export default { | ||||
|   name: 'meetingDetail', | ||||
|   inject: ['top'], | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function, | ||||
|     detail: Object, | ||||
|     listType: String | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       navId: '1', | ||||
|       info: {}, | ||||
|       total: 0, | ||||
|       writeInfo: {reason: ''}, | ||||
|       meetingUserList: [], | ||||
|       innerVisible: false, | ||||
|       search: {joinStatus: ''} | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.dict.load("meetingNoticeAfter", "meetingNoticeBefore").then(() => this.searchDetail(this.detail.id)) | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|     colConfigs() { | ||||
|       return [ | ||||
|         { | ||||
|           slot: 'meetingUserName' | ||||
|         }, | ||||
|         { | ||||
|           slot: 'meetingUnitName' | ||||
|         }, | ||||
|         { | ||||
|           slot: 'joinStatus', | ||||
|         }, | ||||
|         { prop: 'signInStatus', align: 'center', label: '签到', formart: v => v === '1' ? '已签到' : '未签到' }, | ||||
|         { | ||||
|           slot: 'option', | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|     confirmStatus() { | ||||
|       return { | ||||
|         0: {label: '未确认', color: "rgba(255,136,34,1)"}, | ||||
|         1: {label: '已确认', color: "rgba(34,102,255,1)"}, | ||||
|         2: {label: '请假', color: "rgba(255,68,102,1)"}, | ||||
|         3: {label: '待定', color: "rgba(255,136,34,1)"}, | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     toDo() { | ||||
|       this.$confirm("是否确认待定会议?").then(_ => { | ||||
|         this.instance.post("/app/appmeetinginfo/tobeConfirm", null, { | ||||
|           params: { | ||||
|             meetingId: this.detail.id, | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.$message.success("会议待定"); | ||||
|             setTimeout(_ => { | ||||
|               this.$parent.goBack(); | ||||
|             }, 800) | ||||
|           } | ||||
|         }) | ||||
|       }) | ||||
|     }, | ||||
|     searchMeetinguser() { | ||||
|       this.instance.post(`/app/appmeetinguser/list`, null, { | ||||
|         params: {...this.search, size: 999, meetingId: this.info.id} | ||||
|       }).then(res => { | ||||
|         if (res?.data) { | ||||
|           this.info.attendees = res.data.records; | ||||
|           this.total = res.data.total; | ||||
|  | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     searchDetail(id) { | ||||
|       this.instance.post(`/app/appmeetinginfo/info-id`, null, { | ||||
|         params: {id} | ||||
|       }).then(res => { | ||||
|         if (res?.data) { | ||||
|           this.info = { | ||||
|             ...res.data, | ||||
|             content: this.formatContent(res.data.content || ""), | ||||
|             files: res.data.files || [] | ||||
|           }; | ||||
|           this.searchMeetinguser() | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     changeMeeting(title, id) { | ||||
|       this.$confirm(title, { | ||||
|         type: 'warning' | ||||
|       }).then(() => { | ||||
|         if (title == '是否立即发布会议?') { | ||||
|           this.fbMeeting(); | ||||
|         } else if (title == '是否删除会议?') { | ||||
|           this.sdMeeting(); | ||||
|         } else if (title == '是否取消会议?') { | ||||
|           this.qxMeeting(); | ||||
|         } else if (title == '是否确认参会?') { | ||||
|           this.qrMeeting(); | ||||
|         } else if (title == '是否删除此参会人员?') { | ||||
|           this.deleteMeetingPer(id) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     deleteMeetingPer(id) { | ||||
|       this.instance.post(`/app/appmeetinguser/delete`, null, | ||||
|           { | ||||
|             params: { | ||||
|               id | ||||
|             } | ||||
|           } | ||||
|       ).then(res => { | ||||
|  | ||||
|         if (res && res.code == 0) { | ||||
|           this.$message.success("删除成功!"); | ||||
|           this.searchMeetinguser(); | ||||
|         } | ||||
|  | ||||
|       }); | ||||
|     }, | ||||
|     queMeeting(formName) { | ||||
|       this.$refs[formName].validate((valid) => { | ||||
|         if (valid) { | ||||
|           this.instance.post(`/app/appmeetinginfo/absent`, null, | ||||
|               { | ||||
|                 params: { | ||||
|                   meetingId: this.detail.id, | ||||
|                   reason: this.writeInfo.reason | ||||
|                 } | ||||
|               } | ||||
|           ).then(res => { | ||||
|  | ||||
|             if (res && res.code == 0) { | ||||
|               this.innerVisible = false; | ||||
|               this.$parent.goBack(); | ||||
|             } | ||||
|  | ||||
|           }); | ||||
|         } else { | ||||
|           return false; | ||||
|         } | ||||
|       }); | ||||
|  | ||||
|     }, | ||||
|     qrMeeting() { | ||||
|       this.instance.post(`/app/appmeetinginfo/confirm`, null, | ||||
|           { | ||||
|             params: { | ||||
|               meetingId: this.detail.id | ||||
|  | ||||
|             } | ||||
|           } | ||||
|       ).then(res => { | ||||
|  | ||||
|         if (res && res.code == 0) { | ||||
|           this.$message.success("确认参会成功!") | ||||
|           this.$parent.goBack(); | ||||
|         } | ||||
|  | ||||
|       }); | ||||
|     }, | ||||
|     noticeMetting(meetingUserId) { | ||||
|       this.instance.post(`/app/appmeetinginfo/notice`, null, { | ||||
|         params: { | ||||
|           meetingId: this.detail.id, noticeALL: !meetingUserId, meetingUserId | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res && res.code == 0) { | ||||
|           this.$message.success("提醒成功!") | ||||
|         } | ||||
|  | ||||
|       }); | ||||
|     }, | ||||
|     fbMeeting() { | ||||
|       this.instance.post(`/app/appmeetinginfo/release`, null, | ||||
|           { | ||||
|             params: { | ||||
|               meetingId: this.detail.id | ||||
|             } | ||||
|           } | ||||
|       ).then(res => { | ||||
|  | ||||
|         if (res && res.code == 0) { | ||||
|           this.$message.success("发布成功!") | ||||
|           this.$parent.goBack(); | ||||
|         } | ||||
|  | ||||
|       }); | ||||
|  | ||||
|     }, | ||||
|     sdMeeting() { | ||||
|       this.instance.post(`/app/appmeetinginfo/delete`, null, | ||||
|           { | ||||
|             params: { | ||||
|               meetingId: this.detail.id | ||||
|             } | ||||
|           } | ||||
|       ).then(res => { | ||||
|  | ||||
|         if (res && res.code == 0) { | ||||
|           this.$message.success("删除成功!"); | ||||
|           this.$parent.goBack(); | ||||
|         } | ||||
|  | ||||
|       }); | ||||
|     }, | ||||
|     qxMeeting() { | ||||
|       this.instance.post(`/app/appmeetinginfo/cancel`, null, | ||||
|           { | ||||
|             params: { | ||||
|               meetingId: this.detail.id | ||||
|             } | ||||
|           } | ||||
|       ).then(res => { | ||||
|  | ||||
|         if (res && res.code == 0) { | ||||
|           this.$message.success("取消会议成功!"); | ||||
|           this.$parent.goBack(); | ||||
|         } | ||||
|  | ||||
|       }); | ||||
|     }, | ||||
|     editMeeting() { | ||||
|       this.$parent.goBack(); | ||||
|       this.$emit('gotoEdit', this.info) | ||||
|     }, | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| <style lang="scss" scoped> | ||||
| .meetingDetail { | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   background: rgba(255, 255, 255, 1); | ||||
|  | ||||
|   .conference_top_area { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|   } | ||||
|  | ||||
|   .user-search { | ||||
|     width: 100%; | ||||
|     height: 48px; | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     align-items: center; | ||||
|  | ||||
|     .float-right { | ||||
|       width: calc(100% - 200px); | ||||
|       text-align: right; | ||||
|     } | ||||
|  | ||||
|     .input-162 { | ||||
|       display: inline-block; | ||||
|       width: 162px; | ||||
|     } | ||||
|  | ||||
|   } | ||||
|  | ||||
|   .content { | ||||
|     width: 1000px; | ||||
|     height: calc(100% - 50px); | ||||
|     overflow: hidden; | ||||
|     margin: auto; | ||||
|     display: flex; | ||||
|     justify-content: space-around; | ||||
|  | ||||
|     .content-left { | ||||
|       width: 160px; | ||||
|       height: 100%; | ||||
|  | ||||
|       .content-left-nav { | ||||
|         width: 158px; | ||||
|         background-color: #ffffff; | ||||
|         border-radius: 4px; | ||||
|         border: solid 1px #eeeeee; | ||||
|         margin-top: 56px; | ||||
|         overflow: hidden; | ||||
|  | ||||
|         li { | ||||
|           height: 48px; | ||||
|           line-height: 48px; | ||||
|           padding-left: 24px; | ||||
|           font-size: 14px; | ||||
|           font-weight: normal; | ||||
|           font-stretch: normal; | ||||
|           letter-spacing: 0; | ||||
|           color: #666666; | ||||
|           cursor: pointer; | ||||
|           border-left: 3px solid transparent; | ||||
|  | ||||
|           &:hover { | ||||
|             border-left: 3px solid #5088ff; | ||||
|           } | ||||
|  | ||||
|           a { | ||||
|             display: block; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .navActive { | ||||
|           border-left: 3px solid #5088ff; | ||||
|           color: #5088ff; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     .content-right { | ||||
|       width: 780px; | ||||
|       height: calc(100% - 80px); | ||||
|       overflow-y: auto; | ||||
|       margin-left: 40px; | ||||
|       box-sizing: border-box; | ||||
|       overflow-x: hidden; | ||||
|  | ||||
|       .content-right-title { | ||||
|         width: 780px; | ||||
|         height: 56px; | ||||
|         margin-bottom: 16px; | ||||
|         box-shadow: inset 0px -1px 0px 0px #dad5d5; | ||||
|         display: flex; | ||||
|         justify-content: space-between; | ||||
|         align-items: center; | ||||
|  | ||||
|         span { | ||||
|           display: block; | ||||
|           width: 150px; | ||||
|           height: 56px; | ||||
|           line-height: 56px; | ||||
|           color: #333333; | ||||
|           font-weight: bold; | ||||
|  | ||||
|           &:nth-of-type(2) { | ||||
|             text-align: right; | ||||
|             width: 200px; | ||||
|           } | ||||
|  | ||||
|         } | ||||
|  | ||||
|  | ||||
|       } | ||||
|  | ||||
|       .flie { | ||||
|         width: 100%; | ||||
|         height: 40px; | ||||
|         line-height: 40px; | ||||
|         padding: 0 8px; | ||||
|         box-sizing: border-box; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         justify-content: space-between; | ||||
|         font-size: 14px; | ||||
|         color: rgba(51, 51, 51, 1); | ||||
|         background: rgba(255, 255, 255, 1); | ||||
|         border-radius: 4px; | ||||
|         border: 1px solid rgba(208, 212, 220, 1); | ||||
|         margin-bottom: 16px; | ||||
|         cursor: pointer; | ||||
|  | ||||
|         p { | ||||
|           display: flex; | ||||
|           justify-content: flex-start; | ||||
|           align-items: center | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .meeting_name { | ||||
|         width: 100%; | ||||
|         padding-bottom: 25px; | ||||
|         font-size: 16px; | ||||
|         box-shadow: inset 0px -1px 0px 0px #dad5d5; | ||||
|         position: relative; | ||||
|         overflow: hidden; | ||||
|  | ||||
|         .title { | ||||
|           color: #333333; | ||||
|           height: 28px; | ||||
|           line-height: 28px; | ||||
|           margin-left: 0; | ||||
|           font-weight: bold; | ||||
|           margin-top: 14px; | ||||
|         } | ||||
|  | ||||
|         ul { | ||||
|           overflow: hidden; | ||||
|  | ||||
|           li { | ||||
|             width: 33.3%; | ||||
|             float: left; | ||||
|             line-height: 28px; | ||||
|             font-size: 14px; | ||||
|  | ||||
|             span { | ||||
|               width: 70px; | ||||
|               display: block; | ||||
|               float: left; | ||||
|               color: rgba(153, 153, 153, 1) | ||||
|             } | ||||
|  | ||||
|             p { | ||||
|               width: calc(100% - 70px); | ||||
|               float: left; | ||||
|               color: rgba(51, 51, 51, 1); | ||||
|             } | ||||
|           ; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .svg { | ||||
|           width: 88px; | ||||
|           height: 88px; | ||||
|           position: absolute; | ||||
|           right: -20px; | ||||
|           bottom: -20px; | ||||
|         } | ||||
|  | ||||
|       } | ||||
|  | ||||
|  | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										259
									
								
								packages/work/AppConference/list.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										259
									
								
								packages/work/AppConference/list.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,259 @@ | ||||
| <template> | ||||
|   <ai-list isTabs> | ||||
|     <template #content> | ||||
|       <ai-search-bar> | ||||
|         <template #left> | ||||
|           <el-button type="primary" @click="addMetting()">发起会议</el-button> | ||||
|           <ai-select | ||||
|               v-model="search.meetingStatus" | ||||
|               @change="getTableData()" | ||||
|               placeholder="会议状态" | ||||
|               :selectList="dict.getDict($parent.name==0 ? 'meetingStatusSelect' : 'meetingStatus')" | ||||
|           ></ai-select> | ||||
|           <ai-select | ||||
|               v-if="$parent.name==0" | ||||
|               v-model="search.confirmStatus" | ||||
|               @change="getTableData()" | ||||
|               placeholder="确认状态" | ||||
|               :selectList="dict.getDict('confirmStatus')" | ||||
|           ></ai-select> | ||||
|         </template> | ||||
|         <template #right> | ||||
|           <el-input | ||||
|             v-model="search.param" | ||||
|             v-throttle="() => {search.current=1,getTableData()}" | ||||
|             @keyup.enter.native="search.current=1,getTableData()" | ||||
|             placeholder="会议标题/地点" | ||||
|             size="small" suffix-icon="iconfont iconSearch" clearable @clear="getTableData()"></el-input> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <div class="list_main"> | ||||
|         <div class="no-data" style="height:160px;" v-if="tableData.length==0"></div> | ||||
|         <ul v-if="tableData.length>0"> | ||||
|           <li v-for="(item,index) in tableData" :key="index" @click="goDetail(item)"> | ||||
|             <p> | ||||
|               <span class="conference_title">{{ item.title }}</span> | ||||
|               <span class="time" v-if="item.status==1">{{ item.expirationTime }}</span> | ||||
|             </p> | ||||
|             <p style="width:80%;"> | ||||
|               <el-row type="flex" align="middle" class="unit">发起人:{{ item.userName }} | ||||
|               </el-row> | ||||
|               <el-row type="flex" align="middle" class="unit">发起单位:{{ item.unitName }} | ||||
|               </el-row> | ||||
|             </p> | ||||
|             <p style="width:80%;"> | ||||
|               <span class="unit">会议时间:{{ item.startTime.substring(0, 16) + '至' + item.endTime.substring(0, 16) }}</span> | ||||
|               <el-tooltip :content="item.address" placement="top-start" effect="light"> | ||||
|                 <span class="unit" v-if="item.address.length>12">会议地点:{{ | ||||
|                     item.address.substring(0, 12) + '....' | ||||
|                   }}</span> | ||||
|                 <span class="unit" v-else>会议地点:{{ item.address }}</span> | ||||
|               </el-tooltip> | ||||
|             </p> | ||||
|             <!-- <p style="width:80%;"> | ||||
|                   <span | ||||
|                     class="unit">会议时间:{{ | ||||
|                       item.startTime.substring(0, 16) + '至' + item.endTime.substring(0, 16) | ||||
|                     }}</span> | ||||
|               <el-tooltip :content="item.address" placement="top-start" effect="light"> | ||||
|                     <span class="unit address" | ||||
|                           v-if="item.address.length>12">会议地点:{{ item.address.substring(0, 12) + '....' }}</span> | ||||
|                 <span class="unit address" v-else>会议地点:{{ item.address }}</span> | ||||
|               </el-tooltip> | ||||
|             </p> --> | ||||
|             <h5 :class="{color0:item.status==0,color1:item.status==1,color2:item.status==2,color3:item.status==3,color4:item.status==4}"> | ||||
|               <span v-if="item.status==0">草稿箱</span> | ||||
|               <span v-if="item.status==1">未开始</span> | ||||
|               <span v-if="item.status==2">进行中</span> | ||||
|               <span v-if="item.status==3">已取消</span> | ||||
|               <span v-if="item.status==4">已结束</span> | ||||
|             </h5> | ||||
|             <ai-icon class="svg" v-if="item.joinStatus==0" type="svg" icon="iconunidentified"/> | ||||
|             <ai-icon class="svg" v-else-if="item.joinStatus==1" type="svg" icon="iconidentified"/> | ||||
|             <ai-icon class="svg" v-else-if="item.joinStatus==2" type="svg" icon="iconyiqingjia"/> | ||||
|             <ai-icon class="svg" v-else-if="item.joinStatus==3" type="svg" icon="icondaiding"/> | ||||
|           </li> | ||||
|         </ul> | ||||
|       </div> | ||||
|       <div class="pagination" v-if="tableData.length>0"> | ||||
|         <el-pagination | ||||
|             @current-change="handleCurrentChange" | ||||
|             @size-change="handleSizeChange" | ||||
|             background | ||||
|             :current-page.sync="search.current" | ||||
|             :page-sizes="[5, 10, 50, 100,200]" | ||||
|             :page-size="search.size" | ||||
|             layout="total,prev, pager, next,sizes,jumper" | ||||
|             :total="total"> | ||||
|         </el-pagination> | ||||
|       </div> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "list", | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function, | ||||
|     listType: String | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       search: { | ||||
|         meetingStatus: '', | ||||
|         confirmStatus: '', | ||||
|         param: '', | ||||
|         current: 1, | ||||
|         size: 10, | ||||
|         listType: '' | ||||
|       }, | ||||
|       tableData: [], | ||||
|       total: 0, | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     goDetail(item) { | ||||
|       this.$emit('goPage', { | ||||
|         row: item, | ||||
|         comp: 'detail' | ||||
|       }); | ||||
|     }, | ||||
|     addMetting() { | ||||
|       this.$emit('goPage', { | ||||
|         row: {}, | ||||
|         comp: 'addMeeting' | ||||
|       }); | ||||
|     }, | ||||
|  | ||||
|     getTableData() { | ||||
|       this.instance.post(`/app/appmeetinginfo/list`, null, { | ||||
|         params: { | ||||
|           ...this.search, | ||||
|           listType: this.listType | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res && res.data) { | ||||
|           this.tableData = res.data.records; | ||||
|           this.total = res.data.total; | ||||
|  | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     handleCurrentChange(val) { | ||||
|       this.search.current = val; | ||||
|       this.getTableData(); | ||||
|     }, | ||||
|     handleSizeChange(val) { | ||||
|       this.search.size = val; | ||||
|       this.getTableData(); | ||||
|     }, | ||||
|   }, | ||||
|   created() { | ||||
|     this.dict.load("confirmStatus", "meetingStatus", "meetingStatusSelect").then(_ => this.getTableData()) | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .list_main { | ||||
|   width: 100%; | ||||
|  | ||||
|   ul { | ||||
|     overflow: hidden; | ||||
|     padding: 0; | ||||
|     margin: 0; | ||||
|  | ||||
|     li { | ||||
|       width: 100%; | ||||
|       height: 107px; | ||||
|       background: rgba(255, 255, 255, 1); | ||||
|       border-radius: 4px; | ||||
|       border: 1px solid rgba(216, 224, 232, 1); | ||||
|       box-sizing: border-box; | ||||
|       padding: 16px 16px 16px 50px; | ||||
|       margin-top: 8px; | ||||
|       cursor: pointer; | ||||
|       position: relative; | ||||
|       overflow: hidden; | ||||
|  | ||||
|       p { | ||||
|         width: 100%; | ||||
|         height: 25px; | ||||
|         display: flex; | ||||
|         justify-content: space-between; | ||||
|         align-items: center; | ||||
|  | ||||
|         .conference_title { | ||||
|           color: rgba(51, 51, 51, 1); | ||||
|           font-size: 16px; | ||||
|           font-weight: bold; | ||||
|         } | ||||
|  | ||||
|         .time { | ||||
|           font-size: 14px; | ||||
|           color: #2266FF; | ||||
|         } | ||||
|  | ||||
|         .unit { | ||||
|           font-size: 14px; | ||||
|           width: 50%; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       h5 { | ||||
|         width: 100px; | ||||
|         height: 20px; | ||||
|         line-height: 20px; | ||||
|         text-align: center; | ||||
|         position: absolute; | ||||
|         left: -22px; | ||||
|         top: 10px; | ||||
|         box-sizing: border-box; | ||||
|         padding-right: 8px; | ||||
|         font-size: 12px; | ||||
|         transform: rotate(-45deg); | ||||
|         background: #FFF3E8; | ||||
|         color: rgba(255, 136, 34, 1); | ||||
|         box-shadow: -1px 1px 0px 0px rgba(216, 224, 232, 1), 1px -1px 0px 0px rgba(216, 224, 232, 1); | ||||
|         margin: 0; | ||||
|       } | ||||
|  | ||||
|       .color0 { | ||||
|         color: #2244FF; | ||||
|         background: #EFF6FF; | ||||
|       } | ||||
|  | ||||
|       .color1 { | ||||
|         background: #FFF3E8; | ||||
|         color: rgba(255, 136, 34, 1); | ||||
|       } | ||||
|  | ||||
|       .color2 { | ||||
|         background: #EFF6FF; | ||||
|         color: #2266FF; | ||||
|       } | ||||
|  | ||||
|       .color3 { | ||||
|         background-color: #D8E0E8; | ||||
|         color: #999999; | ||||
|       } | ||||
|  | ||||
|       .color4 { | ||||
|         color: #2EA222; | ||||
|         background-color: #D8E0E8; | ||||
|       } | ||||
|  | ||||
|       .svg { | ||||
|         width: 88px; | ||||
|         height: 88px; | ||||
|         position: absolute; | ||||
|         right: -20px; | ||||
|         bottom: -20px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -0,0 +1,68 @@ | ||||
| <template> | ||||
|   <div class="appDispatchManagement"> | ||||
|     <keep-alive :include="['List']"> | ||||
|       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> | ||||
|     </keep-alive> | ||||
|   </div> | ||||
|    | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import Detail from './components/Detail' | ||||
|   import Add from './components/Add' | ||||
|   import List from './components/List' | ||||
|  | ||||
|   export default { | ||||
|     name: "AppDispatchManagement", | ||||
|     label: '公文流转', | ||||
|  | ||||
|     components: {List, Detail, Add}, | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       permissions: Function | ||||
|     }, | ||||
|     data() { | ||||
|       return { | ||||
|         component: 'List', | ||||
|         params: {}, | ||||
|         include: [] | ||||
|       } | ||||
|     }, | ||||
|     created(){ | ||||
|     }, | ||||
|     methods:{ | ||||
|       onChange (data) { | ||||
|         if (data.type === 'detail') { | ||||
|           this.component = 'Detail' | ||||
|           this.params = data.params | ||||
|         } | ||||
|  | ||||
|         if (data.type === 'add') { | ||||
|           console.log(123) | ||||
|           this.component = 'Add' | ||||
|           this.params = data.params | ||||
|         } | ||||
|  | ||||
|         if (data.type === 'list') { | ||||
|           this.component = 'List' | ||||
|           this.params = data.params | ||||
|  | ||||
|           this.$nextTick(() => { | ||||
|             if (data.isRefresh) { | ||||
|               this.$refs.component.getList() | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .appDispatchManagement{ | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										388
									
								
								packages/work/AppDispatchManagement/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										388
									
								
								packages/work/AppDispatchManagement/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,388 @@ | ||||
| <template> | ||||
|   <section class="managementDetail"> | ||||
|     <ai-detail> | ||||
|       <template #title> | ||||
|         <ai-title title="公文登记" isShowBottomBorder isShowBack @onBackClick="cancel(true)"/> | ||||
|       </template> | ||||
|       <template #content> | ||||
|         <ai-card title="公文信息"> | ||||
|           <template slot="content"> | ||||
|             <div class="form_div mar-t16"> | ||||
|               <el-form | ||||
|                 ref="rules" | ||||
|                 :model="form" | ||||
|                 :rules="formRules" | ||||
|                 size="small" | ||||
|                 label-suffix=":" | ||||
|                 label-width="100px" | ||||
|                 > | ||||
|                 <el-form-item label="公文名称" prop="documentName"> | ||||
|                   <el-input | ||||
|                     v-model="form.documentName" | ||||
|                     placeholder="请输入..." | ||||
|                     maxlength="50" | ||||
|                   ></el-input> | ||||
|                 </el-form-item> | ||||
|                 <div class="above"> | ||||
|                   <div class="left"> | ||||
|                     <el-form-item label="公文编号" prop="documentCode"> | ||||
|                       <el-input | ||||
|                         v-model="form.documentCode" | ||||
|                         placeholder="请输入..." | ||||
|                         maxlength="50" | ||||
|                       ></el-input> | ||||
|                     </el-form-item> | ||||
|                   </div> | ||||
|                   <div class="right"> | ||||
|                     <el-form-item label="公文类型" prop="documentType"> | ||||
|                       <el-select | ||||
|                         v-model="form.documentType" | ||||
|                         placeholder="请选择..." | ||||
|                         clearable | ||||
|                       > | ||||
|                         <el-option | ||||
|                           v-for="(item, i) in dict.getDict('officialDocumentName')" | ||||
|                           :key="i" | ||||
|                           :label="item.dictName" | ||||
|                           :value="item.dictValue" | ||||
|                         ></el-option> | ||||
|                       </el-select> | ||||
|                     </el-form-item> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="above"> | ||||
|                   <div class="left"> | ||||
|                     <el-form-item label="保密等级"> | ||||
|                       <el-select | ||||
|                         v-model="form.confidentialityLevel" | ||||
|                         placeholder="请选择..." | ||||
|                         clearable | ||||
|                       > | ||||
|                         <el-option | ||||
|                           v-for="(item, i) in dict.getDict('officialDocumentConfidentialityLevel')" | ||||
|                           :key="i" | ||||
|                           :label="item.dictName" | ||||
|                           :value="item.dictValue" | ||||
|                         ></el-option> | ||||
|                       </el-select> | ||||
|                     </el-form-item> | ||||
|                   </div> | ||||
|                   <div class="right"> | ||||
|                     <el-form-item label="阅示类型" prop="readType"> | ||||
|                       <el-select @change="readTypeChange" | ||||
|                         v-model="form.readType" | ||||
|                         placeholder="请选择..." | ||||
|                         clearable | ||||
|                       > | ||||
|                         <el-option | ||||
|                           v-for="(item, i) in dict.getDict('officialDocumentReadType')" | ||||
|                           :key="i" | ||||
|                           :label="item.dictName" | ||||
|                           :value="item.dictValue" | ||||
|                         ></el-option> | ||||
|                       </el-select> | ||||
|                     </el-form-item> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="above"> | ||||
|                   <div class="left"> | ||||
|                     <el-form-item label="紧急程度"> | ||||
|                       <el-select | ||||
|                         v-model="form.emergencyLevel" | ||||
|                         placeholder="请选择..." | ||||
|                         clearable | ||||
|                       > | ||||
|                         <el-option | ||||
|                           v-for="(item, i) in dict.getDict('officialDocumentEmergencyLevel')" | ||||
|                           :key="i" | ||||
|                           :label="item.dictName" | ||||
|                           :value="item.dictValue" | ||||
|                         ></el-option> | ||||
|                       </el-select> | ||||
|                     </el-form-item> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="above"> | ||||
|                   <div class="left"> | ||||
|                     <el-form-item label="发文机关"> | ||||
|                       <el-input | ||||
|                         v-model="form.issuingUnit" | ||||
|                         placeholder="请输入..." | ||||
|                         maxlength="50" | ||||
|                       ></el-input> | ||||
|                     </el-form-item> | ||||
|                   </div> | ||||
|                   <div class="right"> | ||||
|                     <el-form-item label="发文字号"> | ||||
|                       <el-input | ||||
|                         v-model="form.issuingFont" | ||||
|                         placeholder="请输入..." | ||||
|                         maxlength="50" | ||||
|                       ></el-input> | ||||
|                     </el-form-item> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="above"> | ||||
|                   <div class="left"> | ||||
|                     <el-form-item label="签发人"> | ||||
|                       <el-input | ||||
|                         v-model="form.signer" | ||||
|                         placeholder="请输入..." | ||||
|                         maxlength="50" | ||||
|                       ></el-input> | ||||
|                     </el-form-item> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <el-form-item label="备注"> | ||||
|                   <el-input | ||||
|                     v-model="form.remark" | ||||
|                     type="textarea" | ||||
|                     :rows="5" | ||||
|                     maxlength="200" | ||||
|                     show-word-limit | ||||
|                     placeholder="请输入..." | ||||
|                   ></el-input> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="附件"> | ||||
|                   <div class="upload"> | ||||
|                     <ai-uploader :instance="instance" v-model="form.files" fileType="file" :limit="9" @change="onChange"></ai-uploader> | ||||
|                   </div> | ||||
|                 </el-form-item> | ||||
|               </el-form> | ||||
|             </div> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|         <ai-card title="流转信息"> | ||||
|           <template #content> | ||||
|             <span class="form-label">流转对象:</span> | ||||
|             <div class="user-content"> | ||||
|               <ai-wechat-selecter slot="append" :instance="instance" v-model="form.flowUsers" isShowUser :isMultiple="isMultiple"></ai-wechat-selecter> | ||||
|             </div> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|       </template> | ||||
|       <template #footer> | ||||
|         <el-button class="delete-btn footer-btn" @click="cancel(true)">取消</el-button> | ||||
|         <el-button class="footer-btn" type="primary" @click="save('rules', '1')">保存并流转</el-button> | ||||
|         <el-button class="footer-btn" @click="save('rules', '0')">保存</el-button> | ||||
|       </template> | ||||
|     </ai-detail> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "managementDetail", | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function, | ||||
|     params: Object | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       form: { | ||||
|         documentName: '', | ||||
|         documentCode: '', | ||||
|         documentType: '', | ||||
|         confidentialityLevel: '', | ||||
|         readType: '', | ||||
|         emergencyLevel: '', | ||||
|         issuingTime: '', | ||||
|         issuingUnit: '', | ||||
|         issuingFont: '', | ||||
|         signer: '', | ||||
|         overDescription: '', | ||||
|         overTime: '', | ||||
|         deliver: '', | ||||
|         remark: '', | ||||
|         files: [], | ||||
|         fileIds: [], | ||||
|         flowUsers: [], | ||||
|       }, | ||||
|       isMultiple: true, | ||||
|     }; | ||||
|   }, | ||||
|   computed: { | ||||
|     formRules(){ | ||||
|       return { | ||||
|         documentName: [{required: true, message: "请输入公文名称", trigger: 'change' }], | ||||
|         documentCode: [{required: true, message: "请输入公文编号", trigger: 'change' }], | ||||
|         documentType: [{required: true, message: "请选择公文类型", trigger: 'change' }], | ||||
|         readType: [{required: true, message: "请选择阅示类型", trigger: 'change' }], | ||||
|       } | ||||
|     }, | ||||
|     colConfigs(){ | ||||
|       return [ | ||||
|         { | ||||
|           prop: 'meetingUserName', | ||||
|           align: 'center', | ||||
|           label: '姓名', | ||||
|         }, | ||||
|         { | ||||
|           prop: 'meetingUserPhone', | ||||
|           align: 'center', | ||||
|           label: '手机号码', | ||||
|         }, | ||||
|         { | ||||
|           prop: 'meetingUnitName', | ||||
|           align: 'center', | ||||
|           label: '所属部门', | ||||
|         }, | ||||
|         { | ||||
|           slot: 'joinStatus', | ||||
|         }, | ||||
|         { | ||||
|           slot: 'option', | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|   }, | ||||
|   created() { | ||||
|     this.dict.load('issuingUnit','officialDocumentEmergencyLevel', 'officialDocumentReadType', 'officialDocumentConfidentialityLevel', 'officialDocumentName'); | ||||
|   }, | ||||
|   mounted() { | ||||
|     if(this.params.id) { | ||||
|       this.getDetail() | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     onChange() { | ||||
|  | ||||
|     }, | ||||
|     readTypeChange() { | ||||
|       if(this.form.readType == 0) { | ||||
|         this.isMultiple = false | ||||
|         if(this.form.flowUsers.length > 1) { | ||||
|           this.form.flowUsers = [] | ||||
|         } | ||||
|       }else { | ||||
|         this.isMultiple = true | ||||
|       } | ||||
|     }, | ||||
|     getDetail() { | ||||
|       this.instance.post(`/app/appofficialdocumentinfo/queryDetailById?id=${this.params.id}&flag=0`, null).then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           this.form = {...res.data} | ||||
|           this.form.files = this.form.files || [] | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     save(formName, status){ | ||||
|       this.$refs[formName].validate((valid) => { | ||||
|         if (valid) { | ||||
|           this.submit(status) | ||||
|         } else { | ||||
|           return false; | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     submit(status) { | ||||
|       var flowUsers = [] | ||||
|       this.form.flowUsers.map(item => { | ||||
|         var info = { | ||||
|           flowUserId: item.id, | ||||
|           flowUserName: item.name, | ||||
|           avatar: item.avatar | ||||
|         } | ||||
|         flowUsers.push(info) | ||||
|       }) | ||||
|  | ||||
|       this.form.fileIds = [] | ||||
|       if(this.form.files.length) { | ||||
|         this.form.files.map((item) => { | ||||
|           this.form.fileIds.push(item.id) | ||||
|         }) | ||||
|       } | ||||
|       this.instance.post(`/app/appofficialdocumentinfo/addOrUpdate`, { | ||||
|         ...this.form, | ||||
|         status: status, | ||||
|         flowUsers: flowUsers | ||||
|       }, null).then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           if(this.params.id){ | ||||
|             this.$message.success("编辑成功"); | ||||
|           }else{ | ||||
|             this.$message.success("提交成功"); | ||||
|           } | ||||
|           this.cancel(true) | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     cancel(isRefresh) { | ||||
|       this.$emit('change', { | ||||
|         type: 'list', | ||||
|         isRefresh: !!isRefresh | ||||
|       }) | ||||
|     }, | ||||
|     downFileAll () { | ||||
|       if (this.form.files.length > 0) { | ||||
|         this.instance.post('/app/appofficialdocumentinfo/downLoadAllFileForDetail', null, { | ||||
|           responseType: 'blob', | ||||
|           params: { | ||||
|             id: this.form.id | ||||
|           } | ||||
|         }).then((res) => { | ||||
|           const link = document.createElement('a') | ||||
|           let blob = new Blob([res], { type: 'application/vnd.ms-excel' }) | ||||
|           link.style.display = 'none' | ||||
|           link.href = URL.createObjectURL(blob) | ||||
|           var num = '' | ||||
|           for (let i = 0; i < 10; i++) { | ||||
|             num += Math.ceil(Math.random() * 10) | ||||
|           } | ||||
|           link.setAttribute('download', '公文文件' + '.zip') | ||||
|           document.body.appendChild(link) | ||||
|           link.click() | ||||
|           document.body.removeChild(link) | ||||
|         }) | ||||
|       } else { | ||||
|         this.$message.error('暂无附件提供下载') | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .managementDetail { | ||||
|   height: 100%; | ||||
|   overflow: auto; | ||||
|   background: #f3f6f9; | ||||
|   .above{ | ||||
|     overflow: hidden; | ||||
|     width: 100%; | ||||
|     .left{ | ||||
|       width: 50%; | ||||
|       float: left; | ||||
|     } | ||||
|     .right{ | ||||
|       width: 50%; | ||||
|       float: right; | ||||
|     } | ||||
|     .el-select{ | ||||
|       width: 100%; | ||||
|     } | ||||
|     .el-date-editor.el-input{ | ||||
|       width: 100%; | ||||
|     } | ||||
|   } | ||||
|   .iconEdit,.Edit{ | ||||
|     color:#5088FF; | ||||
|     font-size: 12px; | ||||
|     cursor: pointer; | ||||
|     padding-left: 8px; | ||||
|   } | ||||
|   .form-label{ | ||||
|     display: inline-block; | ||||
|     width: 100px; | ||||
|     color: #666; | ||||
|     font-size: 14px; | ||||
|     text-align: right; | ||||
|   } | ||||
|   .user-content{ | ||||
|     display: inline-block; | ||||
|     width: calc(100% - 100px); | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										563
									
								
								packages/work/AppDispatchManagement/components/Detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										563
									
								
								packages/work/AppDispatchManagement/components/Detail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,563 @@ | ||||
| <template> | ||||
|   <section class="managementDetail"> | ||||
|     <ai-detail> | ||||
|       <template #title> | ||||
|         <ai-title title="公文详情" isShowBottomBorder isShowBack @onBackClick="cancel(true)"> | ||||
|           <template #rightBtn> | ||||
|             <ai-wechat-selecter :instance="instance" v-model="addUser" :isMultiple="form.readType == '0' ? false : true" @change="onChange" v-if="form.status === '0'"> | ||||
|               <el-button | ||||
|                 size="small" | ||||
|                 type="primary" | ||||
|                 icon="iconfont iconMediaPlayer_Play"> | ||||
|                 开始流转 | ||||
|               </el-button> | ||||
|             </ai-wechat-selecter> | ||||
|             <ai-wechat-selecter :instance="instance" v-model="addUser" :isMultiple="form.readType == '0' ? false : true" @change="onChange" v-if="form.status === '2' && form.readType == '0'"> | ||||
|               <el-button | ||||
|                 size="small" | ||||
|                 type="primary" | ||||
|                 icon="iconfont iconResetting"> | ||||
|                 再次流转 | ||||
|               </el-button> | ||||
|             </ai-wechat-selecter> | ||||
|             <el-button | ||||
|             @click="endCirculation" | ||||
|             v-if="form.status === '1'" | ||||
|             size="small" | ||||
|             icon="iconfont iconReject"> | ||||
|             结束流转</el-button> | ||||
|           </template> | ||||
|         </ai-title> | ||||
|          | ||||
|       </template> | ||||
|       <template #content> | ||||
|         <ai-card :title="form.documentName"> | ||||
|           <template slot="content"> | ||||
|             <ai-wrapper class="mar-t16" label-width="80px" :columnsNumber="3"> | ||||
|               <ai-info-item label="公文编号:"><span>{{form.documentCode || '-'}}</span></ai-info-item> | ||||
|               <ai-info-item label="公文类型:"><span>{{$dict.getLabel("officialDocumentName", form.documentType) || '-'}}</span></ai-info-item> | ||||
|               <ai-info-item label="保密等级:"><span>{{$dict.getLabel("officialDocumentConfidentialityLevel", form.confidentialityLevel) || '-'}}</span></ai-info-item> | ||||
|             </ai-wrapper> | ||||
|             <ai-wrapper label-width="80px" :columnsNumber="3"> | ||||
|               <ai-info-item label="阅示类型:"><span>{{$dict.getLabel("officialDocumentReadType", form.readType) || '-'}}</span></ai-info-item> | ||||
|               <ai-info-item label="紧急程度:"><span>{{$dict.getLabel("officialDocumentEmergencyLevel", form.emergencyLevel) || '-'}}</span></ai-info-item> | ||||
|               <ai-info-item label="发文机关:"><span>{{dict.getLabel('issuingUnit',form.issuingUnit)|| '-'}}</span></ai-info-item> | ||||
|             </ai-wrapper> | ||||
|             <ai-wrapper label-width="80px" :columnsNumber="3"> | ||||
|               <ai-info-item label="发文字号:"><span>{{form.issuingFont || '-'}}</span></ai-info-item> | ||||
|               <ai-info-item label="签发人:"><span>{{form.signer || '-'}}</span></ai-info-item> | ||||
|               <ai-info-item label="发文时间:"><span>{{form.createTime || '-'}}</span></ai-info-item> | ||||
|             </ai-wrapper> | ||||
|             <ai-wrapper label-width="80px" :columnsNumber="1"> | ||||
|               <ai-info-item label="备注:"><span>{{form.remark || '-'}}</span></ai-info-item> | ||||
|             </ai-wrapper> | ||||
|             <ai-bar title="附件" > | ||||
|               <template slot="right" v-if="form.files && form.files.length"> | ||||
|                 <span class="Edit" @click="downFileAll"><i class="iconfont iconDownload"></i>下载全部</span> | ||||
|               </template> | ||||
|             </ai-bar> | ||||
|             <ai-file-list v-if="form.files && form.files.length" | ||||
|               :fileList="form.files" | ||||
|               :fileOps="{ name: 'name', size: 'fileSizeStr' }" | ||||
|             ></ai-file-list> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|         <ai-card title="流转信息"> | ||||
|           <template #right> | ||||
|             <ai-wechat-selecter :instance="instance" v-model="addFlow" @change="addPeople" v-if="form.readType==0 && form.status !== '2'"> | ||||
|               <el-button | ||||
|                 size="small" | ||||
|                 type="primary" | ||||
|                 icon="iconfont iconAdd"> | ||||
|                 指派人员 | ||||
|               </el-button> | ||||
|             </ai-wechat-selecter> | ||||
|           </template> | ||||
|  | ||||
|           <template #content> | ||||
|             <ai-wrapper | ||||
|               label-width="70px" | ||||
|               :columnsNumber="3"> | ||||
|               <ai-info-item label="流转状态:"><span :class="'status-' + form.status">{{ dict.getLabel('documentStatus', form.status) }}</span></ai-info-item> | ||||
|               <ai-info-item label="当前流转对象:" label-width="98px" v-if="form.readType === '0'">{{ form.flowUserName || '-' }}</ai-info-item> | ||||
|               <ai-info-item></ai-info-item> | ||||
|             </ai-wrapper> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|         <ai-card title="流转记录"> | ||||
|           <template #right> | ||||
|             <ai-wechat-selecter :instance="instance" v-model="addFlow" @change="addFlowChange" v-if="form.readType === '1' && (form.status === '1' || form.status === '0') && $permissions('app_appofficialdocumentinfo_edit')"> | ||||
|               <el-button | ||||
|                 size="small" | ||||
|                 type="primary" | ||||
|                 icon="iconfont iconAdd"> | ||||
|                 添加人员 | ||||
|               </el-button> | ||||
|             </ai-wechat-selecter> | ||||
|           </template> | ||||
|  | ||||
|           <template #content> | ||||
|             <div class="ai-steps" v-if="form.readType === '0'"> | ||||
|               <div class="ai-steps__item" v-for="(item, index) in form.flowUsers" :key="index"> | ||||
|                 <div class="ai-steps__item--left"> | ||||
|                   <div class="ai-steps__item__avatar"> | ||||
|                     <img :src="item.avatar" v-if="item.avatar"> | ||||
|                     <h2 v-else>{{ formatName(item.flowUserName) }}</h2> | ||||
|                     <i class="iconfont iconSteps_Finished"></i> | ||||
|                   </div> | ||||
|                   <div class="ai-steps__item--content"> | ||||
|                     <span>{{ dict.getLabel('documentFlowStatus', item.flowStatus) }}</span> | ||||
|                     <h2>{{ item.flowUserName }}</h2> | ||||
|                     <p v-if="item.description">{{ item.description }}</p> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="ai-steps__item--right">{{ item.flowTime }}</div> | ||||
|               </div> | ||||
|             </div> | ||||
|             <ai-table | ||||
|               class="table" | ||||
|               v-if="form.readType === '1'" | ||||
|               :tableData="tableData" | ||||
|               :col-configs="colConfigs" | ||||
|               :total="total" | ||||
|               :isShowPagination="false" | ||||
|               :current.sync="search.current" | ||||
|               :size.sync="search.size" | ||||
|               :border="true"> | ||||
|               <el-table-column slot="options" label="操作" align="center" width="120px"> | ||||
|                 <template slot-scope="{ row }"> | ||||
|                   <span | ||||
|                     v-if="$permissions('app_appofficialdocumentinfo_edit')" | ||||
|                     class="iconfont iconDelete" | ||||
|                     title="删除" | ||||
|                     style="cursor: pointer;" | ||||
|                     @click="remove(row.id)"> | ||||
|                   </span> | ||||
|                 </template> | ||||
|               </el-table-column> | ||||
|             </ai-table> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|       </template> | ||||
|     </ai-detail> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "managementDetail", | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function, | ||||
|     params: Object | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       form: { | ||||
|         documentName: '', | ||||
|         documentCode: '', | ||||
|         documentType: '', | ||||
|         confidentialityLevel: '', | ||||
|         readType: '', | ||||
|         emergencyLevel: '', | ||||
|         issuingTime: '', | ||||
|         issuingUnit: '', | ||||
|         issuingFont: '', | ||||
|         signer: '', | ||||
|         overDescription: '', | ||||
|         overTime: '', | ||||
|         deliver: '', | ||||
|         remark: '', | ||||
|         files: [], | ||||
|         fileIds: [], | ||||
|         flowUsers: [], | ||||
|       }, | ||||
|       isAdd: true, | ||||
|       isMultiple: true, | ||||
|       addUser: [], | ||||
|       addFlow: [], | ||||
|       tableData: [], | ||||
|       search: { | ||||
|         size: 10, | ||||
|         current: 1 | ||||
|       }, | ||||
|       total: 10, | ||||
|       colConfigs: [ | ||||
|         { prop: 'flowUserName',  label: '姓名', align: 'center' }, | ||||
|         { prop: 'readTime', label: '时间', align: 'center' }, | ||||
|         { | ||||
|           prop: 'readStatus', | ||||
|           label: '阅示情况', | ||||
|           align: 'center', | ||||
|           render: (h, params) => { | ||||
|             return h('span', { | ||||
|               style: { | ||||
|                 color: params.row.readStatus === '0' ? '#FF8822' : '#2EA222' | ||||
|               } | ||||
|             }, this.$dict.getLabel('readingStatus', params.row.readStatus)) | ||||
|           } | ||||
|         }, | ||||
|         { slot: 'options', label: '操作', align: 'center' } | ||||
|       ], | ||||
|     }; | ||||
|   }, | ||||
|   computed: { | ||||
|     formRules(){ | ||||
|       return { | ||||
|         documentName: [{required: true, message: "请输入公文名称", trigger: 'change' }], | ||||
|         documentCode: [{required: true, message: "请输入公文编号", trigger: 'change' }], | ||||
|         documentType: [{required: true, message: "请选择公文类型", trigger: 'change' }], | ||||
|         readType: [{required: true, message: "请选择阅示类型", trigger: 'change' }], | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|   created() { | ||||
|     this.dict.load('issuingUnit','officialDocumentEmergencyLevel', 'officialDocumentReadType', 'officialDocumentConfidentialityLevel', 'officialDocumentName', 'documentFlowStatus', 'readingStatus'); | ||||
|   }, | ||||
|   mounted() { | ||||
|     this.form = this.params | ||||
|     this.showDetail = true | ||||
|     this.isAdd = false | ||||
|     this.getDetail() | ||||
|      | ||||
|   }, | ||||
|   methods: {  | ||||
|     remove (id) { | ||||
|       if(this.form.flowUsers.length<=1){ | ||||
|         return this.$message.error("至少留一个流转对象!"); | ||||
|       } | ||||
|       this.$confirm('确定删除该传阅人员吗?').then(() => { | ||||
|         this.instance.post(`/app/appofficialdocumentflow/delete?ids=${id}`).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.$message.success('删除成功!') | ||||
|             this.getDetail() | ||||
|           } | ||||
|         }) | ||||
|       }) | ||||
|     }, | ||||
|     formatName (name) { | ||||
|       if(name == undefined){ | ||||
|         return | ||||
|       } | ||||
|       return name.substr(name.length - 2, name.length > 2 ? (name.length - 1) : name.length) | ||||
|     }, | ||||
|     addPeople() {  //指派人员 | ||||
|       this.instance.post(`/app/appofficialdocumentinfo/flowById`,null,{ | ||||
|         params:{ | ||||
|           flowUserId:this.addFlow[0].id, | ||||
|           flowUserName:this.addFlow[0].name, | ||||
|           avatar:this.addFlow[0].avatar, | ||||
|           flag:0, | ||||
|           id:this.form.id, | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.$message({ | ||||
|             message:"指派成功", | ||||
|             type:"success" | ||||
|           }) | ||||
|           this.getDetail() | ||||
|           this.addFlow = [] | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     addFlowChange() { //添加传阅人员 | ||||
|       let data = this.form | ||||
|       const fileIds = data.files.length ? data.files.map(item => item.id) : [] | ||||
|       const flowUsers = [...this.addFlow].map(item => { | ||||
|         return { | ||||
|           flowUserId: item.id, | ||||
|           flowUserName: item.name, | ||||
|           avatar: item.avatar | ||||
|         } | ||||
|       }) | ||||
|       delete data.files | ||||
|       this.instance.post(`/app/appofficialdocumentflow/add`, { | ||||
|         id: this.form.id, | ||||
|         ...data, | ||||
|         status: '1', | ||||
|         flowUsers, | ||||
|         fileIds | ||||
|       }).then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.$message.success('添加成功') | ||||
|           this.getDetail() | ||||
|           this.addFlow = [] | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     onChange() { | ||||
|       if (!this.addUser.length) { | ||||
|         return this.$message.error('请选择流转人员') | ||||
|       } | ||||
|  | ||||
|       if (this.form.readType === '0' && this.form.status === '0') { | ||||
|         // 开始流转 | ||||
|         let data = this.form | ||||
|         const flowUsers = [...this.addUser].map(item => { | ||||
|           return { | ||||
|             flowUserId: item.id, | ||||
|             flowUserName: item.name, | ||||
|             avatar: item.avatar | ||||
|           } | ||||
|         }) | ||||
|         const fileIds = data.files.length ? data.files.map(item => item.id) : [] | ||||
|         delete data.files | ||||
|         this.instance.post(`/app/appofficialdocumentinfo/addOrUpdate`, { | ||||
|           id: this.form.id, | ||||
|           ...data, | ||||
|           status: '1', | ||||
|           flowUsers: flowUsers, | ||||
|           fileIds | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.$message.success('流转成功') | ||||
|             this.getDetail() | ||||
|           } | ||||
|         }) | ||||
|       } else { | ||||
|         // 再次流转 | ||||
|         this.instance.post(`/app/appofficialdocumentinfo/flowById`, null, { | ||||
|           params: { | ||||
|             flag: '1', | ||||
|             flowUserId: this.addUser[0].id, | ||||
|             flowUserName: this.addUser[0].name, | ||||
|             avatar: this.addUser[0].avatar, | ||||
|             id: this.form.id | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.$message.success('添加成功') | ||||
|             this.getDetail(this.id) | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|     readTypeChange() { | ||||
|       if(this.form.readType == 0) { | ||||
|         this.isMultiple = false | ||||
|         if(this.form.flowUsers.length > 1) { | ||||
|           this.form.flowUsers = [] | ||||
|         } | ||||
|       }else { | ||||
|         this.isMultiple = true | ||||
|       } | ||||
|     }, | ||||
|     getDetail() { | ||||
|       this.instance.post(`/app/appofficialdocumentinfo/queryDetailById?id=${this.params.id}&flag=0`, null).then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           this.form = {...res.data} | ||||
|           this.form.files = this.form.files || [] | ||||
|           if (res.data.readType === '1') { | ||||
|             this.tableData = res.data.flowUsers | ||||
|             this.total = res.data.flowUsers.length | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     save(formName, status){ | ||||
|       this.$refs[formName].validate((valid) => { | ||||
|         if (valid) { | ||||
|           this.submit(status) | ||||
|         } else { | ||||
|           return false; | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     submit(status) { | ||||
|       this.form.flowUsers.map(item => { | ||||
|         item.flowUserId = item.id, | ||||
|         item.flowUserName = item.name | ||||
|       }) | ||||
|  | ||||
|       this.form.fileIds = [] | ||||
|       if(this.form.files.length) { | ||||
|         this.form.files.map((item) => { | ||||
|           this.form.fileIds.push(item.id) | ||||
|         }) | ||||
|       } | ||||
|       this.instance.post(`/app/appofficialdocumentinfo/addOrUpdate`, { | ||||
|         ...this.form, | ||||
|         status: status | ||||
|       }, null).then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           if(!this.isAdd){ | ||||
|             this.$message.success("编辑成功"); | ||||
|           }else{ | ||||
|             this.$message.success("提交成功"); | ||||
|             this.cancel(true) | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     addCancel() { | ||||
|       if(this.params.id) { //新增 | ||||
|         this.cancel(true) | ||||
|       }else { | ||||
|         this.showDetail = true | ||||
|       } | ||||
|     }, | ||||
|     cancel(isRefresh) { | ||||
|       this.$emit('change', { | ||||
|         type: 'list', | ||||
|         isRefresh: !!isRefresh | ||||
|       }) | ||||
|     }, | ||||
|     downFileAll () { | ||||
|       if (this.form.files.length > 0) { | ||||
|         this.instance.post('/app/appofficialdocumentinfo/downLoadAllFileForDetail', null, { | ||||
|           responseType: 'blob', | ||||
|           params: { | ||||
|             id: this.form.id | ||||
|           } | ||||
|         }).then((res) => { | ||||
|           const link = document.createElement('a') | ||||
|           let blob = new Blob([res], { type: 'application/vnd.ms-excel' }) | ||||
|           link.style.display = 'none' | ||||
|           link.href = URL.createObjectURL(blob) | ||||
|           var num = '' | ||||
|           for (let i = 0; i < 10; i++) { | ||||
|             num += Math.ceil(Math.random() * 10) | ||||
|           } | ||||
|           link.setAttribute('download', '公文文件' + '.zip') | ||||
|           document.body.appendChild(link) | ||||
|           link.click() | ||||
|           document.body.removeChild(link) | ||||
|         }) | ||||
|       } else { | ||||
|         this.$message.error('暂无附件提供下载') | ||||
|       } | ||||
|     }, | ||||
|     endCirculation () { | ||||
|       this.$confirm('确定结束流转?').then(() => { | ||||
|         this.instance.post(`/app/appofficialdocumentinfo/finishById?id=${this.form.id}`).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.$message.success('操作成功') | ||||
|             this.cancel(true) | ||||
|           } else { | ||||
|             this.$message.error(res.msg) | ||||
|           } | ||||
|         }) | ||||
|       }) | ||||
|     }, | ||||
|   }, | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .managementDetail { | ||||
|   height: 100%; | ||||
|   overflow: auto; | ||||
|   background: #f3f6f9; | ||||
|   .above{ | ||||
|     overflow: hidden; | ||||
|     width: 100%; | ||||
|     .left{ | ||||
|       width: 50%; | ||||
|       float: left; | ||||
|     } | ||||
|     .right{ | ||||
|       width: 50%; | ||||
|       float: right; | ||||
|     } | ||||
|     .el-select{ | ||||
|       width: 100%; | ||||
|     } | ||||
|     .el-date-editor.el-input{ | ||||
|       width: 100%; | ||||
|     } | ||||
|   } | ||||
|   .iconEdit,.Edit{ | ||||
|     color:#5088FF; | ||||
|     font-size: 12px; | ||||
|     cursor: pointer; | ||||
|     padding-left: 8px; | ||||
|   } | ||||
| } | ||||
|   .ai-steps { | ||||
|     padding-bottom: 40px; | ||||
|     .ai-steps__item { | ||||
|       display: flex; | ||||
|       position: relative; | ||||
|       align-items: center; | ||||
|       justify-content: space-between; | ||||
|       padding-bottom: 44px; | ||||
|  | ||||
|       &:after { | ||||
|         position: absolute; | ||||
|         left: 20px; | ||||
|         top: 40px; | ||||
|         width: 1px; | ||||
|         height: 44px; | ||||
|         background: #DDDDDD; | ||||
|         content: ' '; | ||||
|       } | ||||
|  | ||||
|       &:last-child { | ||||
|         padding-bottom: 0; | ||||
|  | ||||
|         &:after { | ||||
|           display: none; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .ai-steps__item--left { | ||||
|         display: flex; | ||||
|         position: relative; | ||||
|  | ||||
|         .ai-steps__item--content { | ||||
|           span { | ||||
|             color: #333; | ||||
|             font-size: 16px; | ||||
|           } | ||||
|  | ||||
|           h2 { | ||||
|             margin-top: 4px; | ||||
|             color: #666666; | ||||
|             font-size: 14px; | ||||
|           } | ||||
|  | ||||
|           p { | ||||
|             margin-top: 8px; | ||||
|             color: #666666; | ||||
|             font-size: 14px; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .ai-steps__item__avatar { | ||||
|           position: relative; | ||||
|           width: 40px; | ||||
|           height: 40px; | ||||
|           margin-right: 16px; | ||||
|  | ||||
|           i { | ||||
|             position: absolute; | ||||
|             bottom: 4px; | ||||
|             right: 0; | ||||
|             color: #2ea222; | ||||
|             font-size: 12px; | ||||
|           } | ||||
|  | ||||
|           img, h2 { | ||||
|             width: 40px; | ||||
|             height: 40px; | ||||
|             line-height: 40px; | ||||
|             text-align: center; | ||||
|             border-radius: 50%; | ||||
|             color: #fff; | ||||
|             font-size: 14px; | ||||
|             background: #2266FF; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .ai-steps__item--right { | ||||
|         margin-left: 20px; | ||||
|         flex-shrink: 0; | ||||
|         color: #999999; | ||||
|         font-size: 14px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										311
									
								
								packages/work/AppDispatchManagement/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										311
									
								
								packages/work/AppDispatchManagement/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,311 @@ | ||||
| <template> | ||||
|   <ai-list class="AppDispatchManagement"> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="公文流转" isShowBottomBorder></ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-search-bar> | ||||
|         <template slot="left"> | ||||
|           <ai-select | ||||
|               v-model="searchObj.documentType" | ||||
|               placeholder="选择公文类型" | ||||
|               clearable | ||||
|               @change="(page.current = 1), getList()" | ||||
|               :selectList="dict.getDict('officialDocumentName')" | ||||
|           ></ai-select> | ||||
|           <ai-select | ||||
|               v-model="searchObj.confidentialityLevel" | ||||
|               placeholder="选择保密等级" | ||||
|               clearable | ||||
|               @change="(page.current = 1), getList()" | ||||
|               :selectList="dict.getDict('officialDocumentConfidentialityLevel')" | ||||
|           ></ai-select> | ||||
|           <ai-select | ||||
|               v-model="searchObj.status" | ||||
|               placeholder="选择流转状态" | ||||
|               clearable | ||||
|               @change="(page.current = 1), getList()" | ||||
|               :selectList="dict.getDict('documentStatus')" | ||||
|           ></ai-select> | ||||
|           <ai-select | ||||
|               v-model="searchObj.readType" | ||||
|               placeholder="选择阅示类型" | ||||
|               clearable | ||||
|               @change="(page.current = 1), getList()" | ||||
|               :selectList="dict.getDict('officialDocumentReadType')" | ||||
|           ></ai-select> | ||||
|  | ||||
|           <!-- <el-row class="dateRange" type="flex" align="middle"> | ||||
|             <span class="dateLabel">操作时间</span> | ||||
|             <el-date-picker | ||||
|               size="small" | ||||
|               v-model="searchObj.createTimeStart" | ||||
|               placeholder="开始日期" | ||||
|               @change="page.current = 1, getList()" | ||||
|               value-format="yyyy-MM-dd" /> | ||||
|             <el-date-picker | ||||
|               size="small" | ||||
|               v-model="searchObj.createTimeEnd" | ||||
|               placeholder="结束日期" | ||||
|               @change="page.current = 1, getList()" | ||||
|               value-format="yyyy-MM-dd" /> | ||||
|           </el-row> --> | ||||
|         </template> | ||||
|         <template slot="right"> | ||||
|           <el-input placeholder="输入公文名称/编号" | ||||
|                     v-model="searchObj.name" | ||||
|                     size="small" | ||||
|                     v-throttle="() => {page.current = 1, getList()}" | ||||
|                     clearable | ||||
|                     @clear="page.current = 1, searchObj.name = '', getList()" | ||||
|                     prefix-icon="iconfont iconSearch"/> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <ai-search-bar class="mt10"> | ||||
|         <template slot="left"> | ||||
|           <el-button type="primary" icon="iconfont iconAdd" @click="toAdd({})" | ||||
|           >添加 | ||||
|           </el-button | ||||
|           > | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <ai-table | ||||
|           :tableData="tableData" | ||||
|           :col-configs="colConfigs" | ||||
|           :total="page.total" | ||||
|           ref="aitableex" | ||||
|           :current.sync="page.current" | ||||
|           row-key="id" | ||||
|           default-expand-all | ||||
|           :tree-props="{ children: 'merchandiseList' }" | ||||
|           :size.sync="page.size" | ||||
|           @getList="getList" | ||||
|           @selection-change="handleSelectionChange" | ||||
|       > | ||||
|         <el-table-column slot="selection" type="selection" width="55"></el-table-column> | ||||
|         <el-table-column slot="options" label="操作" align="center" width="200"> | ||||
|           <template slot-scope="{ row }"> | ||||
|             <el-button v-if="row.status != 0" type="text" @click="goDetail(row)">详情</el-button> | ||||
|             <el-button v-if="row.status == 0" type="text" @click="toAdd(row)">编辑</el-button> | ||||
|             <el-button type="text" @click="del(row)">删除</el-button> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </ai-table> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "management", | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function, | ||||
|     areaId: String, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       searchObj: { | ||||
|         documentType: '', | ||||
|         confidentialityLevel: '', | ||||
|         readType: '', | ||||
|         createTimeStart: null, | ||||
|         createTimeEnd: null, | ||||
|         name: '', | ||||
|       }, | ||||
|       page: { | ||||
|         size: 10, | ||||
|         current: 1, | ||||
|         total: 0, | ||||
|       }, | ||||
|       tableData: [], | ||||
|       shopList: [], | ||||
|       ids: [], | ||||
|     }; | ||||
|   }, | ||||
|   computed: { | ||||
|     colConfigs() { | ||||
|       return [ | ||||
|         {slot: "selection", label: "", align: "center"}, | ||||
|         { | ||||
|           prop: "documentCode", | ||||
|           label: "公文编号", | ||||
|           width: 120, | ||||
|           align: "center", | ||||
|         }, | ||||
|         { | ||||
|           prop: "documentName", | ||||
|           label: "公文名称", | ||||
|         }, | ||||
|         { | ||||
|           prop: "documentType", | ||||
|           label: "公文类型", | ||||
|           width: 120, | ||||
|           align: "center", | ||||
|           formart: (documentType) => | ||||
|               this.$dict.getLabel("officialDocumentName", documentType), | ||||
|         }, | ||||
|         { | ||||
|           prop: "readType", | ||||
|           label: "阅示类型", | ||||
|           width: 120, | ||||
|           align: "center", | ||||
|           formart: (readType) => | ||||
|               this.$dict.getLabel("officialDocumentReadType", readType), | ||||
|         }, | ||||
|         { | ||||
|           prop: "confidentialityLevel", | ||||
|           label: "保密等级", | ||||
|           width: 120, | ||||
|           align: "center", | ||||
|           formart: (confidentialityLevel) => | ||||
|               this.$dict.getLabel("officialDocumentConfidentialityLevel", confidentialityLevel), | ||||
|         }, | ||||
|         { | ||||
|           prop: "flowUserName", | ||||
|           label: "当前流转对象", | ||||
|           width: 180, | ||||
|           align: "center", | ||||
|         }, | ||||
|         { | ||||
|           prop: "status", | ||||
|           label: "流转状态", | ||||
|           width: 120, | ||||
|           align: "center", | ||||
|           render: (h, {row}) => { | ||||
|             return h('span', {style: {color: this.dict.getColor('documentStatus', row.status)}}, this.dict.getLabel('documentStatus', row.status)) | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           prop: "createTime", | ||||
|           label: "操作时间", | ||||
|           width: 180, | ||||
|           align: "center", | ||||
|         }, | ||||
|         { | ||||
|           prop: "createUserName", | ||||
|           label: "操作人", | ||||
|           width: 120, | ||||
|           align: "center", | ||||
|         }, | ||||
|         {slot: "options", label: "操作"}, | ||||
|       ]; | ||||
|     }, | ||||
|   }, | ||||
|   created() { | ||||
|     this.dict.load('officialDocumentName', 'officialDocumentConfidentialityLevel', 'officialDocumentReadType', 'documentStatus').then(() => { | ||||
|       this.$nextTick(() => this.getList()) | ||||
|     }) | ||||
|   }, | ||||
|   methods: { | ||||
|     changeTime() { | ||||
|       this.page.current = 1 | ||||
|       this.getList() | ||||
|     }, | ||||
|     getList() { | ||||
|       this.instance.post(`/app/appofficialdocumentinfo/list`, null, { | ||||
|         params: { | ||||
|           ...this.searchObj, | ||||
|           ...this.page | ||||
|         }, | ||||
|       }).then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           this.tableData = res.data.records; | ||||
|           this.tableData.map((item) => { | ||||
|             if (item.createTime) { | ||||
|               item.createTime = item.createTime.substring(0, 10) | ||||
|             } else { | ||||
|               item.createTime = '-' | ||||
|             } | ||||
|           }) | ||||
|           this.page.total = res.data.total; | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     reset() { | ||||
|       Object.keys(this.searchObj).forEach((e) => { | ||||
|         this.searchObj[e] = ""; | ||||
|       }); | ||||
|       this.searchObj.createTimeStart = null; | ||||
|       this.searchObj.createTimeEnd = null; | ||||
|       this.getList(); | ||||
|     }, | ||||
|     toAdd(params) { | ||||
|       this.$emit('change', { | ||||
|         type: 'add', | ||||
|         params: params | ||||
|       }) | ||||
|     }, | ||||
|     goDetail(row) { | ||||
|       this.$emit('change', { | ||||
|         type: 'detail', | ||||
|         params: { | ||||
|           ...row | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     del(item) { | ||||
|       this.$confirm("删除后不可恢复,是否要删除该公文?", { | ||||
|         type: 'error' | ||||
|       }).then(() => { | ||||
|         this.instance | ||||
|         .post(`/app/appofficialdocumentinfo/delete?ids=${item.id}`) | ||||
|         .then((res) => { | ||||
|           if (res.code == 0) { | ||||
|             this.$message.success("删除成功!"); | ||||
|             this.getList(); | ||||
|           } | ||||
|         }); | ||||
|       }); | ||||
|     }, | ||||
|     handleSelectionChange(val) { | ||||
|       this.ids = []; | ||||
|       val.forEach(e => { | ||||
|         this.ids.push(e.id) | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .AppDispatchManagement { | ||||
|   height: 100%; | ||||
|   overflow: auto; | ||||
|   background: #f3f6f9; | ||||
|  | ||||
|   ::v-deep .el-range-editor--small.el-input__inner { | ||||
|     width: 258px; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .dateRange { | ||||
|     .dateLabel { | ||||
|       height: 32px; | ||||
|       border: 1px solid #D0D4DC; | ||||
|       line-height: 32px; | ||||
|       padding: 0 8px; | ||||
|       background: #F5F5F5; | ||||
|     } | ||||
|  | ||||
|     .el-input__inner { | ||||
|       border-radius: 0; | ||||
|       transform: translateX(-1px); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .iconfont { | ||||
|     cursor: pointer; | ||||
|     margin-right: 8px; | ||||
|   } | ||||
|  | ||||
|   .iconCorrect { | ||||
|     color: #53b43b; | ||||
|   } | ||||
|  | ||||
|   .iconReject { | ||||
|     color: #e75555; | ||||
|     padding: 0 8px; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										766
									
								
								packages/work/AppDispatchManagement/components/statistics.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										766
									
								
								packages/work/AppDispatchManagement/components/statistics.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,766 @@ | ||||
| <template> | ||||
|   <section class="statistics tabs-init el-tabs__content_f3f6f9"> | ||||
|     <div style="margin-top: 16px;height: 270px;"> | ||||
|       <div class="left"> | ||||
|         <div class="item-left mar-b16"> | ||||
|           <div class="item-left-title">公文总数</div> | ||||
|           <div class="item-left-num" style="color:#4B87FE;">{{totalOfficialDocumentStatistics}}</div> | ||||
|         </div> | ||||
|         <div class="item-left"> | ||||
|           <div class="item-left-title">本月新增</div> | ||||
|           <div class="item-left-num" style="color:#2EA222;">{{newMonthonStatistics}}</div> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="right"> | ||||
|         <div class="chart-content" style="padding-right:0;"> | ||||
|           <div class="chart-line"> | ||||
|             <div class="chart-title">近12个月公文登记情况</div> | ||||
|             <div v-if="lineChartData.length" | ||||
|               class="chart-info" | ||||
|               style=" | ||||
|                 width: 100%; | ||||
|                 height: 206px; | ||||
|                 padding: 16px 16px 20px 0; | ||||
|                 box-sizing: border-box; | ||||
|               " | ||||
|               id="chartLine" | ||||
|             ></div> | ||||
|             <ai-empty v-else style="height: 148px;"></ai-empty> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="chart-content"> | ||||
|       <div class="chart-line" style="margin-right: 16px;"> | ||||
|         <div class="chart-title">阅示类型统计</div> | ||||
|         <div style="overflow:hidden;"> | ||||
|           <div | ||||
|             class="chart-info" | ||||
|             style=" | ||||
|               width: 288px; | ||||
|               height: 288px; | ||||
|               padding: 16px 0 0 16px; | ||||
|               box-sizing: border-box; | ||||
|               float:left; | ||||
|             " | ||||
|             id="readType" | ||||
|             ></div> | ||||
|           <div class="list-type mar-t102"> | ||||
|             <div class="item" v-for="(item, index) in readTypeList" :key="index"> | ||||
|               <div class="type-title"> | ||||
|                 <span class="item-color-bg" :style="{'backgroundColor': item.bgColor}"></span>{{item.title}} | ||||
|               </div> | ||||
|               <div class="num">{{item.num}}</div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="chart-line"> | ||||
|         <div class="chart-title">公文类型统计</div> | ||||
|         <div style="overflow:hidden;"> | ||||
|           <div | ||||
|             class="chart-info" | ||||
|             style=" | ||||
|               width: 288px; | ||||
|               height: 288px; | ||||
|               padding: 16px 0 0 16px; | ||||
|               box-sizing: border-box; | ||||
|               float:left; | ||||
|             " | ||||
|             id="docType" | ||||
|           ></div> | ||||
|           <div class="list-type mar-t60"> | ||||
|             <div class="item" v-for="(item, index) in docTypeList" :key="index"> | ||||
|               <div class="type-title"> | ||||
|                 <span class="item-color-bg" :style="{'backgroundColor': item.bgColor}"></span>{{item.title}} | ||||
|               </div> | ||||
|               <div class="num">{{item.num}}</div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import { mapState } from "vuex"; | ||||
| import charts from "echarts"; | ||||
|  | ||||
| export default { | ||||
|   name: "statistics", | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       readTypeList: [ | ||||
|         { | ||||
|           title: '传阅', | ||||
|           num: '0', | ||||
|           bgColor: '#4B87FE' | ||||
|         }, | ||||
|         { | ||||
|           title: '批示', | ||||
|           num: '0', | ||||
|           bgColor: '#FFAA44' | ||||
|         } | ||||
|       ], | ||||
|       docTypeList: [ | ||||
|         { | ||||
|           title: '决议', | ||||
|           num: '0', | ||||
|           bgColor: '#FF4466' | ||||
|         }, | ||||
|         { | ||||
|           title: '决定', | ||||
|           num: '0', | ||||
|           bgColor: '#FFAA44' | ||||
|         }, | ||||
|         { | ||||
|           title: '通知', | ||||
|           num: '0', | ||||
|           bgColor: '#4B87FE' | ||||
|         }, | ||||
|         { | ||||
|           title: '通告', | ||||
|           num: '0', | ||||
|           bgColor: '#45A3FF' | ||||
|         }, | ||||
|         { | ||||
|           title: '函', | ||||
|           num: '0', | ||||
|           bgColor: '#2EA222' | ||||
|         }, | ||||
|         { | ||||
|           title: '其它', | ||||
|           num: '0', | ||||
|           bgColor: '#B244FF' | ||||
|         }, | ||||
|       ], | ||||
|       lineChartTitle: [], | ||||
|       lineChartData: [], | ||||
|       totalOfficialDocumentStatistics: 0, | ||||
|       newMonthonStatistics: 0, | ||||
|     }; | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(["user"]), | ||||
|   }, | ||||
|   mounted() { | ||||
|     this.getInfo() | ||||
|   }, | ||||
|   methods: { | ||||
|     getInfo() { | ||||
|       this.instance.post(`/app/appofficialsenddeliverinfo/getStatistics`).then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           this.newMonthonStatistics = res.data.newMonthonStatistics || 0 | ||||
|           this.totalOfficialDocumentStatistics = res.data.totalOfficialSendStatistics || 0 | ||||
|           if(res.data.officialRegistrationStatistics && res.data.officialRegistrationStatistics.length) { | ||||
|             res.data.officialRegistrationStatistics.map(item => { | ||||
|               this.lineChartTitle.push(item.name) | ||||
|               this.lineChartData.push(item.v1) | ||||
|             }) | ||||
|             this.$nextTick(() => { | ||||
|               this.setLineChart() | ||||
|             }) | ||||
|              | ||||
|           } | ||||
|           if(res.data.readTheTypeStatistics && res.data.readTheTypeStatistics.length) { | ||||
|             res.data.readTheTypeStatistics.map(item => { | ||||
|               if(item.name == 0){ | ||||
|                 this.readTypeList[1].num = item.v1 || 0 | ||||
|               } | ||||
|               if(item.name == 1){ | ||||
|                 this.readTypeList[0].num = item.v1 || 0 | ||||
|               } | ||||
|             }) | ||||
|             this.setReadChart() | ||||
|           } | ||||
|           if(res.data.officialSendTypeStatistics && res.data.officialSendTypeStatistics.length) { | ||||
|             res.data.officialSendTypeStatistics.map(item => { | ||||
|               if(item.name == 0){ | ||||
|                 this.docTypeList[0].num = item.v1 | ||||
|               } | ||||
|               if(item.name == 1){ | ||||
|                 this.docTypeList[1].num = item.v1 | ||||
|               } | ||||
|               if(item.name == 3){ | ||||
|                 this.docTypeList[2].num = item.v1 | ||||
|               } | ||||
|               if(item.name == 2){ | ||||
|                 this.docTypeList[3].num = item.v1 | ||||
|               } | ||||
|               if(item.name == 4){ | ||||
|                 this.docTypeList[4].num = item.v1 | ||||
|               } | ||||
|               if(item.name == 5){ | ||||
|                 this.docTypeList[5].num = item.v1 | ||||
|               } | ||||
|             }) | ||||
|             this.setDocChart() | ||||
|           } | ||||
|  | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     setLineChart() { | ||||
|       var chartLine = charts.init(document.getElementById("chartLine")); | ||||
|       var option = { | ||||
|         title: { | ||||
|           text: "", | ||||
|         }, | ||||
|         tooltip: { | ||||
|           trigger: "axis", | ||||
|         }, | ||||
|         grid: { | ||||
|           top: "10%", | ||||
|           left: "2%", | ||||
|           right: "2%", | ||||
|           bottom: "2%", | ||||
|           containLabel: true, | ||||
|         }, | ||||
|         xAxis: { | ||||
|           type: "category", | ||||
|           boundaryGap: false, | ||||
|           data: this.lineChartTitle, | ||||
|         }, | ||||
|         yAxis: { | ||||
|           type: "value", | ||||
|         }, | ||||
|         series: [ | ||||
|           { | ||||
|             name: "", | ||||
|             type: "line", | ||||
|             itemStyle: { | ||||
|               normal: { | ||||
|                 color: "#26f", | ||||
|               }, | ||||
|             }, | ||||
|             data: this.lineChartData, | ||||
|           }, | ||||
|         ], | ||||
|       }; | ||||
|       chartLine.setOption(option); | ||||
|     }, | ||||
|     setReadChart() { | ||||
|       var chart = charts.init(document.getElementById("readType")); | ||||
|       var option = { | ||||
|         tooltip: { | ||||
|           trigger: "item", | ||||
|           formatter: "{b}: {c} ({d}%)", | ||||
|         }, | ||||
|         series: [ | ||||
|           { | ||||
|             name: "", | ||||
|             type: "pie", | ||||
|             radius: ["50%", "80%"], | ||||
|             avoidLabelOverlap: false, | ||||
|             label: { | ||||
|               show: true, | ||||
|               position: 'inside', | ||||
|               formatter: '{d}%', | ||||
|               fontSize: '14', | ||||
|             }, | ||||
|             emphasis: { | ||||
|               label: { | ||||
|                 show: true, | ||||
|                 fontSize: '14', | ||||
|                 fontWeight: 'bold' | ||||
|               } | ||||
|             }, | ||||
|             labelLine: { | ||||
|               show: false | ||||
|             }, | ||||
|             data: [ | ||||
|               { | ||||
|                 value: this.readTypeList[0].num, | ||||
|                 name: '传阅', | ||||
|                 itemStyle: { | ||||
|                   normal: { | ||||
|                     color: '#4B87FE' | ||||
|                   } | ||||
|                 }, | ||||
|               }, | ||||
|               { | ||||
|                 value: this.readTypeList[1].num, | ||||
|                 name: '批示', | ||||
|                 itemStyle: { | ||||
|                   normal: { | ||||
|                     color: '#FFAA44' | ||||
|                   } | ||||
|                 }, | ||||
|               } | ||||
|             ], | ||||
|           }, | ||||
|         ], | ||||
|       }; | ||||
|       chart.setOption(option); | ||||
|     }, | ||||
|     setDocChart() { | ||||
|       var chart = charts.init(document.getElementById("docType")); | ||||
|       var option = { | ||||
|         tooltip: { | ||||
|           trigger: "item", | ||||
|           formatter: "{b}: {c} ({d}%)", | ||||
|         }, | ||||
|         series: [ | ||||
|           { | ||||
|             name: "", | ||||
|             type: "pie", | ||||
|             radius: ["50%", "80%"], | ||||
|             avoidLabelOverlap: false, | ||||
|             label: { | ||||
|               show: true, | ||||
|               position: 'inside', | ||||
|               formatter: '{d}%', | ||||
|               fontSize: '14', | ||||
|             }, | ||||
|             emphasis: { | ||||
|               label: { | ||||
|                 show: true, | ||||
|                 fontSize: '14', | ||||
|                 fontWeight: 'bold' | ||||
|               } | ||||
|             }, | ||||
|             labelLine: { | ||||
|               show: false | ||||
|             }, | ||||
|             data: [ | ||||
|               { | ||||
|                 value: this.docTypeList[0].num, | ||||
|                 name: '决议', | ||||
|                 itemStyle: { | ||||
|                   normal: { | ||||
|                     color: '#FF4466' | ||||
|                   } | ||||
|                 }, | ||||
|               }, | ||||
|               { | ||||
|                 value: this.docTypeList[1].num, | ||||
|                 name: '决定', | ||||
|                 itemStyle: { | ||||
|                   normal: { | ||||
|                     color: '#FFAA44' | ||||
|                   } | ||||
|                 }, | ||||
|               }, | ||||
|               { | ||||
|                 value: this.docTypeList[2].num, | ||||
|                 name: '通知', | ||||
|                 itemStyle: { | ||||
|                   normal: { | ||||
|                     color: '#4B87FE' | ||||
|                   } | ||||
|                 }, | ||||
|               }, | ||||
|               { | ||||
|                 value: this.docTypeList[3].num, | ||||
|                 name: '通告', | ||||
|                 itemStyle: { | ||||
|                   normal: { | ||||
|                     color: '#45A3FF' | ||||
|                   } | ||||
|                 }, | ||||
|               }, | ||||
|               { | ||||
|                 value: this.docTypeList[4].num, | ||||
|                 name: '函', | ||||
|                 itemStyle: { | ||||
|                   normal: { | ||||
|                     color: '#2EA222' | ||||
|                   } | ||||
|                 }, | ||||
|               }, | ||||
|               { | ||||
|                 value: this.docTypeList[5].num, | ||||
|                 name: '其它', | ||||
|                 itemStyle: { | ||||
|                   normal: { | ||||
|                     color: '#B244FF' | ||||
|                   } | ||||
|                 }, | ||||
|               }, | ||||
|             ], | ||||
|           }, | ||||
|         ], | ||||
|       }; | ||||
|       chart.setOption(option); | ||||
|     }, | ||||
|   }, | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .statistics { | ||||
|   height: 100%; | ||||
|   width: 100%; | ||||
|   overflow: auto; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   background: #f3f6f9; | ||||
|   // overflow: hidden; | ||||
|   .left{ | ||||
|     width: 29%; | ||||
|     float: left; | ||||
|     margin-left: 16px; | ||||
|     .item-left{ | ||||
|       padding: 0 20px; | ||||
|       width: 100%; | ||||
|       height: 120px; | ||||
|       background: #FFFFFF; | ||||
|       box-shadow: 0px 16px 32px 0px rgba(0, 0, 0, 0.02); | ||||
|       border-radius: 4px; | ||||
|       box-sizing: border-box; | ||||
|       .item-left-title{ | ||||
|         color: #333; | ||||
|         font-size: 16px; | ||||
|         padding: 20px 0 16px 0; | ||||
|       } | ||||
|       .item-left-num{ | ||||
|         font-size: 32px; | ||||
|         text-align: right; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   .right{ | ||||
|     width: calc(70% - 20px); | ||||
|     float: left; | ||||
|   } | ||||
|   .mar-t102{ | ||||
|     margin-top: 102px; | ||||
|   } | ||||
|   .mar-t60{ | ||||
|     margin-top: 60px; | ||||
|   } | ||||
|   .list-type{ | ||||
|     width:calc(100% - 360px); | ||||
|     float:right; | ||||
|     margin-left: 20px; | ||||
|     font-size: 14px; | ||||
|     padding-right: 40px; | ||||
|     .item{ | ||||
|       display: flex; | ||||
|       justify-content: space-between; | ||||
|       line-height: 20px; | ||||
|       margin-bottom: 8px; | ||||
|     } | ||||
|     .type-title{ | ||||
|       color: #666; | ||||
|       .item-color-bg{ | ||||
|         display: inline-block; | ||||
|         width: 8px; | ||||
|         height: 8px; | ||||
|         background: #4B87FE; | ||||
|         border-radius: 1px; | ||||
|         margin-right: 6px; | ||||
|       } | ||||
|     } | ||||
|     .num{ | ||||
|       color: #333; | ||||
|       text-align: right; | ||||
|     } | ||||
|   } | ||||
|   .chart-content { | ||||
|     width: 100%; | ||||
|     // height: 336px; | ||||
|     border-radius: 4px; | ||||
|     padding: 0 16px 16px 16px; | ||||
|     box-sizing: border-box; | ||||
|     display: flex; | ||||
|     .chart-line { | ||||
|       width: 100%; | ||||
|       height: 100%; | ||||
|       background-color: #fff; | ||||
|       box-shadow: 0px 16px 32px 0px rgba(0, 0, 0, 0.02); | ||||
|     } | ||||
|     .chart-title { | ||||
|       line-height: 48px; | ||||
|       border-bottom: 1px solid #e6e8ee; | ||||
|       padding-left: 16px; | ||||
|       color: #333; | ||||
|       font-size: 16px; | ||||
|     } | ||||
|     div { | ||||
|       flex: 1; | ||||
|     } | ||||
|   } | ||||
|   .tab-row { | ||||
|     padding: 16px 16px 16px 16px; | ||||
|     width: 100%; | ||||
|     box-sizing: border-box; | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|  | ||||
|     .tab-col { | ||||
|       height: 64px; | ||||
|       flex: 1; | ||||
|       background-color: #fff; | ||||
|       margin-right: 20px; | ||||
|       border-radius: 4px; | ||||
|       border: 1px solid rgba(216, 224, 232, 1); | ||||
|       overflow: hidden; | ||||
|  | ||||
|       .tab-title { | ||||
|         display: inline-block; | ||||
|         font-size: 14px; | ||||
|         color: #333; | ||||
|         height: 14px; | ||||
|         line-height: 14px; | ||||
|         vertical-align: super; | ||||
|       } | ||||
|  | ||||
|       .tab-num { | ||||
|         height: 24px; | ||||
|         font-size: 20px; | ||||
|         font-weight: bold; | ||||
|         color: #333; | ||||
|         line-height: 24px; | ||||
|         font-family: DINAlternate-Bold, serif; | ||||
|         float: right; | ||||
|         line-height: 64px; | ||||
|         padding-right: 16px; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .tab-col:nth-last-child(1) { | ||||
|       margin-right: 0; | ||||
|     } | ||||
|   } | ||||
|   .icon { | ||||
|     display: inline-block; | ||||
|     width: 24px; | ||||
|     height: 24px; | ||||
|     padding: 20px 8px 0 16px; | ||||
|   } | ||||
|  | ||||
|   .card-panel { | ||||
|     flex: 1; | ||||
|     background: #fff; | ||||
|     border: 1px solid #d8e0e8; | ||||
|     border-radius: 4px; | ||||
|     box-sizing: border-box; | ||||
|     padding: 12px 16px 0 16px; | ||||
|  | ||||
|     b { | ||||
|       font-size: 16px; | ||||
|       font-weight: 600; | ||||
|       color: rgba(51, 51, 51, 1); | ||||
|       line-height: 22px; | ||||
|     } | ||||
|  | ||||
|     #ASBarChart { | ||||
|       height: 286px; | ||||
|  | ||||
|       & + .no-data { | ||||
|         margin: 83px auto; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     #PartyAgePieChart, | ||||
|     #PartyEduPieChart { | ||||
|       height: 264px; | ||||
|  | ||||
|       & + .no-data { | ||||
|         margin: 72px auto; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .party_title { | ||||
|     height: 48px; | ||||
|     line-height: 48px; | ||||
|     background: #fff; | ||||
|     text-indent: 16px; | ||||
|     font-weight: bold; | ||||
|   } | ||||
|  | ||||
|   .party_content { | ||||
|     flex: 1; | ||||
|     display: flex; | ||||
|     padding: 16px; | ||||
|  | ||||
|     .party_left { | ||||
|       width: 280px; | ||||
|       background: #eaedf1; | ||||
|       border: 1px solid #d8dce3; | ||||
|       position: relative; | ||||
|       border-radius: 4px; | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|  | ||||
|       .p { | ||||
|         height: 28px; | ||||
|         line-height: 28px; | ||||
|         background: #d9e0e9; | ||||
|         font-size: 12px; | ||||
|         color: #333; | ||||
|         text-indent: 16px; | ||||
|       } | ||||
|  | ||||
|       .left_tree { | ||||
|         padding: 8px; | ||||
|         flex: 1; | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|         position: relative; | ||||
|  | ||||
|         .left_cont { | ||||
|           width: 95%; | ||||
|           position: absolute; | ||||
|           top: 38px; | ||||
|           margin-top: 8px; | ||||
|           height: calc(100% - 80px); | ||||
|           overflow-y: auto; | ||||
|  | ||||
|           .el-tree { | ||||
|             background: #eaedf1; | ||||
|           } | ||||
|  | ||||
|           .right_btn { | ||||
|             width: 96px; | ||||
|             background: #fff; | ||||
|             border-radius: 2px; | ||||
|             font-size: 12px; | ||||
|             padding: 4px 0; | ||||
|             position: fixed; | ||||
|             z-index: 999; | ||||
|  | ||||
|             li { | ||||
|               height: 28px; | ||||
|               line-height: 28px; | ||||
|               cursor: pointer; | ||||
|               text-indent: 12px; | ||||
|             } | ||||
|  | ||||
|             li:hover { | ||||
|               background-color: #eff6ff; | ||||
|               color: #5088ff; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .btn_img { | ||||
|         position: absolute; | ||||
|         bottom: 0; | ||||
|         background: #f5f6f7; | ||||
|         height: 32px; | ||||
|         line-height: 32px; | ||||
|         width: 100%; | ||||
|         display: flex; | ||||
|         text-align: center; | ||||
|         border-top: 1px solid #d8dce3; | ||||
|         border-radius: 0 0 4px 4px; | ||||
|  | ||||
|         span { | ||||
|           flex: 1; | ||||
|           width: 16px; | ||||
|           height: 16px; | ||||
|           cursor: pointer; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .party_right { | ||||
|       flex: 1; | ||||
|       overflow: auto; | ||||
|       margin-left: 11px; | ||||
|  | ||||
|       .total-panel { | ||||
|         margin-bottom: 21px; | ||||
|  | ||||
|         li { | ||||
|           flex: 1; | ||||
|           margin-right: 32px; | ||||
|           display: flex; | ||||
|           background: #fff; | ||||
|           border: 1px solid #d8e0e8; | ||||
|           border-radius: 4px; | ||||
|           color: #333; | ||||
|           padding: 20px; | ||||
|           font-weight: bold; | ||||
|           height: 97px; | ||||
|           box-sizing: border-box; | ||||
|  | ||||
|           .icon { | ||||
|             width: 24px; | ||||
|             height: 24px; | ||||
|             margin-right: 8px; | ||||
|           } | ||||
|  | ||||
|           &:last-child { | ||||
|             margin-right: 0; | ||||
|           } | ||||
|  | ||||
|           p { | ||||
|             font-size: 14px; | ||||
|             color: rgba(51, 51, 51, 1); | ||||
|             line-height: 24px; | ||||
|           } | ||||
|  | ||||
|           b { | ||||
|             font-size: 20px; | ||||
|             color: rgba(51, 51, 51, 1); | ||||
|             line-height: 40px; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   .operation { | ||||
|     overflow: hidden; | ||||
|     position: absolute; | ||||
|     bottom: 0; | ||||
|     left: 0; | ||||
|     width: 100%; | ||||
|     height: 64px; | ||||
|     line-height: 64px; | ||||
|     display: flex; | ||||
|     z-index: 1000; | ||||
|     align-items: center; | ||||
|     justify-content: center; | ||||
|     background-color: #f3f6f9; | ||||
|     box-shadow: inset 0px 1px 0px 0px #eeeeee; | ||||
|  | ||||
|     button { | ||||
|       width: 92px; | ||||
|       height: 32px; | ||||
|       padding: 0 !important; | ||||
|     } | ||||
|  | ||||
|     .delete-btn { | ||||
|       background-color: #fff; | ||||
|     } | ||||
|   } | ||||
|   .mask { | ||||
|     .content { | ||||
|       padding-bottom: 100px; | ||||
|     } | ||||
|     .el-table { | ||||
|       border: 1px solid #d8e0e8; | ||||
|       border-bottom: 0; | ||||
|     } | ||||
|     p { | ||||
|       line-height: 28px; | ||||
|       text-align: right; | ||||
|       cursor: pointer; | ||||
|       color: #5088ff; | ||||
|       width: 88px; | ||||
|       float: right; | ||||
|       padding-bottom: 8px; | ||||
|     } | ||||
|   } | ||||
|   .vc-input-120 { | ||||
|     width: 120px !important; | ||||
|     float: right; | ||||
|     padding-right: 16px; | ||||
|  | ||||
|     .el-input__inner { | ||||
|       width: 120px !important; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										66
									
								
								packages/work/AppForm/AppForm.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								packages/work/AppForm/AppForm.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| <template> | ||||
|   <div class="doc-circulation"> | ||||
|     <keep-alive :include="['List']"> | ||||
|       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> | ||||
|     </keep-alive> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import List from './components/List' | ||||
|   import Add from './components/Add' | ||||
|  | ||||
|   export default { | ||||
|     name: 'AppForm', | ||||
|     label: '配置表单', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         component: 'List', | ||||
|         params: {}, | ||||
|         include: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     components: { | ||||
|       Add, | ||||
|       List | ||||
|     }, | ||||
|  | ||||
|     mounted () { | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       onChange (data) { | ||||
|         if (data.type === 'Add') { | ||||
|           this.component = 'Add' | ||||
|           this.params = data.params | ||||
|         } | ||||
|  | ||||
|         if (data.type === 'list') { | ||||
|           this.component = 'List' | ||||
|           this.params = data.params | ||||
|  | ||||
|           this.$nextTick(() => { | ||||
|             if (data.isRefresh) { | ||||
|               this.$refs.component.getList() | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss"> | ||||
|   .doc-circulation { | ||||
|     height: 100%; | ||||
|     background: #F3F6F9; | ||||
|     overflow: auto; | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										281
									
								
								packages/work/AppForm/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								packages/work/AppForm/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,281 @@ | ||||
| <template> | ||||
|   <ai-detail class="form-add" :class="[currIndex === 1 ? 'form-add__active' : '']"> | ||||
|     <ai-title title="表单配置" slot="title" isShowBottomBorder isShowBack  @onBackClick="cancel(false)"></ai-title> | ||||
|     <template #content> | ||||
|       <div class="ai-step"> | ||||
|         <div class="ai-step__item" | ||||
|           :class="[currIndex >= index ? 'ai-step__item--active' : '']" | ||||
|           v-for="(item, index) in statusList" | ||||
|           :key="index"> | ||||
|           <div class="ai-step__item--icon" v-if="currIndex <= index"> | ||||
|             <i v-if="currIndex === index"></i> | ||||
|           </div> | ||||
|           <div class="el-icon-success" v-if="currIndex > index"> | ||||
|           </div> | ||||
|           <span>{{ item }}</span> | ||||
|         </div> | ||||
|       </div> | ||||
|       <basic-info ref="basicInfo" v-model="basicInfo" v-show="currIndex === 0" :dict="dict" :instance="instance"></basic-info> | ||||
|       <form-layout :appType="basicInfo.appType" :currIndex="currIndex" class="form-config__wrapper" v-model="tableInfos" ref="form" v-show="currIndex === 1" :dict="dict" :instance="instance"></form-layout> | ||||
|       <form-config | ||||
|         ref="config" | ||||
|         :showListFields="showListFields" | ||||
|         :btns="btns" | ||||
|         :fuzzyQueryFields="fuzzyQueryFields" | ||||
|         :tableInfos="tableInfos" | ||||
|         :orderFields="orderFields" | ||||
|         v-if="currIndex === 2"> | ||||
|       </form-config> | ||||
|     </template> | ||||
|     <template #footer> | ||||
|       <el-button @click="cancel">取消</el-button> | ||||
|       <el-button @click="back" v-if="currIndex > 0">上一步</el-button> | ||||
|       <el-button @click="next" type="primary">{{ currIndex === 2 ? '完成' : '下一步' }}</el-button> | ||||
|     </template> | ||||
|   </ai-detail> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import BasicInfo from './BasicInfo.vue' | ||||
|   import FormLayout from './FormLayout.vue' | ||||
|   import FormConfig from './FormConfig.vue' | ||||
|   export default { | ||||
|     name: 'add', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       params: Object, | ||||
|       type: String | ||||
|     }, | ||||
|  | ||||
|     components: { | ||||
|       FormLayout, | ||||
|       BasicInfo, | ||||
|       FormConfig | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         currIndex: 0, | ||||
|         basicInfo: { | ||||
|           saasPlatformId: '', | ||||
|           menuLeve1Style: '', | ||||
|           saasPlatformName: '', | ||||
|           menuLevel1Name: '', | ||||
|           menuLevel3Name: '', | ||||
|           menuLevel2Name: '', | ||||
|           appType: '' | ||||
|         }, | ||||
|         orderFields: [], | ||||
|         showListFields: [], | ||||
|         fuzzyQueryFields: [], | ||||
|         btns: [], | ||||
|         btnKeys: ['insertEnable', 'importEnable', 'exportEnalbe', 'editEnable', 'deleteEnable', 'batchDelEnable'], | ||||
|         configInfo: { | ||||
|           btns: [], | ||||
|           orderType: '0', | ||||
|           fieldName: '' | ||||
|         }, | ||||
|         info: {}, | ||||
|         tableInfos: [], | ||||
|         statusList: ['基础设置', '表单设计', '列表设计'] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     mounted () { | ||||
|       if (this.params.id) { | ||||
|         this.getInfo() | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       cancel (isRefresh) { | ||||
|         this.$emit('change', { | ||||
|           type: 'list', | ||||
|           isRefresh: isRefresh ? true : false, | ||||
|           isQuote: this.params.isQuote ? true : false | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       confirm () { | ||||
|  | ||||
|       }, | ||||
|  | ||||
|       back () { | ||||
|         this.currIndex = this.currIndex - 1 | ||||
|       }, | ||||
|  | ||||
|       confirmBasicInfo () { | ||||
|         return this.$refs.basicInfo.validate() | ||||
|       }, | ||||
|  | ||||
|       getInfo () { | ||||
|         this.instance.post(`/app/appapplicationinfo/queryDetailById?id=${this.params.id}`).then(res => { | ||||
|           if (res.code === 0) { | ||||
|             this.info = res.data | ||||
|             this.basicInfo = { | ||||
|               saasPlatformId: res.data.saasPlatformId, | ||||
|               menuLeve1Style: res.data.menuLeve1Style, | ||||
|               saasPlatformName: res.data.saasPlatformName, | ||||
|               menuLevel1Name: res.data.menuLevel1Name, | ||||
|               menuLevel3Name: res.data.menuLevel3Name, | ||||
|               menuLevel2Name: res.data.menuLevel2Name, | ||||
|               appType: res.data.appType, | ||||
|               corpId: res.data.corpId, | ||||
|               corpName: res.data.corpName | ||||
|             } | ||||
|             this.fuzzyQueryFields = res.data.fuzzyQueryFields | ||||
|             this.tableInfos = res.data.tableInfos | ||||
|             this.showListFields = res.data.showListFields | ||||
|             this.orderFields = res.data.orderFields | ||||
|             this.btns = Object.keys(res.data).filter(v => { | ||||
|               return this.btnKeys.indexOf(v) > -1 && res.data[v] === '1' | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       submit (info) { | ||||
|         this.instance.post(`/app/appapplicationinfo/addOrUpdate`, { | ||||
|           ...this.info, | ||||
|           ...this.basicInfo, | ||||
|           tableInfos: this.tableInfos, | ||||
|           ...info.btns, | ||||
|           id: this.params.id, | ||||
|           applicationName: this.basicInfo.menuLevel3Name || this.basicInfo.menuLevel2Name, | ||||
|           fuzzyQueryFields: info.fuzzyQueryFields, | ||||
|           orderType: info.orderType, | ||||
|           orderFields: info.orderFields, | ||||
|           showListFields: info.showListFields | ||||
|         }).then(res => { | ||||
|           if (res.code === 0) { | ||||
|             this.$message.success(this.params.id ? '编辑成功' : '添加成功') | ||||
|             this.cancel(true) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       next () { | ||||
|         if (this.currIndex === 0) { | ||||
|           if (!this.$refs.basicInfo.validate()) return | ||||
|         } | ||||
|  | ||||
|         if (this.currIndex === 1) { | ||||
|           this.$refs.form.onConfirm() | ||||
|         } | ||||
|  | ||||
|         if (this.currIndex === 2) { | ||||
|           const info = this.$refs.config.validate() | ||||
|           if (!info) return | ||||
|  | ||||
|           this.submit(info) | ||||
|  | ||||
|           return false | ||||
|         } | ||||
|  | ||||
|         this.currIndex = this.currIndex + 1 | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .form-add { | ||||
|     &.form-add__active { | ||||
|       ::v-deep .ai-detail__content--wrapper { | ||||
|         max-width: 100%!important; | ||||
|         height: 100%!important; | ||||
|         background: #F5F6F9; | ||||
|       } | ||||
|  | ||||
|       .form-config__wrapper { | ||||
|         height: calc(100% - 52px); | ||||
|         overflow-y: hidden; | ||||
|       } | ||||
|  | ||||
|       ::v-deep .ai-detail__content { | ||||
|         height: calc(100% - 114px)!important; | ||||
|         padding: 0!important; | ||||
|         overflow: hidden!important; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .ai-step { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|       margin-top: 4px; | ||||
|       margin-bottom: 24px; | ||||
|  | ||||
|       .ai-step__item { | ||||
|         display: flex; | ||||
|         position: relative; | ||||
|         align-items: center; | ||||
|         margin-right: 216px; | ||||
|  | ||||
|         &.ai-step__item--active { | ||||
|           span { | ||||
|             color: #2266FF; | ||||
|           } | ||||
|  | ||||
|           .ai-step__item--icon { | ||||
|             display: flex; | ||||
|             align-items: center; | ||||
|             justify-content: center; | ||||
|             border-color: #2266FF; | ||||
|  | ||||
|             i { | ||||
|               width: 12px; | ||||
|               height: 12px; | ||||
|               border-radius: 50%; | ||||
|               background: #2266FF; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         &:after { | ||||
|           position: absolute; | ||||
|           top: 50%; | ||||
|           right: -208px; | ||||
|           width: 200px; | ||||
|           height: 2px; | ||||
|           background: #D0D4DC; | ||||
|           content: ' '; | ||||
|           transform: translateY(-50%); | ||||
|         } | ||||
|  | ||||
|         &:last-child { | ||||
|           margin-right: 0; | ||||
|  | ||||
|           &::after { | ||||
|             display: none; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .ai-step__item--icon { | ||||
|           width: 24px; | ||||
|           height: 24px; | ||||
|           margin-right: 8px; | ||||
|           border-radius: 50%; | ||||
|           background: #FFFFFF; | ||||
|           border: 2px solid #D0D4DC; | ||||
|         } | ||||
|  | ||||
|         .el-icon-success { | ||||
|           width: 24px; | ||||
|           height: 24px; | ||||
|           font-size: 24px; | ||||
|           margin-right: 8px; | ||||
|           color: #2266FF; | ||||
|           border-radius: 50%; | ||||
|         } | ||||
|  | ||||
|         span { | ||||
|           color: #666666; | ||||
|           font-size: 14px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										151
									
								
								packages/work/AppForm/components/BasicInfo.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								packages/work/AppForm/components/BasicInfo.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,151 @@ | ||||
| <template> | ||||
|   <div class="basicInfo"> | ||||
|     <el-form ref="form" :model="form" label-width="110px" label-position="right"> | ||||
|       <ai-card title="基本信息"> | ||||
|         <template #content> | ||||
|           <div class="ai-form"> | ||||
|             <el-form-item label="所属平台" prop="saasPlatformId" style="width: 100%;" :rules="[{ required: true, message: '请选择所属平台', trigger: 'change' }]"> | ||||
|               <el-select | ||||
|                 size="small" | ||||
|                 style="width: 100%;" | ||||
|                 placeholder="请选择所属平台" | ||||
|                 clearable | ||||
|                 @change="onChange" | ||||
|                 v-model="form.saasPlatformId"> | ||||
|                 <el-option | ||||
|                   v-for="(item, index) in sassList" | ||||
|                   :key="index" | ||||
|                   :label="item.name" | ||||
|                   :value="item.id"> | ||||
|                 </el-option> | ||||
|               </el-select> | ||||
|             </el-form-item> | ||||
|             <el-form-item v-if="form.saasPlatformId" style="width: 100%;" label="所属企业" prop="corpId" :rules="[{ required: true, message: '请选择所属企业', trigger: 'change' }]"> | ||||
|               <ai-select | ||||
|                 v-model="form.corpId" | ||||
|                 placeholder="请选择所属企业" | ||||
|                 clearable | ||||
|                 @change="onCompanyChange" | ||||
|                 :selectList="companyList"> | ||||
|               </ai-select> | ||||
|             </el-form-item> | ||||
|             <el-form-item  style="width: 100%;" label="一级菜单名称" prop="menuLevel1Name" :rules="[{ required: true, message: '请输入一级菜单名称', trigger: 'change' }]"> | ||||
|               <el-input size="small" placeholder="请输入一级菜单名称" :maxlength="8" v-model="form.menuLevel1Name"></el-input> | ||||
|             </el-form-item> | ||||
|             <el-form-item style="width: 100%;" label="二级菜单名称" prop="menuLevel2Name" :rules="[{ required: true, message: '请输入二级菜单名称', trigger: 'change' }]"> | ||||
|               <el-input size="small" placeholder="请输入二级菜单名称" :maxlength="8" v-model="form.menuLevel2Name"></el-input> | ||||
|             </el-form-item> | ||||
|             <el-form-item style="width: 100%;" label="三级菜单名称" prop="menuLevel3Name"> | ||||
|               <el-input size="small" placeholder="请输入三级菜单名称" :maxlength="8" v-model="form.menuLevel3Name"></el-input> | ||||
|             </el-form-item> | ||||
|             <el-form-item style="width: 100%;" label="应用类型" prop="appType"> | ||||
|               <ai-select | ||||
|                 v-model="form.appType" | ||||
|                 placeholder="请选择应用类型" | ||||
|                 clearable | ||||
|                 :selectList="dict.getDict('diyAppType')"> | ||||
|               </ai-select> | ||||
|             </el-form-item> | ||||
|           </div> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|     </el-form> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   export default { | ||||
|     name: 'basicInfo', | ||||
|  | ||||
|     model: { | ||||
|       prop: 'value', | ||||
|       event: 'change', | ||||
|     }, | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       value: Object | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         form: { | ||||
|           saasPlatformId: '', | ||||
|           menuLeve1Style: '', | ||||
|           saasPlatformName: '', | ||||
|           menuLevel1Name: '', | ||||
|           menuLevel2Name: '', | ||||
|           menuLevel3Name: '', | ||||
|           appType: '', | ||||
|           corpId: '', | ||||
|           corpName: '' | ||||
|         }, | ||||
|         companyList: [], | ||||
|         sassList: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     watch: { | ||||
|       value (v) { | ||||
|         this.form = JSON.parse(JSON.stringify(v)) | ||||
|         if (this.form.saasPlatformId) { | ||||
|           this.getCompanyList() | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       this.dict.load('diyAppType') | ||||
|     }, | ||||
|  | ||||
|     mounted () { | ||||
|       this.getSassList() | ||||
|       this.form = JSON.parse(JSON.stringify(this.value)) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       onChange (e) { | ||||
|         this.form.saasPlatformName = this.sassList.filter(v => v.id === e)[0].name | ||||
|         this.form.saasPlatformId && this.getCompanyList() | ||||
|       }, | ||||
|  | ||||
|       validate () { | ||||
|         let result = false | ||||
|         this.$refs.form.validate(valid => { | ||||
|           result = valid | ||||
|         }) | ||||
|         this.$emit('change', this.form) | ||||
|         return result  | ||||
|       }, | ||||
|  | ||||
|       onCompanyChange (e) { | ||||
|         this.form.corpName = this.companyList.filter(v => v.dictValue === e)[0].dictName | ||||
|       }, | ||||
|  | ||||
|       getCompanyList () { | ||||
|         this.instance.post(`/app/appCorp/page?current=1&size=1000&saasId=${this.form.saasPlatformId}`).then(res => { | ||||
|           if (res.data.records.length) { | ||||
|             this.companyList = res.data.records.map(v => { | ||||
|               return { | ||||
|                 dictValue: v.corpId, | ||||
|                 dictName: v.name | ||||
|               } | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       getSassList () { | ||||
|         this.instance.post(`/app/appSaas/listAll`).then(res => { | ||||
|           if (res.data) { | ||||
|             this.sassList = res.data | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| </style> | ||||
							
								
								
									
										244
									
								
								packages/work/AppForm/components/FormConfig.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								packages/work/AppForm/components/FormConfig.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | ||||
| <template> | ||||
|   <div class="basicInfo"> | ||||
|     <ai-card title="搜索字段" class="search-wrapper"> | ||||
|       <template #content> | ||||
|         <el-checkbox-group v-model="queryFields"> | ||||
|           <el-checkbox | ||||
|             :label="`${item.fieldDbName}~${item.fieldName}`" | ||||
|             v-for="(item, index) in tableInfos" | ||||
|             :key="index"> | ||||
|             {{ item.fieldName }} | ||||
|           </el-checkbox> | ||||
|         </el-checkbox-group> | ||||
|       </template> | ||||
|     </ai-card> | ||||
|     <ai-card title="表格字段"> | ||||
|       <template #content> | ||||
|         <div class="ai-table"> | ||||
|           <div class="el-table el-table--border ai-header__border"> | ||||
|             <el-scrollbar> | ||||
|               <table cellspacing="0" cellpadding="0" border="0" class="el-table__body"> | ||||
|                 <draggable element="thead" animation="500" class="el-table__header is-leaf ai-table__header" :sort="true" v-model="showFields"> | ||||
|                   <th v-for="(item, index) in showFields" style="background: #f3f4f5; text-align: center;" class="ai-table__header" :key="index">{{ item.fieldName }}</th> | ||||
|                 </draggable>  | ||||
|                 <tbody element="tbody"> | ||||
|                   <tr> | ||||
|                     <td @click="handleShow(index, item.isShow)" v-for="(item, index) in showFields" :key="index">{{ item.isShow ? '已显示' : '已隐藏' }}</td> | ||||
|                   </tr> | ||||
|                 </tbody>  | ||||
|               </table> | ||||
|             </el-scrollbar> | ||||
|           </div> | ||||
|         </div> | ||||
|       </template> | ||||
|     </ai-card> | ||||
|     <ai-card title="排序和操作按钮"> | ||||
|       <template #content> | ||||
|         <el-form ref="form" class="ai-form" :model="form" label-width="110px" label-position="right"> | ||||
|           <el-form-item label="排序字段" prop="field"> | ||||
|             <el-select | ||||
|               size="small" | ||||
|               placeholder="默认按创建时间排序" | ||||
|               clearable | ||||
|               v-model="form.field"> | ||||
|               <el-option | ||||
|                 v-for="(filed, index) in tableInfos" | ||||
|                 :key="index" | ||||
|                 :label="filed.fieldName" | ||||
|                 :value="`${filed.fieldDbName}~${filed.fieldName}`"> | ||||
|               </el-option> | ||||
|             </el-select> | ||||
|           </el-form-item> | ||||
|           <el-form-item label="排序类型" prop="orderType" :rules="[{ required: true, message: '请输入排序类型', trigger: 'change' }]"> | ||||
|             <el-radio-group v-model="form.orderType"> | ||||
|               <el-radio label="asc">升序</el-radio> | ||||
|               <el-radio label="desc">降序</el-radio> | ||||
|             </el-radio-group> | ||||
|           </el-form-item> | ||||
|           <el-form-item label="按钮配置" prop="btns" style="width: 100%;" :rules="[{ required: true, message: '请输入按钮配置', trigger: 'change' }]"> | ||||
|             <el-checkbox-group v-model="form.btns"> | ||||
|               <el-checkbox label="insertEnable">添加</el-checkbox> | ||||
|               <el-checkbox label="importEnable">导入</el-checkbox> | ||||
|               <el-checkbox label="exportEnalbe">导出</el-checkbox> | ||||
|               <el-checkbox label="editEnable">编辑</el-checkbox> | ||||
|               <el-checkbox label="deleteEnable">删除</el-checkbox> | ||||
|               <el-checkbox label="batchDelEnable">批量删除</el-checkbox> | ||||
|             </el-checkbox-group> | ||||
|           </el-form-item> | ||||
|         </el-form> | ||||
|       </template> | ||||
|     </ai-card> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import draggable from 'vuedraggable' | ||||
|   export default { | ||||
|     name: 'configForm', | ||||
|  | ||||
|     props: { | ||||
|       tableInfos: Array, | ||||
|       btns: Array, | ||||
|       showListFields: Array, | ||||
|       orderFields: Array, | ||||
|       fuzzyQueryFields: Array | ||||
|     }, | ||||
|  | ||||
|     components: { | ||||
|       draggable | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         queryFields: [], | ||||
|         tableData: [{}], | ||||
|         btnKeys: ['insertEnable', 'importEnable', 'exportEnalbe', 'editEnable', 'deleteEnable', 'batchDelEnable'], | ||||
|         form: { | ||||
|           btns: [], | ||||
|           orderType: 'asc', | ||||
|           field: '' | ||||
|         }, | ||||
|         showFields: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     mounted () { | ||||
|       const showIds = this.showListFields.map(v => v.fieldDbName) | ||||
|       this.showFields = JSON.parse(JSON.stringify(this.tableInfos)).map(item => { | ||||
|         item.isShow = showIds.indexOf(item.fieldDbName) > -1 ? true : false | ||||
|  | ||||
|         return item | ||||
|       }) | ||||
|  | ||||
|       if (!this.showListFields.length) { | ||||
|         this.showFields.map(v => { | ||||
|           v.isShow = true | ||||
|           return v | ||||
|         }) | ||||
|       } | ||||
|  | ||||
|       this.tableInfos.map(item => { | ||||
|         this.tableData[0][item.fieldDbName] = '删除' | ||||
|       }) | ||||
|  | ||||
|       if (this.btns.length) { | ||||
|         this.form.btns = this.btns | ||||
|       } | ||||
|  | ||||
|       const tableInfosIds = this.tableInfos.map(v => v.fieldDbName) | ||||
|  | ||||
|       if (this.orderFields.length) { | ||||
|         let arr = this.orderFields.filter(v => { | ||||
|           return tableInfosIds.indexOf(v.fieldDbName) > -1 | ||||
|         }).map(item => { | ||||
|           return `${item.fieldDbName}~${item.fieldName}` | ||||
|         }) | ||||
|  | ||||
|         if (arr.length) { | ||||
|           this.form.field = arr[0] | ||||
|         } | ||||
|       } | ||||
|       if (this.fuzzyQueryFields.length) { | ||||
|         this.queryFields = this.fuzzyQueryFields.filter(v => { | ||||
|           return tableInfosIds.indexOf(v.fieldDbName) > -1 | ||||
|         }).map(item => { | ||||
|           return `${item.fieldDbName}~${item.fieldName}` | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       validate () { | ||||
|         let result = false | ||||
|         this.$refs.form.validate(valid => { | ||||
|           result = valid | ||||
|         }) | ||||
|  | ||||
|         if (!result) { | ||||
|           return false | ||||
|         } | ||||
|  | ||||
|         const btns = {} | ||||
|         this.btnKeys.forEach(item => { | ||||
|           btns[item] = this.form.btns.indexOf(item) > -1 ? 1 : 0  | ||||
|         }) | ||||
|  | ||||
|         return { | ||||
|           btns, | ||||
|           orderFields: [{ | ||||
|             fieldName: this.form.field.split('~')[1], | ||||
|             fieldDbName: this.form.field.split('~')[0], | ||||
|             orderType: this.form.orderType | ||||
|           }], | ||||
|           showListFields: this.showFields.filter(v => v.isShow).map((v, index) => { | ||||
|             return { | ||||
|               fieldName: v.fieldName, | ||||
|               fieldDbName: v.fieldDbName, | ||||
|               showListIndex: index | ||||
|             } | ||||
|           }), | ||||
|           fuzzyQueryFields: this.queryFields.map(v => { | ||||
|             return { | ||||
|               fieldName: v.split('~')[1], | ||||
|               fieldDbName: v.split('~')[0] | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       }, | ||||
|  | ||||
|       handleShow (index, isShow) { | ||||
|         const total = this.showFields.map(v => v.isShow).filter(v => !!v) | ||||
|         if (total.length <= 1 && isShow) { | ||||
|           return this.$message.error('表格列数不能小于1') | ||||
|         } | ||||
|  | ||||
|         this.$set(this.showFields[index], 'isShow', !isShow) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
|   .basicInfo { | ||||
|     .search-wrapper { | ||||
|       ::v-deep .el-checkbox-group { | ||||
|         display: flex; | ||||
|         flex-wrap: wrap; | ||||
|  | ||||
|         .el-checkbox { | ||||
|           width: 16.66%; | ||||
|           margin-bottom: 10px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .ai-table { | ||||
|     .el-table--border { | ||||
|       border: 1px solid #d0d4dc; | ||||
|       border-bottom: none; | ||||
|       border-right: none; | ||||
|     } | ||||
|     table { | ||||
|       min-width: 100%; | ||||
|     } | ||||
|  | ||||
|     th, tr { | ||||
|       min-width: 100px; | ||||
|       cursor: move; | ||||
|     } | ||||
|  | ||||
|     tr { | ||||
|       td { | ||||
|         cursor: pointer; | ||||
|         color: #26f; | ||||
|         text-align: center; | ||||
|         user-select: none; | ||||
|  | ||||
|         &:hover { | ||||
|           opacity: 0.7; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										1198
									
								
								packages/work/AppForm/components/FormLayout.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1198
									
								
								packages/work/AppForm/components/FormLayout.vue
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										182
									
								
								packages/work/AppForm/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								packages/work/AppForm/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,182 @@ | ||||
| <template> | ||||
|   <ai-list class="appform"> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="表单配置" isShowBottomBorder></ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-search-bar class="search-bar"> | ||||
|         <template #left> | ||||
|           <el-button size="small" type="primary" icon="iconfont iconAdd" @click="toAdd('')">添加</el-button> | ||||
|         </template> | ||||
|         <template slot="right"> | ||||
|           <el-input | ||||
|             v-model="search.applicationName" | ||||
|             size="small" | ||||
|             v-throttle="() => {search.current = 1, getList()}" | ||||
|             placeholder="请输入菜单名称" | ||||
|             clearable | ||||
|             @clear="search.current = 1, search.applicationName = '', getList()" | ||||
|             suffix-icon="iconfont iconSearch"> | ||||
|           </el-input> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <ai-table | ||||
|         :tableData="tableData" | ||||
|         :col-configs="colConfigs" | ||||
|         :total="total" | ||||
|         v-loading="loading" | ||||
|         style="margin-top: 6px;" | ||||
|         :current.sync="search.current" | ||||
|         :size.sync="search.size" | ||||
|         @getList="getList"> | ||||
|         <el-table-column slot="options" width="180px" fixed="right" label="操作" align="center"> | ||||
|           <template slot-scope="{ row }"> | ||||
|             <div class="table-options"> | ||||
|               <el-button type="text" @click="push(row.id)" v-if="row.pushStatus === '0'">推送</el-button> | ||||
|               <el-button type="text" @click="operate(row.id, row.status)">{{ row.status === '1' ? '停用' : '启用' }}</el-button> | ||||
|               <el-button type="text" @click="toAdd(row.id)">编辑</el-button> | ||||
|               <el-button type="text" @click="remove(row.id)">删除</el-button> | ||||
|             </div> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </ai-table> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import { mapState } from 'vuex' | ||||
|   export default { | ||||
|     name: 'List', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object | ||||
|     }, | ||||
|  | ||||
|     data() { | ||||
|       return { | ||||
|         search: { | ||||
|           current: 1, | ||||
|           size: 10, | ||||
|           applicationName: '' | ||||
|         }, | ||||
|         loading: false, | ||||
|         total: 10, | ||||
|         colConfigs: [ | ||||
|           { prop: 'saasPlatformName', label: '所属平台' }, | ||||
|           { prop: 'menuLevel1Name', label: '一级菜单名称'}, | ||||
|           { prop: 'menuLevel2Name', label: '二级菜单名称'}, | ||||
|           { prop: 'menuLevel3Name', label: '三级菜单名称'}, | ||||
|           { prop: 'createUserName', label: '编辑人' }, | ||||
|           { prop: 'createTime', label: '编辑时间' }, | ||||
|           { | ||||
|             prop: 'status', | ||||
|             label: '状态', | ||||
|             align: 'center', | ||||
|             render (h, {row}) { | ||||
|               return h('span',{ | ||||
|                 style: { | ||||
|                   color: row.status === '1' ? '#2EA222' : '#F46' | ||||
|                 } | ||||
|               }, row.status === '1' ? '启用' : '停用') | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             prop: 'pushStatus', | ||||
|             label: '推送状态', | ||||
|             align: 'center', | ||||
|             render (h, {row}) { | ||||
|               return h('span',{ | ||||
|                 style: { | ||||
|                   color: row.pushStatus === '1' ? '#2EA222' : '#F46' | ||||
|                 } | ||||
|               }, row.pushStatus === '1' ? '成功' : '失败') | ||||
|             } | ||||
|           } | ||||
|         ], | ||||
|         tableData: [], | ||||
|         ids: '' | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       ...mapState(['user']) | ||||
|     }, | ||||
|  | ||||
|     mounted() { | ||||
|       this.getList() | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getList () { | ||||
|         this.loading = true | ||||
|         this.instance.post(`/app/appapplicationinfo/list`, null, { | ||||
|           params: { | ||||
|             ...this.search | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.tableData = res.data.records | ||||
|             this.total = res.data.total | ||||
|  | ||||
|             this.$nextTick(() => { | ||||
|               this.loading = false | ||||
|             }) | ||||
|           } else { | ||||
|             this.loading = false | ||||
|           } | ||||
|         }).catch(() => { | ||||
|           this.loading = false | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       removeAll () { | ||||
|         if (!this.ids) return | ||||
|  | ||||
|         this.remove(this.ids) | ||||
|       }, | ||||
|  | ||||
|       push (id) { | ||||
|         this.instance.post(`/app/appapplicationinfo/push?id=${id}`).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.$message.success(`推送成功`) | ||||
|             this.getList() | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       operate (id, status) { | ||||
|         this.instance.post(`/app/appapplicationinfo/enable?id=${id}`).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.$message.success(`${status === '1' ? '停用成功' : '启用成功'}`) | ||||
|             this.getList() | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       remove (id) { | ||||
|         this.$confirm('确定删除该数据?').then(() => { | ||||
|           this.instance.post(`/app/appapplicationinfo/delete?ids=${id}`).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.$message.success('删除成功!') | ||||
|               this.getList() | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       toAdd(id) { | ||||
|         this.$emit('change', { | ||||
|           type: 'Add', | ||||
|           params: { | ||||
|             id: id || '' | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| </style> | ||||
							
								
								
									
										272
									
								
								packages/work/AppForm/components/config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										272
									
								
								packages/work/AppForm/components/config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,272 @@ | ||||
| export const components = [ | ||||
| 	{ | ||||
| 		type: 'info', | ||||
| 		tips: '(不能重复添加同一元素)', | ||||
| 		label: '信息', | ||||
| 		children: [ | ||||
| 			{ | ||||
| 				type: 'name', | ||||
| 				fieldName: '姓名', | ||||
| 				fieldTips: '请输入姓名', | ||||
| 				fixedLabel: '姓名', | ||||
| 				disable: '0', | ||||
| 				grid: 0.5, | ||||
| 				defaultValue: '', | ||||
| 				icon: 'icontext_box', | ||||
| 				mustFill: '1', | ||||
| 				maxLength: 20 | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'idNumber', | ||||
| 				fieldName: '身份证号', | ||||
| 				fixedLabel: '身份证号', | ||||
| 				fieldTips: '请输入身份证号', | ||||
| 				defaultValue: '', | ||||
| 				icon: 'icontext_area', | ||||
| 				mustFill: '1', | ||||
| 				maxLength: 20, | ||||
| 				disable: '0', | ||||
| 				grid: 0.5 | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'phone', | ||||
| 				fieldName: '联系方式', | ||||
| 				fixedLabel: '联系方式', | ||||
| 				fieldTips: '请输入联系方式', | ||||
| 				defaultValue: '', | ||||
| 				icon: 'icontext_area', | ||||
| 				mustFill: '1', | ||||
| 				maxLength: 20, | ||||
| 				disable: '0', | ||||
| 				grid: 0.5 | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'area', | ||||
| 				fieldName: '地区', | ||||
| 				fixedLabel: '地区', | ||||
| 				fieldTips: '请选择地区', | ||||
| 				defaultValue: '', | ||||
| 				icon: 'icontext_area', | ||||
| 				mustFill: '1', | ||||
| 				areaPattern: '', | ||||
| 				disable: '0', | ||||
| 				grid: 0.5 | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	{ | ||||
| 		type: 'options', | ||||
| 		tips: '(可重复添加)', | ||||
| 		label: '选项', | ||||
| 		children: [ | ||||
| 			{ | ||||
| 				type: 'radio', | ||||
| 				fieldName: '单选', | ||||
| 				fixedLabel: '单选', | ||||
| 				fieldTips: '请选择', | ||||
| 				grid: 0.5, | ||||
| 				icon: 'iconradio', | ||||
| 				mustFill: '1', | ||||
| 				disable: '0', | ||||
| 				defaultValue: '', | ||||
| 				options: [ | ||||
| 					{ | ||||
| 						label: '选项1', | ||||
| 						value: '' | ||||
| 					}, | ||||
| 					{ | ||||
| 						label: '选项2', | ||||
| 						value: '' | ||||
| 					} | ||||
| 				], | ||||
| 				title: '' | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'checkbox', | ||||
| 				fieldName: '多选', | ||||
| 				fixedLabel: '多选', | ||||
| 				fieldTips: '请选择', | ||||
| 				icon: 'iconcheck_box', | ||||
| 				mustFill: '1', | ||||
| 				grid: 0.5, | ||||
| 				disable: '0', | ||||
| 				defaultValue: [], | ||||
| 				options: [ | ||||
| 					{ | ||||
| 						label: '选项1', | ||||
| 						value: '' | ||||
| 					}, | ||||
| 					{ | ||||
| 						label: '选项2', | ||||
| 						value: '' | ||||
| 					} | ||||
| 				], | ||||
| 				title: '' | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'select', | ||||
| 				fieldName: '单下拉框', | ||||
| 				fixedLabel: '单下拉框', | ||||
| 				grid: 0.5, | ||||
| 				fieldTips: '请选择', | ||||
| 				icon: 'iconSelect', | ||||
| 				mustFill: '1', | ||||
| 				defaultValue: '', | ||||
| 				disable: '0', | ||||
| 				options: [ | ||||
| 					{ | ||||
| 						label: '选项1', | ||||
| 						value: '' | ||||
| 					}, | ||||
| 					{ | ||||
| 						label: '选项2', | ||||
| 						value: '' | ||||
| 					} | ||||
| 				], | ||||
| 				title: '' | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'onOff', | ||||
| 				fieldName: '开关', | ||||
| 				fixedLabel: '开关', | ||||
| 				grid: 0.5, | ||||
| 				fieldTips: '请选择开关', | ||||
| 				icon: 'iconSelect', | ||||
| 				mustFill: '1', | ||||
| 				defaultValue: '0', | ||||
| 				disable: '0', | ||||
| 				title: '' | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'date', | ||||
| 				fieldName: '日期', | ||||
| 				fixedLabel: '日期', | ||||
| 				grid: 0.5, | ||||
| 				datetimePattern: 'yyyy-MM-dd', | ||||
| 				fieldTips: '请选择日期', | ||||
| 				icon: 'iconSelect', | ||||
| 				mustFill: '1', | ||||
| 				disable: '0', | ||||
| 				title: '' | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'time', | ||||
| 				fieldName: '时间', | ||||
| 				fixedLabel: '时间', | ||||
| 				grid: 0.5, | ||||
| 				datetimePattern: 'HH:mm:ss', | ||||
| 				fieldTips: '请选择时间', | ||||
| 				icon: 'iconSelect', | ||||
| 				mustFill: '1', | ||||
| 				disable: '0', | ||||
| 				title: '' | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'datetime', | ||||
| 				fieldName: '日期时间', | ||||
| 				fixedLabel: '日期时间', | ||||
| 				grid: 0.5, | ||||
| 				datetimePattern: 'yyyy-MM-dd HH:mm:ss', | ||||
| 				fieldTips: '请选择日期时间', | ||||
| 				icon: 'iconSelect', | ||||
| 				mustFill: '1', | ||||
| 				disable: '0', | ||||
| 				title: '' | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	{ | ||||
| 		type: 'input', | ||||
| 		tips: '(可重复添加)', | ||||
| 		label: '填空', | ||||
| 		children: [ | ||||
| 			{ | ||||
| 				type: 'input', | ||||
| 				fieldName: '单行填空', | ||||
| 				fieldTips: '请输入', | ||||
| 				fixedLabel: '单行填空', | ||||
| 				disable: '0', | ||||
| 				grid: 0.5, | ||||
| 				defaultValue: '', | ||||
| 				icon: 'icontext_box', | ||||
| 				mustFill: '1', | ||||
| 				maxLength: 50 | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'textarea', | ||||
| 				fieldName: '多行填空', | ||||
| 				fixedLabel: '多行填空', | ||||
| 				fieldTips: '请输入', | ||||
| 				lineNumber: 4, | ||||
| 				defaultValue: '', | ||||
| 				icon: 'icontext_area', | ||||
| 				mustFill: '1', | ||||
| 				maxLength: 500, | ||||
| 				disable: '0', | ||||
| 				grid: 1 | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'number', | ||||
| 				fieldName: '数字输入', | ||||
| 				fixedLabel: '数字输入', | ||||
| 				fieldTips: '请输入数字', | ||||
| 				defaultValue: '', | ||||
| 				icon: 'icontext_area', | ||||
| 				mustFill: '1', | ||||
| 				maxValue: 10000, | ||||
| 				decimalPlaces: 0, | ||||
| 				minValue: 0, | ||||
| 				maxLength: 500, | ||||
| 				disable: '0', | ||||
| 				grid: 0.5 | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'rtf', | ||||
| 				fieldName: '富文本', | ||||
| 				fixedLabel: '富文本', | ||||
| 				fieldTips: '请输入', | ||||
| 				defaultValue: '', | ||||
| 				icon: 'icontext_area', | ||||
| 				mustFill: '1', | ||||
| 				maxLength: 5000, | ||||
| 				disable: '0', | ||||
| 				grid: 1 | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	{ | ||||
| 		type: 'annex', | ||||
| 		tips: '(可重复添加)', | ||||
| 		label: '附件', | ||||
| 		children: [ | ||||
| 			{ | ||||
| 				type: 'upload', | ||||
| 				fieldTips: '请上传', | ||||
| 				fieldName: '上传附件', | ||||
| 				fixedLabel: '上传附件', | ||||
| 				disable: '0', | ||||
| 				fileChoseSize: 10, | ||||
| 				fileMaxCount: 9, | ||||
| 				defaultValue: '', | ||||
| 				icon: 'iconpic', | ||||
| 				mustFill: '1', | ||||
| 				grid: 1 | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	{ | ||||
| 		type: 'layout', | ||||
| 		tips: '(可重复添加)', | ||||
| 		label: '分组', | ||||
| 		children: [ | ||||
| 			{ | ||||
| 				type: 'group', | ||||
| 				fieldName: '卡片', | ||||
| 				fixedLabel: '卡片', | ||||
| 				icon: 'iconpic', | ||||
| 				groupName: '分组标题', | ||||
| 				column: [] | ||||
| 			} | ||||
| 		] | ||||
| 	} | ||||
| ]; | ||||
							
								
								
									
										42
									
								
								packages/work/AppHelpedResident/AppHelpedResident.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								packages/work/AppHelpedResident/AppHelpedResident.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| <template> | ||||
|   <section class="AppHelpedResident"> | ||||
|     <component :is="currentComponent" :instance="instance" :dict="dict" :permissions="permissions"/> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|  | ||||
| import HrAdd from "./hrAdd"; | ||||
| import HrDetail from "./hrDetail"; | ||||
| import HrList from "./hrList"; | ||||
|  | ||||
| export default { | ||||
|   name: "AppHelpedResident", | ||||
|   components: {HrList, HrDetail, HrAdd}, | ||||
|   label: "监测对象(防返贫帮扶对象)", | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function | ||||
|   }, | ||||
|   computed: { | ||||
|     currentComponent() { | ||||
|       return this.$route.hash == "#add" ? HrAdd : | ||||
|           this.$route.query.id ? HrDetail : HrList | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.dict.load("fpYear", "sex", "fpNation", "fpPrtpStatus", "fpHealth", "fpStudentsInSchool", 'fpYesOrNo', "fpRelationship", | ||||
|       "yesOrNo", "fpLaborSkills", "fpEducation", "fpPoliticalOutlook","fpType", "fpRiskType", "fpAssistanceMeasures", | ||||
|       "fpPublicWelfarePostAssistance","fpHealthAssistance","fpFnancialAssistance","fpEmploymentAssistance","fpEducationalAssistance", | ||||
|       "fpIndustrialAssistance","fpSocialAssistance", "fpRiskEliminationMethod", "fpNaturalDisaster", "fpHouseType", "fpHouseRoadType", | ||||
|       "fpFuelType", "fpDisabilityType", "fpEmploymentChannels") | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .AppHelpedResident { | ||||
|   height: 100%; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										148
									
								
								packages/work/AppHelpedResident/detail/hrLog.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								packages/work/AppHelpedResident/detail/hrLog.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | ||||
| <template> | ||||
|   <section class="hrLog"> | ||||
|     <ai-card title="走访日志"> | ||||
|       <template #right> | ||||
|         <!-- <ai-select placeholder="档案状态" v-model="search.status" :selectList="dict.getDict('fpPrtpStatus')" @change="page.current=1,getTableData()"/> --> | ||||
|         <el-button type="text" icon="el-icon-plus" @click="dialog=true" v-if="$permissions('app_apppreventionreturntopovertylog_edit')">添加</el-button> | ||||
|       </template> | ||||
|       <template #content> | ||||
|         <div class="logItem" v-for="row in tableData" :key="row.id"> | ||||
|           <el-row type="flex" align="middle" justify="space-between"> | ||||
|             <b v-text="row.createUserName"/> | ||||
|             <span v-text="row.createTime"/> | ||||
|           </el-row> | ||||
|           <p>操作类型:{{row.operationDesc}}</p> | ||||
|           <div class="content" v-text="row.detail"/> | ||||
|           <ai-uploader v-model="row.files" disabled/> | ||||
|           <div class="btns" v-if="row.bizType == 0"> | ||||
|             <el-button type="text" @click="handleEdit(row)" v-if="$permissions('app_apppreventionreturntopovertylog_edit')">编辑</el-button> | ||||
|             <el-button type="text" @click="handleDelete(row.id)" v-if="$permissions('app_apppreventionreturntopovertylog_del')">删除</el-button> | ||||
|           </div> | ||||
|         </div> | ||||
|         <ai-empty v-if="tableData.length==0"/> | ||||
|       </template> | ||||
|     </ai-card> | ||||
|     <ai-dialog :visible.sync="dialog" :title="addTitle" @closed="form={}" @onConfirm="submit" width="600px"> | ||||
|       <el-form :model="form" :rules="rules" ref="DialogForm" size="small" label-width="80px"> | ||||
|         <el-form-item label="走访日志" prop="detail"> | ||||
|           <el-input type="textarea" v-model="form.detail" placeholder="请输入" maxlength="500" show-word-limit rows="5"/> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="图片" prop="files"> | ||||
|           <ai-uploader v-model="form.files" :instance="instance" acceptType=".jpg,.jpeg,.png"> | ||||
|             <template #tips> | ||||
|               最多9张,仅支持10M以内的jpg、jpeg、png格式照片 | ||||
|             </template> | ||||
|           </ai-uploader> | ||||
|         </el-form-item> | ||||
|       </el-form> | ||||
|     </ai-dialog> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapState} from "vuex"; | ||||
|  | ||||
| export default { | ||||
|   name: "hrLog", | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|     addTitle() { | ||||
|       return this.form.id ? "编辑走访日志" : "新建走访日志" | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       dialog: false, | ||||
|       form: {}, | ||||
|       rules: { | ||||
|         detail: {required: true, message: "请输入走访日志"} | ||||
|       }, | ||||
|       tableData: [] | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     getTableData() { | ||||
|       let {id: pid} = this.$route.query | ||||
|       this.instance.post("/app/apppreventionreturntopovertylog/list", null, { | ||||
|         params: {size: 9999, pid, type: 0} | ||||
|       }).then(res => { | ||||
|         if (res?.data) { | ||||
|           this.tableData = res.data?.records || [] | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     submit() { | ||||
|       this.$refs.DialogForm.validate(v => { | ||||
|         if (v) { | ||||
|           let {id: pid} = this.$route.query | ||||
|           this.instance.post(`/app/apppreventionreturntopovertylog/addOrUpdate`, { | ||||
|             ...this.form, | ||||
|             pid, | ||||
|             type: 0 | ||||
|           }).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.form = {} | ||||
|               this.$message.success('提交成功!'); | ||||
|               this.dialog = false | ||||
|               this.getTableData() | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     handleEdit(row) { | ||||
|       this.dialog = true | ||||
|       this.form = JSON.parse(JSON.stringify(row)) | ||||
|     }, | ||||
|     handleDelete(ids) { | ||||
|       this.$confirm("是否要删除走访日志").then(() => { | ||||
|         this.instance.post("/app/apppreventionreturntopovertylog/delete", null, { | ||||
|           params: {ids: ids?.toString()} | ||||
|         }).then(res => { | ||||
|           if (res?.code == 0) { | ||||
|             this.$message.success("删除成功!") | ||||
|             this.getTableData() | ||||
|           } | ||||
|         }) | ||||
|       }).catch(() => 0) | ||||
|     }, | ||||
|   }, | ||||
|   created() { | ||||
|     this.getTableData() | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .hrLog { | ||||
|   .logItem { | ||||
|     position: relative; | ||||
|     padding: 8px 16px; | ||||
|     border-radius: 4px; | ||||
|  | ||||
|     &:hover { | ||||
|       background: #eee; | ||||
|  | ||||
|       .btns { | ||||
|         display: block; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .content { | ||||
|       margin: 8px 0; | ||||
|     } | ||||
|  | ||||
|     .btns { | ||||
|       display: none; | ||||
|       position: absolute; | ||||
|       right: 8px; | ||||
|       bottom: 8px; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										150
									
								
								packages/work/AppHelpedResident/detail/hrMeasure.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								packages/work/AppHelpedResident/detail/hrMeasure.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,150 @@ | ||||
| <template> | ||||
|   <section class="hrMeasure"> | ||||
|     <ai-card title="帮扶措施"> | ||||
|       <template #right> | ||||
|         <el-button type="text" icon="el-icon-plus" @click="dialog=true">添加</el-button> | ||||
|       </template> | ||||
|       <template #content> | ||||
|         <div class="logItem" v-for="row in tableData" :key="row.id"> | ||||
|           <el-row type="flex" align="middle" justify="space-between"> | ||||
|             <b v-text="row.createUserName"/> | ||||
|             <span v-text="row.createTime"/> | ||||
|           </el-row> | ||||
|           <p>帮扶类型:{{dict.getLabel('fpAssistanceMeasures', row.operationDesc)}}</p> | ||||
|           <div class="content" v-text="row.detail"/> | ||||
|           <ai-uploader v-model="row.files" disabled/> | ||||
|           <div class="btns"> | ||||
|             <el-button type="text" @click="handleEdit(row)">编辑</el-button> | ||||
|             <el-button type="text" @click="handleDelete(row.id)">删除</el-button> | ||||
|           </div> | ||||
|         </div> | ||||
|         <ai-empty v-if="tableData.length==0"/> | ||||
|       </template> | ||||
|     </ai-card> | ||||
|     <ai-dialog :visible.sync="dialog" :title="addTitle" @closed="form={}" @onConfirm="submit" width="600px"> | ||||
|       <el-form :model="form" :rules="rules" ref="DialogForm" size="small" label-width="80px"> | ||||
|         <el-form-item label="帮扶类型" prop="operationDesc"> | ||||
|           <ai-select v-model="form.operationDesc" :selectList="dict.getDict('fpAssistanceMeasures')"/> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="帮扶措施"> | ||||
|           <el-input type="textarea" v-model="form.detail" placeholder="请输入" maxlength="500" show-word-limit rows="5"/> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="图片"> | ||||
|           <ai-uploader v-model="form.files" :instance="instance" acceptType=".jpg,.jpeg,.png"> | ||||
|             <template #tips> | ||||
|               最多9张,仅支持10M以内的jpg、jpeg、png格式照片 | ||||
|             </template> | ||||
|           </ai-uploader> | ||||
|         </el-form-item> | ||||
|       </el-form> | ||||
|     </ai-dialog> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapState} from "vuex"; | ||||
|  | ||||
| export default { | ||||
|   name: "hrMeasure", | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|     addTitle() { | ||||
|       return this.form.id ? "编辑措施" : "新建措施" | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       dialog: false, | ||||
|       form: {}, | ||||
|       rules: { | ||||
|         operationDesc: {required: true, message: "请输入帮扶措施"} | ||||
|       }, | ||||
|       tableData: [] | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     getTableData() { | ||||
|       let {id: pid} = this.$route.query | ||||
|       this.instance.post("/app/apppreventionreturntopovertylog/list", null, { | ||||
|         params: {size: 9999, pid, type: 1} | ||||
|       }).then(res => { | ||||
|         if (res?.data) { | ||||
|           this.tableData = res.data?.records || [] | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     submit() { | ||||
|       this.$refs.DialogForm.validate(v => { | ||||
|         if (v) { | ||||
|           let {id: pid} = this.$route.query | ||||
|           this.instance.post(`/app/apppreventionreturntopovertylog/addOrUpdate`, { | ||||
|             ...this.form, | ||||
|             pid, | ||||
|             type: 1 | ||||
|           }).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.form = {} | ||||
|               this.$message.success('提交成功!'); | ||||
|               this.dialog = false | ||||
|               this.getTableData() | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     handleEdit(row) { | ||||
|       this.dialog = true | ||||
|       this.form = JSON.parse(JSON.stringify(row)) | ||||
|     }, | ||||
|     handleDelete(ids) { | ||||
|       this.$confirm("是否要删除帮扶措施").then(() => { | ||||
|         this.instance.post("/app/apppreventionreturntopovertylog/delete", null, { | ||||
|           params: {ids: ids?.toString()} | ||||
|         }).then(res => { | ||||
|           if (res?.code == 0) { | ||||
|             this.$message.success("删除成功!") | ||||
|             this.getTableData() | ||||
|           } | ||||
|         }) | ||||
|       }).catch(() => 0) | ||||
|     }, | ||||
|   }, | ||||
|   created() { | ||||
|     this.getTableData() | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .hrMeasure { | ||||
|   .logItem { | ||||
|     position: relative; | ||||
|     padding: 8px 16px; | ||||
|     border-radius: 4px; | ||||
|  | ||||
|     &:hover { | ||||
|       background: #eee; | ||||
|  | ||||
|       .btns { | ||||
|         display: block; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .content { | ||||
|       margin: 8px 0; | ||||
|     } | ||||
|  | ||||
|     .btns { | ||||
|       display: none; | ||||
|       position: absolute; | ||||
|       right: 8px; | ||||
|       bottom: 8px; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										546
									
								
								packages/work/AppHelpedResident/hrAdd.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										546
									
								
								packages/work/AppHelpedResident/hrAdd.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,546 @@ | ||||
| <template> | ||||
|   <section class="hrAdd"> | ||||
|     <ai-detail> | ||||
|       <ai-title slot="title" :title="addTitle" isShowBottomBorder isShowBack @onBackClick="back"/> | ||||
|       <template #content> | ||||
|         <el-form :model="form" ref="ruleForm" :rules="rules" label-width="160px" label-position="right" size="small"> | ||||
|           <ai-card title="基本信息"> | ||||
|             <template #content> | ||||
|               <div flex class="half wrap"> | ||||
|                 <div flex class="column"> | ||||
|                   <el-form-item label="户主姓名" prop="name"> | ||||
|                     <el-input size="small" class="user-selecter" v-model="form.name" placeholder="请输入姓名" clearable :disabled="isEdit || isSelectUser"> | ||||
|                       <template slot="append"> | ||||
|                         <ai-person-select :instance="instance" @selectPerson="checkName" | ||||
|                                           :url="'/app/appresident/list?auditStatus=1&householdName=1&areaId='+user.info.areaId"/> | ||||
|                       </template> | ||||
|                     </el-input> | ||||
|                   </el-form-item> | ||||
|                   <el-form-item label="联系方式" prop="phone"> | ||||
|                     <el-input v-model="form.phone" placeholder="请输入联系方式" :maxlength="11" show-word-limit/> | ||||
|                   </el-form-item> | ||||
|                   <el-form-item label="证件号码" prop="idNumber"> | ||||
|                     <el-input v-model="form.idNumber" placeholder="请输入证件号码" :maxlength="20" :disabled="isEdit || isSelectUser" | ||||
|                               @change="handleIdNumberAutocomplete"/> | ||||
|                   </el-form-item> | ||||
|                 </div> | ||||
|                 <el-form-item label="个人照片" prop="photo"> | ||||
|                   <ai-avatar :instance="instance" v-model="form.photo"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="性别" prop="sex"> | ||||
|                   <ai-select v-model="form.sex" :selectList="dict.getDict('sex')" disabled/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="出生日期" prop="birthDate"> | ||||
|                   <el-date-picker disabled value-format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd" v-model="form.birthDate" type="date" placeholder="选择日期"/> | ||||
|                 </el-form-item> | ||||
|                 <!-- <el-form-item label="年龄" prop="age"> | ||||
|                   <el-input disabled v-model="form.age" placeholder="请输入年龄" type="number"/> | ||||
|                 </el-form-item> --> | ||||
|                 <el-form-item label="民族"> | ||||
|                   <ai-select v-model="form.nation" :selectList="dict.getDict('fpNation')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="文化程度"> | ||||
|                   <ai-select v-model="form.education" :selectList="dict.getDict('fpEducation')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="政治面貌"> | ||||
|                   <ai-select v-model="form.politicsStatus" :selectList="dict.getDict('fpPoliticalOutlook')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="在校生状况"> | ||||
|                   <ai-select v-model="form.schoolStatus" :selectList="dict.getDict('fpStudentsInSchool')"/> | ||||
|                 </el-form-item> | ||||
|               </div> | ||||
|               <el-form-item label="健康状况"> | ||||
|                 <el-checkbox-group v-model="form.healthyStatusList"> | ||||
|                   <el-checkbox :label="item.dictValue" v-for="(item, index) in dict.getDict('fpHealth')" :key="index">{{ item.dictName }}</el-checkbox> | ||||
|                 </el-checkbox-group> | ||||
|               </el-form-item> | ||||
|               <div flex class="half wrap"> | ||||
|                 <el-form-item label="残疾类别"> | ||||
|                   <ai-select v-model="form.disabilityType" :selectList="dict.getDict('fpDisabilityType')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="残疾办证年度"> | ||||
|                   <ai-select v-model="form.disabilityCertificateYear" :selectList="dict.getDict('fpYear')"/> | ||||
|                 </el-form-item> | ||||
|               </div> | ||||
|               <el-form-item label="基础保险"> | ||||
|                 <el-checkbox-group v-model="form.basicsList"> | ||||
|                   <el-checkbox :label="item.value" v-for="(item, index) in basicsCheckList" :key="index">{{ item.label }}</el-checkbox> | ||||
|                 </el-checkbox-group> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="保障措施"> | ||||
|                 <el-checkbox-group v-model="form.guaranteeList"> | ||||
|                   <el-checkbox :label="item.value" v-for="(item, index) in guaranteeCheckList" :key="index">{{ item.label }}</el-checkbox> | ||||
|                 </el-checkbox-group> | ||||
|               </el-form-item> | ||||
|               <div flex class="half wrap"> | ||||
|                 <el-form-item label="劳动技能"> | ||||
|                   <ai-select v-model="form.labourStatus" :selectList="dict.getDict('fpLaborSkills')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否会讲普通话"> | ||||
|                   <ai-select v-model="form.mandarin" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="务工时间(月)"> | ||||
|                   <el-input type="number" v-model="form.workeMonths" placeholder="请输入" clearable @input="numberInput('workeMonths')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="就业渠道"> | ||||
|                   <ai-select v-model="form.employmentChannels" :selectList="dict.getDict('fpEmploymentChannels')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="务工企业名称"> | ||||
|                   <el-input v-model="form.migrantEnterprises" placeholder="请输入" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="公益性岗位"> | ||||
|                   <el-input v-model="form.publicWelfarePosts" placeholder="请输入" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否国外务工"> | ||||
|                   <ai-select v-model="form.foreignWorkers" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="公益性岗位(月数)"> | ||||
|                   <el-input type="number" v-model="form.publicWelfarePostsMonths" placeholder="请输入" clearable @input="numberInput('publicWelfarePostsMonths')"/> | ||||
|                 </el-form-item> | ||||
|               </div> | ||||
|               <el-form-item label="务工所在地"> | ||||
|                 <el-input v-model="form.foreignWorkersAddress" placeholder="请输入" clearable maxlength="30" show-word-limit/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="现住址" prop="currentAreaId"> | ||||
|                 <ai-area-get :instance="instance" v-model="form.currentAreaId" :root="rootArea" valueLevel="5"/> | ||||
|                 <el-form-item prop="currentAddress"> | ||||
|                   <el-input v-model="form.currentAddress" placeholder="详细地址" maxlength="30" show-word-limit clearable/> | ||||
|                 </el-form-item> | ||||
|               </el-form-item> | ||||
|             </template> | ||||
|           </ai-card> | ||||
|           <ai-card title="生产生活条件"> | ||||
|             <template slot="content"> | ||||
|               <div flex class="half wrap"> | ||||
|                 <el-form-item label="住房面积(m²)"> | ||||
|                   <el-input v-model="form.houseArea" placeholder="请输入" :maxlength="8"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="户类型"> | ||||
|                   <ai-select v-model="form.houseType" :selectList="dict.getDict('fpHouseType')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="与村主干路距离(公里)"> | ||||
|                   <el-input v-model="form.trunkRoadDistance" placeholder="请输入" :maxlength="8"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="入户路类型"> | ||||
|                   <ai-select v-model="form.houseRoadType" :selectList="dict.getDict('fpHouseRoadType')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否危房"> | ||||
|                   <ai-select v-model="form.dilapidatedHousehold" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否住房损耗"> | ||||
|                   <ai-select v-model="form.houseDamage" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否解决安全饮水"> | ||||
|                   <ai-select v-model="form.drinkingWaterSafety" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否饮水设施损坏"> | ||||
|                   <ai-select v-model="form.drinkingWaterDamage" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否有卫生厕所"> | ||||
|                   <ai-select v-model="form.toilet" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="主要燃料类型"> | ||||
|                   <ai-select v-model="form.fuelType" :selectList="dict.getDict('fpFuelType')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否通生活用电"> | ||||
|                   <ai-select v-model="form.electric" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否通广播电视"> | ||||
|                   <ai-select v-model="form.television" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="耕地面积(亩)"> | ||||
|                   <el-input v-model="form.cultivatedLandArea" placeholder="请输入" :maxlength="8"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="林地面积(亩)"> | ||||
|                   <el-input v-model="form.woodlandArea" placeholder="请输入" :maxlength="8"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="林果面积(亩)"> | ||||
|                   <el-input v-model="form.orchardArea" placeholder="请输入" :maxlength="8"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="退耕还林面积(亩)"> | ||||
|                   <el-input v-model="form.grainForGreenArea" placeholder="请输入" :maxlength="8"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="牧草地面积(亩)"> | ||||
|                   <el-input v-model="form.grazingGrasslandArea" placeholder="请输入" :maxlength="8"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="水面面积(亩)"> | ||||
|                   <el-input v-model="form.watersArea" placeholder="请输入" :maxlength="8"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否加入农民专业合作社"> | ||||
|                   <ai-select v-model="form.nongheshe" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否有龙头企业带动"> | ||||
|                   <ai-select v-model="form.longtouqiye" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否有创业致富人带头人带动"> | ||||
|                   <ai-select v-model="form.cyzfdtr" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否通生产通电"> | ||||
|                   <ai-select v-model="form.produceElectric" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|               </div> | ||||
|             </template> | ||||
|           </ai-card> | ||||
|           <ai-card title="家庭风险情况"> | ||||
|             <template slot="content"> | ||||
|               <div flex class="half wrap"> | ||||
|                 <el-form-item label="监测对象类型" prop="objectType"> | ||||
|                   <ai-select v-model="form.objectType" :selectList="dict.getDict('fpType')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否军烈属"> | ||||
|                   <ai-select v-model="form.militaryMartyrs" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="风险因素" prop="riskType"> | ||||
|                   <ai-select v-model="form.riskType" :selectList="dict.getDict('fpRiskType')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="脱贫年度"> | ||||
|                   <ai-select v-model="form.povertyYear" :selectList="dict.getDict('fpYear')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="因自然灾害子项"> | ||||
|                   <ai-select v-model="form.naturalDisasterType" :selectList="dict.getDict('fpNaturalDisaster')"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="是否义务阶段失学辍学"> | ||||
|                   <ai-select v-model="form.dropOutOfSchool" :selectList="dict.getDict('fpYesOrNo')"/> | ||||
|                 </el-form-item> | ||||
|               </div> | ||||
|               <el-form-item label="义务阶段未上学原因"> | ||||
|                 <el-input v-model="form.dropOutOfSchoolReason" type="textarea" placeholder="请输入" maxlength="500" show-word-limit clearable/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="备注说明"> | ||||
|                 <el-input v-model="form.detail" placeholder="请输入" type="textarea" maxlength="500" show-word-limit clearable/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="图片(最多9张)"> | ||||
|                 <ai-uploader | ||||
|                     :isShowTip="true" | ||||
|                     :instance="instance" | ||||
|                     v-model="form.files" | ||||
|                     fileType="img" | ||||
|                     acceptType=".png,.jpg,.jpeg" | ||||
|                     :limit="9"> | ||||
|                   <template slot="tips">最多上传9张图片,单张图片最大10MB<br/>支持.png,.jpg,.jpeg格式</template> | ||||
|                 </ai-uploader> | ||||
|               </el-form-item> | ||||
|             </template> | ||||
|           </ai-card> | ||||
|           <ai-card title="家庭收支情况"> | ||||
|             <template slot="content"> | ||||
|               <div flex class="half wrap"> | ||||
|                 <el-form-item label="纳入监测对象的收入参考范围"> | ||||
|                   <el-input v-model="form.income1" placeholder="请输入" type="number" @input="decimalInput('income1')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="纳入监测对象的人均收入参考范围"> | ||||
|                   <el-input v-model="form.income2" placeholder="请输入" type="number" @input="decimalInput('income2')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="工资性收入(元)"> | ||||
|                   <el-input v-model="form.income3" placeholder="请输入" type="number" @input="decimalInput('income3')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="生产经营性收入(元)"> | ||||
|                   <el-input v-model="form.income4" placeholder="请输入" type="number" @input="decimalInput('income4')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="计划生育金(元)"> | ||||
|                   <el-input v-model="form.income5" placeholder="请输入" type="number" @input="decimalInput('income5')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="资产收益扶贫分红收入"> | ||||
|                   <el-input v-model="form.income6" placeholder="请输入" type="number" @input="decimalInput('income6')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="低保金(元)"> | ||||
|                   <el-input v-model="form.income7" placeholder="请输入" type="number" @input="decimalInput('income7')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="特困供养金(元)"> | ||||
|                   <el-input v-model="form.income8" placeholder="请输入" type="number" @input="decimalInput('income8')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="养老保险金(元)"> | ||||
|                   <el-input v-model="form.income9" placeholder="请输入" type="number" @input="decimalInput('income9')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="生态补偿金(元)"> | ||||
|                   <el-input v-model="form.income10" placeholder="请输入" type="number" @input="decimalInput('income10')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="转移性收入(元)"> | ||||
|                   <el-input v-model="form.income11" placeholder="请输入" type="number" @input="decimalInput('income11')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="其它转移性收入(元)"> | ||||
|                   <el-input v-model="form.income12" placeholder="请输入" type="number" @input="decimalInput('income12')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="财产性收入(元)"> | ||||
|                   <el-input v-model="form.income13" placeholder="请输入" type="number" @input="decimalInput('income13')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="其它财产收入(元)"> | ||||
|                   <el-input v-model="form.income14" placeholder="请输入" type="number" @input="decimalInput('income14')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="生产经营性支出(元)"> | ||||
|                   <el-input v-model="form.income15" placeholder="请输入" type="number" @input="decimalInput('income15')" clearable/> | ||||
|                 </el-form-item> | ||||
|               </div> | ||||
|             </template> | ||||
|           </ai-card> | ||||
|  | ||||
|           <ai-card title="风险消除情况" v-if="form.status == 3"> | ||||
|             <template slot="content"> | ||||
|               <div flex class="half wrap"> | ||||
|                 <el-form-item label="工资性收入情况"> | ||||
|                   <el-input v-model="form.fxxcIncome1" placeholder="请输入" type="number" @input="decimalInput('fxxcIncome1')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="生产经营性收入情况"> | ||||
|                   <el-input v-model="form.fxxcIncome2" placeholder="请输入" type="number" @input="decimalInput('fxxcIncome2')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="财产性收入情况"> | ||||
|                   <el-input v-model="form.fxxcIncome3" placeholder="请输入" type="number" @input="decimalInput('fxxcIncome3')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="转移性收入情况"> | ||||
|                   <el-input v-model="form.fxxcIncome4" placeholder="请输入" type="number" @input="decimalInput('fxxcIncome4')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="理赔收入情况"> | ||||
|                   <el-input v-model="form.fxxcIncome5" placeholder="请输入" type="number" @input="decimalInput('fxxcIncome5')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="生产经营性支出情况"> | ||||
|                   <el-input v-model="form.fxxcIncome6" placeholder="请输入" type="number" @input="decimalInput('fxxcIncome6')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="合规自然收支情况"> | ||||
|                   <el-input v-model="form.fxxcIncome7" placeholder="请输入" type="number" @input="decimalInput('fxxcIncome7')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="家庭纯收入情况"> | ||||
|                   <el-input v-model="form.fxxcIncome8" placeholder="请输入" type="number" @input="decimalInput('fxxcIncome8')" clearable/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="家庭人均纯收入情况"> | ||||
|                   <el-input v-model="form.fxxcIncome9" placeholder="请输入" type="number" @input="decimalInput('fxxcIncome9')" clearable/> | ||||
|                 </el-form-item> | ||||
|               </div> | ||||
|             </template> | ||||
|           </ai-card> | ||||
|         </el-form> | ||||
|       </template> | ||||
|       <template #footer> | ||||
|         <el-button @click="back">取消</el-button> | ||||
|         <el-button type="primary" @click="submit">提交</el-button> | ||||
|       </template> | ||||
|     </ai-detail> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|  | ||||
| import {mapState} from "vuex"; | ||||
|  | ||||
| export default { | ||||
|   name: "hrAdd", | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|     isEdit() { | ||||
|       return !!this.$route.query.id | ||||
|     }, | ||||
|     addTitle() { | ||||
|       return this.isEdit ? "编辑监测对象" : "添加监测对象" | ||||
|     }, | ||||
|     rules() { | ||||
|       return { | ||||
|         idNumber: [{required: true, message: "请输入证件号"}], | ||||
|         name: [{required: true, message: "请输入姓名"}], | ||||
|         sex: [{required: true, message: "请选择性别"}], | ||||
|         phone: [{required: true, message: "请输入联系方式"}], | ||||
|         currentAreaId: [ | ||||
|           {required: true, message: "请选择现住址"}, | ||||
|           {pattern: /[^0]0{0,2}$/, message: "请选择到村/社区"}, | ||||
|         ], | ||||
|         isHousehold: [{required: true, message: "请选择是否户主"}], | ||||
|         householdRelation: [{required: true, message: "请选择与户主关系"}], | ||||
|         householdIdNumber: [{required: true, message: "请选择户主证件号"}], | ||||
|         riskType: [{required: true, message: "请选择风险因素"}], | ||||
|         objectType: [{required: true, message: "请选择监测对象类型"}], | ||||
|       } | ||||
|     }, | ||||
|     rootArea() { | ||||
|       return this.user.info?.areaId?.replace(/(\d{6})\d+/g, '$1' + Array(7).join("0")) || "" | ||||
|     }, | ||||
|     guaranteeCheckList() { | ||||
|       return [ | ||||
|         {label: '享受农村最低生活保障', value: '0'}, | ||||
|         {label: '是否特困供养人员', value: '1'}, | ||||
|         {label: '分散供养五保户转集中供养(减少)', value: '2'}, | ||||
|         {label: '是否接受医疗救助', value: '3'}, | ||||
|         {label: '是否接受其它健康扶贫', value: '4'}, | ||||
|       ] | ||||
|     }, | ||||
|     basicsCheckList() { | ||||
|       return [ | ||||
|         {label: '城乡居民基本医疗保险', value: '0'}, | ||||
|         {label: '城镇职工基本医疗保险', value: '1'}, | ||||
|         {label: '大病保险', value: '2'}, | ||||
|         {label: '商业补充医疗保险', value: '3'}, | ||||
|         {label: '城乡居民基本养老保险', value: '4'}, | ||||
|         {label: '城镇职工基本养老保险', value: '5'}, | ||||
|         {label: '享受人身意外保险补贴', value: '6'}, | ||||
|       ] | ||||
|     }, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       form: { | ||||
|         householdRelation: "", | ||||
|         healthyStatus: '', | ||||
|         healthyStatusList: [], | ||||
|         guaranteeList: [], | ||||
|         basicsList: [], | ||||
|         file: [], | ||||
|       }, | ||||
|       isSelectUser: false, //是否选择人员 | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     checkName(e) { | ||||
|       if (!e) { | ||||
|         this.isSelectUser = false | ||||
|         this.form.name = '' | ||||
|         this.form.idNumber = '' | ||||
|         this.form.phone = '' | ||||
|         this.form.currentAreaId = '' | ||||
|         this.form.currentAddress = '' | ||||
|         this.form.birthDate = '' | ||||
|         this.form.sex = '' | ||||
|         this.form.age = '' | ||||
|         return | ||||
|       } | ||||
|       this.form.name = e.name | ||||
|       this.form.idNumber = e.idNumber | ||||
|       this.form.phone = e.phone | ||||
|       this.form.currentAreaId = e.currentAreaId | ||||
|       this.form.currentAddress = e.currentAddress | ||||
|       this.handleIdNumberAutocomplete(e.idNumber) | ||||
|       this.isSelectUser = true | ||||
|     }, | ||||
|     back() { | ||||
|       this.$router.push({}) | ||||
|     }, | ||||
|     getDetail() { | ||||
|       let {id} = this.$route.query | ||||
|       id && this.instance.post("/app/apppreventionreturntopoverty/queryDetailById", null, { | ||||
|         params: {id} | ||||
|       }).then(res => { | ||||
|         if (res?.data) { | ||||
|           res.data.healthyStatusList = [] | ||||
|           res.data.basicsList = [] | ||||
|           res.data.guaranteeList = [] | ||||
|           if (res.data.healthyStatus) { | ||||
|             res.data.healthyStatusList = res.data.healthyStatus.split(',') | ||||
|           } | ||||
|           if (res.data.basicsCheck) { | ||||
|             res.data.basicsList = res.data.basicsCheck.split(',') | ||||
|           } | ||||
|           if (res.data.guaranteeCheck) { | ||||
|             res.data.guaranteeList = res.data.guaranteeCheck.split(',') | ||||
|           } | ||||
|           console.log(res.data) | ||||
|           this.form = {...res.data} | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     handleIdNumberAutocomplete(v) { | ||||
|       var idNumber = v | ||||
|       if (v.length == 20) { | ||||
|         idNumber = v.substring(0, 18) | ||||
|       } | ||||
|       let {birthday: birthDate, sex} = this.idCardNoUtil.getIdCardInfo(idNumber) | ||||
|       this.form = {...this.form, birthDate, sex, age: this.$calcAge(idNumber)} | ||||
|     }, | ||||
|     submit() { | ||||
|       this.$refs.ruleForm.validate(v => { | ||||
|         if (v) { | ||||
|           this.form.isHousehold = 1 | ||||
|           this.form.householdIdNumber = this.form.idNumber | ||||
|           if (this.form.healthyStatusList.length) { | ||||
|             this.form.healthyStatus = this.form.healthyStatusList.join(',') | ||||
|           } | ||||
|           if (this.user.info.girdCheckType == 1) { | ||||
|             this.form.girdId = this.user.info.girdId | ||||
|           } | ||||
|           if (this.form.basicsList.length) { | ||||
|             this.form.basicsCheck = this.form.basicsList.join(',') | ||||
|           } | ||||
|           if (this.form.guaranteeList.length) { | ||||
|             this.form.guaranteeCheck = this.form.basicsList.join(',') | ||||
|           } | ||||
|           if ([1, 2, 3].includes(2)) { | ||||
|             this.form.jcbxCxyiliao = '01' | ||||
|           } else { | ||||
|             this.form.jcbxCxyiliao = '02' | ||||
|           } | ||||
|           this.checkInit('jcbxCxyiliao', this.form.basicsList, '0') | ||||
|           this.checkInit('jcbxCzyiliao', this.form.basicsList, '1') | ||||
|           this.checkInit('jcbxDabing', this.form.basicsList, '2') | ||||
|           this.checkInit('jcbxShangye', this.form.basicsList, '3') | ||||
|           this.checkInit('jcbxCxyanglao', this.form.basicsList, '4') | ||||
|           this.checkInit('jcbxCzyanglao', this.form.basicsList, '5') | ||||
|           this.checkInit('jcbxRenshenyiwai', this.form.basicsList, '6') | ||||
|  | ||||
|           this.checkInit('bzcsNongcundibao', this.form.guaranteeList, '0') | ||||
|           this.checkInit('bzcsTekungongyang', this.form.guaranteeList, '1') | ||||
|           this.checkInit('bzcsWubaohu', this.form.guaranteeList, '2') | ||||
|           this.checkInit('bzcsYiliaojiuzhu', this.form.guaranteeList, '3') | ||||
|           this.checkInit('bzcsQita', this.form.guaranteeList, '4') | ||||
|           let loading = this.$loading({text: "提交中..."}) | ||||
|           this.instance.post(`/app/apppreventionreturntopoverty/addOrUpdate`, this.form).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.$message.success('提交成功!'); | ||||
|               this.back() | ||||
|             } | ||||
|           }).finally(() => { | ||||
|             loading.close() | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     checkInit(formName, list, value) { | ||||
|       if (list.includes(value)) { | ||||
|         this.form[formName] = '01' | ||||
|       } else { | ||||
|         this.form[formName] = '02' | ||||
|       } | ||||
|     }, | ||||
|     decimalInput(name) { | ||||
|       if (!/^(([1-9]{1}\d*)|(0{1}))(\.\d{1,2})?$/g.test(this.form[name])) { | ||||
|         this.form[name] = '' | ||||
|         return this.$message.error('最多只保留两位小数点') | ||||
|       } | ||||
|     }, | ||||
|     numberInput(name) { | ||||
|       if (!/^[0-9]*[1-9][0-9]*$/g.test(this.form[name])) { | ||||
|         this.form[name] = '' | ||||
|         return this.$message.error('请输入正整数') | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|   created() { | ||||
|     this.getDetail() | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .hrAdd { | ||||
|   height: 100%; | ||||
|  | ||||
|   .half { | ||||
|     align-items: flex-start; | ||||
|  | ||||
|     & > .el-form-item, & > div { | ||||
|       width: 50%; | ||||
|  | ||||
|       .el-form-item { | ||||
|         width: 100%; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .el-date-editor { | ||||
|     width: 100%; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .AiPersonSelect .el-button { | ||||
|     color: #fff; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										953
									
								
								packages/work/AppHelpedResident/hrDetail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										953
									
								
								packages/work/AppHelpedResident/hrDetail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,953 @@ | ||||
| <template> | ||||
|   <section class="hrDetail"> | ||||
|     <ai-detail> | ||||
|       <ai-title slot="title" title="监测对象详情" isShowBottomBorder isShowBack @onBackClick="back"> | ||||
|         <template #rightBtn> | ||||
|           <el-button type="primary" icon="iconfont iconEdit" @click="gotoEdit" | ||||
|                      v-if="$permissions('app_apppreventionreturntopoverty_edit')">编辑 | ||||
|           </el-button> | ||||
|           <template v-if="isGridAdmin"> | ||||
|             <template v-if="detail.status == 0 || detail.status == 4"> | ||||
|               <el-button type="primary" @click="applyMonitor('纳入监测', 1)" v-if="girdAdminApplyStatus != 1">纳入监测 | ||||
|               </el-button> | ||||
|               <el-button type="primary" @click="examine('纳入监测审批', 2)" v-if="girdAdminApplyStatus == 1">纳入监测审批 | ||||
|               </el-button> | ||||
|             </template> | ||||
|             <el-button type="primary" @click="applyMonitor('纳入监测', 1)" v-if="detail.status == 3">纳入监测</el-button> | ||||
|             <el-button type="primary" @click="applyMonitor('解除风险', 4)" v-if="detail.status == 1">解除风险</el-button> | ||||
|             <el-button type="primary" @click="examine('解除风险审批', 5)" v-if="detail.status == 2">解除风险审批</el-button> | ||||
|           </template> | ||||
|           <template v-if="user.info.girdCheckType == 1"> | ||||
|             <el-button type="primary" @click="applyMonitor('申请纳入监测', 0)" | ||||
|                        v-if="detail.status == 4 || detail.status == 3">申请纳入监测 | ||||
|             </el-button> | ||||
|             <el-button type="primary" @click="applyMonitor('申请解除风险', 3)" v-if="detail.status == 1">申请解除风险</el-button> | ||||
|           </template> | ||||
|           <template v-if="detail.status == 3 || detail.status == 4"> | ||||
|             <el-button v-if="$permissions('app_apppreventionreturntopoverty_del') && user.info.girdCheckType != 0" | ||||
|                        icon="iconfont iconDelete" @click="handleDelete(detail.id)">删除 | ||||
|             </el-button> | ||||
|           </template> | ||||
|         </template> | ||||
|       </ai-title> | ||||
|       <template #content> | ||||
|         <el-form :model="detail" label-width="160px" label-position="right" size="small"> | ||||
|           <el-tabs tabPosition="left" v-model="currentTab"> | ||||
|             <el-tab-pane label="基本信息" lazy> | ||||
|               <ai-card :title="detail.name || '无名氏'"> | ||||
|                 <template #content> | ||||
|                   <div flex class="flex-start"> | ||||
|                     <div flex class="half wrap fill"> | ||||
|                       <el-form-item label="联系电话">{{ detail.phone }}</el-form-item> | ||||
|                       <el-form-item label="证件号">{{ detail.idNumber }}</el-form-item> | ||||
|                       <el-form-item label="性别" prop="sex">{{ dict.getLabel("sex", detail.sex) }}</el-form-item> | ||||
|                       <el-form-item label="出生日期">{{ detail.birthDate }}</el-form-item> | ||||
|                       <!-- <el-form-item label="年龄" prop="age">{{ detail.age}}</el-form-item> --> | ||||
|                       <el-form-item label="民族">{{ dict.getLabel("fpNation", detail.nation) }}</el-form-item> | ||||
|                       <el-form-item label="文化程度">{{ dict.getLabel("fpEducation", detail.education) }}</el-form-item> | ||||
|                       <el-form-item label="政治面貌">{{ dict.getLabel("fpPoliticalOutlook", detail.politicsStatus) }} | ||||
|                       </el-form-item> | ||||
|                       <el-form-item label="在校生状况">{{ dict.getLabel("fpStudentsInSchool", detail.schoolStatus) }} | ||||
|                       </el-form-item> | ||||
|                     </div> | ||||
|                     <ai-avatar :instance="instance" v-model="detail.photo" :editable="false"/> | ||||
|                   </div> | ||||
|                   <el-form-item label="健康状况"> | ||||
|                     <span v-for="(item, index) in detail.healthyStatusList" :key="index"><span v-if="index > 0">,</span>{{ | ||||
|                         dict.getLabel("fpHealth", item) | ||||
|                       }}</span> | ||||
|                   </el-form-item> | ||||
|                   <div flex class="half wrap"> | ||||
|                     <el-form-item label="残疾类别">{{ dict.getLabel("fpDisabilityType", detail.disabilityType) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="残疾办证年度">{{ dict.getLabel("fpYear", detail.disabilityCertificateYear) }} | ||||
|                     </el-form-item> | ||||
|                   </div> | ||||
|                   <div flex class="half wrap"> | ||||
|                     <el-form-item label="城乡居民基本医疗保险">{{ dict.getLabel("fpYesOrNo", detail.jcbxCxyiliao) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="城镇职工基本医疗保险">{{ dict.getLabel("fpYesOrNo", detail.jcbxCzyiliao) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="大病保险">{{ dict.getLabel("fpYesOrNo", detail.jcbxDabing) }}</el-form-item> | ||||
|                     <el-form-item label="商业补充医疗保险">{{ dict.getLabel("fpYesOrNo", detail.jcbxShangye) }}</el-form-item> | ||||
|                     <el-form-item label="城乡居民基本养老保险">{{ dict.getLabel("fpYesOrNo", detail.jcbxCxyanglao) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="城镇职工基本养老保险">{{ dict.getLabel("fpYesOrNo", detail.jcbxCzyanglao) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="享受人身意外保险补贴">{{ dict.getLabel("fpYesOrNo", detail.jcbxRenshenyiwai) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="享受农村最低生活保障">{{ dict.getLabel("fpYesOrNo", detail.bzcsNongcundibao) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="是否特困供养人员">{{ dict.getLabel("fpYesOrNo", detail.bzcsTekungongyang) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="分散供养五保户转集中供养(减少)">{{ dict.getLabel("fpYesOrNo", detail.bzcsWubaohu) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="是否接受医疗救助">{{ dict.getLabel("fpYesOrNo", detail.bzcsYiliaojiuzhu) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="是否接受其它健康扶贫">{{ dict.getLabel("fpYesOrNo", detail.bzcsQita) }}</el-form-item> | ||||
|                     <el-form-item label="劳动技能">{{ dict.getLabel("fpLaborSkills", detail.labourStatus) }}</el-form-item> | ||||
|                     <el-form-item label="是否会讲普通话">{{ dict.getLabel("fpYesOrNo", detail.mandarin) }}</el-form-item> | ||||
|                     <el-form-item label="务工时间(月)">{{ detail.workeMonths }}</el-form-item> | ||||
|                     <el-form-item label="就业渠道">{{ dict.getLabel("fpEmploymentChannels", detail.employmentChannels) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="务工企业名称">{{ detail.migrantEnterprises }}</el-form-item> | ||||
|                     <el-form-item label="公益性岗位">{{ detail.publicWelfarePosts }}</el-form-item> | ||||
|                     <el-form-item label="是否国外务工">{{ dict.getLabel("fpYesOrNo", detail.foreignWorkers) }}</el-form-item> | ||||
|                     <el-form-item label="公益性岗位(月数)">{{ detail.publicWelfarePostsMonths }}</el-form-item> | ||||
|                   </div> | ||||
|                   <el-form-item label="务工所在地">{{ detail.foreignWorkersAddress }} | ||||
|                   </el-form-item> | ||||
|                   <el-form-item label="现住址">{{ currentFullAddress }}</el-form-item> | ||||
|                 </template> | ||||
|               </ai-card> | ||||
|               <ai-card title="生产生活条件"> | ||||
|                 <template slot="content"> | ||||
|                   <div flex class="half wrap"> | ||||
|                     <el-form-item label="住房面积(m²)">{{ detail.houseArea }}</el-form-item> | ||||
|                     <el-form-item label="户类型">{{ dict.getLabel("fpHouseType", detail.houseType) }}</el-form-item> | ||||
|                     <el-form-item label="与村主干路距离(公里)">{{ detail.trunkRoadDistance }}</el-form-item> | ||||
|                     <el-form-item label="入户路类型">{{ dict.getLabel("fpHouseRoadType", detail.houseRoadType) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="是否危房">{{ dict.getLabel("fpYesOrNo", detail.dilapidatedHousehold) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="是否住房损耗">{{ dict.getLabel("fpYesOrNo", detail.houseDamage) }}</el-form-item> | ||||
|                     <el-form-item label="是否解决安全饮水">{{ dict.getLabel("fpYesOrNo", detail.drinkingWaterSafety) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="是否饮水设施损坏">{{ dict.getLabel("fpYesOrNo", detail.drinkingWaterDamage) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="是否有卫生厕所">{{ dict.getLabel("fpYesOrNo", detail.toilet) }}</el-form-item> | ||||
|                     <el-form-item label="主要燃料类型">{{ dict.getLabel("fpFuelType", detail.fuelType) }}</el-form-item> | ||||
|                     <el-form-item label="是否通生活用电">{{ dict.getLabel("fpYesOrNo", detail.electric) }}</el-form-item> | ||||
|                     <el-form-item label="是否通广播电视">{{ dict.getLabel("fpYesOrNo", detail.television) }}</el-form-item> | ||||
|                     <el-form-item label="耕地面积(亩)">{{ detail.cultivatedLandArea }}</el-form-item> | ||||
|                     <el-form-item label="林地面积(亩)">{{ detail.woodlandArea }}</el-form-item> | ||||
|                     <el-form-item label="林果面积(亩)">{{ detail.orchardArea }}</el-form-item> | ||||
|                     <el-form-item label="退耕还林面积(亩)">{{ detail.grainForGreenArea }}</el-form-item> | ||||
|                     <el-form-item label="牧草地面积(亩)">{{ detail.grazingGrasslandArea }}</el-form-item> | ||||
|                     <el-form-item label="水面面积(亩)">{{ detail.watersArea }}</el-form-item> | ||||
|                     <el-form-item label="是否加入农民专业合作社">{{ dict.getLabel("fpYesOrNo", detail.nongheshe) }}</el-form-item> | ||||
|                     <el-form-item label="是否有龙头企业带动">{{ dict.getLabel("fpYesOrNo", detail.longtouqiye) }}</el-form-item> | ||||
|                     <el-form-item label="是否有创业致富人带头人带动">{{ dict.getLabel("fpYesOrNo", detail.cyzfdtr) }}</el-form-item> | ||||
|                     <el-form-item label="是否通生产通电">{{ dict.getLabel("fpYesOrNo", detail.produceElectric) }} | ||||
|                     </el-form-item> | ||||
|                   </div> | ||||
|                 </template> | ||||
|               </ai-card> | ||||
|               <ai-card title="家庭风险情况"> | ||||
|                 <template slot="content"> | ||||
|                   <div flex class="half wrap"> | ||||
|                     <el-form-item label="监测对象类型" prop="objectType">{{ dict.getLabel("fpType", detail.objectType) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="是否军烈属">{{ dict.getLabel("fpYesOrNo", detail.militaryMartyrs) }}</el-form-item> | ||||
|                     <el-form-item label="风险因素" prop="riskType">{{ dict.getLabel("fpRiskType", detail.riskType) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="脱贫年度">{{ dict.getLabel("fpYear", detail.povertyYear) }}</el-form-item> | ||||
|                     <el-form-item label="因自然灾害子项">{{ dict.getLabel("fpNaturalDisaster", detail.naturalDisasterType) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="是否义务阶段失学辍学">{{ dict.getLabel("fpYesOrNo", detail.dropOutOfSchool) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="识别监测时间">{{ detail.createTime }}</el-form-item> | ||||
|                     <el-form-item label="风险是否已消除">{{ dict.getLabel("fpYesOrNo", detail.riskEliminated) }}</el-form-item> | ||||
|                     <el-form-item label="是否有家庭成员未参加医疗保险"> | ||||
|                       {{ dict.getLabel("fpYesOrNo", detail.notCoveredMedicalInsurance) }} | ||||
|                     </el-form-item> | ||||
|                     <el-form-item label="信息采集人">{{ detail.updateUserName }}</el-form-item> | ||||
|                     <el-form-item label="信息采集人联系电话">{{ detail.updateUserPhone }}</el-form-item> | ||||
|                   </div> | ||||
|                   <el-form-item label="义务阶段未上学原因">{{ detail.dropOutOfSchoolReason }}</el-form-item> | ||||
|                   <!-- <el-form-item label="备注说明">{{detail.detail}}</el-form-item> | ||||
|                   <el-form-item label="图片"> | ||||
|                     <ai-uploader disabled v-model="detail.files"></ai-uploader> | ||||
|                   </el-form-item> --> | ||||
|                 </template> | ||||
|               </ai-card> | ||||
|               <ai-card title="家庭收支情况"> | ||||
|                 <template slot="content"> | ||||
|                   <div flex class="half wrap"> | ||||
|                     <el-form-item label="纳入监测对象的收入参考范围">{{ detail.income1 }}</el-form-item> | ||||
|                     <el-form-item label="纳入监测对象的人均收入参考范围">{{ detail.income2 }}</el-form-item> | ||||
|                     <el-form-item label="工资性收入(元)">{{ detail.income3 }}</el-form-item> | ||||
|                     <el-form-item label="生产经营性收入(元)">{{ detail.income4 }}</el-form-item> | ||||
|                     <el-form-item label="计划生育金(元)">{{ detail.income5 }}</el-form-item> | ||||
|                     <el-form-item label="资产收益扶贫分红收入">{{ detail.income6 }}</el-form-item> | ||||
|                     <el-form-item label="低保金(元)">{{ detail.income7 }}</el-form-item> | ||||
|                     <el-form-item label="特困供养金(元)">{{ detail.income8 }}</el-form-item> | ||||
|                     <el-form-item label="养老保险金(元)">{{ detail.income9 }}</el-form-item> | ||||
|                     <el-form-item label="生态补偿金(元)">{{ detail.income10 }}</el-form-item> | ||||
|                     <el-form-item label="转移性收入(元)">{{ detail.income11 }}</el-form-item> | ||||
|                     <el-form-item label="其它转移性收入(元)">{{ detail.income12 }}</el-form-item> | ||||
|                     <el-form-item label="财产性收入(元)">{{ detail.income13 }}</el-form-item> | ||||
|                     <el-form-item label="其它财产收入(元)">{{ detail.income14 }}</el-form-item> | ||||
|                     <el-form-item label="生产经营性支出(元)">{{ detail.income15 }}</el-form-item> | ||||
|                     <el-form-item label="年收入(元)">{{ detail.income16 }}</el-form-item> | ||||
|                     <el-form-item label="家庭纯收入(元)">{{ detail.familyIncome }}</el-form-item> | ||||
|                     <el-form-item label="人均纯收入(元)">{{ detail.perCapitaIncome }}</el-form-item> | ||||
|                   </div> | ||||
|                 </template> | ||||
|               </ai-card> | ||||
|               <ai-card title="风险消除情况" v-if="detail.status == 3"> | ||||
|                 <template slot="content"> | ||||
|                   <div flex class="half wrap"> | ||||
|                     <el-form-item label="工资性收入情况">{{ detail.fxxcIncome1 }}</el-form-item> | ||||
|                     <el-form-item label="生产经营性收入情况">{{ detail.fxxcIncome2 }}</el-form-item> | ||||
|                     <el-form-item label="财产性收入情况">{{ detail.fxxcIncome3 }}</el-form-item> | ||||
|                     <el-form-item label="转移性收入情况">{{ detail.fxxcIncome4 }}</el-form-item> | ||||
|                     <el-form-item label="理赔收入情况">{{ detail.fxxcIncome5 }}</el-form-item> | ||||
|                     <el-form-item label="生产经营性支出情况">{{ detail.fxxcIncome6 }}</el-form-item> | ||||
|                     <el-form-item label="合规自然收支情况">{{ detail.fxxcIncome7 }}</el-form-item> | ||||
|                     <el-form-item label="家庭纯收入情况">{{ detail.fxxcIncome8 }}</el-form-item> | ||||
|                     <el-form-item label="家庭人均纯收入情况">{{ detail.fxxcIncome9 }}</el-form-item> | ||||
|                   </div> | ||||
|                 </template> | ||||
|               </ai-card> | ||||
|               <ai-card title="家庭成员"> | ||||
|                 <template #right> | ||||
|                   <span style=" color: #2266ff; margin-left: 16px;cursor: pointer;font-size: 12px;" | ||||
|                         @click="addFamily({})">添加</span> | ||||
|                 </template> | ||||
|                 <template #content> | ||||
|                   <ai-table :tableData="detail.family" :colConfigs="colConfigs" :dict="dict" :isShowPagination="false"> | ||||
|                     <el-table-column slot="options" label="操作" align="center" width="200px"> | ||||
|                       <template slot-scope="{ row }"> | ||||
|                         <el-button type="text" @click="viewFamily(row)">详情</el-button> | ||||
|                         <template v-if="row.isHousehold==0"> | ||||
|                           <el-button type="text" @click="addFamily(row)">编辑</el-button> | ||||
|                           <el-button type="text" @click="delFamily(row)">删除</el-button> | ||||
|                         </template> | ||||
|                       </template> | ||||
|                     </el-table-column> | ||||
|                   </ai-table> | ||||
|                 </template> | ||||
|               </ai-card> | ||||
|               <div style="height:20px;"></div> | ||||
|             </el-tab-pane> | ||||
|             <el-tab-pane label="走访日志" lazy name="HrLog" | ||||
|                          v-if="$permissions('app_apppreventionreturntopovertylog_detail')"> | ||||
|               <hr-log v-if="currentTab == 'HrLog'" :instance="instance" :dict="dict" :permissions="permissions"/> | ||||
|             </el-tab-pane> | ||||
|             <el-tab-pane label="帮扶措施" lazy name="HrMeasure"> | ||||
|               <hr-measure v-if="currentTab == 'HrMeasure'" :instance="instance" :dict="dict" | ||||
|                           :permissions="permissions"/> | ||||
|             </el-tab-pane> | ||||
|           </el-tabs> | ||||
|         </el-form> | ||||
|         <ai-dialog :visible.sync="isShowAdd" width="1000px" height="500px" title="添加家庭成员" @close="onClose" | ||||
|                    @onConfirm="onConfirm"> | ||||
|           <el-form :model="form" ref="ruleForm" :rules="rules" label-width="130px" label-position="right" size="small"> | ||||
|             <div flex class="half wrap"> | ||||
|               <div flex class="column"> | ||||
|                 <el-form-item label="成员姓名" prop="name"> | ||||
|                   <el-input size="small" class="user-selecter" v-model="form.name" placeholder="请输入姓名" clearable | ||||
|                             :disabled="isEdit || isSelectUser"> | ||||
|                     <template slot="append"> | ||||
|                       <ai-person-select :instance="instance" @selectPerson="checkName" | ||||
|                                         :url="'/app/appresident/list?auditStatus=1&areaId='+user.info.areaId"></ai-person-select> | ||||
|                     </template> | ||||
|                   </el-input> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="联系方式" prop="phone"> | ||||
|                   <el-input v-model="form.phone" placeholder="请输入联系方式" :maxlength="11" show-word-limit/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="证件号码" prop="idNumber"> | ||||
|                   <el-input v-model="form.idNumber" placeholder="请输入证件号码" :maxlength="18" | ||||
|                             :disabled="isEdit || isSelectUser" @change="handleIdNumberAutocomplete"/> | ||||
|                 </el-form-item> | ||||
|               </div> | ||||
|               <el-form-item label="个人照片" prop="photo"> | ||||
|                 <ai-avatar :instance="instance" v-model="form.photo"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="性别" prop="sex"> | ||||
|                 <ai-select v-model="form.sex" :selectList="dict.getDict('sex')" disabled/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="出生日期" prop="birthDate"> | ||||
|                 <el-date-picker disabled value-format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd" v-model="form.birthDate" | ||||
|                                 type="date" placeholder="选择日期"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="与户主关系" prop="householdRelation"> | ||||
|                 <ai-select v-model="form.householdRelation" :selectList="dict.getDict('fpRelationship')"/> | ||||
|               </el-form-item> | ||||
|               <!-- <el-form-item label="年龄" prop="age"> | ||||
|                 <el-input disabled v-model="form.age" placeholder="请输入年龄" type="number"/> | ||||
|               </el-form-item> --> | ||||
|               <el-form-item label="民族"> | ||||
|                 <ai-select v-model="form.nation" :selectList="dict.getDict('fpNation')"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="文化程度"> | ||||
|                 <ai-select v-model="form.education" :selectList="dict.getDict('fpEducation')"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="政治面貌"> | ||||
|                 <ai-select v-model="form.politicsStatus" :selectList="dict.getDict('fpPoliticalOutlook')"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="在校生状况"> | ||||
|                 <ai-select v-model="form.schoolStatus" :selectList="dict.getDict('fpStudentsInSchool')"/> | ||||
|               </el-form-item> | ||||
|             </div> | ||||
|             <el-form-item label="健康状况"> | ||||
|               <el-checkbox-group v-model="form.healthyStatusList"> | ||||
|                 <el-checkbox :label="item.dictValue" v-for="(item, index) in dict.getDict('fpHealth')" :key="index"> | ||||
|                   {{ item.dictName }} | ||||
|                 </el-checkbox> | ||||
|               </el-checkbox-group> | ||||
|             </el-form-item> | ||||
|             <div flex class="half wrap"> | ||||
|               <el-form-item label="残疾类别"> | ||||
|                 <ai-select v-model="form.disabilityType" :selectList="dict.getDict('fpDisabilityType')" | ||||
|                            placeholder="请选择"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="残疾办证年度"> | ||||
|                 <ai-select v-model="form.disabilityCertificateYear" :selectList="dict.getDict('fpYear')"/> | ||||
|               </el-form-item> | ||||
|             </div> | ||||
|             <el-form-item label="基础保险"> | ||||
|               <el-checkbox-group v-model="form.basicsList"> | ||||
|                 <el-checkbox :label="item.value" v-for="(item, index) in basicsCheckList" :key="index"> | ||||
|                   {{ item.label }} | ||||
|                 </el-checkbox> | ||||
|               </el-checkbox-group> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="保障措施"> | ||||
|               <el-checkbox-group v-model="form.guaranteeList"> | ||||
|                 <el-checkbox :label="item.value" v-for="(item, index) in guaranteeCheckList" :key="index"> | ||||
|                   {{ item.label }} | ||||
|                 </el-checkbox> | ||||
|               </el-checkbox-group> | ||||
|             </el-form-item> | ||||
|             <div flex class="half wrap"> | ||||
|               <el-form-item label="劳动技能"> | ||||
|                 <ai-select v-model="form.labourStatus" :selectList="dict.getDict('fpLaborSkills')"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="是否会讲普通话"> | ||||
|                 <ai-select v-model="form.mandarin" :selectList="dict.getDict('fpYesOrNo')" placeholder="请选择"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="务工时间(月)"> | ||||
|                 <el-input type="number" v-model="form.workeMonths" placeholder="请输入" clearable | ||||
|                           @input="numberInput('workeMonths')"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="就业渠道"> | ||||
|                 <ai-select v-model="form.employmentChannels" :selectList="dict.getDict('fpEmploymentChannels')"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="务工企业名称"> | ||||
|                 <el-input v-model="form.migrantEnterprises" placeholder="请输入" clearable/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="公益性岗位"> | ||||
|                 <el-input v-model="form.publicWelfarePosts" placeholder="请输入" clearable/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="是否国外务工"> | ||||
|                 <ai-select v-model="form.foreignWorkers" :selectList="dict.getDict('fpYesOrNo')" placeholder="请选择"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="公益性岗位(月数)"> | ||||
|                 <el-input type="number" v-model="form.publicWelfarePostsMonths" placeholder="请输入" clearable | ||||
|                           @input="numberInput('publicWelfarePostsMonths')"/> | ||||
|               </el-form-item> | ||||
|             </div> | ||||
|             <el-form-item label="务工所在地"> | ||||
|               <el-input v-model="form.foreignWorkersAddress" placeholder="请输入" clearable maxlength="30" | ||||
|                         show-word-limit/> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="现住址" prop="currentAreaId"> | ||||
|               <ai-area-get :instance="instance" v-model="form.currentAreaId" :root="rootArea" valueLevel="5"/> | ||||
|               <el-form-item prop="currentAddress"> | ||||
|                 <el-input v-model="form.currentAddress" placeholder="详细地址" maxlength="30" show-word-limit clearable/> | ||||
|               </el-form-item> | ||||
|             </el-form-item> | ||||
|           </el-form> | ||||
|         </ai-dialog> | ||||
|         <ai-dialog customFooter :visible.sync="isShowDetail" width="1000px" height="500px" title="家庭成员详情"> | ||||
|           <el-form :model="familyInfo" label-width="160px" label-position="right" size="small"> | ||||
|             <div flex class="flex-start"> | ||||
|               <div flex class="half wrap fill"> | ||||
|                 <el-form-item label="联系电话">{{ familyInfo.phone }}</el-form-item> | ||||
|                 <el-form-item label="证件号">{{ familyInfo.idNumber }}</el-form-item> | ||||
|                 <el-form-item label="性别" prop="sex">{{ dict.getLabel("sex", familyInfo.sex) }}</el-form-item> | ||||
|                 <el-form-item label="出生日期">{{ familyInfo.birthDate }}</el-form-item> | ||||
|                 <el-form-item label="与户主关系">{{ dict.getLabel("fpRelationship", familyInfo.householdRelation) }} | ||||
|                 </el-form-item> | ||||
|                 <!-- <el-form-item label="年龄" prop="age">{{ familyInfo.age}}</el-form-item> --> | ||||
|                 <el-form-item label="民族">{{ dict.getLabel("fpNation", familyInfo.nation) }}</el-form-item> | ||||
|                 <el-form-item label="文化程度">{{ dict.getLabel("fpEducation", familyInfo.education) }}</el-form-item> | ||||
|                 <el-form-item label="政治面貌">{{ dict.getLabel("fpPoliticalOutlook", familyInfo.politicsStatus) }} | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="在校生状况">{{ dict.getLabel("fpStudentsInSchool", familyInfo.schoolStatus) }} | ||||
|                 </el-form-item> | ||||
|               </div> | ||||
|               <ai-avatar :instance="instance" v-model="familyInfo.photo" :editable="false"/> | ||||
|             </div> | ||||
|             <el-form-item label="健康状况"> | ||||
|               <span v-for="(item, index) in familyInfo.healthyStatusList" :key="index"><span | ||||
|                   v-if="index > 0">,</span>{{ dict.getLabel("fpHealth", item) }}</span> | ||||
|             </el-form-item> | ||||
|             <div flex class="half wrap"> | ||||
|               <el-form-item label="残疾类别">{{ dict.getLabel("fpDisabilityType", familyInfo.disabilityType) }}</el-form-item> | ||||
|               <el-form-item label="残疾办证年度">{{ dict.getLabel("fpYear", familyInfo.disabilityCertificateYear) }}</el-form-item> | ||||
|             </div> | ||||
|             <div flex class="half wrap"> | ||||
|               <el-form-item label="城乡居民基本医疗保险">{{ dict.getLabel("fpYesOrNo", familyInfo.jcbxCxyiliao) }}</el-form-item> | ||||
|               <el-form-item label="城镇职工基本医疗保险">{{ dict.getLabel("fpYesOrNo", familyInfo.jcbxCzyiliao) }}</el-form-item> | ||||
|               <el-form-item label="大病保险">{{ dict.getLabel("fpYesOrNo", familyInfo.jcbxDabing) }}</el-form-item> | ||||
|               <el-form-item label="商业补充医疗保险">{{ dict.getLabel("fpYesOrNo", familyInfo.jcbxShangye) }}</el-form-item> | ||||
|               <el-form-item label="城乡居民基本养老保险">{{ dict.getLabel("fpYesOrNo", familyInfo.jcbxCxyanglao) }}</el-form-item> | ||||
|               <el-form-item label="城镇职工基本养老保险">{{ dict.getLabel("fpYesOrNo", familyInfo.jcbxCzyanglao) }}</el-form-item> | ||||
|               <el-form-item label="享受人身意外保险补贴">{{ dict.getLabel("fpYesOrNo", familyInfo.jcbxRenshenyiwai) }}</el-form-item> | ||||
|               <el-form-item label="享受农村最低生活保障">{{ dict.getLabel("fpYesOrNo", familyInfo.bzcsNongcundibao) }}</el-form-item> | ||||
|               <el-form-item label="是否特困供养人员">{{ dict.getLabel("fpYesOrNo", familyInfo.bzcsTekungongyang) }}</el-form-item> | ||||
|               <el-form-item label="分散供养五保户转集中供养(减少)">{{ dict.getLabel("fpYesOrNo", familyInfo.bzcsWubaohu) }}</el-form-item> | ||||
|               <el-form-item label="是否接受医疗救助">{{ dict.getLabel("fpYesOrNo", familyInfo.bzcsYiliaojiuzhu) }}</el-form-item> | ||||
|               <el-form-item label="是否接受其它健康扶贫">{{ dict.getLabel("fpYesOrNo", familyInfo.bzcsQita) }}</el-form-item> | ||||
|               <el-form-item label="劳动技能">{{ dict.getLabel("fpLaborSkills", familyInfo.labourStatus) }}</el-form-item> | ||||
|               <el-form-item label="是否会讲普通话">{{ dict.getLabel("fpYesOrNo", familyInfo.mandarin) }}</el-form-item> | ||||
|               <el-form-item label="务工时间(月)">{{ familyInfo.workeMonths }}</el-form-item> | ||||
|               <el-form-item label="就业渠道">{{ dict.getLabel("fpEmploymentChannels", familyInfo.employmentChannels) }}</el-form-item> | ||||
|               <el-form-item label="务工企业名称">{{ familyInfo.migrantEnterprises }}</el-form-item> | ||||
|               <el-form-item label="公益性岗位">{{ familyInfo.publicWelfarePosts }}</el-form-item> | ||||
|               <el-form-item label="是否国外务工">{{ dict.getLabel("fpYesOrNo", familyInfo.foreignWorkers) }}</el-form-item> | ||||
|               <el-form-item label="公益性岗位(月数)">{{ familyInfo.publicWelfarePostsMonths }}</el-form-item> | ||||
|             </div> | ||||
|             <el-form-item label="务工所在地">{{ familyInfo.foreignWorkersAddress }}</el-form-item> | ||||
|             <el-form-item label="现住址">{{ currentFullAddressFamily }}</el-form-item> | ||||
|           </el-form> | ||||
|           <template slot="footer"> | ||||
|             <el-button @click="isShowDetail=false">关闭</el-button> | ||||
|           </template> | ||||
|         </ai-dialog> | ||||
|         <ai-dialog :visible.sync="isShowApply" :title="dialogTitle" @closed="applyInfo={},applyFileList=[]" | ||||
|                    @onConfirm="submitApply" width="600px"> | ||||
|           <el-form :model="applyInfo" :rules="rulesApply" ref="dialogApplyInfo" size="small" label-width="120px"> | ||||
|             <el-form-item label="风险因素" prop="riskType" v-if="changeStatus == 0 || changeStatus == 1"> | ||||
|               <ai-select v-model="applyInfo.riskType" :selectList="dict.getDict('fpRiskType')"/> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="风险消除方式" prop="riskEliminationMethod" v-if="changeStatus == 3 || changeStatus == 4"> | ||||
|               <ai-select v-model="applyInfo.riskEliminationMethod" | ||||
|                          :selectList="dict.getDict('fpRiskEliminationMethod')"/> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="备注说明"> | ||||
|               <el-input type="textarea" v-model="applyInfo.opinion" placeholder="请输入" maxlength="500" show-word-limit | ||||
|                         rows="5"/> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="图片"> | ||||
|               <ai-uploader v-model="applyFileList" :instance="instance" acceptType=".jpg,.jpeg,.png"> | ||||
|                 <template #tips> | ||||
|                   最多9张,仅支持10M以内的jpg、jpeg、png格式照片 | ||||
|                 </template> | ||||
|               </ai-uploader> | ||||
|             </el-form-item> | ||||
|           </el-form> | ||||
|         </ai-dialog> | ||||
|         <ai-dialog :visible.sync="isShowExamine" :title="dialogTitle" width="800px" customFooter> | ||||
|           <el-steps :active="examineStep" align-center> | ||||
|             <el-step title="申请信息"></el-step> | ||||
|             <el-step title="处理意见"></el-step> | ||||
|             <el-step title="完成"></el-step> | ||||
|           </el-steps> | ||||
|           <div class="info" v-if="examineStep == 1"> | ||||
|             <ai-wrapper label-width="120px" :columnsNumber="2" style="margin-top: 16px;"> | ||||
|               <ai-info-item label="操作类型" :value="changeStatus == 2 ? '申请纳入监测' : '申请解除风险' "/> | ||||
|               <ai-info-item label="风险因素" :value="dict.getLabel('fpRiskType', examineInfo.bizDictValue)" | ||||
|                             v-if="changeStatus == 2"/> | ||||
|               <ai-info-item label="风险消除方式" :value="dict.getLabel('fpRiskEliminationMethod', examineInfo.bizDictValue)" | ||||
|                             v-if="changeStatus == 5"/> | ||||
|               <ai-info-item label="申请人" :value="examineInfo.operationUserName"/> | ||||
|               <ai-info-item label="申请时间" :value="examineInfo.createTime"/> | ||||
|             </ai-wrapper> | ||||
|             <ai-wrapper label-width="120px" :columnsNumber="1"> | ||||
|               <ai-info-item label="备注说明" :value="examineInfo.detail"/> | ||||
|             </ai-wrapper> | ||||
|             <ai-uploader v-model="examineInfo.files" disabled style="padding-left:150px;"/> | ||||
|           </div> | ||||
|           <div class="form" v-if="examineStep == 2"> | ||||
|             <el-form :model="examineFrom" size="small" label-width="80px"> | ||||
|               <el-form-item label="审核结果" required> | ||||
|                 <el-radio-group v-model="examineFrom.pass"> | ||||
|                   <el-radio :label="1" v-if="changeStatus == 5">解除风险</el-radio> | ||||
|                   <el-radio :label="1" v-if="changeStatus == 2">纳入监测</el-radio> | ||||
|                   <el-radio :label="0">驳回申请</el-radio> | ||||
|                 </el-radio-group> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="备注说明"> | ||||
|                 <el-input type="textarea" v-model="examineFrom.opinion" placeholder="请输入" maxlength="500" | ||||
|                           show-word-limit rows="5"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="图片"> | ||||
|                 <ai-uploader v-model="examineFileList" :instance="instance" acceptType=".jpg,.jpeg,.png"> | ||||
|                   <template #tips> | ||||
|                     最多9张,仅支持10M以内的jpg、jpeg、png格式照片 | ||||
|                   </template> | ||||
|                 </ai-uploader> | ||||
|               </el-form-item> | ||||
|             </el-form> | ||||
|           </div> | ||||
|           <div class="success" v-if="examineStep == 3"> | ||||
|             <i class="el-icon-success"></i> | ||||
|             <p>审核成功</p> | ||||
|           </div> | ||||
|           <template slot="footer" v-if="examineStep != 3"> | ||||
|             <el-button @click="cancelExamine">{{ examineStep == 2 ? '上一步' : '取消' }}</el-button> | ||||
|             <el-button type="primary" @click="examineNext">下一步</el-button> | ||||
|           </template> | ||||
|           <template slot="footer" v-if="examineStep == 3"> | ||||
|             <el-button @click="back">关闭</el-button> | ||||
|           </template> | ||||
|         </ai-dialog> | ||||
|       </template> | ||||
|     </ai-detail> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapState} from "vuex"; | ||||
| import HrMeasure from "./detail/hrMeasure"; | ||||
| import HrLog from "./detail/hrLog"; | ||||
|  | ||||
| export default { | ||||
|   name: "hrDetail", | ||||
|   components: {HrLog, HrMeasure}, | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function, | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(["user"]), | ||||
|     colConfigs() { | ||||
|       return [ | ||||
|         { | ||||
|           label: "与户主关系", | ||||
|           prop: "householdRelation", | ||||
|           dict: "fpRelationship", | ||||
|         }, | ||||
|         {label: "姓名", prop: "name"}, | ||||
|         {label: "性别", prop: "sex", dict: "sex"}, | ||||
|         {label: "年龄", prop: "age"}, | ||||
|         { | ||||
|           label: "证件号", | ||||
|           render: (h, {row}) => | ||||
|               h("p", null, this.idCardNoUtil.hideId(row.idNumber)), | ||||
|         }, | ||||
|         {slot: "options"}, | ||||
|       ]; | ||||
|     }, | ||||
|     isGridAdmin() { | ||||
|       return this.user.info.girdCheckType == 2; | ||||
|     }, | ||||
|     currentFullAddress() { | ||||
|       let {countyName, townName, villageName, currentAddress} = this.detail; | ||||
|       return [countyName, townName, villageName, currentAddress].join(""); | ||||
|     }, | ||||
|     currentFullAddressFamily() { | ||||
|       let {countyName, townName, villageName, currentAddress} = this.familyInfo; | ||||
|       return [countyName, townName, villageName, currentAddress].join(""); | ||||
|     }, | ||||
|     rules() { | ||||
|       return { | ||||
|         idNumber: [{required: true, message: "请输入证件号"}], | ||||
|         name: [{required: true, message: "请输入姓名"}], | ||||
|         sex: [{required: true, message: "请选择性别"}], | ||||
|         phone: [{required: true, message: "请输入联系方式"}], | ||||
|         currentAreaId: [ | ||||
|           {required: true, message: "请选择现住址"}, | ||||
|           {pattern: /[^0]0{0,2}$/, message: "请选择到村/社区"}, | ||||
|         ], | ||||
|         isHousehold: [{required: true, message: "请选择是否户主"}], | ||||
|         householdRelation: [{required: true, message: "请选择与户主关系"}], | ||||
|         householdIdNumber: [{required: true, message: "请选择户主证件号"}], | ||||
|       }; | ||||
|     }, | ||||
|     rulesApply() { | ||||
|       return { | ||||
|         riskType: [{required: true, message: "请选择风险因素"}], | ||||
|         riskEliminationMethod: [{required: true, message: "请选择风险消除方式"}], | ||||
|       }; | ||||
|     }, | ||||
|     rootArea() { | ||||
|       return this.user.info?.areaId?.replace(/(\d{6})\d+/g, '$1' + Array(7).join("0")) || "" | ||||
|     }, | ||||
|     guaranteeCheckList() { | ||||
|       return [ | ||||
|         {label: '享受农村最低生活保障', value: '0'}, | ||||
|         {label: '是否特困供养人员', value: '1'}, | ||||
|         {label: '分散供养五保户转集中供养(减少)', value: '2'}, | ||||
|         {label: '是否接受医疗救助', value: '3'}, | ||||
|         {label: '是否接受其它健康扶贫', value: '4'}, | ||||
|       ] | ||||
|     }, | ||||
|     basicsCheckList() { | ||||
|       return [ | ||||
|         {label: '城乡居民基本医疗保险', value: '0'}, | ||||
|         {label: '城镇职工基本医疗保险', value: '1'}, | ||||
|         {label: '大病保险', value: '2'}, | ||||
|         {label: '商业补充医疗保险', value: '3'}, | ||||
|         {label: '城乡居民基本养老保险', value: '4'}, | ||||
|         {label: '城镇职工基本养老保险', value: '5'}, | ||||
|         {label: '享受人身意外保险补贴', value: '6'}, | ||||
|       ] | ||||
|     }, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       detail: {}, | ||||
|       currentTab: "", | ||||
|       isShowAdd: false, | ||||
|       form: {healthyStatusList: [], basicsList: [], guaranteeList: []}, | ||||
|       isEdit: false, | ||||
|       isShowDetail: false, | ||||
|       familyInfo: {}, | ||||
|       isSelectUser: false, | ||||
|       isShowApply: false, | ||||
|       dialogTitle: '', | ||||
|       applyInfo: {}, | ||||
|       isShowExamine: false, | ||||
|       examineInfo: {}, | ||||
|       examineStep: 1, //审批步骤 | ||||
|       examineFrom: {pass: 1}, | ||||
|       applyFileList: [], | ||||
|       examineFileList: [], | ||||
|       changeStatus: 0,  //操作状态 0:申请纳入监测 1:纳入监测 2:纳入监测审批 3:申请解除风险 4:解除风险 5:解除风险审批 | ||||
|       girdAdminApplyStatus: 0, //网格长纳入监测状态 0:纳入监测 1:纳入监测审批 | ||||
|     }; | ||||
|   }, | ||||
|   methods: { | ||||
|     checkName(e) { | ||||
|       if (!e) { | ||||
|         this.isSelectUser = false | ||||
|         this.form.name = '' | ||||
|         this.form.idNumber = '' | ||||
|         this.form.phone = '' | ||||
|         this.form.areaId = '' | ||||
|         this.form.birthDate = '' | ||||
|         this.form.sex = '' | ||||
|         this.form.age = '' | ||||
|         this.form.currentAreaId = '' | ||||
|         this.form.currentAddress = '' | ||||
|         return | ||||
|       } | ||||
|       this.form.name = e.name | ||||
|       this.form.idNumber = e.idNumber | ||||
|       this.form.phone = e.phone | ||||
|       this.form.currentAreaId = e.currentAreaId | ||||
|       this.form.currentAddress = e.currentAddress | ||||
|       this.handleIdNumberAutocomplete(e.idNumber) | ||||
|       this.isSelectUser = true | ||||
|     }, | ||||
|     addFamily(row) { | ||||
|       if (row && row.id) { | ||||
|         this.isEdit = true | ||||
|       } | ||||
|       row.healthyStatusList = [] | ||||
|       row.basicsList = [] | ||||
|       row.guaranteeList = [] | ||||
|       if (row && row.healthyStatus) { | ||||
|         row.healthyStatusList = row.healthyStatus.split(',') | ||||
|       } | ||||
|       if (row && row.basicsCheck) { | ||||
|         row.basicsList = row.basicsCheck.split(',') | ||||
|       } | ||||
|       if (row && row.guaranteeCheck) { | ||||
|         row.guaranteeList = row.guaranteeCheck.split(',') | ||||
|       } | ||||
|       this.form = {...row} | ||||
|       this.isShowAdd = true | ||||
|     }, | ||||
|     viewFamily(row) { | ||||
|       row.healthyStatusList = [] | ||||
|       row.basicsList = [] | ||||
|       row.guaranteeList = [] | ||||
|       if (row.healthyStatus) { | ||||
|         row.healthyStatusList = row.healthyStatus.split(',') | ||||
|       } | ||||
|       if (row.basicsCheck) { | ||||
|         row.basicsList = row.basicsCheck.split(',') | ||||
|       } | ||||
|       if (row.guaranteeCheck) { | ||||
|         row.guaranteeList = row.guaranteeCheck.split(',') | ||||
|       } | ||||
|       this.familyInfo = {...row} | ||||
|       this.isShowDetail = true | ||||
|     }, | ||||
|     delFamily(row) { | ||||
|       if (row.isHousehold == 1) { | ||||
|         return this.$message.error('户主信息不允许删除'); | ||||
|       } | ||||
|       this.$confirm("是否删除该家庭成员").then(() => { | ||||
|         this.instance.post(`/app/apppreventionreturntopoverty/delete?ids=${row.id}`).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.getDetail() | ||||
|             this.$message.success('删除成功!'); | ||||
|           } | ||||
|         }) | ||||
|       }) | ||||
|     }, | ||||
|     handleIdNumberAutocomplete(v) { | ||||
|       let {birthday: birthDate, sex} = this.idCardNoUtil.getIdCardInfo(v); | ||||
|       this.form = {...this.form, birthDate, sex, age: this.$calcAge(v)}; | ||||
|     }, | ||||
|     onConfirm() { | ||||
|       this.$refs.ruleForm.validate((v) => { | ||||
|         if (v) { | ||||
|           this.form.isHousehold = 0 | ||||
|           this.form.householdIdNumber = this.detail.idNumber | ||||
|           if (this.form.healthyStatusList.length) { | ||||
|             this.form.healthyStatus = this.form.healthyStatusList.join(',') | ||||
|           } | ||||
|           if (this.form.basicsList.length) { | ||||
|             this.form.basicsCheck = this.form.basicsList.join(',') | ||||
|           } | ||||
|           if (this.form.guaranteeList.length) { | ||||
|             this.form.guaranteeCheck = this.form.basicsList.join(',') | ||||
|           } | ||||
|           this.checkInit('jcbxCxyiliao', this.form.basicsList, '0') | ||||
|           this.checkInit('jcbxCzyiliao', this.form.basicsList, '1') | ||||
|           this.checkInit('jcbxDabing', this.form.basicsList, '2') | ||||
|           this.checkInit('jcbxShangye', this.form.basicsList, '3') | ||||
|           this.checkInit('jcbxCxyanglao', this.form.basicsList, '4') | ||||
|           this.checkInit('jcbxCzyanglao', this.form.basicsList, '5') | ||||
|           this.checkInit('jcbxRenshenyiwai', this.form.basicsList, '6') | ||||
|  | ||||
|           this.checkInit('bzcsNongcundibao', this.form.guaranteeList, '0') | ||||
|           this.checkInit('bzcsTekungongyang', this.form.guaranteeList, '1') | ||||
|           this.checkInit('bzcsWubaohu', this.form.guaranteeList, '2') | ||||
|           this.checkInit('bzcsYiliaojiuzhu', this.form.guaranteeList, '3') | ||||
|           this.checkInit('bzcsQita', this.form.guaranteeList, '4') | ||||
|           this.instance.post(`/app/apppreventionreturntopoverty/addOrUpdate`, this.form).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.getDetail() | ||||
|               this.$message.success('提交成功!'); | ||||
|               this.isShowAdd = false | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     checkInit(formName, list, value) { | ||||
|       if (list.includes(value)) { | ||||
|         this.form[formName] = '01' | ||||
|       } else { | ||||
|         this.form[formName] = '02' | ||||
|       } | ||||
|     }, | ||||
|     onClose() { | ||||
|       this.isShowAdd = false; | ||||
|     }, | ||||
|     back() { | ||||
|       this.$router.push({}); | ||||
|     }, | ||||
|     getDetail() { | ||||
|       let {id} = this.$route.query; | ||||
|       id && | ||||
|       this.instance | ||||
|       .post("/app/apppreventionreturntopoverty/queryDetailById", null, { | ||||
|         params: {id}, | ||||
|       }) | ||||
|       .then((res) => { | ||||
|         if (res?.data) { | ||||
|           this.detail = res.data; | ||||
|           this.detail.family?.map((e) => { | ||||
|             e.householdRelation = e.householdRelation || "户主"; | ||||
|           }); | ||||
|  | ||||
|           if (this.detail.healthyStatus) { | ||||
|             this.detail.healthyStatusList = this.detail.healthyStatus.split(',') | ||||
|           } | ||||
|           if (this.detail.basicsCheck) { | ||||
|             this.detail.basicsList = this.detail.basicsCheck.split(',') | ||||
|           } | ||||
|           if (this.detail.guaranteeCheck) { | ||||
|             this.detail.guaranteeList = this.detail.guaranteeCheck.split(',') | ||||
|           } | ||||
|  | ||||
|           if (this.detail.status == 0 && this.isGridAdmin) { | ||||
|             this.instance.post(`/app/apppreventionreturntopoverty/popup?id=${this.detail.id}`).then(res => { | ||||
|               if (res.code == 0 && res.data) { //纳入监测审批 | ||||
|                 this.girdAdminApplyStatus = 1 | ||||
|               } | ||||
|             }) | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     gotoEdit() { | ||||
|       let {query} = this.$route; | ||||
|       this.$router.push({query, hash: "#add"}); | ||||
|     }, | ||||
|     applyMonitor(title, status) { | ||||
|       this.dialogTitle = title | ||||
|       this.changeStatus = status | ||||
|       this.isShowApply = true | ||||
|     }, | ||||
|     submitApply() { | ||||
|       this.$refs.dialogApplyInfo.validate((v) => { | ||||
|         if (v) { | ||||
|           this.applyInfo.id = this.detail.id | ||||
|           if (this.changeStatus == 1 || this.changeStatus == 4) { //网格长直接纳入监测/解除风险 | ||||
|             this.applyInfo.pass = 1 | ||||
|           } | ||||
|           var url = `/app/apppreventionreturntopoverty/examine` //0, 1纳入监测 | ||||
|           if (this.changeStatus == 3 || this.changeStatus == 4) { //3, 4解除风险 | ||||
|             url = `/app/apppreventionreturntopoverty/relieve` | ||||
|           } | ||||
|  | ||||
|           if (this.applyFileList.length) { | ||||
|             var ids = this.applyFileList.map((item) => { | ||||
|               return item.id | ||||
|             }) | ||||
|             this.applyInfo.files = ids.join(',') | ||||
|           } | ||||
|           let fromData = new FormData() | ||||
|           for (let key in this.applyInfo) { | ||||
|             fromData.append(key, this.applyInfo[key]) | ||||
|           } | ||||
|           this.instance.post(url, fromData).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.getDetail() | ||||
|               this.$message.success('提交成功!'); | ||||
|               this.isShowApply = false | ||||
|             } | ||||
|           }) | ||||
|  | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|     examine(title, status) { | ||||
|       this.dialogTitle = title | ||||
|       this.changeStatus = status | ||||
|       this.instance.post(`/app/apppreventionreturntopoverty/popup?id=${this.detail.id}`).then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.examineInfo = res.data | ||||
|           this.isShowExamine = true | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     examineNext() { | ||||
|       if (this.examineStep == 2) { //审批操作 | ||||
|         if (this.examineFileList.length) { | ||||
|           var ids = this.examineFileList.map((item) => { | ||||
|             return item.id | ||||
|           }) | ||||
|           this.examineFrom.files = ids.join(',') | ||||
|         } | ||||
|         this.examineFrom.id = this.detail.id | ||||
|         var url = `/app/apppreventionreturntopoverty/examine` //2 纳入监测 | ||||
|         if (this.changeStatus == 5) { //5 解除风险 | ||||
|           url = `/app/apppreventionreturntopoverty/relieve` | ||||
|         } | ||||
|         let fromData = new FormData() | ||||
|         for (let key in this.examineFrom) { | ||||
|           fromData.append(key, this.examineFrom[key]) | ||||
|         } | ||||
|         this.instance.post(url, fromData).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.getDetail() | ||||
|             this.$message.success('提交成功!'); | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|       if (this.examineStep == 3) { | ||||
|         this.isShowExamine = false | ||||
|         this.examineFrom = {pass: 1} | ||||
|         return | ||||
|       } | ||||
|       this.examineStep++ | ||||
|     }, | ||||
|     cancelExamine() { | ||||
|       if (this.examineStep == 2) { | ||||
|         return this.examineStep-- | ||||
|       } | ||||
|       this.isShowExamine = false | ||||
|     }, | ||||
|     handleDelete(ids) { | ||||
|       this.$confirm("是否要删除监测对象").then(() => { | ||||
|         this.instance.post("/app/apppreventionreturntopoverty/delete", null, {params: {ids: ids?.toString()},}).then((res) => { | ||||
|           if (res?.code == 0) { | ||||
|             this.$message.success("删除成功!"); | ||||
|             this.back(); | ||||
|           } | ||||
|         }); | ||||
|       }) | ||||
|     }, | ||||
|     numberInput(name) { | ||||
|       if (!/^[0-9]*[1-9][0-9]*$/g.test(this.form[name])) { | ||||
|         this.form[name] = '' | ||||
|         return this.$message.error('请输入正整数') | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|   created() { | ||||
|     this.getDetail(); | ||||
|   }, | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .hrDetail { | ||||
|  | ||||
|   .flex-start { | ||||
|     align-items: flex-start; | ||||
|  | ||||
|     .AiAvatar { | ||||
|       margin-left: 20px; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .half { | ||||
|     align-items: flex-start; | ||||
|  | ||||
|     & > .el-form-item, | ||||
|     & > div { | ||||
|       width: 50%; | ||||
|  | ||||
|       .el-form-item { | ||||
|         width: 100%; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .success { | ||||
|     text-align: center; | ||||
|     padding-top: 20px; | ||||
|  | ||||
|     .el-icon-success { | ||||
|       color: rgb(46, 162, 34); | ||||
|       font-size: 100px; | ||||
|     } | ||||
|  | ||||
|     p { | ||||
|       text-align: center; | ||||
|       font-size: 16px; | ||||
|       padding-top: 20px; | ||||
|       color: #000; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ::v-deep .ai-dialog__content--wrapper { | ||||
|     overflow-y: hidden !important; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .AiPersonSelect .el-button { | ||||
|     color: #fff; | ||||
|   } | ||||
|  | ||||
|   ::v-deep.el-tabs__content { | ||||
|     max-height: calc(100vh - 136px); | ||||
|     overflow-y: auto; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .el-step__icon { | ||||
|     border-color: #ccc !important; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .el-step__line { | ||||
|     background-color: #ccc !important; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .el-step__title, | ||||
|   ::v-deep .is-wait { | ||||
|     color: #666 !important; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .is-finish { | ||||
|     color: #26f !important; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .is-finish .el-step__icon { | ||||
|     border-color: #26f !important; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										173
									
								
								packages/work/AppHelpedResident/hrList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								packages/work/AppHelpedResident/hrList.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| <template> | ||||
|   <section class="hrList"> | ||||
|     <ai-list> | ||||
|       <ai-title slot="title" title="监测对象" isShowBottomBorder isShowArea v-model="search.areaId" :instance="instance" | ||||
|                 @change="page.current=1,getTableData()"> | ||||
|         <template #rightBtn> | ||||
|           <el-button type="primary" icon="iconfont iconSetting" @click="dialog=true" v-if="$permissions('app_apppreventionreturntopovertyalarmconfig_edit')"> | ||||
|             预警规则 | ||||
|           </el-button> | ||||
|         </template> | ||||
|       </ai-title> | ||||
|       <template #content> | ||||
|         <ai-search-bar> | ||||
|           <template #left> | ||||
|             <ai-select placeholder="档案状态" v-model="search.status" :selectList="dict.getDict('fpPrtpStatus')" @change="page.current=1,getTableData()"/> | ||||
|             <ai-select placeholder="监测对象类型" v-model="search.objectType" :selectList="dict.getDict('fpType')" @change="page.current=1,getTableData()"/> | ||||
|             <ai-select placeholder="风险因素" v-model="search.riskType" :selectList="dict.getDict('fpRiskType')" @change="page.current=1,getTableData()"/> | ||||
|             <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.birthStart" type="date" size="small" unlink-panels placeholder="选择出生开始日期" | ||||
|                             @change="page.current=1,getTableData()"/> | ||||
|             <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.birthEnd" type="date" size="small" placeholder="选择出生结束日期" unlink-panels | ||||
|                             @change="page.current=1,getTableData()"/> | ||||
|             <ai-select placeholder="性别" v-model="search.sex" :selectList="dict.getDict('sex')" @change="page.current=1,getTableData()"/> | ||||
|             <!-- <ai-select placeholder="文化程度" v-model="search.education" :selectList="dict.getDict('fpEducation')" @change="page.current=1,getTableData()"/> | ||||
|             <ai-select placeholder="民族" v-model="search.nation" :selectList="dict.getDict('fpNation')" @change="page.current=1,getTableData()"/> | ||||
|             <ai-select placeholder="政治面貌" v-model="search.politicsStatus" :selectList="dict.getDict('fpPoliticalOutlook')" @change="page.current=1,getTableData()"/> --> | ||||
|           </template> | ||||
|           <template #right> | ||||
|             <el-input size="small" placeholder="姓名/证件/联系方式" v-model="search.con" clearable @change="page.current=1,getTableData()"/> | ||||
|           </template> | ||||
|         </ai-search-bar> | ||||
|         <ai-search-bar> | ||||
|           <template #left> | ||||
|             <el-button type="primary" icon="iconfont iconAdd" @click="showEdit()" v-if="$permissions('app_apppreventionreturntopoverty_edit')">添加</el-button> | ||||
|             <el-button icon="iconfont iconDelete" :disabled="!ids.length" @click="handleDelete(ids)" | ||||
|                        v-if="$permissions('app_apppreventionreturntopoverty_del')">删除 | ||||
|             </el-button> | ||||
|           </template> | ||||
|           <template #right> | ||||
|             <ai-import :instance="instance" name="监测对象" title="导入监测对象" | ||||
|                        suffixName="xlsx" | ||||
|                        url="/app/apppreventionreturntopoverty/downloadTemplate" | ||||
|                        importUrl="/app/apppreventionreturntopoverty/import" | ||||
|                        @onSuccess="page.current=1,getTableData()"/> | ||||
|             <ai-download url="/app/apppreventionreturntopoverty/export" :params="{...search,ids}" | ||||
|                          :instance="instance" fileName="监测对象导出文件"/> | ||||
|           </template> | ||||
|         </ai-search-bar> | ||||
|         <ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size" | ||||
|                   @getList="getTableData" :col-configs="colConfigs" :dict="dict" | ||||
|                   @selection-change="v=>ids=v.map(e=>e.id)"> | ||||
|           <el-table-column slot="options" label="操作" fixed="right" align="center"> | ||||
|             <template slot-scope="{row}"> | ||||
|               <el-button type="text" @click="showDetail(row.id)" v-if="$permissions('app_apppreventionreturntopoverty_detail')">详情</el-button> | ||||
|               <el-button type="text" @click="handleDelete(row.id)" v-if="$permissions('app_apppreventionreturntopoverty_del') &&/[34]/.test(row.status)">删除 | ||||
|               </el-button> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|         </ai-table> | ||||
|       </template> | ||||
|     </ai-list> | ||||
|     <ai-dialog :visible.sync="dialog" title="预警规则设置" @closed="form={}" @onConfirm="submitDialog" width="600px"> | ||||
|       <el-form :model="form" :rules="rules" ref="DialogForm" size="small" label-width="160px"> | ||||
|         <el-form-item label="家庭纯收入标准" prop="type0"> | ||||
|           <el-input v-model.number="form.type0" placeholder="请输入" maxlength="8" show-word-limit/> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="家庭人均纯收入标准" prop="type1"> | ||||
|           <el-input v-model.number="form.type1" placeholder="请输入" maxlength="8" show-word-limit/> | ||||
|         </el-form-item> | ||||
|       </el-form> | ||||
|     </ai-dialog> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapState} from "vuex"; | ||||
|  | ||||
| export default { | ||||
|   name: "hrList", | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|     colConfigs() { | ||||
|       return [ | ||||
|         {type: 'selection'}, | ||||
|         {label: "姓名", prop: "name", align: "center"}, | ||||
|         {label: "性别", prop: "sex", dict: 'sex', align: "center"}, | ||||
|         {label: "证件号", render: (h, {row}) => h('p', this.idCardNoUtil.hideId(row.idNumber))}, | ||||
|         {label: "年龄", prop: "age", align: "center"}, | ||||
|         {label: "民族", prop: "nation", align: "center", dict: "fpNation"}, | ||||
|         {label: "文化程度", prop: "education", align: "center", dict: "fpEducation"}, | ||||
|         {label: "监测对象类型", prop: "objectType", align: "center", dict: "fpType"}, | ||||
|         {label: "风险因素", prop: "riskType", align: "center", dict: "fpRiskType"}, | ||||
|         {label: "档案状态", prop: "status", dict: "fpPrtpStatus", align: "center"}, | ||||
|         {slot: "options"} | ||||
|       ] | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       search: {name: '', objectType: '', riskType: '', isHousehold: 1}, | ||||
|       page: {current: 1, size: 10, total: 0}, | ||||
|       tableData: [], | ||||
|       ids: [], | ||||
|       dialog: false, | ||||
|       form: {}, | ||||
|       rules: { | ||||
|         type0: [{required: true, message: "请输入家庭纯收入标准", trigger: "change"}], | ||||
|         type1: [{required: true, message: "请输入家庭人均纯收入标准", trigger: "change"}], | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     getTableData() { | ||||
|       this.instance.post("/app/apppreventionreturntopoverty/list", null, { | ||||
|         params: {...this.page, ...this.search} | ||||
|       }).then(res => { | ||||
|         if (res?.data) { | ||||
|           this.tableData = res.data?.records | ||||
|           this.page.total = res.data.total | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     showEdit(id) { | ||||
|       this.$router.push({query: {id}, hash: "#add"}) | ||||
|     }, | ||||
|     showDetail(id) { | ||||
|       this.$router.push({query: {id}}) | ||||
|     }, | ||||
|     handleDelete(ids) { | ||||
|       this.$confirm("是否要删除监测对象").then(() => { | ||||
|         this.instance.post("/app/apppreventionreturntopoverty/delete", null, { | ||||
|           params: {ids: ids?.toString()} | ||||
|         }).then(res => { | ||||
|           if (res?.code == 0) { | ||||
|             this.$message.success("删除成功!") | ||||
|             this.getTableData() | ||||
|           } | ||||
|         }) | ||||
|       }).catch(() => 0) | ||||
|     }, | ||||
|     submitDialog() { | ||||
|       this.$refs.DialogForm.validate(v => { | ||||
|         if (v) { | ||||
|           let loading = this.$loading({text: "提交中..."}) | ||||
|           this.instance.post(`/app/apppreventionreturntopovertyalarmconfig/addOrUpdate`, this.form).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.$message.success('预警规则设置成功'); | ||||
|               this.getTableData() | ||||
|               this.dialog = false | ||||
|             } | ||||
|           }).finally(() => { | ||||
|             loading.close() | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.search.areaId = this.user.info.areaId | ||||
|     this.getTableData() | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .hrList { | ||||
|   height: 100%; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										73
									
								
								packages/work/AppRiskWarning/AppRiskWarning.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								packages/work/AppRiskWarning/AppRiskWarning.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| <template> | ||||
|   <div class="doc-circulation ailist-wrapper"> | ||||
|     <keep-alive :include="['List']"> | ||||
|       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> | ||||
|     </keep-alive> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import List from './components/List' | ||||
|   import Add from './components/Add' | ||||
|   import Detail from './components/Detail' | ||||
|  | ||||
|   export default { | ||||
|     name: 'AppRiskWarning', | ||||
|     label: '风险告知', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         component: 'List', | ||||
|         params: {}, | ||||
|         include: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     components: { | ||||
|       Add, | ||||
|       List, | ||||
|       Detail | ||||
|     }, | ||||
|  | ||||
|     mounted () { | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       onChange (data) { | ||||
|         if (data.type === 'Add') { | ||||
|           this.component = 'Add' | ||||
|           this.params = data.params | ||||
|         } | ||||
|  | ||||
|         if (data.type === 'Detail') { | ||||
|           this.component = 'Detail' | ||||
|           this.params = data.params | ||||
|         } | ||||
|  | ||||
|         if (data.type === 'List') { | ||||
|           this.component = 'List' | ||||
|           this.params = data.params | ||||
|  | ||||
|           this.$nextTick(() => { | ||||
|             if (data.isRefresh) { | ||||
|               this.$refs.component.getList() | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss"> | ||||
|   .doc-circulation { | ||||
|     height: 100%; | ||||
|     background: #F3F6F9; | ||||
|     overflow: auto; | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										173
									
								
								packages/work/AppRiskWarning/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								packages/work/AppRiskWarning/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| <template> | ||||
|   <ai-detail> | ||||
|     <template slot="title"> | ||||
|       <ai-title :title="params.id ? '编辑风险人员' : '添加风险人员'" isShowBack isShowBottomBorder @onBackClick="cancel(false)"> | ||||
|       </ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-card title="基本信息"> | ||||
|         <template #content> | ||||
|           <el-form ref="form" class="ai-form" :model="form" label-width="110px" label-position="right"> | ||||
|             <el-form-item label="姓名" prop="name" :rules="[{ required: true, message: '请输入姓名', trigger: 'blur' }]"> | ||||
|               <el-input v-model="form.name" size="small" placeholder="请输入姓名"></el-input> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="联系方式" prop="phone" :rules="[{ required: true, validator: validatorPhone, trigger: 'blur' }]"> | ||||
|               <el-input v-model="form.phone" :maxlength="11" size="small" placeholder="请输入..."></el-input> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="风险类型" prop="riskType" :rules="[{ required: true, message: '请选择风险类型', trigger: 'blur' }]"> | ||||
|               <ai-select | ||||
|                 v-model="form.riskType" | ||||
|                 clearable | ||||
|                 placeholder="请选择风险类型" | ||||
|                 :selectList="dict.getDict('fpRiskType')"> | ||||
|               </ai-select> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="身份证号" prop="idNumber" :rules="[{ required: true, validator: validatorId, trigger: 'blur' }]"> | ||||
|               <el-input v-model="form.idNumber" :maxlength="20" size="small" placeholder="请输入..."></el-input> | ||||
|             </el-form-item> | ||||
|             <el-form-item | ||||
|               style="width: 100%!important;" | ||||
|               label="所在地区" | ||||
|               prop="areaId" | ||||
|               :rules="[{ required: true, pattern: /([^0]\d{2}|0[^0]\d|0\d[^0])$/, message: '请选择到村', trigger: 'change' }]"> | ||||
|               <ai-area-select | ||||
|                 v-model="form.areaId" | ||||
|                 always-show | ||||
|                 :instance="instance" | ||||
|                 clearable | ||||
|                 @fullname="v=>form.areaName = v" | ||||
|                 :disabledLevel="disabledLevel"/> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="联系地址" prop="address" style="width: 100%;"> | ||||
|               <el-input v-model="form.address" :maxlength="30" size="small" placeholder="请输入联系地址"></el-input> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="备注说明" prop="remarks" style="width: 100%;"> | ||||
|               <el-input v-model="form.remarks" :rows="5" style="width: 100%;" type="textarea" :maxlength="500" size="small" placeholder="请简要说明风险情况"></el-input> | ||||
|             </el-form-item> | ||||
|           </el-form> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|     </template> | ||||
|     <template #footer> | ||||
|       <el-button @click="cancel">取消</el-button> | ||||
|       <el-button type="primary" @click="confirm" :loading="isLoading">提交</el-button> | ||||
|     </template> | ||||
|   </ai-detail> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import { mapState } from 'vuex' | ||||
|   export default { | ||||
|     name: 'Add', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       params: Object | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       const validatorId = (rule, value, callback) => { | ||||
|         if (value === '') { | ||||
|           callback(new Error('请输入身份证号')) | ||||
|         } else if (!this.idCardNoUtil.checkIdCardNo(value)) { | ||||
|           callback(new Error('身份证号格式错误')) | ||||
|         } else { | ||||
|           callback() | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       const validatorPhone = function (rule, value, callback) { | ||||
|         if (value === '') { | ||||
|           callback(new Error('请输入联系方式')) | ||||
|         } else if (!/^1\d{10}$/.test(value)) { | ||||
|           callback(new Error('手机号格式错误')) | ||||
|         } else { | ||||
|           callback() | ||||
|         } | ||||
|       } | ||||
|       return { | ||||
|         info: {}, | ||||
|         validatorId, | ||||
|         validatorPhone, | ||||
|         form: { | ||||
|           name: '', | ||||
|           idNumber: '', | ||||
|           address: '', | ||||
|           areaId: '', | ||||
|           areaName: '', | ||||
|           remarks: '', | ||||
|           phone: '', | ||||
|           riskType: '' | ||||
|         }, | ||||
|         id: '', | ||||
|         isLoading: false, | ||||
|         disabledLevel: 3 | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       ...mapState(['user']) | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       this.form.areaName = this.user.info.areaName | ||||
|       this.form.areaId = this.user.info.areaId | ||||
|       this.disabledLevel = this.user.info.areaList.length | ||||
|       if (this.params && this.params.id) { | ||||
|         this.id = this.params.id | ||||
|         this.getInfo(this.params.id) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getInfo (id) { | ||||
|         this.instance.post(`/app/apppreventionreturntopovertyriskperson/queryDetailById?id=${id}`).then(res => { | ||||
|           if (res.code === 0) { | ||||
|             this.form = { | ||||
|               ...res.data, | ||||
|               images: res.data.images ? JSON.parse(res.data.images) : [] | ||||
|             } | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       onClose () { | ||||
|         this.form.explain = '' | ||||
|       }, | ||||
|  | ||||
|       confirm () { | ||||
|         this.$refs.form.validate((valid) => { | ||||
|           if (valid) { | ||||
|             this.isLoading = true | ||||
|             this.instance.post(`/app/apppreventionreturntopovertyriskperson/addOrUpdate`, { | ||||
|               ...this.form | ||||
|             }).then(res => { | ||||
|               if (res.code == 0) { | ||||
|                 this.$message.success('提交成功') | ||||
|                 setTimeout(() => { | ||||
|                   this.cancel(true) | ||||
|                   this.isLoading = false | ||||
|                 }, 600) | ||||
|               } else { | ||||
|                 this.isLoading = false | ||||
|               } | ||||
|             }).catch(() => { | ||||
|               this.isLoading = false | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       cancel (isRefresh) { | ||||
|         this.$emit('change', { | ||||
|           type: 'List', | ||||
|           isRefresh: !!isRefresh | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| </style> | ||||
							
								
								
									
										69
									
								
								packages/work/AppRiskWarning/components/Detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								packages/work/AppRiskWarning/components/Detail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| <template> | ||||
|   <ai-detail> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)"> | ||||
|       </ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-card title="基本信息"> | ||||
|         <template #content> | ||||
|           <ai-wrapper> | ||||
|             <ai-info-item label="姓名" :value="info.name"></ai-info-item> | ||||
|             <ai-info-item label="联系方式" :value="info.phone"></ai-info-item> | ||||
|             <ai-info-item label="风险类型" :value="dict.getLabel('fpRiskType', info.riskType)"></ai-info-item> | ||||
|             <ai-info-item label="身份证号" :value="info.idNumber"></ai-info-item> | ||||
|             <ai-info-item label="所在地区" :value="info.areaName"></ai-info-item> | ||||
|             <ai-info-item label="联系地址" isLine :value="info.address"></ai-info-item> | ||||
|             <ai-info-item label="备注说明" isLine :value="info.remarks"></ai-info-item> | ||||
|           </ai-wrapper> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|     </template> | ||||
|   </ai-detail> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   export default { | ||||
|     name: 'Detail', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       params: Object | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         info: {}, | ||||
|         id: '' | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       if (this.params && this.params.id) { | ||||
|         this.id = this.params.id | ||||
|         this.getInfo(this.params.id) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getInfo (id) { | ||||
|         this.instance.post(`/app/apppreventionreturntopovertyriskperson/queryDetailById?id=${id}`).then(res => { | ||||
|           if (res.code === 0) { | ||||
|             this.info = res.data | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       cancel (isRefresh) { | ||||
|         this.$emit('change', { | ||||
|           type: 'List', | ||||
|           isRefresh: !!isRefresh | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| </style> | ||||
							
								
								
									
										179
									
								
								packages/work/AppRiskWarning/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								packages/work/AppRiskWarning/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,179 @@ | ||||
| <template> | ||||
|   <ai-list class="notice"> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="风险告知" isShowBottomBorder></ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-search-bar bottomBorder> | ||||
|         <template #left> | ||||
|           <ai-select | ||||
|             v-model="search.riskType" | ||||
|             clearable | ||||
|             placeholder="请选择风险类型" | ||||
|             :selectList="dict.getDict('fpRiskType')" | ||||
|             @change="search.current = 1, getList()"> | ||||
|           </ai-select> | ||||
|           <el-button icon="iconfont iconAdd" type="primary" size="small" @click="toAdd('')">添加 </el-button> | ||||
|         </template> | ||||
|         <template #right> | ||||
|           <el-input | ||||
|             v-model="search.name" | ||||
|             size="small" | ||||
|             placeholder="姓名/备注说明/操作人" | ||||
|             clearable | ||||
|             v-throttle="() => {search.current = 1, getList()}" | ||||
|             @clear="search.current = 1, search.name = '', getList()" | ||||
|             suffix-icon="iconfont iconSearch"> | ||||
|           </el-input> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <ai-search-bar bottomBorder style="margin-top: 12px;"> | ||||
|         <template #left> | ||||
|           <el-button icon="iconfont iconDelete" size="small" @click="removeAll" :disabled="ids.length == 0">删除 </el-button> | ||||
|         </template> | ||||
|         <template #right> | ||||
|           <ai-download :instance="instance" url="/app/apppreventionreturntopovertyriskperson/export" :params="params" fileName="风险预警人员" :disabled="tableData.length == 0"> | ||||
|             <el-button icon="iconfont iconExported" :disabled="tableData.length == 0">导出</el-button> | ||||
|           </ai-download> | ||||
|           <ai-import :instance="instance" :dict="dict" type="apppreventionreturntopovertyriskperson" name="风险预警人员" @success="getList()"> | ||||
|             <el-button icon="iconfont iconImport">导入</el-button> | ||||
|           </ai-import> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <ai-table | ||||
|         :tableData="tableData" | ||||
|         :col-configs="colConfigs" | ||||
|         :total="total" | ||||
|         style="margin-top: 12px;" | ||||
|         :current.sync="search.current" | ||||
|         :size.sync="search.size" | ||||
|         @selection-change="(v) => (ids = v.map((e) => e.id))" | ||||
|         @getList="getList"> | ||||
|         <el-table-column slot="tags" label="标签"> | ||||
|           <template slot-scope="{ row }"> | ||||
|             <div class="table-tags"> | ||||
|               <el-tag type="info" v-for="(item, index) in row.tags" size="small" :key="index">{{ item }}</el-tag> | ||||
|             </div> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column slot="options" width="120px" fixed="right" label="操作" align="center"> | ||||
|           <div class="table-options" slot-scope="{ row }"> | ||||
|             <el-button type="text" @click="toDetail(row.id)">详情</el-button> | ||||
|             <el-button type="text" @click="remove(row.id)">删除</el-button> | ||||
|           </div> | ||||
|         </el-table-column> | ||||
|       </ai-table> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import { mapState } from 'vuex' | ||||
|   export default { | ||||
|     name: 'List', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object | ||||
|     }, | ||||
|  | ||||
|     data() { | ||||
|       return { | ||||
|         search: { | ||||
|           current: 1, | ||||
|           size: 10, | ||||
|           title: '', | ||||
|           riskType: '' | ||||
|         }, | ||||
|         ids: [], | ||||
|         total: 10, | ||||
|         colConfigs: [ | ||||
|           { type: 'selection' }, | ||||
|           {prop: 'name', label: '姓名', align: 'left'}, | ||||
|           {prop: 'phone', label: '联系方式', align: 'center' }, | ||||
|           {prop: 'riskType', label: '风险类型', align: 'center', formart: v => this.dict.getLabel('fpRiskType', v) }, | ||||
|           {prop: 'areaName', label: '所属区域', align: 'center' }, | ||||
|           {prop: 'remarks', label: '备注说明', align: 'center' }, | ||||
|           {prop: 'createTime', label: '操作时间', align: 'center'}, | ||||
|           {prop: 'createUserName', label: '操作人', align: 'center' }, | ||||
|           {prop: 'departmentName', label: '归口部门', align: 'center' }, | ||||
|           {slot: 'options', label: '操作'} | ||||
|         ], | ||||
|         tableData: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       ...mapState(['user']), | ||||
|  | ||||
|       params () { | ||||
|         if (this.ids.length) { | ||||
|           return { | ||||
|             ids: this.ids | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         return this.search | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       this.dict.load('fpRiskType').then(() => { | ||||
|         this.getList() | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getList() { | ||||
|         this.instance.post(`/app/apppreventionreturntopovertyriskperson/list`, null, { | ||||
|           params: { | ||||
|             ...this.search, | ||||
|             listType: 1 | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.tableData = res.data.records | ||||
|             this.total = res.data.total | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       removeAll () { | ||||
|         var id = this.ids.join(',') | ||||
|         this.remove(id) | ||||
|       }, | ||||
|  | ||||
|       remove(id) { | ||||
|         this.$confirm('确定删除该数据?').then(() => { | ||||
|           this.instance.post(`/app/apppreventionreturntopovertyriskperson/delete?ids=${id}`).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.$message.success('删除成功!') | ||||
|               this.getList() | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       toDetail (id) { | ||||
|         this.$emit('change', { | ||||
|           type: 'Detail', | ||||
|           params: { | ||||
|             id: id || '' | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       toAdd(id) { | ||||
|         this.$emit('change', { | ||||
|           type: 'Add', | ||||
|           params: { | ||||
|             id: id || '' | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| </style> | ||||
							
								
								
									
										66
									
								
								packages/work/AppVisitToVerify/AppVisitToVerify.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								packages/work/AppVisitToVerify/AppVisitToVerify.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| <template> | ||||
|   <div class="doc-circulation ailist-wrapper"> | ||||
|     <keep-alive :include="['List']"> | ||||
|       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> | ||||
|     </keep-alive> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import List from './components/List' | ||||
|   import Detail from './components/Detail' | ||||
|  | ||||
|   export default { | ||||
|     name: 'AppVisitToVerify', | ||||
|     label: '走访核实', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         component: 'List', | ||||
|         params: {}, | ||||
|         include: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     components: { | ||||
|       List, | ||||
|       Detail | ||||
|     }, | ||||
|  | ||||
|     mounted () { | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       onChange (data) { | ||||
|         if (data.type === 'Detail') { | ||||
|           this.component = 'Detail' | ||||
|           this.params = data.params | ||||
|         } | ||||
|  | ||||
|         if (data.type === 'List') { | ||||
|           this.component = 'List' | ||||
|           this.params = data.params | ||||
|  | ||||
|           this.$nextTick(() => { | ||||
|             if (data.isRefresh) { | ||||
|               this.$refs.component.getList() | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss"> | ||||
|   .doc-circulation { | ||||
|     height: 100%; | ||||
|     background: #F3F6F9; | ||||
|     overflow: auto; | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										182
									
								
								packages/work/AppVisitToVerify/components/Detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								packages/work/AppVisitToVerify/components/Detail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,182 @@ | ||||
| <template> | ||||
|   <ai-detail> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)"> | ||||
|         <template #rightBtn> | ||||
|           <el-button | ||||
|             size="small" | ||||
|             type="primary" | ||||
|             @click="isShow = true" | ||||
|             v-if="(checkType === '1' || checkType === '2') && info.status !== '3' && info.status !== '2'"> | ||||
|             {{ checkType === '1' ? '走访核实' : '处理结果' }} | ||||
|           </el-button> | ||||
|         </template> | ||||
|       </ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-card title="基本信息"> | ||||
|         <template #content> | ||||
|           <ai-wrapper> | ||||
|             <ai-info-item label="姓名" :value="info.name"></ai-info-item> | ||||
|             <ai-info-item label="联系方式" :value="info.phone"></ai-info-item> | ||||
|             <ai-info-item label="风险类型" :value="dict.getLabel('fpRiskType', info.riskType)"></ai-info-item> | ||||
|             <ai-info-item label="身份证号" :value="info.idNumber"></ai-info-item> | ||||
|             <ai-info-item label="所在地区" :value="info.areaName"></ai-info-item> | ||||
|             <ai-info-item label="联系地址" isLine :value="info.address"></ai-info-item> | ||||
|             <ai-info-item label="备注说明" isLine :value="info.remarks"></ai-info-item> | ||||
|             <ai-info-item label="操作人" :value="info.createUserName"></ai-info-item> | ||||
|             <ai-info-item label="归口部门" :value="info.departmentName"></ai-info-item> | ||||
|             <ai-info-item label="操作时间" isLine :value="info.createTime"></ai-info-item> | ||||
|             <ai-info-item label="状态" isLine :value="dict.getLabel('fpRiskPersonStatus', info.status)"></ai-info-item> | ||||
|           </ai-wrapper> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|       <ai-card title="走访核实" v-if="info.visitTime"> | ||||
|         <template #content> | ||||
|           <ai-wrapper> | ||||
|             <ai-info-item label="处理意见" :value="info.visitOpinion"></ai-info-item> | ||||
|             <ai-info-item label="处理时间" :value="info.visitTime"></ai-info-item> | ||||
|             <ai-info-item label="业务员" :value="info.visitUserName"></ai-info-item> | ||||
|             <ai-info-item label="照片" isLine> | ||||
|               <ai-uploader | ||||
|                 disabled | ||||
|                 :instance="instance" | ||||
|                 v-model="info.visitFiles" | ||||
|                 :limit="9"> | ||||
|               </ai-uploader> | ||||
|             </ai-info-item> | ||||
|           </ai-wrapper> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|       <ai-card title="处理结果" v-if="info.auditTime"> | ||||
|         <template #content> | ||||
|           <ai-wrapper> | ||||
|             <ai-info-item label="处理意见" :value="info.auditOpinion"></ai-info-item> | ||||
|             <ai-info-item label="处理时间" :value="info.auditTime"></ai-info-item> | ||||
|             <ai-info-item label="业务员" :value="info.auditUserName"></ai-info-item> | ||||
|             <ai-info-item label="照片" isLine> | ||||
|               <ai-uploader | ||||
|                 disabled | ||||
|                 :instance="instance" | ||||
|                 v-model="info.auditFiles" | ||||
|                 :limit="9"> | ||||
|               </ai-uploader> | ||||
|             </ai-info-item> | ||||
|           </ai-wrapper> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|       <ai-dialog | ||||
|         :visible.sync="isShow" | ||||
|         width="800px" | ||||
|         @close="onClose" | ||||
|         title="审核" | ||||
|         @onConfirm="onConfirm"> | ||||
|         <el-form class="ai-form" label-width="110px" :model="form" ref="form"> | ||||
|           <el-form-item label="处理意见" prop="operation" style="width: 100%;" :rules="[{ required: true, message: '请选择处理意见' }]"> | ||||
|             <el-radio-group v-model="form.operation"> | ||||
|               <el-radio label="0" v-if="checkType === '1'">疑似风险</el-radio> | ||||
|               <el-radio label="1" v-if="checkType === '2'">纳入监测</el-radio> | ||||
|               <el-radio label="2">解除风险</el-radio> | ||||
|             </el-radio-group> | ||||
|             <!-- <span v-if="info.status != '2'">解除风险</span> | ||||
|             <span v-if="info.status === '0' && checkType === '1'">疑似风险</span> | ||||
|             <span v-if="info.status !== '2' && checkType === '2'">纳入监测</span> --> | ||||
|           </el-form-item> | ||||
|           <el-form-item label="备注说明" prop="opinion" style="width: 100%;" :rules="[{ required: true, message: '请输入备注说明' }]"> | ||||
|             <el-input type="textarea" :rows="5" :maxlength="200" v-model="form.opinion" clearable placeholder="请输入备注说明" show-word-limit></el-input> | ||||
|           </el-form-item> | ||||
|           <el-form-item label="照片" prop="files" style="width: 100%;"> | ||||
|             <ai-uploader | ||||
|               :instance="instance" | ||||
|               v-model="form.files" | ||||
|               :limit="9"> | ||||
|               <template slot="tips"> | ||||
|                 <p>最多上传9张图片,单个文件最大10MB,支持jpg、jpeg、png格式</p> | ||||
|               </template> | ||||
|             </ai-uploader> | ||||
|           </el-form-item> | ||||
|         </el-form> | ||||
|       </ai-dialog> | ||||
|     </template> | ||||
|   </ai-detail> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   export default { | ||||
|     name: 'Detail', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       params: Object | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         info: {}, | ||||
|         id: '', | ||||
|         checkType: '', | ||||
|         form: { | ||||
|           opinion: '', | ||||
|           operation: '', | ||||
|           ids: '' | ||||
|         }, | ||||
|         isShow: false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       if (this.params && this.params.id) { | ||||
|         this.id = this.params.id | ||||
|         this.getInfo(this.params.id) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getInfo (id) { | ||||
|         this.instance.post(`/app/apppreventionreturntopovertyriskperson/queryDetailById?id=${id}`).then(res => { | ||||
|           if (res.code === 0) { | ||||
|             this.info = res.data | ||||
|           } | ||||
|         }) | ||||
|         this.instance.post('/app/appgirdmemberinfo/checkLogOnUser').then((res) => { | ||||
|           if (res.code == 0) { | ||||
|             this.checkType = res.data.checkType | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       onClose () { | ||||
|         this.form.opinion = '' | ||||
|         this.form.operation = '' | ||||
|       }, | ||||
|  | ||||
|       onConfirm () { | ||||
|         this.$refs.form.validate(v => { | ||||
|           if (v) { | ||||
|             this.instance.post(`/app/apppreventionreturntopovertyriskperson/monitor`, { | ||||
|               ...this.form, | ||||
|               ids: [this.params.id] | ||||
|             }).then(res => { | ||||
|               if (res.code == 0) { | ||||
|                 this.$message.success('操作成功!') | ||||
|                 this.isShow = false | ||||
|                 this.getInfo(this.params.id) | ||||
|               } | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       cancel () { | ||||
|         this.$emit('change', { | ||||
|           type: 'List', | ||||
|           isRefresh: true | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| </style> | ||||
							
								
								
									
										199
									
								
								packages/work/AppVisitToVerify/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								packages/work/AppVisitToVerify/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,199 @@ | ||||
| <template> | ||||
|   <ai-list class="notice"> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="走访核实" isShowBottomBorder :isShowArea="true" v-model="search.areaId" :instance="instance" @change="getList"></ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-search-bar> | ||||
|         <template #left> | ||||
|           <ai-select | ||||
|             v-model="search.riskType" | ||||
|             clearable | ||||
|             placeholder="请选择风险类型" | ||||
|             :selectList="dict.getDict('fpRiskType')" | ||||
|             @change="search.current = 1, getList()"> | ||||
|           </ai-select> | ||||
|           <ai-select | ||||
|             v-model="search.status" | ||||
|             clearable | ||||
|             placeholder="请选择状态" | ||||
|             :selectList="dict.getDict('fpRiskPersonStatus')" | ||||
|             @change="search.current = 1, getList()"> | ||||
|           </ai-select> | ||||
|           <el-button size="small" v-if="checkType === '2'" :disabled="addIds.length == 0" type="primary" @click="addMonitor">纳入监测</el-button> | ||||
|           <el-button size="small" v-if="checkType !== '0'" :disabled="removeIds.length == 0" @click="removeAll">解除风险</el-button> | ||||
|         </template> | ||||
|         <template #right> | ||||
|           <el-input | ||||
|             v-model="search.name" | ||||
|             size="small" | ||||
|             placeholder="姓名/备注说明/操作人" | ||||
|             clearable | ||||
|             v-throttle="() => {search.current = 1, getList()}" | ||||
|             @clear="search.current = 1, search.name = '', getList()" | ||||
|             suffix-icon="iconfont iconSearch"> | ||||
|           </el-input> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <ai-table | ||||
|         :tableData="tableData" | ||||
|         :col-configs="colConfigs" | ||||
|         :total="total" | ||||
|         style="margin-top: 12px;" | ||||
|         :current.sync="search.current" | ||||
|         :size.sync="search.size" | ||||
|         @selection-change="(v) => chooseList = v" | ||||
|         @getList="getList"> | ||||
|         <el-table-column slot="options" width="90px" fixed="right" label="操作" align="center"> | ||||
|           <div class="table-options" slot-scope="{ row }"> | ||||
|             <el-button type="text" @click="toDetail(row.id)">详情</el-button> | ||||
|           </div> | ||||
|         </el-table-column> | ||||
|       </ai-table> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import { mapState } from 'vuex' | ||||
|   export default { | ||||
|     name: 'List', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object | ||||
|     }, | ||||
|  | ||||
|     data() { | ||||
|       return { | ||||
|         search: { | ||||
|           current: 1, | ||||
|           size: 10, | ||||
|           name: '', | ||||
|           areaId: '', | ||||
|           riskType: '', | ||||
|           status: '' | ||||
|         }, | ||||
|         chooseList: [], | ||||
|         total: 10, | ||||
|         checkType: '', | ||||
|         tableData: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       ...mapState(['user']), | ||||
|  | ||||
|       colConfigs () { | ||||
|         return [ | ||||
|           { type: 'selection' }, | ||||
|           { prop: 'name', label: '姓名', align: 'left'}, | ||||
|           { prop: 'phone', label: '联系方式', align: 'center' }, | ||||
|           { prop: 'riskType', label: '风险类型', align: 'center', formart: v => this.dict.getLabel('fpRiskType', v) }, | ||||
|           { prop: 'areaName', label: '所属区域', align: 'center' }, | ||||
|           { prop: 'remarks', label: '备注说明', align: 'center' }, | ||||
|           { prop: 'status', label: '状态', align: 'center', formart: v => this.dict.getLabel('fpRiskPersonStatus', v) }, | ||||
|           { prop: 'createTime', label: '处理时间', align: 'center' }, | ||||
|           { prop: 'createUserName', label: '处理人', align: 'center' } | ||||
|         ] | ||||
|       }, | ||||
|  | ||||
|       addIds () { | ||||
|         if (!this.chooseList.length) { | ||||
|           return [] | ||||
|         } | ||||
|  | ||||
|         return this.chooseList.filter(v => v.status === '0' || v.status === '1').map(v => v.id) | ||||
|       }, | ||||
|  | ||||
|       removeIds () { | ||||
|         if (!this.chooseList.length) { | ||||
|           return [] | ||||
|         } | ||||
|  | ||||
|         return this.chooseList.filter(v => v.status === '0' || v.status === '1').map(v => v.id) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       this.search.areaId = this.user.info.areaId | ||||
|       this.dict.load('fpRiskType', 'fpRiskPersonStatus').then(() => { | ||||
|         this.getList() | ||||
|       }) | ||||
|  | ||||
|       this.getInfo() | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getList() { | ||||
|         this.instance.post(`/app/apppreventionreturntopovertyriskperson/list`, null, { | ||||
|           params: { | ||||
|             ...this.search | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.tableData = res.data.records | ||||
|             this.total = res.data.total | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       getInfo () { | ||||
|         this.instance.post('/app/appgirdmemberinfo/checkLogOnUser').then((res) => { | ||||
|           if (res.code == 0) { | ||||
|             this.checkType = res.data.checkType | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       addMonitor () { | ||||
|         this.$confirm('是否纳入监测对象?').then(() => { | ||||
|           this.instance.post(`/app/apppreventionreturntopovertyriskperson/monitor`, { | ||||
|             ids: this.addIds, | ||||
|             operation: 1 | ||||
|           }).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.$message.success('操作成功!') | ||||
|               this.getList() | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       removeAll () { | ||||
|         this.$confirm('确定删除该数据?').then(() => { | ||||
|           this.instance.post(`/app/apppreventionreturntopovertyriskperson/monitor`, { | ||||
|             ids: this.removeIds, | ||||
|             operation: 2 | ||||
|           }).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.$message.success('操作成功!') | ||||
|               this.getList() | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       toDetail (id) { | ||||
|         this.$emit('change', { | ||||
|           type: 'Detail', | ||||
|           params: { | ||||
|             id: id || '' | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       toAdd(id) { | ||||
|         this.$emit('change', { | ||||
|           type: 'Add', | ||||
|           params: { | ||||
|             id: id || '' | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| </style> | ||||
							
								
								
									
										62
									
								
								packages/work/AppVisitVondolence/AppVisitVondolence.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								packages/work/AppVisitVondolence/AppVisitVondolence.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| <template> | ||||
|   <div class="AppVisitVondolence"> | ||||
|     <keep-alive :include="['List']"> | ||||
|       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> | ||||
|     </keep-alive> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import List from './components/List.vue' | ||||
|   import Detail from './components/Detail.vue' | ||||
|  | ||||
|   export default { | ||||
|     name: 'AppVisitVondolence', | ||||
|     label: '走访慰问', | ||||
|  | ||||
|     components: { | ||||
|       List, | ||||
|       Detail | ||||
|     }, | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       permissions: Function | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         component: 'List', | ||||
|         params: {} | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       onChange (data) { | ||||
|         if (data.type === 'Detail') { | ||||
|           this.component = 'Detail' | ||||
|           this.isShowDetail = true | ||||
|           this.params = data.params | ||||
|         } | ||||
|  | ||||
|         if (data.type === 'list') { | ||||
|           this.component = 'List' | ||||
|           this.params = data.params | ||||
|  | ||||
|           this.$nextTick(() => { | ||||
|             if (data.isRefresh) { | ||||
|               this.$refs.component.getList() | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .AppVisitVondolence { | ||||
|     height: 100%; | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										89
									
								
								packages/work/AppVisitVondolence/components/Detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								packages/work/AppVisitVondolence/components/Detail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
|  <template> | ||||
|   <ai-detail> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="详情" isShowBack isShowBottomBorder @onBackClick="cancel(true)"> | ||||
|       </ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-card title="基本信息"> | ||||
|         <template #content> | ||||
|           <ai-wrapper | ||||
|             label-width="120px"> | ||||
|             <ai-info-item label="标题" :value="info.title" isLine></ai-info-item> | ||||
|             <ai-info-item label="描述" isLine :value="info.description"></ai-info-item> | ||||
|             <ai-info-item label="图片" isLine :value="info.idNumber"> | ||||
|               <ai-uploader v-model="info.images" :instance="instance" :limit="9" disabled/> | ||||
|             </ai-info-item> | ||||
|             <ai-info-item label="慰问对象" :value="info.name"></ai-info-item> | ||||
|             <ai-info-item label="对象类型" :value="info.type"></ai-info-item> | ||||
|             <ai-info-item label="现实状态" isLine :value="dict.getLabel('visitCondolenceReality', info.reality)"></ai-info-item> | ||||
|             <ai-info-item label="走访人" :value="info.createUserName"></ai-info-item> | ||||
|             <ai-info-item label="走访时间" :value="info.visitTime"></ai-info-item> | ||||
|           </ai-wrapper> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|     </template> | ||||
|   </ai-detail> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   export default { | ||||
|     name: 'Detail', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       params: Object | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         info: {}, | ||||
|         id: '' | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       this.id = this.params.id | ||||
|       this.dict.load(['visitCondolenceReality']).then(() => { | ||||
|         this.getDictList() | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getInfo (id) { | ||||
|         this.instance.post(`/app/appvisitvondolence/queryDetailById?id=${id}`).then(res => { | ||||
|           if (res.code === 0) { | ||||
|             this.info = res.data | ||||
|             this.info.images = res.data.images ? JSON.parse(res.data.images) : [] | ||||
|             this.info.type = this.dictList.filter(v => v.dictValue === res.data.applicationId)[0].dictName | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       getDictList () { | ||||
|         this.instance.post(`/app/appapplicationinfo/queryApplicationListByType`).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.dictList = res.data.map(v => { | ||||
|               return { | ||||
|                 dictValue: v.id, | ||||
|                 dictName: v.applicationName | ||||
|               } | ||||
|             }) | ||||
|             this.getInfo(this.params.id) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       cancel (isRefresh) { | ||||
|         this.$emit('change', { | ||||
|           type: 'list', | ||||
|           isRefresh: !!isRefresh | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| </style> | ||||
							
								
								
									
										155
									
								
								packages/work/AppVisitVondolence/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								packages/work/AppVisitVondolence/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,155 @@ | ||||
| <template> | ||||
|   <ai-list class="list"> | ||||
|     <ai-title slot="title" title="走访慰问" isShowBottomBorder></ai-title> | ||||
|     <template slot="content"> | ||||
|       <div class="content"> | ||||
|         <ai-search-bar bottomBorder> | ||||
|           <template #left> | ||||
|             <ai-select | ||||
|               v-model="search.applicationId" | ||||
|               clearable | ||||
|               placeholder="请选择对象类型" | ||||
|               :selectList="dictList" | ||||
|               @change="search.current = 1, getList()"> | ||||
|             </ai-select> | ||||
|             <ai-select | ||||
|               v-model="search.reality" | ||||
|               clearable | ||||
|               placeholder="请选择现实状态" | ||||
|               :selectList="dict.getDict('visitCondolenceReality')" | ||||
|               @change="search.current = 1, getList()"> | ||||
|             </ai-select> | ||||
|           </template> | ||||
|           <template #right> | ||||
|             <el-input | ||||
|               v-model="search.title" | ||||
|               size="small" | ||||
|               placeholder="标题、慰问对象、走访人" | ||||
|               clearable | ||||
|               v-throttle="() => {search.current = 1, getList()}" | ||||
|               @clear="search.current = 1, search.title = '', getList()" | ||||
|               suffix-icon="iconfont iconSearch"> | ||||
|             </el-input> | ||||
|           </template> | ||||
|         </ai-search-bar> | ||||
|         <ai-table | ||||
|           :tableData="tableData" | ||||
|           :col-configs="colConfigs" | ||||
|           :total="total" | ||||
|           style="margin-top: 16px;" | ||||
|           :current.sync="search.current" | ||||
|           :size.sync="search.size" | ||||
|           @getList="getList"> | ||||
|           <el-table-column slot="options" width="120px" fixed="right" label="操作" align="center"> | ||||
|             <template slot-scope="{ row }"> | ||||
|               <div class="table-options"> | ||||
|                 <el-button type="text" @click="toDetail(row.id)">详情</el-button> | ||||
|                 <el-button type="text" @click="remove(row.id)">删除</el-button> | ||||
|               </div> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|         </ai-table> | ||||
|       </div> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import { mapState } from 'vuex' | ||||
|   export default { | ||||
|     name: 'List', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         search: { | ||||
|           current: 1, | ||||
|           size: 10, | ||||
|           title: '', | ||||
|           reality: '', | ||||
|           menuLevel3Name: '' | ||||
|         }, | ||||
|         dictList: [], | ||||
|         info: {}, | ||||
|         colConfigs: [ | ||||
|           { prop: 'title', label: '标题' }, | ||||
|           { prop: 'visitTime', align: 'center', label: '走访时间' }, | ||||
|           { prop: 'name', align: 'center', label: '慰问对象' }, | ||||
|           { prop: 'menuLevel3Name', align: 'center', label: '对象类型' }, | ||||
|           { prop: 'reality', align: 'center', label: '现实状态', formart: v => v ? this.dict.getLabel('visitCondolenceReality', v) : '-' }, | ||||
|           { prop: 'createUserName', align: 'center', label: '走访人' } | ||||
|         ], | ||||
|         tableData: [], | ||||
|         total: 0 | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       ...mapState(['user']) | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       this.getDictList() | ||||
|       this.dict.load(['visitCondolenceReality']).then(() => { | ||||
|         this.getList() | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getList () { | ||||
|         this.instance.post(`/app/appvisitvondolence/list`, null, { | ||||
|           params: { | ||||
|             ...this.search | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.tableData = res.data.records | ||||
|             this.total = res.data.total | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       getDictList () { | ||||
|         this.instance.post(`/app/appapplicationinfo/queryApplicationListByType`).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.dictList = res.data.map(v => { | ||||
|               return { | ||||
|                 dictValue: v.id, | ||||
|                 dictName: v.applicationName | ||||
|               } | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       remove(id) { | ||||
|         this.$confirm('确定删除该数据?').then(() => { | ||||
|           this.instance.post(`/app/appvisitvondolence/delete?ids=${id}`).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.$message.success('删除成功!') | ||||
|               this.getList() | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       toDetail (id) { | ||||
|         this.$emit('change', { | ||||
|           type: 'Detail', | ||||
|           params: { | ||||
|             id: id || '' | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
|   .list { | ||||
|   } | ||||
| </style> | ||||
| @@ -0,0 +1,94 @@ | ||||
| <template> | ||||
|   <section class="AppApprovalManage"> | ||||
|     <ai-list v-if="showList"> | ||||
|       <template slot="title"> | ||||
|         <ai-title title="审批管理" :isShowBottomBorder="false"/> | ||||
|       </template> | ||||
|       <template slot="tabs"> | ||||
|         <el-tabs class="tabs-page" v-model="currIndex"> | ||||
|           <el-tab-pane v-for="(tab,i) in tabs" :key="i" :label="tab.label" :name="String(i)"> | ||||
|             <component :is="tab.comp" v-if="currIndex==i" :ref="currIndex" :instance="instance" :dict="dict" | ||||
|                        :permissions="permissions" :listType="tab.value" @goPage="goPage"/> | ||||
|           </el-tab-pane> | ||||
|         </el-tabs> | ||||
|       </template> | ||||
|     </ai-list> | ||||
|     <component v-if="!showList" :is="currentPage" :instance="instance" :listType="currentTab.value" :dict="dict" | ||||
|                :permissions="permissions" :detail="detail" @goBack="goBack"></component> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import forMyApproval from "./components/forMyApproval"; | ||||
|   import approvalDetail from "./components/approvalDetail"; | ||||
|  | ||||
|   export default { | ||||
|     name: "AppApprovalManage", | ||||
|     label: "审批管理", | ||||
|     components: {approvalDetail}, | ||||
|     provide() { | ||||
|       return { | ||||
|         approval: this | ||||
|       } | ||||
|     }, | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       permissions: Function | ||||
|     }, | ||||
|     data() { | ||||
|       return { | ||||
|         currIndex: '0', | ||||
|         showList: true, | ||||
|         currentPage: "", | ||||
|         detail: {}, | ||||
|       } | ||||
|     }, | ||||
|     computed: { | ||||
|       tabs() { | ||||
|         return [ | ||||
|           { | ||||
|             label: "待我审批", name: "forMyApproval", value: "0", comp: forMyApproval, detail: approvalDetail, | ||||
|             permission: "" | ||||
|           }, | ||||
|           { | ||||
|             label: "我已审批", name: "forMyApproval", value: "1", comp: forMyApproval, detail: approvalDetail, | ||||
|             permission: "" | ||||
|           }, | ||||
|           { | ||||
|             label: "抄送我的", name: "forMyApproval", value: "3", comp: forMyApproval, detail: approvalDetail, | ||||
|             permission: "" | ||||
|           }, | ||||
|           { | ||||
|             label: "超时督办", name: "forMyApproval", value: "4", comp: forMyApproval, detail: approvalDetail, | ||||
|             permission: "" | ||||
|           }, | ||||
|         ] | ||||
|       }, | ||||
|       currentTab() { | ||||
|         return this.tabs[this.currIndex] || {} | ||||
|       } | ||||
|     }, | ||||
|     methods: { | ||||
|       goPage(obj) { | ||||
|         this.currentPage = this.tabs[Number(this.currIndex)][obj.key]; | ||||
|         obj.row && (this.detail = obj.row) | ||||
|         this.showList = false; | ||||
|       }, | ||||
|       goBack() { | ||||
|         this.showList = true; | ||||
|         this.$nextTick(() => { | ||||
|           this.$refs[this.currIndex][0].getList(); | ||||
|         }) | ||||
|       }, | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .AppApprovalManage { | ||||
|     width: 100%; | ||||
|     height: 100%; | ||||
|     background-color: #F3F6F9; | ||||
|   } | ||||
| </style> | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,218 @@ | ||||
| <template> | ||||
|   <div class="for-my-approval"> | ||||
|     <ai-list isTabs> | ||||
|       <template #content> | ||||
|         <ai-search-bar> | ||||
|           <template #right> | ||||
|             <el-input | ||||
|               v-model="search.param" | ||||
|               size="small" | ||||
|               placeholder="标题/发起人" | ||||
|               v-throttle="() => {search.current = 1, getList()}" | ||||
|               @clear="reset" | ||||
|               clearable | ||||
|               suffix-icon="iconfont iconSearch"/> | ||||
|           </template> | ||||
|         </ai-search-bar> | ||||
|         <ul class="list-wrap"> | ||||
|           <li v-for="(item,index) in tableData" :key="index" @click="goTo('detail',item)"> | ||||
|             <div class="list-title">{{item.processDefName}}</div> | ||||
|             <div class="info"> | ||||
|               <div class="item"> | ||||
|                 <label>发起人:</label> | ||||
|                 <span>{{item.createUserName}}</span> | ||||
|               </div> | ||||
|               <div class="item"> | ||||
|                 <label>所属部门:</label> | ||||
|                 <span>{{dict.getLabel('hbDepartment',item.department)}}</span> | ||||
|               </div> | ||||
|               <div class="item"> | ||||
|                 <label>所属分类:</label> | ||||
|                 <span>{{item.classificationName}}</span> | ||||
|               </div> | ||||
|               <div class="item"> | ||||
|                 <label>发起时间:</label> | ||||
|                 <span>{{item.createTime|format}}</span> | ||||
|               </div> | ||||
|             </div> | ||||
|             <svgIcon :class-name="icon(item.approvalStatus)" class="svg"></svgIcon> | ||||
|           </li> | ||||
|         </ul> | ||||
|         <div class="no-data" v-if="tableData.length==0"></div> | ||||
|         <el-pagination class="pagination" background :current-page="search.current" @current-change="handleCurrent" | ||||
|                        layout="total,prev, pager, next,sizes, jumper" | ||||
|                        :total="total" | ||||
|                        @size-change="handleSizeChange" | ||||
|                        :page-size="search.size" | ||||
|                        :page-sizes="[10, 20, 50, 100,200]"> | ||||
|         </el-pagination> | ||||
|       </template> | ||||
|     </ai-list> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import svgIcon from "./svgIcon"; | ||||
|   import day from 'dayjs' | ||||
|  | ||||
|   export default { | ||||
|     name: "forMyApproval", | ||||
|     components: {svgIcon}, | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       permissions: Function, | ||||
|       listType: String, | ||||
|     }, | ||||
|     data() { | ||||
|       return { | ||||
|         search: { | ||||
|           param:"", | ||||
|           current: 1, | ||||
|           size: 10, | ||||
|         }, | ||||
|         tableData: [], | ||||
|         total: 0 | ||||
|       } | ||||
|     }, | ||||
|     methods: { | ||||
|       icon(icon) { | ||||
|         if(icon==0){ | ||||
|           return "iconsp_ing" | ||||
|         }else if(icon==1){ | ||||
|           return "iconsp-pass" | ||||
|         }else if(icon==2){ | ||||
|           return "iconsp_refused" | ||||
|         } | ||||
|         return "iconcancel" | ||||
|       }, | ||||
|  | ||||
|       goTo(key = '', row) { | ||||
|         this.$emit('goPage', {key, row}); | ||||
|       }, | ||||
|  | ||||
|       reset() { | ||||
|         this.search.param = "" | ||||
|         this.search.current = 1 | ||||
|         this.search.size = 10 | ||||
|         this.getList() | ||||
|       }, | ||||
|  | ||||
|       handleCurrent(val) { | ||||
|         this.search.current = val; | ||||
|         this.getList(); | ||||
|       }, | ||||
|  | ||||
|       handleSizeChange(val) { | ||||
|         this.search.size = val; | ||||
|         this.getList(); | ||||
|       }, | ||||
|  | ||||
|       getList() { | ||||
|         this.instance.post(`/app/approv-alapply-info/list`,null,{ | ||||
|           params:{ | ||||
|             listType: this.listType, | ||||
|             ...this.search | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res && res.data) { | ||||
|             this.tableData = res.data.records | ||||
|             this.total = res.data.total | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     filters:{ | ||||
|       format(time){ | ||||
|         return time ? day(time).format('YYYY-MM-DD HH:mm') : '-' | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     created(){ | ||||
|       this.dict.load(['hbDepartment']).then(()=>{ | ||||
|         this.getList() | ||||
|       }) | ||||
|     }, | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .for-my-approval { | ||||
|     height: 100%; | ||||
|     background: #f3f6f9; | ||||
|     overflow: auto; | ||||
|  | ||||
|     .list-wrap { | ||||
|       width: 100%; | ||||
|       min-height: 100%; | ||||
|  | ||||
|       li { | ||||
|         width: 100%; | ||||
|         height: 80px; | ||||
|         border-radius: 4px; | ||||
|         border: 1px solid #D8E0E8; | ||||
|         margin-bottom: 8px; | ||||
|         box-sizing: border-box; | ||||
|         padding: 16px 32px; | ||||
|         user-select: none; | ||||
|         cursor: pointer; | ||||
|         position: relative; | ||||
|  | ||||
|         .list-title { | ||||
|           font-size: 16px; | ||||
|           font-weight: 600; | ||||
|           color: #333333; | ||||
|           padding-bottom: 6px; | ||||
|         } | ||||
|  | ||||
|         .info { | ||||
|           width: 90%; | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           justify-content: space-between; | ||||
|  | ||||
|           .item { | ||||
|             width: 30%; | ||||
|             & > label { | ||||
|               color: #666666; | ||||
|             } | ||||
|  | ||||
|             & > span { | ||||
|               color: #333333; | ||||
|             } | ||||
|           } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         .svg { | ||||
|           width: 66px; | ||||
|           height: 61px; | ||||
|           position: absolute; | ||||
|           right: 0; | ||||
|           bottom: 0; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .no-data { | ||||
|       background-size: 120px 120px; | ||||
|       height: 160px; | ||||
|       margin: 48px auto 10px; | ||||
|     } | ||||
|  | ||||
|     .pagination { | ||||
|       box-sizing: border-box; | ||||
|       padding: 24px 0 32px 0; | ||||
|     } | ||||
|  | ||||
|     .iconfont { | ||||
|       user-select: none; | ||||
|       cursor: pointer; | ||||
|     } | ||||
|  | ||||
|     ::v-deep .AiSearchBar { | ||||
|       margin-bottom: 16px; | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
| @@ -0,0 +1,25 @@ | ||||
| <template> | ||||
|   <svg class="icon" aria-hidden="true" v-bind="$attrs"> | ||||
|     <use :xlink:href="iconName"></use> | ||||
|   </svg> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   export default { | ||||
|     name: "svgIcon", | ||||
|     props: { | ||||
|       className: { | ||||
|         type: String, | ||||
|       } | ||||
|     }, | ||||
|     computed: { | ||||
|       iconName() { | ||||
|         return `#${this.className}` | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|  | ||||
| </style> | ||||
| @@ -0,0 +1,186 @@ | ||||
| <template> | ||||
|   <section class="AppCorporateSeal"> | ||||
|       <ai-list v-if="showList"> | ||||
|         <template slot="title"> | ||||
|           <ai-title title="企业印章" :isShowBottomBorder="true"></ai-title> | ||||
|         </template> | ||||
|         <template slot="content"> | ||||
|           <div class="signaturePane"> | ||||
|             <div class="signatureCard" v-for="(op,i) in signatures" :key="i"> | ||||
|               <div class="default" v-if="op.isDefault==1">默认</div> | ||||
|               <div class="body"> | ||||
|                 <el-image :src="`data:image/png;base64,${op.signSealData}`"/> | ||||
|               </div> | ||||
|               <div class="footer"> | ||||
|                 <el-button type="text" :disabled="op.isDefault==1" @click.stop="handleSetDefault(op.id)">设为默认</el-button> | ||||
|                 <hr/> | ||||
|                 <el-button type="text" :disabled="op.isDefault==1||op.signType==1" @click.stop="handleDelete(op.id)">删除 | ||||
|                 </el-button> | ||||
|               </div> | ||||
|             </div> | ||||
|             <div class="signatureCard add" @click="showList=false"> | ||||
|               <ai-icon icon="iconAdd" size="32px"/> | ||||
|               <span>点击添加印章</span> | ||||
|             </div> | ||||
|           </div> | ||||
|         </template> | ||||
|       </ai-list> | ||||
|     <seal-detail v-else/> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import SealDetail from "./sealDetail"; | ||||
|  | ||||
|   export default { | ||||
|     name: "AppCorporateSeal", | ||||
|     label: "企业印章", | ||||
|     components: {SealDetail}, | ||||
|     provide() { | ||||
|       return { | ||||
|         seal: this | ||||
|       } | ||||
|     }, | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       permissions: Function | ||||
|     }, | ||||
|     data() { | ||||
|       return { | ||||
|         signatures: [], | ||||
|         showList: true | ||||
|       } | ||||
|     }, | ||||
|     created() { | ||||
|       this.getSignatures() | ||||
|     }, | ||||
|     methods: { | ||||
|       getSignatures() { | ||||
|         this.instance.post("/app/syssignaccount/list", null, { | ||||
|           params: { | ||||
|             signType: 2, | ||||
|             size: 999 | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res?.data) { | ||||
|             this.signatures = res.data.records | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       handleSetDefault(id) { | ||||
|         this.$confirm("是否设置该印章为默认印章?").then(() => { | ||||
|           this.instance.post("/app/syssignaccount/default", null, {params: {id, listType: 1}}).then(res => { | ||||
|             if (res?.code == 0) { | ||||
|               this.$message.success("设置成功!") | ||||
|               this.getSignatures() | ||||
|             } | ||||
|           }).catch(() => 0) | ||||
|         }) | ||||
|       }, | ||||
|       handleDelete(ids) { | ||||
|         this.$confirm("是否删除该印章?").then(() => { | ||||
|           this.instance.post("/app/syssignaccount/delete", null, {params: {ids}}).then(res => { | ||||
|             if (res?.code == 0) { | ||||
|               this.$message.success("删除成功!") | ||||
|               this.getSignatures() | ||||
|             } | ||||
|           }).catch(() => 0) | ||||
|         }) | ||||
|       }, | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .AppCorporateSeal { | ||||
|     height: 100%; | ||||
|     background: #f3f6f9; | ||||
|  | ||||
|     ::v-deep .signaturePane { | ||||
|       display: flex; | ||||
|       gap: 16px; | ||||
|       flex-wrap: wrap; | ||||
|       padding: 16px; | ||||
|  | ||||
|       .signatureCard { | ||||
|         width: 290px; | ||||
|         height: 258px; | ||||
|         background: #FFFFFF; | ||||
|         border-radius: 4px; | ||||
|         position: relative; | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|         overflow: hidden; | ||||
|  | ||||
|         &.add { | ||||
|           justify-content: center; | ||||
|           align-items: center; | ||||
|           color: #666666; | ||||
|           cursor: pointer; | ||||
|  | ||||
|           .AiIcon { | ||||
|             width: 32px; | ||||
|             height: 32px; | ||||
|             font-size: 32px; | ||||
|           } | ||||
|  | ||||
|           & > span { | ||||
|             font-size: 12px; | ||||
|             line-height: 16px; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .default { | ||||
|           position: absolute; | ||||
|           width: 56px; | ||||
|           height: 24px; | ||||
|           background: #3573FF; | ||||
|           border-radius: 0 0 4px 0; | ||||
|           top: 0; | ||||
|           left: 0; | ||||
|           text-align: center; | ||||
|           line-height: 24px; | ||||
|           font-size: 12px; | ||||
|           color: #FFF; | ||||
|         } | ||||
|  | ||||
|         .body { | ||||
|           min-height: 0; | ||||
|           flex: 1; | ||||
|           display: flex; | ||||
|           justify-content: center; | ||||
|           align-items: center; | ||||
|           padding: 50px; | ||||
|           cursor: pointer; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         .footer { | ||||
|           flex-shrink: 0; | ||||
|           height: 40px; | ||||
|           background: rgba(#30426F, .5); | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           padding: 8px 0; | ||||
|           box-sizing: border-box; | ||||
|  | ||||
|           hr { | ||||
|             height: 100%; | ||||
|             border-color: rgba(#fff, .5); | ||||
|           } | ||||
|  | ||||
|           & > .el-button { | ||||
|             flex: 1; | ||||
|             color: #fff; | ||||
|  | ||||
|             &[disabled] { | ||||
|               color: rgba(#fff, .5); | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| </style> | ||||
							
								
								
									
										233
									
								
								packages/work/processManagement/corporateSeal/sealDetail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								packages/work/processManagement/corporateSeal/sealDetail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,233 @@ | ||||
| <template> | ||||
|   <section class="sealDetail"> | ||||
|     <ai-detail> | ||||
|       <template #title> | ||||
|         <ai-title title="添加企业印章" isShowBack isShowBottomBorder @onBackClick="back"/> | ||||
|       </template> | ||||
|       <template #content> | ||||
|         <el-form size="small" ref="SealForm" :model="form" :rules="rules" label-suffix=":" label-width="160px"> | ||||
|           <ai-title title="单位信息" isShowBottomBorder/> | ||||
|           <el-form-item label="单位名称" prop="organizeName"> | ||||
|             <el-input clearable v-model="form.organizeName" placeholder="请输入..." maxlength="25" show-word-limit/> | ||||
|           </el-form-item> | ||||
|           <el-form-item label="单位类型" prop="organizeType"> | ||||
|             <el-select clearable v-model="form.organizeType" placeholder="请输入..."> | ||||
|               <el-option v-for="(op,i) in $dict.getDict('organizeType')" :key="i" :value="op.dictValue" | ||||
|                          :label="op.dictName"/> | ||||
|             </el-select> | ||||
|           </el-form-item> | ||||
|           <div class="flexFillRow"> | ||||
|             <el-form-item label="企业注册类型" prop="organRegType"> | ||||
|               <el-select clearable v-model="form.organRegType" placeholder="请输入..."> | ||||
|                 <el-option v-for="(op,i) in $dict.getDict('organRegType')" :key="i" :value="op.dictValue" | ||||
|                            :label="op.dictName"/> | ||||
|               </el-select> | ||||
|             </el-form-item> | ||||
|             <el-form-item v-if="!!form.organRegType" :label="$dict.getLabel('organRegType',form.organRegType)" | ||||
|                           prop="organCode"> | ||||
|               <el-input clearable v-model="form.organCode" placeholder="请输入..."/> | ||||
|             </el-form-item> | ||||
|             <div v-else/> | ||||
|           </div> | ||||
|           <div class="flexFillRow"> | ||||
|             <el-form-item label="注册类型" prop="registerType"> | ||||
|               <el-select clearable v-model="form.registerType" placeholder="请输入..."> | ||||
|                 <el-option v-for="(op,i) in $dict.getDict('registerType')" :key="i" :value="op.dictValue" | ||||
|                            :label="op.dictName"/> | ||||
|               </el-select> | ||||
|             </el-form-item> | ||||
|             <div/> | ||||
|           </div> | ||||
|           <template v-if="form.registerType==1"> | ||||
|             <div class="flexFillRow"> | ||||
|               <el-form-item label="代理人姓名" prop="agentName"> | ||||
|                 <el-input clearable v-model="form.agentName" placeholder="请输入..."/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="代理人身份证号" prop="agentIdNumber"> | ||||
|                 <el-input clearable v-model="form.agentIdNumber" placeholder="请输入..."/> | ||||
|               </el-form-item> | ||||
|             </div> | ||||
|             <div class="flexFillRow"> | ||||
|               <el-form-item label="代理人手机号" prop="signPhone"> | ||||
|                 <el-input clearable v-model="form.signPhone" placeholder="请输入..."/> | ||||
|               </el-form-item> | ||||
|               <div/> | ||||
|             </div> | ||||
|           </template> | ||||
|           <template v-if="form.registerType==2"> | ||||
|             <div class="flexFillRow"> | ||||
|               <el-form-item label="法人姓名" prop="legalName"> | ||||
|                 <el-input clearable v-model="form.legalName" placeholder="请输入..."/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="法人身份证号" prop="legalIdNumber"> | ||||
|                 <el-input clearable v-model="form.legalIdNumber" placeholder="请输入..."/> | ||||
|               </el-form-item> | ||||
|             </div> | ||||
|             <div class="flexFillRow"> | ||||
|               <el-form-item label="法人手机号" prop="signPhone"> | ||||
|                 <el-input clearable v-model="form.signPhone" placeholder="请输入..."/> | ||||
|               </el-form-item> | ||||
|               <div/> | ||||
|             </div> | ||||
|           </template> | ||||
|           <ai-title title="印章信息" isShowBottomBorder/> | ||||
|           <el-form-item class="sealImageTypes" label="生成印章类型" prop="organizeTemplateType"> | ||||
|             <div v-for="(op,i) in sealImageTypes" :key="i" class="item" @click="form.organizeTemplateType=op.value"> | ||||
|               <el-image :src="op.image" fit="contain"/> | ||||
|               <el-radio :label="op.value" v-model="form.organizeTemplateType">{{ op.name }}</el-radio> | ||||
|             </div> | ||||
|           </el-form-item> | ||||
|           <el-form-item label="横向文内容" prop="htext"> | ||||
|             <el-input clearable v-model="form.htext" placeholder="0-8个字,如合同专用章,财务专用章等" maxlength="8" show-word-limit/> | ||||
|           </el-form-item> | ||||
|           <el-form-item label="下弦文内容" prop="qtext"> | ||||
|             <el-input clearable v-model="form.qtext" placeholder="0-20个字,下弦文是指的贵司公章底部一串防伪数字" maxlength="20" | ||||
|                       show-word-limit/> | ||||
|           </el-form-item> | ||||
|         </el-form> | ||||
|       </template> | ||||
|       <template #footer> | ||||
|         <el-button @click="back">取消</el-button> | ||||
|         <el-button type="primary" @click="handleSubmit" v-loading="loading">提交</el-button> | ||||
|       </template> | ||||
|     </ai-detail> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "sealDetail", | ||||
|   inject: ['seal'], | ||||
|   data() { | ||||
|     return { | ||||
|       form: { | ||||
|         organizeTemplateType: "STAR", | ||||
|         organizeType: "4", | ||||
|         organRegType: "NORMAL", | ||||
|         registerType: "1" | ||||
|       }, | ||||
|       loading: false | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     sealImageTypes() { | ||||
|       return this.$dict.getDict("organizeTemplateType")?.map(e => ({ | ||||
|         image: e.dictColor, | ||||
|         value: e.dictValue, | ||||
|         name: e.dictName | ||||
|       })) || [] | ||||
|     }, | ||||
|     rules() { | ||||
|       return { | ||||
|         organizeName: [{required: true, message: "请填写单位名称"}], | ||||
|         organCode: [{required: true, message: `请填写${this.$dict.getLabel('organRegType', this.form.organRegType)}`}], | ||||
|         legalName: [{required: true, message: "请填写法人姓名"}], | ||||
|         agentName: [{required: true, message: "请填写代理人姓名"}], | ||||
|         organizeTemplateType: [{required: true}], | ||||
|         htext: [{required: true, message: "请填写横向文内容"}], | ||||
|         qtext: [{required: true, message: "请填写下弦文内容"}], | ||||
|         organizeType: [{required: true, message: "请选择单位类型"}], | ||||
|         organRegType: [{required: true, message: "请选择企业注册类型"}], | ||||
|         registerType: [{required: true, message: "请选择注册类型"}], | ||||
|         signPhone: [ | ||||
|           {required: true, message: "请填写手机号码"}, | ||||
|           {pattern: /^1[3456789]\d{9}$/, message: "手机号码格式有误"} | ||||
|         ], | ||||
|         legalIdNumber: [ | ||||
|           {required: true, message: "请填写法人身份证号码"}, | ||||
|           {validator: (r, v, cb) => cb(this.idCardNoUtil.checkIdCardNo(v) ? undefined : "身份证号码格式有误")} | ||||
|         ], | ||||
|         agentIdNumber: [ | ||||
|           {required: true, message: "请填写代理人身份证号码"}, | ||||
|           {validator: (r, v, cb) => cb(this.idCardNoUtil.checkIdCardNo(v) ? undefined : "身份证号码格式有误")} | ||||
|         ], | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.$dict.load("registerType", "organRegType", "organizeType", "organizeTemplateType") | ||||
|   }, | ||||
|   methods: { | ||||
|     back() { | ||||
|       this.seal.showList = true | ||||
|       this.seal.getSignatures() | ||||
|     }, | ||||
|     handleSubmit() { | ||||
|       this.$refs.SealForm.validate(v => { | ||||
|         if (v) { | ||||
|           this.loading = true | ||||
|           this.seal.instance.post("/app/syssignaccount/register", { | ||||
|             userType: 0, | ||||
|             signType: 2, | ||||
|             signPhone: this.form.signPhone, | ||||
|             registerInfo: {...this.form, legalArea: 0}, | ||||
|             style: {...this.form, sealColor: "RED"} | ||||
|           }).then(res => { | ||||
|             this.loading = false | ||||
|             if (res?.code == 0) { | ||||
|               this.$message.success("添加成功!") | ||||
|               this.back() | ||||
|             } | ||||
|           }).catch(() => this.loading = false) | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .sealDetail { | ||||
|   height: inherit; | ||||
|  | ||||
|   ::v-deep .ai-detail__content--wrapper { | ||||
|     .el-form { | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       gap: 24px; | ||||
|     } | ||||
|  | ||||
|     .el-form-item { | ||||
|       margin-bottom: 0; | ||||
|  | ||||
|       .el-select { | ||||
|         width: 100%; | ||||
|       } | ||||
|  | ||||
|       &.sealImageTypes > .el-form-item__content { | ||||
|         display: flex; | ||||
|         gap: 40px; | ||||
|  | ||||
|         .item { | ||||
|           display: flex; | ||||
|           flex-direction: column; | ||||
|           align-items: center; | ||||
|           justify-content: center; | ||||
|           gap: 8px; | ||||
|           cursor: pointer; | ||||
|  | ||||
|           .el-image { | ||||
|             width: 80px; | ||||
|             height: 80px; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .flexFillRow { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|  | ||||
|       & > * { | ||||
|         flex: 1; | ||||
|         min-width: 0; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ::v-deep .ai-detail__footer > .el-button { | ||||
|     width: 92px; | ||||
|     height: 32px; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -0,0 +1,204 @@ | ||||
| <template> | ||||
|   <section class="examination-approval"> | ||||
|     <ai-list v-if="!showList"> | ||||
|       <template #title> | ||||
|         <ai-title title="审批分类" :isShowBottomBorder="true" :instance="instance"></ai-title> | ||||
|       </template> | ||||
|       <template #content> | ||||
|         <ai-search-bar> | ||||
|           <template #left> | ||||
|             <el-button type="primary" icon="iconfont iconAdd" @click="showList = true">添加分类</el-button> | ||||
|           </template> | ||||
|           <template #right> | ||||
|             <el-input | ||||
|               v-model="search.name" | ||||
|               size="small" | ||||
|               placeholder="分类名称/创建人" | ||||
|               v-throttle="() => {search.current = 1, getList()}" | ||||
|               @clear="reset" | ||||
|               clearable | ||||
|               suffix-icon="iconfont iconSearch"/> | ||||
|           </template> | ||||
|         </ai-search-bar> | ||||
|         <ai-table | ||||
|           :tableData="tableData" | ||||
|           :col-configs="colConfigs" | ||||
|           :total="total" | ||||
|           :header-cell-style="{fontWeight:'bold',color:'#333'}" | ||||
|           :current.sync="search.current" | ||||
|           :size.sync="search.size" | ||||
|           @getList="getList"> | ||||
|  | ||||
|           <el-table-column label="是否启用" slot="status" align="center" width="150"> | ||||
|             <template v-slot="{row}"> | ||||
|               <el-switch | ||||
|                 v-model="row.status" | ||||
|                 @change="onChange(row)" active-value="1" inactive-value="0" | ||||
|                 active-color="#5088FF" | ||||
|                 inactive-color="#D0D4DC"> | ||||
|               </el-switch> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|            | ||||
|           <el-table-column label="操作" slot="options" align="center" width="150"> | ||||
|             <template v-slot="{row}"> | ||||
|               <el-button type="text" title="修改" @click="editInfo(row)">修改</el-button> | ||||
|               <el-button type="text" title="删除" @click="deleteInfo(row)">删除</el-button> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|         </ai-table> | ||||
|       </template> | ||||
|     </ai-list> | ||||
|     <addClassification v-else @back="showList=false;row={},getList()" :instance="instance" | ||||
|                        :row="row"></addClassification> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|  | ||||
|   import addClassification from "./components/addClassification"; | ||||
|   import day from 'dayjs' | ||||
|  | ||||
|   export default { | ||||
|     name: "AppExaminationApproval", | ||||
|     label: "审批分类", | ||||
|     components: {addClassification}, | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       permissions: Function | ||||
|     }, | ||||
|     data() { | ||||
|       return { | ||||
|         search: { | ||||
|           current: 1, | ||||
|           size: 10, | ||||
|           name: "", | ||||
|         }, | ||||
|         total: 0, | ||||
|         tableData: [], | ||||
|         row: {}, | ||||
|         showList: false | ||||
|       } | ||||
|     }, | ||||
|     computed: { | ||||
|       colConfigs() { | ||||
|         return [ | ||||
|           { | ||||
|             prop: 'name', | ||||
|             align: 'left', | ||||
|             label: '分类名称', | ||||
|           }, | ||||
|           { | ||||
|             prop: 'desc', | ||||
|             align: 'left', | ||||
|             label: '分类描述', | ||||
|           }, | ||||
|           { | ||||
|             prop: 'createUserName', | ||||
|             align: 'center', | ||||
|             label: '创建人', | ||||
|           }, | ||||
|           { | ||||
|             prop: 'createTime', | ||||
|             align: 'center', | ||||
|             label: '创建日期', | ||||
|           }, | ||||
|           { | ||||
|             prop: 'showIndex', | ||||
|             align: 'center', | ||||
|             label: '排序', | ||||
|           }, | ||||
|           { | ||||
|             slot: 'status', | ||||
|             align: 'center', | ||||
|             label: '是否启用', | ||||
|           }, | ||||
|           { | ||||
|             slot: 'options', | ||||
|             align: 'center', | ||||
|             label: '操作', | ||||
|           }, | ||||
|         ] | ||||
|       }, | ||||
|     }, | ||||
|     methods: { | ||||
|       /** | ||||
|        * 编辑 | ||||
|        * */ | ||||
|       editInfo(row) { | ||||
|         this.row = row | ||||
|         this.showList = true | ||||
|       }, | ||||
|  | ||||
|       /** | ||||
|        * 启用、停用 | ||||
|        */ | ||||
|       onChange(row) { | ||||
|         this.instance.post(`/app/zwspapprovalclassification/enable?id=${row.id}`).then(res => { | ||||
|           if (res?.code == 0) { | ||||
|             this.$message.success(+row.status ? "已启用" : '不启用') | ||||
|             this.getList() | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       reset() { | ||||
|         this.search.name = "" | ||||
|         this.getList() | ||||
|       }, | ||||
|  | ||||
|       getList() { | ||||
|         this.instance.post(`/app/zwspapprovalclassification/list`, null, { | ||||
|           params: { | ||||
|             ...this.search, | ||||
|           }, | ||||
|         }).then(res => { | ||||
|           if (res && res.data) { | ||||
|             this.tableData = res.data.records.map(e => ({ | ||||
|               ...e, | ||||
|               createTime: day(e.createTime).format("YYYY-MM-DD"), | ||||
|             })); | ||||
|             this.total = res.data.total; | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       /** | ||||
|        * 删除 | ||||
|        */ | ||||
|       deleteInfo({id}) { | ||||
|         this.$confirm("是否删除?").then(() => { | ||||
|           this.instance.post(`/app/zwspapprovalclassification/delete?ids=${id}`).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.$message.success("删除成功") | ||||
|               this.getList() | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|     }, | ||||
|  | ||||
|     mounted() { | ||||
|       this.getList() | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .examination-approval { | ||||
|     height: 100%; | ||||
|     background: #f3f6f9; | ||||
|     overflow: auto; | ||||
|  | ||||
|     .iconfont { | ||||
|       user-select: none; | ||||
|       cursor: pointer; | ||||
|     } | ||||
|  | ||||
|     ::v-deep .ai-table { | ||||
|       margin-top: 16px; | ||||
|     } | ||||
|  | ||||
|   } | ||||
| </style> | ||||
| @@ -0,0 +1,197 @@ | ||||
| <template> | ||||
|   <section class="add-classification"> | ||||
|     <ai-detail> | ||||
|       <ai-title slot="title" :title="pageTitle" isShowBack isShowBottomBorder @onBackClick="$emit('back')"/> | ||||
|       <template #content> | ||||
|         <ai-card title="基本信息"> | ||||
|           <template #content> | ||||
|             <el-form :model="form" :rules="rules" ref="addClassification" label-suffix=":" label-width="100px" | ||||
|                      size="small"> | ||||
|               <el-form-item label="分类名称" prop="name"> | ||||
|                 <el-input v-model.trim="form.name" size="small" clearable placeholder="如“社会保障”(限10个字)" :maxlength="10" | ||||
|                           show-word-limit/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="排序" prop="showIndex"> | ||||
|                 <el-input v-model.number="form.showIndex" size="small" clearable placeholder="请输入数字,数字越小排序越前"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="分类描述" prop="desc"> | ||||
|                 <el-input v-model.trim="form.desc" type="textarea" size="small" clearable placeholder="限500个字" | ||||
|                           :maxlength="500" show-word-limit :rows="4"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="分类图标" prop="icon" class="icon-form"> | ||||
|                 <el-upload ref="iconUploader" action="#" :auto-upload="false" :on-change="handleUploadIcon" :limit="1" | ||||
|                            :show-file-list="false"> | ||||
|                   <el-image v-if="!!form.icon" class="el-upload-list__item" :src="form.icon"> | ||||
|                     <i class="el-icon-picture-outline"/> | ||||
|                   </el-image> | ||||
|                   <div v-else class="el-upload--picture-card"><i class="el-icon-plus"/></div> | ||||
|                 </el-upload> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="是否启用" prop="status"> | ||||
|                 <el-radio v-model="form.status" label="1">是</el-radio> | ||||
|                 <el-radio v-model="form.status" label="0">否</el-radio> | ||||
|               </el-form-item> | ||||
|             </el-form> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|       </template> | ||||
|       <template #footer> | ||||
|         <el-button class="btn" @click="$emit('back')">取消</el-button> | ||||
|         <el-button class="btn" type="primary" @click="submit">提交</el-button> | ||||
|       </template> | ||||
|     </ai-detail> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|  | ||||
|   export default { | ||||
|     name: "addClassification", | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       row: Object, | ||||
|     }, | ||||
|     data() { | ||||
|       return { | ||||
|         form: { | ||||
|           id: "", | ||||
|           name: "", | ||||
|           showIndex: "", | ||||
|           desc: "", | ||||
|           icon: "", | ||||
|           status: "1" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     computed: { | ||||
|       pageTitle() { | ||||
|         return this.row?.id ? "编辑分类" : "添加分类" | ||||
|       }, | ||||
|       rules() { | ||||
|         return { | ||||
|           name: [{required: true, message: '请输入分类名称', trigger: 'blur'}], | ||||
|           showIndex: [ | ||||
|             {required: true, message: '请输入排序数字'}, | ||||
|             {min: 1, max: 999, type: "number", message: '排序只能输入1~999之间的整数'}, | ||||
|           ], | ||||
|           desc: [{required: true, message: '请填写描述', trigger: 'blur'}], | ||||
|           icon: [{required: true, message: '请选择分类图标', trigger: 'blur'}], | ||||
|           status: [{required: true, message: '请选择是否启用', trigger: 'change'}], | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     methods: { | ||||
|  | ||||
|       /** | ||||
|        * 提交 | ||||
|        */ | ||||
|       submit() { | ||||
|         this.$refs['addClassification'].validate(valid => { | ||||
|           if (valid) { | ||||
|             this.instance.post(`/app/zwspapprovalclassification/addOrUpdate`, { | ||||
|               ...this.form, | ||||
|               status: Number(this.form.status) | ||||
|             }).then(res => { | ||||
|               if (res.code == 0) { | ||||
|                 this.$message.success(this.row.id ? "编辑成功" : "添加成功") | ||||
|                 this.$emit('back') | ||||
|               } | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       /** | ||||
|        * 获取详情 | ||||
|        */ | ||||
|       getDetail() { | ||||
|         this.instance.post(`/app/zwspapprovalclassification/queryDetailById?id=${this.row.id}`).then(res => { | ||||
|           if (res?.data) { | ||||
|             this.form = res.data | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       /** | ||||
|        * 上传图标 | ||||
|        */ | ||||
|       handleUploadIcon(file) { | ||||
|         let data = new FormData() | ||||
|         data.append("file", file.raw) | ||||
|         this.instance.post(`/admin/file/add`, data).then(res => { | ||||
|           if (res?.data) { | ||||
|             this.form.icon = res.data?.[0].replace(/;.*/, '') | ||||
|           } | ||||
|           this.$refs.iconUploader?.clearFiles() | ||||
|         }).catch(() => this.$refs.iconUploader?.clearFiles()); | ||||
|       } | ||||
|     }, | ||||
|     created() { | ||||
|       if (this.row.id) { | ||||
|         this.getDetail() | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .add-classification { | ||||
|     height: 100%; | ||||
|  | ||||
|     .iconAudit { | ||||
|       font-size: 36px; | ||||
|       color: #3D94FB; | ||||
|     } | ||||
|  | ||||
|     .el-upload-list__item { | ||||
|       width: 80px; | ||||
|       height: 80px; | ||||
|     } | ||||
|  | ||||
|     .icon-form { | ||||
|       ::v-deep .el-form-item__content { | ||||
|         display: flex; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .select-icon { | ||||
|       width: 96px; | ||||
|       height: 28px; | ||||
|       line-height: 0; | ||||
|     } | ||||
|  | ||||
|     .iconfont { | ||||
|       margin-right: 8px; | ||||
|     } | ||||
|  | ||||
|     .icon-style { | ||||
|       display: flex; | ||||
|       flex-wrap: wrap; | ||||
|  | ||||
|       .icon:hover { | ||||
|         border-color: #5088FF; | ||||
|       } | ||||
|  | ||||
|       .icon_color { | ||||
|         border-color: #5088FF; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .icon { | ||||
|       width: 48px; | ||||
|       height: 48px; | ||||
|       border: 1px solid #ddd; | ||||
|       border-radius: 4px; | ||||
|       margin-right: 16px; | ||||
|       margin-bottom: 16px; | ||||
|       cursor: pointer; | ||||
|     } | ||||
|  | ||||
|     .btn { | ||||
|       width: 92px; | ||||
|       height: 32px; | ||||
|  | ||||
|       &:nth-child(2) { | ||||
|         margin-left: 24px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
| @@ -0,0 +1,101 @@ | ||||
| <template> | ||||
|   <section class="AppLeavingMessage"> | ||||
|     <ai-list v-if="!showDetail"> | ||||
|       <template slot="title"> | ||||
|         <ai-title title="群众留言" :isShowBottomBorder="false" :instance="instance" :isShowArea="true" v-model="areaId" @change="changeArea"></ai-title> | ||||
|       </template> | ||||
|       <template slot="tabs"> | ||||
|         <el-tabs v-model="activeName" @tab-click="handleClick" class="tabs-page"> | ||||
|           <el-tab-pane v-for="(item, index) in paneList" :key="index" :label="item.label" :name="item.name"> | ||||
|             <component :is="comp" ref="list" :instance="instance" :dict="dict" :activeName="activeName" @toDetail="toDetail" | ||||
|                        :areaId="areaId"></component> | ||||
|           </el-tab-pane> | ||||
|         </el-tabs> | ||||
|       </template> | ||||
|     </ai-list> | ||||
|     <template v-if="showDetail"> | ||||
|       <message-detail :instance="instance" :dict="dict" :detailId="detailId" @back="showDetail=false"></message-detail> | ||||
|     </template> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import {mapState} from "vuex"; | ||||
|   import AlreadyList from "./components/alreadyList"; | ||||
|   import MessageDetail from "./components/messageDetail"; | ||||
|  | ||||
|   export default { | ||||
|     name: 'AppMassesMessage', | ||||
|     label: "群众留言", | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       permissions: Function, | ||||
|       openim: Function | ||||
|     }, | ||||
|     components: {AlreadyList, MessageDetail}, | ||||
|     data() { | ||||
|       return { | ||||
|         activeName: '0', | ||||
|         comp:"AlreadyList", | ||||
|         paneList: [ | ||||
|           { | ||||
|             label: '待我回复', | ||||
|             name: '0' | ||||
|           }, | ||||
|           { | ||||
|             label: '我已回复', | ||||
|             name: '1' | ||||
|           }, | ||||
|           { | ||||
|             label: '处理完成', | ||||
|             name: '2' | ||||
|           } | ||||
|         ], | ||||
|         showDetail: false, | ||||
|         detailId: '', | ||||
|         oldActiveName: '', | ||||
|         areaId: '', | ||||
|         hideLevel: '' | ||||
|       } | ||||
|     }, | ||||
|     computed: { | ||||
|       ...mapState(['user']) | ||||
|     }, | ||||
|     created() { | ||||
|       this.areaId = this.user.info.areaId | ||||
|       this.hideLevel = this.user.info.areaList.length | ||||
|     }, | ||||
|     methods: { | ||||
|       changeArea() { | ||||
|         this.$nextTick(() => { | ||||
|           this.$refs.list.getAppLeaveMessage() | ||||
|         }) | ||||
|       }, | ||||
|       openIM() { | ||||
|         if (this.openim) this.openim() | ||||
|       }, | ||||
|       handleClick(tab) { | ||||
|         if (this.oldActiveName == this.activeName) { | ||||
|           return | ||||
|         } | ||||
|         this.activeName = tab.name | ||||
|         this.$nextTick(() => { | ||||
|           this.$refs.list[0].getAppLeaveMessage() | ||||
|           this.$refs.list.search = {} | ||||
|           this.oldActiveName = tab.name | ||||
|         }) | ||||
|       }, | ||||
|       toDetail(id) { | ||||
|         this.detailId = id | ||||
|         this.showDetail = true | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
| <style lang="scss" scoped> | ||||
|   .AppLeavingMessage { | ||||
|     height: 100%; | ||||
|     background-color: #f3f6f9; | ||||
|   } | ||||
| </style> | ||||
| @@ -0,0 +1,273 @@ | ||||
| <template> | ||||
|   <section class="already-list"> | ||||
|     <ai-list isTabs> | ||||
|       <template #content> | ||||
|         <ai-search-bar bottomBorder> | ||||
|           <template #right> | ||||
|             <el-input size="small" v-model="search.title" placeholder="标题/编号" | ||||
|                       @keyup.enter.native="page.current=1,getAppLeaveMessage()" | ||||
|                       prefix-icon="iconfont iconSearch" clearable></el-input> | ||||
|             <el-button size="mini" type="primary" icon="iconfont iconSearch" style="margin-left:5px;" | ||||
|                        @click="page.current=1,getAppLeaveMessage()">查询 | ||||
|             </el-button> | ||||
|             <el-button size="mini" icon="el-icon-refresh-right" style="margin-left:5px;" @click="resetSearch"> | ||||
|               重置 | ||||
|             </el-button> | ||||
|           </template> | ||||
|         </ai-search-bar> | ||||
|         <ai-table  :tableData="tableData" | ||||
|                    :col-configs="colConfigs" | ||||
|                    :total="total" | ||||
|                    ref="aitableex" | ||||
|                    :current.sync="search.current" | ||||
|                    :size.sync="search.size" | ||||
|                    @getList="getAppLeaveMessage"> | ||||
|           <el-table-column label="是否公示" slot="isPublic" align="center" width="150"> | ||||
|             <template v-slot="{row}"> | ||||
|               <el-switch v-model="row.isPublic" @change="onChange(row)" active-value="0" inactive-value="1" | ||||
|                          active-color="#D0D4DC" inactive-color="#5088FF"/> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|  | ||||
|           <el-table-column label="操作" slot="options" align="center" width="150"> | ||||
|             <template v-slot="{row}"> | ||||
|               <el-button type="text" title="详情" @click="toDetail(row.id)" v-if="$permissions('app_appleavemessagereply_detail')">详情</el-button> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|         </ai-table> | ||||
|       </template> | ||||
|     </ai-list> | ||||
|  | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapState} from "vuex"; | ||||
| import day from 'dayjs' | ||||
|  | ||||
| export default { | ||||
|   name: "alreadyList", | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function, | ||||
|     activeName: String, | ||||
|     areaId: String | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       tableData: [], | ||||
|       columns: [ | ||||
|         { | ||||
|           label: '留言编号', | ||||
|           prop: 'msgCode', | ||||
|           type: '', | ||||
|           dict: '' | ||||
|         }, | ||||
|         { | ||||
|           label: '留言类型', | ||||
|           prop: 'type', | ||||
|           type: 'select', | ||||
|           dict: 'leaveMessageType' | ||||
|         }, | ||||
|         { | ||||
|           label: '标题', | ||||
|           prop: 'title', | ||||
|           type: '', | ||||
|           dict: '' | ||||
|         }, | ||||
|         { | ||||
|           label: '留言人', | ||||
|           prop: 'leaveName', | ||||
|           type: '', | ||||
|           dict: '' | ||||
|         }, | ||||
|         { | ||||
|           label: '创建时间', | ||||
|           prop: 'createTime', | ||||
|           type: 'time', | ||||
|           dict: '' | ||||
|         }, | ||||
|         { | ||||
|           label: '最后回复时间', | ||||
|           prop: 'lastReplyTime', | ||||
|           type: 'time', | ||||
|           dict: '' | ||||
|         }, | ||||
|         { | ||||
|           label: '处理状态0、待回复1、已回复', | ||||
|           prop: 'status', | ||||
|           type: '', | ||||
|           dict: '' | ||||
|         }, | ||||
|         { | ||||
|           label: '操作', | ||||
|           prop: 'operate', | ||||
|           type: '', | ||||
|           dict: '' | ||||
|         }, | ||||
|       ], | ||||
|       search: { | ||||
|         style: {}, | ||||
|         title: "" | ||||
|       }, | ||||
|       page: { | ||||
|         current: 1, | ||||
|         size: 10, | ||||
|       }, | ||||
|       total: 0, | ||||
|       detailId: '', | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     onChange({id, isPublic}) { | ||||
|       this.instance.post(`/app/appleavemessage/public?id=${id}`).then(res => { | ||||
|         if (res.code == 0) { | ||||
|           console.log(isPublic) | ||||
|           this.$message.success(isPublic == 1 ? "已公示" : "不公示") | ||||
|           this.getAppLeaveMessage() | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     navClick(item) { | ||||
|       this.navStatus = item.status | ||||
|     }, | ||||
|     isPermit(params) { | ||||
|       return this.permissions ? this.permissions(params) : false | ||||
|     }, | ||||
|     resetSearch() { | ||||
|       this.page.current = 1 | ||||
|       this.page.size = 10 | ||||
|       this.columns.map(c => { | ||||
|         if (c.type) this.search[c.prop] = null | ||||
|       }) | ||||
|       Object.keys(this.search).forEach((e) => { | ||||
|         this.search[e] = null; | ||||
|       }) | ||||
|       this.getAppLeaveMessage() | ||||
|     }, | ||||
|     handleCurrentChange(val) { | ||||
|       this.page.current = val | ||||
|       this.getAppLeaveMessage() | ||||
|     }, | ||||
|     handleSizeChange(val) { | ||||
|       this.page.size = val; | ||||
|       this.getAppLeaveMessage(); | ||||
|     }, | ||||
|     getAppLeaveMessage() { | ||||
|       this.search.status = this.activeName | ||||
|       this.search.areaId = this.user.info.areaId | ||||
|       this.instance.post("/app/appleavemessage/list", null, { | ||||
|         params: { | ||||
|           ...this.search, | ||||
|           ...this.page, | ||||
|           areaId: this.areaId | ||||
|         } | ||||
|       }).then(res => { | ||||
|             this.tableData = res.data.records | ||||
|             this.total = res.data.total | ||||
|           } | ||||
|       ) | ||||
|     }, | ||||
|  | ||||
|     addOrUpdateAppLeaveMessage() { | ||||
|       this.instance.post("/app/appleavemessage/addOrUpdate", this.dialog.add).then(() => { | ||||
|             this.getAppLeaveMessage() | ||||
|             this.$message.success("添加或修改成功!") | ||||
|           } | ||||
|       ) | ||||
|     }, | ||||
|     deleteAppLeaveMessage(ids) { | ||||
|       this.$confirm("是否要删除这些账号?", { | ||||
|         type: 'warning' | ||||
|       }).then(() => { | ||||
|         this.instance.post("/app/appleavemessage/delete", null, { | ||||
|           params: { | ||||
|             ids: ids | ||||
|           } | ||||
|         }).then(() => { | ||||
|               this.getAppLeaveMessage() | ||||
|               this.$message.success("删除成功!") | ||||
|             } | ||||
|         ) | ||||
|       }).catch(() => { | ||||
|           } | ||||
|       ) | ||||
|     }, | ||||
|     toDetail(id) { | ||||
|       this.$emit('toDetail', id) | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   filters: { | ||||
|     format(time) { | ||||
|       return time ? day(time).format("YYYY-MM-DD HH:mm") : '-' | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   mounted() { | ||||
|     if (this.dict) this.dict.load(this.columns.map(e => e.type == 'select' ? e.dict : '')) | ||||
|     this.resetSearch() | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|     colConfigs() { | ||||
|       return [ | ||||
|         { prop: 'msgCode',  label: '编号', align: 'center' }, | ||||
|         { prop: 'title',  label: '标题', align: 'center' }, | ||||
|         { prop: 'type',  label: '类型', align: 'center', | ||||
|           render:(h,{row})=>[<span>{this.dict.getLabel('leaveMessageType', row.type)}</span>] }, | ||||
|         { prop: 'leaveName',  label: '留言人', align: 'center' }, | ||||
|         { prop: 'createTime',  label: '留言提交时间', align: 'center' }, | ||||
|         { prop: 'lastReplyTime',  label: '最后回复时间', align: 'center' }, | ||||
|         { slot: 'isPublic'}, | ||||
|         { slot: 'options'}, | ||||
|       ] | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .already-list { | ||||
|   background-color: #f3f6f9; | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   overflow: hidden; | ||||
|  | ||||
|   .el-table::before { | ||||
|     background-color: #fff !important; | ||||
|   } | ||||
|  | ||||
|   .header { | ||||
|     padding: 0 16px; | ||||
|     width: 100%; | ||||
|     background-color: #ffffff; | ||||
|     height: 48px; | ||||
|     line-height: 48px; | ||||
|     box-shadow: inset 0px -1px 0px 0px #d8dce3; | ||||
|  | ||||
|   } | ||||
|  | ||||
|   .main-content { | ||||
|     box-sizing: border-box; | ||||
|     margin: 16px; | ||||
|     height: calc(100% - 80px); | ||||
|     background-color: white; | ||||
|     border: 1px solid #eee; | ||||
|     padding: 12px 16px; | ||||
|  | ||||
|     .searchBar { | ||||
|  | ||||
|       .el-col { | ||||
|         margin-bottom: 12px; | ||||
|       } | ||||
|  | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -0,0 +1,461 @@ | ||||
| <template> | ||||
|   <div class="message-detail iconPhoto-content"> | ||||
|     <ai-detail> | ||||
|       <ai-title slot="title" :title="titleText" isShowBack isShowBottomBorder @onBackClick="$emit('back')"></ai-title> | ||||
|       <template #rightBtn> | ||||
|         <p class="resident_top_area" style="text-align: right;" v-if="data.status != '2' && $permissions('app_appleavemessagereply_edit')"> | ||||
|           <el-button type="primary" class="el-icon-edit" v-if="data.status == '0'" @click="maskShow = true" style="width:104px">回复留言</el-button> | ||||
|           <el-button class="el-icon-switch-button del-btn-list" @click="close()" style="width:104px">关闭留言</el-button> | ||||
|         </p> | ||||
|       </template> | ||||
|  | ||||
|       <template #content> | ||||
|         <ai-card :title="data.title"> | ||||
|           <template #content> | ||||
|             <div class="content-main"> | ||||
|               <div class="main-header mar-b16"> | ||||
|                 <h6 style="font-weight:600;">{{ data.title }}</h6> | ||||
|                 <div class="time"> | ||||
|                   <span class="time-label" style="width: 243px;" | ||||
|                     >留言编号:<span style="color:#333">{{ data.msgCode }}</span></span | ||||
|                   > | ||||
|                   <span class="time-label" | ||||
|                     >留言时间:<span style="color:#333">{{ data.createTime }}</span></span | ||||
|                   > | ||||
|                   <span class="time-label" style="width: 258px;text-align: right" | ||||
|                     >留言人:<span style="color:#333">{{ data.leaveName }}  {{ data.leavePhone }}</span></span | ||||
|                   > | ||||
|                   <svg class="status-icon" aria-hidden="true"> | ||||
|                     <use xlink:href="#iconno_response" v-if="data.status == '0'"></use> | ||||
|                     <use xlink:href="#iconreplied" v-if="data.status == '1'"></use> | ||||
|                     <use xlink:href="#iconfinished" v-if="data.status == '2'"></use> | ||||
|                   </svg> | ||||
|                 </div> | ||||
|                 <p class="message-text border-t" style="padding: 16px">{{ data.content }}</p> | ||||
|                 <div v-if="data.images.length"> | ||||
|                   <div class="content-img" v-viewer> | ||||
|                     <img v-for="(item, index) in data.images" :src="item.accessUrl" alt="" :key="index" /> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <div class="main-list"> | ||||
|                 <div class="main-header mar-b16"> | ||||
|                   <h6 style="font-weight:600;">沟通记录</h6> | ||||
|                 </div> | ||||
|                 <div v-for="(item, index) in data.appLeaveMessageReplyList" :key="index" :class="item.headPortrait == null ? 'message-for reply' : 'message-for'" v-if="data.appLeaveMessageReplyList.length > 0"> | ||||
|                   <div class="message-title"> | ||||
|                     <img :src="item.headPortrait" alt="" class="user-img" v-if="item.headPortrait" /> | ||||
|                     <span class="iconfont iconProfile_Picture" v-else></span> | ||||
|                     <span class="user-name" v-if="!item.headPortrait"> | ||||
|                       <span style="color:#5088FF">{{ item.createUnitName }}  <span style="color:#333"> 回复</span></span | ||||
|                       ><br /> | ||||
|                       <span style="color:#999;font-size:12px">操作员:{{ item.createUserName }}{{ item.createUserPhone }}</span> | ||||
|                     </span> | ||||
|                     <span class="user-name" v-else>{{ item.createUserName }}</span> | ||||
|  | ||||
|                     <span style="color:#999;vertical-align: text-bottom">{{ item.createTime }}</span> | ||||
|                   </div> | ||||
|                   <p class="message-text">{{ item.content }}</p> | ||||
|                   <div v-if="item.images.length"> | ||||
|                     <div class="message-img-list" v-viewer> | ||||
|                       <img class="message-img" v-for="(items, index) in item.images" :src="items.accessUrl" :key="index" v-if="items.accessUrl" /> | ||||
|                     </div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div v-if="data.appLeaveMessageReplyList.length == 0" style="width:100%;text-align:center;color:#999;font-size:14px">暂无沟通记录</div> | ||||
|               </div> | ||||
|             </div> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|       </template> | ||||
|     </ai-detail> | ||||
|     <ai-dialog :title="maskText" :visible.sync="maskShow" @onConfirm="confirm('ruleForm')" @onCancel="hideMask" :before-close="hideMask" width="720px"> | ||||
|       <el-form :rules="rules" ref="ruleForm" :model="ruleForm" label-width="auto"> | ||||
|         <el-form-item label="回复内容:" prop="content"> | ||||
|           <el-input type="textarea" v-model.trim="ruleForm.content" :row="4" show-word-limit :maxlength="1000" placeholder="请输入回复内容"></el-input> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="图片附件:" class="user"> | ||||
|           <span class="upload-more left-84">(最多9张)</span> | ||||
|           <el-upload class="upload-demo upload-list-small" ref="upload" multiple action list-type="picture-card" :file-list="images" :http-request="uploadFile" :on-remove="handleRemove" :on-change="handleChange" accept="jpeg/jpg/png"> | ||||
|             <div class="upload-img-small"> | ||||
|               <span class="iconfont iconPhoto iconPhoto2"></span> | ||||
|               <div class="upload-text">上传照片</div> | ||||
|             </div> | ||||
|           </el-upload> | ||||
|         </el-form-item> | ||||
|       </el-form> | ||||
|     </ai-dialog> | ||||
|   </div> | ||||
| </template> | ||||
| <script> | ||||
| import { mapState } from 'vuex' | ||||
| // import 'viewerjs/dist/viewer.css' | ||||
| import Viewer from 'v-viewer' | ||||
| import Vue from 'vue' | ||||
| Vue.use(Viewer) | ||||
|  | ||||
| export default { | ||||
|   name: 'messageDetail', | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function, | ||||
|     detailId: String, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       titleText: '留言详情', | ||||
|       maskShow: false, | ||||
|       maskText: '回复留言', | ||||
|       images: [], | ||||
|       data: { | ||||
|         appLeaveMessageReplyList: [], | ||||
|       }, | ||||
|       rules: { | ||||
|         content: [{ required: true, message: '请输入回复内容', trigger: 'blur' }], | ||||
|       }, | ||||
|       ruleForm: { | ||||
|         content: '', | ||||
|       }, | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|   }, | ||||
|   created() {}, | ||||
|   mounted() { | ||||
|     console.log(this.user) | ||||
|     this.getDetailInfo() | ||||
|   }, | ||||
|   methods: { | ||||
|     getDetailInfo() { | ||||
|       this.data.appLeaveMessageReplyList = [] | ||||
|       this.instance.post(`app/appleavemessage/queryDetailById?id=` + this.detailId).then((res) => { | ||||
|         this.data = res.data | ||||
|         this.data.images = JSON.parse(res.data.images) | ||||
|         if (this.data.appLeaveMessageReplyList.length) { | ||||
|           this.data.appLeaveMessageReplyList.map((item) => { | ||||
|             if (item.images) { | ||||
|               item.images = JSON.parse(item.images || '[]') | ||||
|             } | ||||
|             return item | ||||
|           }) | ||||
|         } | ||||
|         this.data.appLeaveMessageReplyList.reverse() | ||||
|       }) | ||||
|     }, | ||||
|     confirm(formName) { | ||||
|       this.$refs[formName].validate((valid) => { | ||||
|         if (valid) { | ||||
|           this.confirmFn() | ||||
|         } else { | ||||
|           return false | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     confirmFn() { | ||||
|       let images = [] | ||||
|       this.images.map((item) => { | ||||
|         images.push({ fileId: item.fileId, accessUrl: item.accessUrl }) | ||||
|       }) | ||||
|       let params = { | ||||
|         content: this.ruleForm.content, | ||||
|         images: JSON.stringify(images), | ||||
|         msgCode: this.data.msgCode, | ||||
|         userType: '1', | ||||
|         createUnitId: this.user.info.unitId, | ||||
|         createUnitName: this.user.info.unitName, | ||||
|       } | ||||
|       this.instance.post(`app/appleavemessagereply/addOrUpdate`, params).then((res) => { | ||||
|         console.log(res) | ||||
|         this.maskShow = false | ||||
|         this.getDetailInfo() | ||||
|       }) | ||||
|     }, | ||||
|     hideMask() { | ||||
|       this.maskShow = false | ||||
|       this.images = [] | ||||
|       this.$nextTick(() => { | ||||
|         this.$refs.ruleForm.resetFields() | ||||
|       }) | ||||
|     }, | ||||
|     close() { | ||||
|       this.$confirm('关闭留言之后,双方都将无法再进行回复,是否确定关闭本次留言?', { | ||||
|         type: 'warning', | ||||
|       }) | ||||
|         .then(() => { | ||||
|           let params = this.data | ||||
|           params.status = '2' | ||||
|           params.images = JSON.stringify(params.images) | ||||
|           if (params.appLeaveMessageReplyList.length) { | ||||
|             params.appLeaveMessageReplyList.map((item) => { | ||||
|               item.images = JSON.stringify(item.images) | ||||
|               return item | ||||
|             }) | ||||
|           } | ||||
|           this.instance.post(`app/appleavemessage/addOrUpdate`, params).then((res) => { | ||||
|             this.getDetailInfo() | ||||
|           }) | ||||
|         }) | ||||
|         .catch(() => {}) | ||||
|     }, | ||||
|     // 上传照片 | ||||
|     uploadFile(file) { | ||||
|       console.log(this.images.length > 9) | ||||
|       if (this.images.length > 9) { | ||||
|         this.$message.warning('上传图片不能超过9张') | ||||
|         this.images.map((item, index) => { | ||||
|           if (item.uid == file.file.uid) { | ||||
|             this.images.splice(index, 1) | ||||
|           } | ||||
|           return this.images | ||||
|         }) | ||||
|       } | ||||
|       const isLt2M = file.file.size / 1024 / 1024 < 2 | ||||
|       if (!isLt2M) { | ||||
|         this.$message.warning('图片大小不能超过 2MB!') | ||||
|         return | ||||
|       } | ||||
|       let formData = new FormData() | ||||
|       formData.append('file', file.file) | ||||
|       let file2 = formData | ||||
|       this.instance.post(`/admin/file/add`, file2, { withCredentials: false }).then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           let imgInfo = res.data[0].split(';') | ||||
|           let img = { | ||||
|             fileId: imgInfo[1], | ||||
|             accessUrl: imgInfo[0], | ||||
|           } | ||||
|           this.images.map((item, index) => { | ||||
|             if (item.uid == file.file.uid) { | ||||
|               this.images[index].fileId = img.fileId | ||||
|               this.images[index].accessUrl = img.accessUrl | ||||
|               this.images[index].url = img.accessUrl | ||||
|             } | ||||
|             return this.images | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     handleChange(file, fileList) { | ||||
|       this.images = fileList | ||||
|     }, | ||||
|     handleRemove(file, fileList) { | ||||
|       this.images = fileList | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
| <style lang="scss" scoped> | ||||
| .message-detail { | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   overflow: auto; | ||||
|   position: relative; | ||||
|   background-color: #f3f6f9; | ||||
|   .left-84 { | ||||
|     left: -84px; | ||||
|   } | ||||
|   .iconProfile_Picture { | ||||
|     font-size: 40px; | ||||
|   } | ||||
|  | ||||
|   .iconBack_Large { | ||||
|     width: 16px; | ||||
|     height: 16px; | ||||
|     color: #2266ff; | ||||
|     cursor: pointer; | ||||
|   } | ||||
|   .content { | ||||
|     padding-top: 24px; | ||||
|     width: 100%; | ||||
|     height: calc(100% - 80px); | ||||
|     overflow-y: scroll; | ||||
|     .content-main { | ||||
|       width: 760px; | ||||
|       margin: 0 auto; | ||||
|       .main-header { | ||||
|         width: 100%; | ||||
|         box-sizing: border-box; | ||||
|         background-color: #fff; | ||||
|         border: 1px solid #eee; | ||||
|         h6 { | ||||
|           font-size: 16px; | ||||
|           color: #333; | ||||
|           padding: 0 16px; | ||||
|           min-height: 54px; | ||||
|           line-height: 54px; | ||||
|           box-sizing: border-box; | ||||
|         } | ||||
|         .time { | ||||
|           height: 54px; | ||||
|           line-height: 54px; | ||||
|           font-size: 12px; | ||||
|           padding: 0 16px; | ||||
|           box-sizing: border-box; | ||||
|           position: relative; | ||||
|           overflow: hidden; | ||||
|           .time-label { | ||||
|             color: #999; | ||||
|             display: inline-block; | ||||
|           } | ||||
|         } | ||||
|         .status-icon { | ||||
|           position: absolute; | ||||
|           width: 66px; | ||||
|           height: 66px; | ||||
|           top: -5px; | ||||
|           right: 0; | ||||
|         } | ||||
|       } | ||||
|       .main-list { | ||||
|         background-color: #fff; | ||||
|         padding-bottom: 80px; | ||||
|         .message-for { | ||||
|           width: 728px; | ||||
|           margin: 0 auto 24px auto; | ||||
|           padding: 16px 16px 8px; | ||||
|           box-sizing: border-box; | ||||
|           font-size: 14px; | ||||
|           .message-title { | ||||
|             height: 40px; | ||||
|             line-height: 40px; | ||||
|             margin-bottom: 6px; | ||||
|             .user-img { | ||||
|               display: inline-block; | ||||
|               width: 40px; | ||||
|               height: 40px; | ||||
|               border-radius: 50%; | ||||
|               background-color: red; | ||||
|             } | ||||
|             .user-name { | ||||
|               display: inline-block; | ||||
|               width: 510px; | ||||
|               color: #333; | ||||
|               vertical-align: text-bottom; | ||||
|               padding-left: 8px; | ||||
|               box-sizing: border-box; | ||||
|             } | ||||
|           } | ||||
|           .message-text { | ||||
|             padding-left: 48px; | ||||
|             color: #666; | ||||
|             margin-bottom: 16px; | ||||
|           } | ||||
|           .message-img-list { | ||||
|             padding-left: 48px; | ||||
|             .message-img { | ||||
|               display: inline-block; | ||||
|               width: 113px; | ||||
|               height: 113px; | ||||
|               margin: 0 16px 16px 0; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|         .reply { | ||||
|           background-color: #f5f6f7; | ||||
|           .message-title { | ||||
|             .user-name { | ||||
|               line-height: 20px; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .content-img { | ||||
|     padding: 0 16px; | ||||
|     img { | ||||
|       width: 84px; | ||||
|       height: 84px; | ||||
|       margin: 0 16px 16px 0; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .operation-foot { | ||||
|     overflow: hidden; | ||||
|     //   position: absolute; | ||||
|     bottom: 0; | ||||
|     left: 0; | ||||
|     width: 100%; | ||||
|     height: 64px; | ||||
|     line-height: 64px; | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     justify-content: center; | ||||
|     background-color: #f3f6f9; | ||||
|     box-shadow: inset 0px 1px 0px 0px #eeeeee; | ||||
|     button { | ||||
|       width: 92px; | ||||
|       height: 32px; | ||||
|       padding: 0 !important; | ||||
|     } | ||||
|     .delete-btn { | ||||
|       background-color: #fff; | ||||
|     } | ||||
|   } | ||||
|   .mask { | ||||
|     overflow: hidden; | ||||
|     .el-form-item__content { | ||||
|       float: left; | ||||
|       width: calc(100% - 100px) p { | ||||
|         font-size: 14px; | ||||
|         color: #222222; | ||||
|       } | ||||
|     } | ||||
|     .el-form-item__label { | ||||
|       display: inline-block; | ||||
|       width: 130px; | ||||
|       text-align: right; | ||||
|       font-size: 14px; | ||||
|       float: left; | ||||
|     } | ||||
|     .operation { | ||||
|       overflow: hidden; | ||||
|       //   position: absolute; | ||||
|       bottom: 0; | ||||
|       left: 0; | ||||
|       width: 100%; | ||||
|       height: 64px; | ||||
|       line-height: 64px; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|       background-color: #f3f6f9; | ||||
|       box-shadow: inset 0px 1px 0px 0px #eeeeee; | ||||
|     } | ||||
|   } | ||||
|   .status { | ||||
|     span { | ||||
|       display: inline-block; | ||||
|       width: 24px; | ||||
|       height: 24px; | ||||
|       line-height: 24px; | ||||
|       text-align: center; | ||||
|     } | ||||
|   } | ||||
|   .status0 { | ||||
|     background-color: #eff6ff; | ||||
|     color: #2266ff; | ||||
|   } | ||||
|   .status1 { | ||||
|     background-color: #e8ecff; | ||||
|     color: #2244ff; | ||||
|   } | ||||
|   .status2 { | ||||
|     background-color: #fff3e8; | ||||
|     color: #ff8822; | ||||
|   } | ||||
|   .status3 { | ||||
|     background-color: #eaf5e8; | ||||
|     color: #2ea222; | ||||
|   } | ||||
|   .icon { | ||||
|     display: inline-block; | ||||
|     width: 32px; | ||||
|     height: 32px; | ||||
|     margin-top: 16px; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -0,0 +1,82 @@ | ||||
| <template> | ||||
|   <section class="matters-config"> | ||||
|     <ai-list v-if="!showDetail"> | ||||
|       <template #title> | ||||
|         <ai-title title="事项配置" :isShowBottomBorder="false"></ai-title> | ||||
|       </template> | ||||
|       <template slot="tabs"> | ||||
|         <el-tabs class="tabs-page" v-model="currIndex"> | ||||
|           <el-tab-pane v-for="(tab,i) in tabs" :key="i" :label="tab.label" :name="String(i)"> | ||||
|             <component :is="tab.comp" v-if="currIndex==i" :ref="currIndex" :instance="instance" :dict="dict" | ||||
|                        :permissions="permissions" @goPage="goPage" :tab="currentTab"/> | ||||
|           </el-tab-pane> | ||||
|         </el-tabs> | ||||
|       </template> | ||||
|     </ai-list> | ||||
|     <component v-else :is="currentComp" :instance="instance" :dict="dict" | ||||
|                :processType="currentTab.value" :row="row"></component> | ||||
|  | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import addConfig from './components/addConfig' | ||||
| import configList from "./components/configList"; | ||||
| import guidance from "./components/guidance"; | ||||
|  | ||||
| export default { | ||||
|   name: "AppMattersConfig", | ||||
|   label: '事项配置', | ||||
|   components: {addConfig,guidance}, | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       currIndex: "0", | ||||
|       row: {}, | ||||
|       currentComp: "", | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     tabs() { | ||||
|       return [ | ||||
|         {label: "网上办事", name: "configList", value: "0", comp: configList, detail: addConfig, permission: ""}, | ||||
|         {label: "办事指南", name: "configList", value: "2", comp: configList, detail: guidance, permission: ""}, | ||||
|       ] | ||||
|     }, | ||||
|     currentTab() { | ||||
|       return this.tabs?.[this.currIndex] || {} | ||||
|     }, | ||||
|     showDetail() { | ||||
|       return !!this.$route.query?.id || !!this.$route.query?.processType | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     goPage(params) { | ||||
|       this.row = params.row | ||||
|       this.currentComp = params.comp | ||||
|       this.$router.push({query: {processType: this.currentTab.value}}) | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.$router.push({query: {}}); | ||||
|     this.$dict.load("hbDepartment", 'sex', 'nation', 'marital', 'native_place', 'education', 'candidateApproverType', 'scopeCandidates', 'nodeType') | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .matters-config { | ||||
|   height: 100%; | ||||
|   background: #f3f6f9; | ||||
|   overflow: auto; | ||||
|  | ||||
|   .iconfont { | ||||
|     user-select: none; | ||||
|     cursor: pointer; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -0,0 +1,252 @@ | ||||
| <template> | ||||
|   <div class="add-config" :class="[activeStep == 1 ? 'formLayout' : '']"> | ||||
|     <ai-detail> | ||||
|       <ai-title slot="title" :title="detailTitle" isShowBack isShowBottomBorder @onBackClick="handleBack"/> | ||||
|       <template slot="step"> | ||||
|         <div class="step"> | ||||
|           <el-steps :active="activeStep" simple> | ||||
|             <el-step v-for="(step,i) in processList" :key="i" v-bind="step" :icon="getStepIcon(i)"/> | ||||
|           </el-steps> | ||||
|         </div> | ||||
|       </template> | ||||
|       <template #content v-if="refresh"> | ||||
|         <baseInfo ref="baseInfo" :instance="instance" :dict="dict" v-show="activeStep==0"/> | ||||
|         <applyForm ref="applyForm" :value="filedList" :instance="instance" :dict="dict" v-show="activeStep==1"/> | ||||
|         <attachmentMaterial ref="attachmentMaterial" :instance="instance" v-show="activeStep==2"/> | ||||
|         <processApproval ref="processApproval" :approvalSteps="applyForm.approvalSteps" :instance="instance" | ||||
|                          :dict="dict" v-show="activeStep==3"/> | ||||
|       </template> | ||||
|       <template #footer> | ||||
|         <el-button class="btn" v-if="activeStep==0" @click="handleBack">取消</el-button> | ||||
|         <el-button class="btn" v-else @click="preStep">上一步</el-button> | ||||
|         <el-button class="btn" type="primary" v-if="[0,1,2].includes(activeStep)" @click="nextStep">下一步</el-button> | ||||
|         <el-button class="btn" type="primary" v-if="activeStep==3" @click="save">保存</el-button> | ||||
|       </template> | ||||
|     </ai-detail> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {applyForm, attachmentMaterial, baseInfo, processApproval} from './index' | ||||
|  | ||||
| export default { | ||||
|   name: "addConfig", | ||||
|   provide() { | ||||
|     return { | ||||
|       config: this | ||||
|     } | ||||
|   }, | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     row: Object, | ||||
|     processType: String | ||||
|   }, | ||||
|   components: {baseInfo, applyForm, attachmentMaterial, processApproval}, | ||||
|   data() { | ||||
|     return { | ||||
|       activeStep: 0, | ||||
|       baseInfo: {}, | ||||
|       applyForm: { | ||||
|         tableId: "", | ||||
|         approvalSteps: "", | ||||
|       }, | ||||
|       processAnnexDefs: [], | ||||
|       detailObj: { | ||||
|         tableInfo: {} | ||||
|       }, | ||||
|       refresh: true, | ||||
|       filedList: [], | ||||
|       tableFieldInfos: [] | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     processList() { | ||||
|       return [ | ||||
|         {title: '基本信息', activeIndex: 0}, | ||||
|         {title: '申请表单', activeIndex: 1}, | ||||
|         {title: '附件材料', activeIndex: 2}, | ||||
|         {title: '审批流程', activeIndex: 3} | ||||
|       ] | ||||
|     }, | ||||
|     detailTitle() { | ||||
|       return this.detailObj?.id ? "编辑事项" : "添加事项" | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     /** | ||||
|      * 上一步 | ||||
|      * */ | ||||
|     preStep() { | ||||
|       this.activeStep-- | ||||
|     }, | ||||
|     /** | ||||
|      * 下一步 | ||||
|      */ | ||||
|     nextStep() { | ||||
|       switch (this.activeStep) { | ||||
|         case 0: | ||||
|           this.handleBaseInfo() | ||||
|           break | ||||
|         case 1: | ||||
|           this.$refs['applyForm'].onConfirm().then(res => { | ||||
|             if (!res.length) { | ||||
|               return this.$message.error('表单配置不能为空') | ||||
|             } | ||||
|             this.tableFieldInfos = res | ||||
|             this.activeStep++ | ||||
|           }) | ||||
|           break | ||||
|         case 2: | ||||
|           this.$refs['attachmentMaterial'].handleAttachmentMaterial().then(res => { | ||||
|             this.annexs = res | ||||
|             this.activeStep++ | ||||
|           }).catch(err => { | ||||
|             console.error(err); | ||||
|           }) | ||||
|           break | ||||
|       } | ||||
|     }, | ||||
|     handleBaseInfo() { | ||||
|       this.$refs['baseInfo'].banseInfoForm().then(res => { | ||||
|         if (res) { | ||||
|           // this.$refs['applyForm'].getFormList() | ||||
|           this.baseInfo = res | ||||
|           this.activeStep++ | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     /** | ||||
|      * 保存 | ||||
|      */ | ||||
|     save() { | ||||
|       this.$refs['processApproval'].handleProcessApproval().then(res => { | ||||
|         this.instance.post(`/app/approval-process-def/add-update`, { | ||||
|           ...this.detailObj, | ||||
|           ...this.baseInfo, | ||||
|           processDefStatus: Number(this.baseInfo.processDefStatus), | ||||
|           tableInfo: { | ||||
|             ...this.detailObj.tableInfo, | ||||
|             tableFieldInfos: this.tableFieldInfos | ||||
|           }, | ||||
|           tableType: 0, | ||||
|           processAnnexDefs: this.annexs.map(e => ({...e, mustFill: Number(e.mustFill)})), | ||||
|           processNodeList: res.processNodeList, | ||||
|           processType: this.processType | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.$message.success("保存成功") | ||||
|             this.$router.push({query:{}}) | ||||
|           } | ||||
|         }) | ||||
|       }).catch(err => { | ||||
|         console.error(err); | ||||
|       }) | ||||
|     }, | ||||
|     getDetail(id) { | ||||
|       this.instance.post(`/app/approval-process-def/info-id`, null, {params: {id}}).then(res => { | ||||
|         if (res?.data) { | ||||
|           this.detailObj = res.data | ||||
|           this.filedList = res.data.tableInfo.tableFieldInfos | ||||
|           this.refreshDetail() | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     getStepIcon(rowIndex) { | ||||
|       if (rowIndex < this.activeStep) return "iconfont iconSteps_Finished" | ||||
|       else if (this.activeStep == rowIndex) return "iconfont iconSteps_In_Progress" | ||||
|       return "" | ||||
|     }, | ||||
|     refreshDetail() { | ||||
|       this.refresh = false | ||||
|       this.$nextTick(() => this.refresh = true) | ||||
|     }, | ||||
|     handleBack() { | ||||
|       this.$router.push({query: {}}) | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     if (this.row?.id) { | ||||
|       this.getDetail(this.row?.id) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .add-config { | ||||
|   height: 100%; | ||||
|  | ||||
|   &.formLayout { | ||||
|     ::v-deep .ai-detail__content--wrapper { | ||||
|       max-width: 100%; | ||||
|       height: calc(100%)!important; | ||||
|       padding: 0!important; | ||||
|       overflow: hidden!important; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .step { | ||||
|     width: 100%; | ||||
|     height: 72px; | ||||
|     font-size: 14px; | ||||
|  | ||||
|     .el-steps { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       height: 72px; | ||||
|       padding: 0 calc(50% - 380px); | ||||
|  | ||||
|  | ||||
|       ::v-deep .el-step { | ||||
|         font-weight: bold; | ||||
|  | ||||
|         ::v-deep .el-step__icon { | ||||
|           width: 24px; | ||||
|           height: 24px; | ||||
|           background: #fff; | ||||
|  | ||||
|           .iconfont { | ||||
|             font-size: 24px; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         ::v-deep .el-step__main { | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|  | ||||
|           .el-step__arrow { | ||||
|             background: #D0D4DC; | ||||
|             margin: 0 8px; | ||||
|             height: 2px; | ||||
|  | ||||
|             &:before, &:after { | ||||
|               display: none; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .is-process { | ||||
|           color: #2266FF; | ||||
|         } | ||||
|  | ||||
|         .is-wait { | ||||
|           color: #666; | ||||
|           border-color: #D0D4DC; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|     } | ||||
|  | ||||
|   } | ||||
|  | ||||
|   .btn { | ||||
|     width: 92px; | ||||
|     height: 32px; | ||||
|  | ||||
|     &:nth-child(2) { | ||||
|       margin-left: 24px; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -0,0 +1,895 @@ | ||||
| <template> | ||||
|   <div class="form-config"> | ||||
|     <el-scrollbar class="left"> | ||||
|       <div class="left-item" v-for="(component, index) in components" :key="index"> | ||||
|         <div class="left-item__title"> | ||||
|           <h2>{{ component.label }}</h2> | ||||
|           <span>{{ component.tips }}</span> | ||||
|         </div> | ||||
|         <div class="left-item__list"> | ||||
|           <draggable | ||||
|             class="components-draggable" | ||||
|             :list="component.children" | ||||
|             :group="{ name: 'componentsGroup', pull: 'clone', put: false }" | ||||
|             :sort="false" | ||||
|             :move="onMove" | ||||
|             :clone="cloneComponent" | ||||
|             @end="onEnd"> | ||||
|             <div class="left-item__item" v-for="(item, i) in component.children" :key="i" @click="clone(item)"> | ||||
|               <i class="iconfont" :class="item.icon"></i> | ||||
|               <span>{{ item.fixedLabel }}</span> | ||||
|             </div> | ||||
|           </draggable> | ||||
|         </div> | ||||
|       </div> | ||||
|     </el-scrollbar> | ||||
|     <el-scrollbar class="middle"> | ||||
|       <div class="middle-content"> | ||||
|         <div class="middle-content__wrapper"> | ||||
|           <el-form label-width="100px" label-position="right"> | ||||
|             <draggable | ||||
|               class="middle-draggable" | ||||
|               style="height: 100%;" | ||||
|               :animation="340" | ||||
|               scroll | ||||
|               v-model="targetList" | ||||
|               element="div" | ||||
|               @end="onElEnd" | ||||
|               :sort="true"> | ||||
|               <ai-card | ||||
|                 :class="[groupIndex === j && isGroup ? 'active' : '']" | ||||
|                 :data-index="j" | ||||
|                 @click.native.stop="groupIndex = j, activeIndex = -1, isGroup = true" | ||||
|                 :title="group.groupName" v-for="(group, j) in targetList" | ||||
|                 :key="j"> | ||||
|                 <template #content> | ||||
|                   <draggable | ||||
|                     class="ai-form" | ||||
|                     style="height: 100%;" | ||||
|                     v-model="group.column" | ||||
|                     :animation="340" | ||||
|                     scroll | ||||
|                     @end="onElEnd" | ||||
|                     element="div" | ||||
|                     draggable=".components-item" | ||||
|                     group="componentsGroup" | ||||
|                     :sort="true"> | ||||
|                     <div | ||||
|                       class="components-item" | ||||
|                       v-for="(item, i) in group.column" | ||||
|                       :style="{width: item.grid * 100 + '%'}" | ||||
|                       :class="[groupIndex === j && activeIndex === i ? 'active' : '']" | ||||
|                       @click.stop="groupIndex = j, activeIndex = i, isGroup = false" | ||||
|                       :key="i"> | ||||
|                       <div class="left-item__item--remove" title="删除字段" v-show="groupIndex === j && activeIndex === i" @click.stop="removeItem(j, i)"> | ||||
|                         <i class="iconfont iconDelete"></i> | ||||
|                         <span>删除字段</span> | ||||
|                       </div> | ||||
|                       <el-form-item style="width: 100%;" :label="item.fieldName" :rules="[{ required: item.mustFill === '1' ? true : false }]"> | ||||
|                         <template v-if="item.fieldDataType === '1'"> | ||||
|                           <el-input :disabled="item.disable === '1'" size="small" placeholder="请输入" v-model="item.defaultValue"></el-input> | ||||
|                         </template> | ||||
|                         <template v-if="item.fieldDataType === '4'"> | ||||
|                           <el-radio-group v-model="item.defaultValue" :disabled="item.disable === '1'"> | ||||
|                             <el-radio :label="field.label" v-for="(field, index) in item.options" :key="index">{{ field.label }}</el-radio> | ||||
|                           </el-radio-group> | ||||
|                         </template> | ||||
|                         <template v-if="item.fieldDataType === '0'"> | ||||
|                           <el-input-number style="width: 100%;" v-model="item.defaultValue" :placeholder="item.fieldTips"></el-input-number> | ||||
|                         </template> | ||||
|                         <template v-if="item.fieldDataType === '3'"> | ||||
|                           <el-date-picker | ||||
|                             v-model="item.defaultValue" | ||||
|                             size="small" | ||||
|                             :placeholder="item.fieldTips"> | ||||
|                           </el-date-picker> | ||||
|                         </template> | ||||
|                         <template v-if="item.fieldDataType === '8'"> | ||||
|                           <el-date-picker | ||||
|                             v-model="item.defaultValue" | ||||
|                             size="small" | ||||
|                             :placeholder="item.fieldTips"> | ||||
|                           </el-date-picker> | ||||
|                         </template> | ||||
|                         <template v-if="item.fieldDataType === '9'"> | ||||
|                           <el-select :disabled="item.disable === '1'" style="width: 100%;" size="small" :placeholder="item.fieldTips" v-model="item.defaultValue"> | ||||
|                             <el-option | ||||
|                               v-for="(filed, index) in item.options" | ||||
|                               :key="index" | ||||
|                               :label="filed.label" | ||||
|                               :value="filed.label"> | ||||
|                             </el-option> | ||||
|                           </el-select> | ||||
|                         </template> | ||||
|                         <template v-if="item.fieldDataType === '5'" > | ||||
|                           <el-checkbox-group v-model="item.defaultValue" :disabled="item.disable === '1'"> | ||||
|                             <el-checkbox :label="field.label" v-for="(field, index) in item.options" :key="index">{{ field.label }}</el-checkbox> | ||||
|                           </el-checkbox-group> | ||||
|                         </template> | ||||
|                       </el-form-item> | ||||
|                     </div> | ||||
|                   </draggable> | ||||
|                 </template> | ||||
|               </ai-card> | ||||
|             </draggable> | ||||
|           </el-form> | ||||
|         </div> | ||||
|       </div> | ||||
|     </el-scrollbar> | ||||
|     <el-scrollbar class="right"> | ||||
|       <div class="right-item" v-if="isGroup"> | ||||
|         <div class="right-item__title no-solid"> | ||||
|           <h2>分组名称</h2> | ||||
|         </div> | ||||
|         <div class="right-item__content"> | ||||
|           <el-input placeholder="请输入分组名称" :maxlength="32" show-word-limit v-model="currTarget.groupName"></el-input> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="layout-right__del" @click="removeGroup" v-if="isGroup && targetList.length > 1"> | ||||
|         <span>删除分组</span> | ||||
|       </div> | ||||
|       <div class="right-item" v-if="activeIndex > -1"> | ||||
|         <div class="right-item__title no-solid"> | ||||
|           <h2>标题名称</h2> | ||||
|         </div> | ||||
|         <div class="right-item__content"> | ||||
|           <el-input placeholder="标题名称" :maxlength="32" show-word-limit v-model="currTarget.fieldName"></el-input> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="right-item right-item__select" v-if="['9', '4', '5'].includes(currTarget.fieldDataType)"> | ||||
|         <div class="right-item__title no-solid"> | ||||
|           <h2>选项设置</h2> | ||||
|         </div> | ||||
|         <div class="right-item__select--wrapper"> | ||||
|           <draggable | ||||
|             v-model="currTarget.options" | ||||
|             :animation="340" | ||||
|             group="select" | ||||
|             handle=".mover" | ||||
|             :sort="true"> | ||||
|             <div class="select-item" v-for="(item, index) in currTarget.options" :key="index"> | ||||
|               <i class="iconfont iconjdq_led_show mover"></i> | ||||
|               <el-input placeholder="请输入选项名" :maxlength="30" show-word-limit v-model="item.label"></el-input> | ||||
|               <i class="iconfont iconDelete" @click="removeOptions(index)"></i> | ||||
|             </div> | ||||
|           </draggable> | ||||
|         </div> | ||||
|         <el-button type="text" class="add-select" @click="addOptions">添加选项</el-button> | ||||
|       </div> | ||||
|       <div class="right-item__group" v-if="activeIndex > -1" key="radio"> | ||||
|         <div class="right-item" v-if="currTarget.fieldDataType == 1 || currTarget.fieldDataType == 0"> | ||||
|           <div class="right-item__title"> | ||||
|             <h2>最多输入字符</h2> | ||||
|           </div> | ||||
|           <div class="right-item__content"> | ||||
|             <el-input placeholder="字符个数" v-model="currTarget.fieldLength"> | ||||
|               <span slot="append">个</span> | ||||
|             </el-input> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="right-item"> | ||||
|           <div class="right-item__title no-solid"> | ||||
|             <div class="right-item__title--left"> | ||||
|               <h2>是否必填</h2> | ||||
|             </div> | ||||
|             <el-switch v-model="currTarget.mustFill" active-value="1" inactive-value="0"></el-switch> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </el-scrollbar> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import draggable from 'vuedraggable' | ||||
|   import { components } from './config' | ||||
|  | ||||
|   export default { | ||||
|     name: 'applyForm', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       params: Object, | ||||
|       type: String, | ||||
|       value: Array | ||||
|     }, | ||||
|  | ||||
|     components: { | ||||
|       draggable | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         isGroup: false, | ||||
|         components: components, | ||||
|         targetList: [{ | ||||
|           type: 'group', | ||||
|           fieldName: '卡片', | ||||
|           fixedLabel: '卡片', | ||||
|           icon: 'iconpic', | ||||
|           groupName: '基础信息', | ||||
|           column: [] | ||||
|         }], | ||||
|         groupIndex: -1, | ||||
|         activeIndex: -1, | ||||
|         currTarget: {} | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     watch: { | ||||
|       activeIndex () { | ||||
|         if (this.activeIndex > -1 && this.groupIndex > -1 && !this.isGroup) { | ||||
|           const filed = this.targetList[this.groupIndex].column[this.activeIndex] | ||||
|           this.currTarget = filed | ||||
|  | ||||
|           return | ||||
|         } | ||||
|  | ||||
|         if (this.groupIndex > -1 && this.isGroup) { | ||||
|           this.currTarget = this.targetList[this.groupIndex].column[this.activeIndex] | ||||
|  | ||||
|           return  | ||||
|         } | ||||
|  | ||||
|         this.currTarget = {} | ||||
|       }, | ||||
|  | ||||
|       groupIndex () { | ||||
|         if (this.activeIndex > -1 && this.groupIndex > -1 && !this.isGroup) { | ||||
|           const filed = this.targetList[this.groupIndex].column[this.activeIndex] | ||||
|           this.currTarget = filed | ||||
|  | ||||
|           return | ||||
|         } | ||||
|  | ||||
|         if (this.groupIndex > -1 && this.isGroup) { | ||||
|           this.currTarget = this.targetList[this.groupIndex] | ||||
|           return  | ||||
|         } | ||||
|  | ||||
|         this.currTarget = {} | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     mounted () { | ||||
|       this.init() | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       removeItem (j, i) { | ||||
|         this.groupIndex = -1 | ||||
|         this.activeIndex = -1 | ||||
|         this.targetList[j].column.splice(i, 1) | ||||
|       }, | ||||
|  | ||||
|       init () { | ||||
|         if (this.value.length) { | ||||
|           let arr = this.value | ||||
|           let groups = this.unique(arr.map(v => v.groupName)) | ||||
|           this.targetList = groups.map(groupName => { | ||||
|             const column = arr.filter(v => v.groupName === groupName).map(item => { | ||||
|               if (['9', '4', '5'].includes(item.fieldDataType)) { | ||||
|                 item.options = item.selectValues.split('`').map(v => { | ||||
|                   return { | ||||
|                     label: v, | ||||
|                     value: '' | ||||
|                   } | ||||
|                 }) | ||||
|               } | ||||
|  | ||||
|               if (item.fieldDataType === '5') { | ||||
|                   item.defaultValue = [] | ||||
|               } | ||||
|  | ||||
|               return { | ||||
|                 ...item, | ||||
|                 grid: 1 | ||||
|               } | ||||
|             }) | ||||
|  | ||||
|             return { | ||||
|               type: 'group', | ||||
|               fieldName: '卡片', | ||||
|               fixedLabel: '卡片', | ||||
|               icon: 'iconpic', | ||||
|               groupName, | ||||
|               column: column | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       }, | ||||
|  | ||||
|       removeGroup () { | ||||
|         if (this.targetList.length === 1) { | ||||
|           return this.$message.error('分组不能小于1') | ||||
|         } | ||||
|  | ||||
|         this.targetList.splice(this.groupIndex, 1) | ||||
|         this.groupIndex = 0 | ||||
|         this.isGroup = true | ||||
|         this.activeIndex = -1 | ||||
|       }, | ||||
|  | ||||
|       unique (arr) { | ||||
|         return arr.filter((item, index) => { | ||||
|           return arr.indexOf(item, 0) === index | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       onConfirm () { | ||||
|         let result = [] | ||||
|         this.targetList.forEach((group, i) => { | ||||
|           group.column.forEach(item => { | ||||
|             result.push({ | ||||
|               ...item, | ||||
|               groupIndex: i, | ||||
|               groupName: group.groupName, | ||||
|               selectValues: item.options ? item.options.map(v => v.label).join('`') : '' | ||||
|             }) | ||||
|           }) | ||||
|         }) | ||||
|  | ||||
|         return new Promise(resolve => { | ||||
|           resolve(result) | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       addOptions () { | ||||
|         const len = this.targetList[this.groupIndex].column[this.activeIndex].options.length | ||||
|         let label = `选项${len + 1}` | ||||
|  | ||||
|         const index= this.targetList[this.groupIndex].column[this.activeIndex].options.findIndex(v => label === v.label) | ||||
|         if (index > -1) { | ||||
|           label = `新选项${len + 1}` | ||||
|         } | ||||
|  | ||||
|         this.targetList[this.groupIndex].column[this.activeIndex].options.push({ | ||||
|           label: label, | ||||
|           value: '' | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       removeOptions (index) { | ||||
|         const len = this.targetList[this.groupIndex].column[this.activeIndex].options.length | ||||
|  | ||||
|         if (len === 2) { | ||||
|           return this.$message.error('选项不能少于2个') | ||||
|         } | ||||
|         this.targetList[this.groupIndex].column[this.activeIndex].options.splice(index, 1) | ||||
|       }, | ||||
|  | ||||
|       onEnd (e) { | ||||
|         const el = e.to.parentElement.parentElement | ||||
|         this.isGroup = false | ||||
|         this.activeIndex = e.newIndex | ||||
|         this.groupIndex = Number(el.getAttribute('data-index')) | ||||
|       }, | ||||
|  | ||||
|       onElEnd (e) { | ||||
|         if (this.isGroup) { | ||||
|           this.groupIndex = e.newIndex | ||||
|         } else { | ||||
|           this.activeIndex = e.newIndex | ||||
|         } | ||||
|       }, | ||||
|  | ||||
|       clone (e) { | ||||
|         if (e.type === 'group') { | ||||
|           this.targetList.push(JSON.parse(JSON.stringify(e))) | ||||
|  | ||||
|           this.$nextTick(() => { | ||||
|             this.isGroup = true | ||||
|             this.groupIndex = this.targetList.length - 1 | ||||
|             this.activeIndex = -1 | ||||
|           }) | ||||
|  | ||||
|           return | ||||
|         } | ||||
|  | ||||
|         if (this.isGroup) { | ||||
|           this.targetList[this.groupIndex].column.push(JSON.parse(JSON.stringify(e))) | ||||
|         } else { | ||||
|           this.targetList[0].column.push(JSON.parse(JSON.stringify(e))) | ||||
|         } | ||||
|  | ||||
|         this.$nextTick(() => { | ||||
|           this.groupIndex = this.isGroup ? this.groupIndex : 0 | ||||
|           this.activeIndex = this.targetList[0].column.length - 1 | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       onMove (e) { | ||||
|         const el = e.draggedContext.element | ||||
|         if (el.type === 'group') { | ||||
|           return false | ||||
|         } | ||||
|  | ||||
|         return true | ||||
|       }, | ||||
|  | ||||
|       cloneComponent (e) { | ||||
|         if (e.type === 'group') { | ||||
|           this.targetList.push(JSON.parse(JSON.stringify(e))) | ||||
|  | ||||
|           return | ||||
|         } | ||||
|  | ||||
|         return JSON.parse(JSON.stringify(e)) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .layout-right__del { | ||||
|     position: absolute; | ||||
|     bottom: 100px; | ||||
|     left: 0; | ||||
|     z-index: 11; | ||||
|     width: 100%; | ||||
|     padding: 0 16px; | ||||
|  | ||||
|     span { | ||||
|       display: block; | ||||
|       width: 100%; | ||||
|       height: 40px; | ||||
|       line-height: 40px; | ||||
|       text-align: center; | ||||
|       border-radius: 6px; | ||||
|       color: #F46; | ||||
|       cursor: pointer; | ||||
|       border: 1px solid #F46; | ||||
|  | ||||
|       &:hover { | ||||
|         opacity: 0.7; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   .form-config { | ||||
|     display: flex; | ||||
|     height: 100%; | ||||
|     padding: 10px 20px 0; | ||||
|  | ||||
|     .ai-form .el-form-item { | ||||
|       margin-bottom: 0; | ||||
|     } | ||||
|  | ||||
|     .right-item__maintitle { | ||||
|       height: 62px; | ||||
|       line-height: 62px; | ||||
|       margin-bottom: 20px; | ||||
|       border-bottom: 1px solid #EEEEEE; | ||||
|       color: #222222; | ||||
|  | ||||
|       h2 { | ||||
|         font-size: 14px; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     ::v-deep .ai-card { | ||||
|       cursor: move; | ||||
|  | ||||
|       &.active { | ||||
|         background: #f6f7ff; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     ::v-deep .ai-detail__content { | ||||
|       height: calc(100% - 52px)!important; | ||||
|       padding: 0!important; | ||||
|       overflow: hidden!important; | ||||
|     } | ||||
|  | ||||
|     .ai-dialog__success { | ||||
|       ::v-deep .ai-dialog__content { | ||||
|         max-height: initial!important; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .middle-draggable { | ||||
|       // display: flex; | ||||
|       // justify-content: space-between; | ||||
|       // flex-wrap: wrap; | ||||
|       .left-item__item { | ||||
|         width: 50%; | ||||
|         min-height: 73px; | ||||
|       } | ||||
|  | ||||
|       .el-date-editor.el-input { | ||||
|         width: 100%; | ||||
|       } | ||||
|  | ||||
|       & > span { | ||||
|         display: block; | ||||
|         width: 100%; | ||||
|         height: 100%; | ||||
|         min-height: 600px; | ||||
|         padding-bottom: 20px; | ||||
|       } | ||||
|  | ||||
|       .components-item { | ||||
|         position: relative; | ||||
|         margin-bottom: 16px; | ||||
|         padding: 16px 16px; | ||||
|         cursor: move; | ||||
|  | ||||
|         &::after { | ||||
|           position: absolute; | ||||
|           left: 0; | ||||
|           top: 0; | ||||
|           z-index: 1111; | ||||
|           width: 100%; | ||||
|           height: 100%; | ||||
|           content: ' '; | ||||
|         } | ||||
|  | ||||
|         .left-item__item--remove { | ||||
|           display: flex; | ||||
|           position: absolute; | ||||
|           align-items: center; | ||||
|           justify-content: center; | ||||
|           right: 4px; | ||||
|           top: 4px; | ||||
|           z-index: 1113; | ||||
|           width: 84px; | ||||
|           height: 28px; | ||||
|           background: #FF4466; | ||||
|           border-radius: 2px; | ||||
|           cursor: pointer; | ||||
|           color: #fff; | ||||
|           font-size: 12px; | ||||
|  | ||||
|           i { | ||||
|             margin-right: 6px; | ||||
|             font-size: 12px; | ||||
|  | ||||
|             &:hover { | ||||
|               color: #fff; | ||||
|             } | ||||
|           } | ||||
|  | ||||
|           &:hover { | ||||
|             opacity: 0.8; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         &:hover { | ||||
|           background: #f6f7ff; | ||||
|         } | ||||
|  | ||||
|         &.active { | ||||
|           background: #f6f7ff; | ||||
|         } | ||||
|  | ||||
|         .left-item__item--upload { | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           justify-content: center; | ||||
|           flex-direction: column; | ||||
|           width: 120px; | ||||
|           height: 120px; | ||||
|           line-height: 1; | ||||
|           border-radius: 6px; | ||||
|           border: 1px dashed #bbb; | ||||
|  | ||||
|           i { | ||||
|             font-size: 24px; | ||||
|             color: #8899bb; | ||||
|           } | ||||
|  | ||||
|           span { | ||||
|             margin-top: 10px; | ||||
|             font-size: 12px; | ||||
|             color: #555; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .text-item { | ||||
|           input { | ||||
|             display: block; | ||||
|             width: 100%; | ||||
|             height: 40px; | ||||
|             border: none; | ||||
|             border-bottom: 1px solid #ddd; | ||||
|  | ||||
|             &:focus { | ||||
|               outline: none; | ||||
|             } | ||||
|  | ||||
|             &:disabled { | ||||
|               background: #fff; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .textarea-item { | ||||
|           textarea { | ||||
|             width: 100%; | ||||
|             height: 120px; | ||||
|             resize: none; | ||||
|             border: 1px solid #ddd; | ||||
|             padding: 10px; | ||||
|  | ||||
|             &:focus { | ||||
|               outline: none; | ||||
|             } | ||||
|  | ||||
|             &:disabled { | ||||
|               background: #fff; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .radio-item { | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           margin-bottom: 10px; | ||||
|  | ||||
|           &:last-child { | ||||
|             margin-bottom: 0; | ||||
|           } | ||||
|  | ||||
|           label { | ||||
|             margin-left: 10px; | ||||
|           } | ||||
|  | ||||
|           img { | ||||
|             margin-left: 10px; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .left-item__item--title { | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         margin-bottom: 10px; | ||||
|  | ||||
|         i { | ||||
|           margin-right: 5px; | ||||
|           color: #E22120; | ||||
|         } | ||||
|  | ||||
|         h2 { | ||||
|           color: #333333; | ||||
|           font-size: 15px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .middle-content { | ||||
|       width: 96%; | ||||
|       margin: 0 auto; | ||||
|       padding: 0px 0 1px; | ||||
|  | ||||
|       .middle-content__wrapper { | ||||
|         // min-height: 800px; | ||||
|         // background: #fff; | ||||
|  | ||||
|         & > div { | ||||
|           &.active { | ||||
|             background: #f6f7ff; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .radio-item { | ||||
|           img { | ||||
|             width: 40px; | ||||
|             height: 40px; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     div { | ||||
|       box-sizing: border-box; | ||||
|     } | ||||
|  | ||||
|     .right-item__select--wrapper { | ||||
|       .select-item { | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     ::v-deep .ai-detail__title { | ||||
|       margin: 0!important; | ||||
|       margin-bottom: 4px!important; | ||||
|       padding: 0 20px; | ||||
|       box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.08); | ||||
|     } | ||||
|  | ||||
|     ::v-deep .ai-detail__content--wrapper { | ||||
|       display: flex; | ||||
|       max-width: 100%!important; | ||||
|       height: 100%!important; | ||||
|       padding: 0!important; | ||||
|       background: #F5F6F9; | ||||
|     } | ||||
|  | ||||
|     .middle { | ||||
|       flex: 1; | ||||
|       height: 100%; | ||||
|  | ||||
|       ::v-deep .el-scrollbar__view { | ||||
|         height: 100%; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .add-select { | ||||
|       height: auto; | ||||
|       line-height: 1; | ||||
|       margin: 10px 0 0 26px; | ||||
|       padding: 0; | ||||
|     } | ||||
|  | ||||
|     .right-item__select--wrapper { | ||||
|       .select-item { | ||||
|         margin-bottom: 10px; | ||||
|  | ||||
|         &:last-child { | ||||
|           margin-bottom: 0; | ||||
|         } | ||||
|  | ||||
|         i { | ||||
|           margin-right: 8px; | ||||
|           color: #8c9dbd; | ||||
|         } | ||||
|  | ||||
|         .mover { | ||||
|           cursor: move; | ||||
|         } | ||||
|  | ||||
|         .iconDelete { | ||||
|           cursor: pointer; | ||||
|           margin-left: 10px; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       ::v-deep .el-upload-list__item { | ||||
|         width: 40px!important; | ||||
|         height: 40px!important; | ||||
|         object-fit: cover; | ||||
|       } | ||||
|  | ||||
|       .config-item__select { | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         justify-content: center; | ||||
|         width: 40px; | ||||
|         height: 40px; | ||||
|         border: 1px solid #D0D4DC; | ||||
|  | ||||
|         &:hover { | ||||
|           opacity: 0.7; | ||||
|         } | ||||
|  | ||||
|         i { | ||||
|           font-size: 18px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .right { | ||||
|       width: 320px; | ||||
|       height: 100%; | ||||
|       overflow-y: auto; | ||||
|       overflow: hidden; | ||||
|       background: #FFFFFF; | ||||
|  | ||||
|       .el-checkbox { | ||||
|         display: block; | ||||
|         margin-bottom: 10px; | ||||
|  | ||||
|         &:last-child { | ||||
|           margin-bottom: 0; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .right-item { | ||||
|         margin-top: 20px; | ||||
|         padding: 0 20px; | ||||
|  | ||||
|         .right-item__tips { | ||||
|           margin-top: 10px; | ||||
|           color: #888888; | ||||
|           font-size: 12px; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .right-item__title { | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         justify-content: space-between; | ||||
|         margin-bottom: 10px; | ||||
|  | ||||
|         .right-item__title--left { | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|  | ||||
|           i { | ||||
|             color: #888888; | ||||
|             font-size: 12px; | ||||
|             font-style: normal; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         h2 { | ||||
|           color: #222222; | ||||
|           font-size: 14px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .left { | ||||
|       width: 280px; | ||||
|       height: 100%; | ||||
|       overflow-y: auto; | ||||
|       overflow: hidden; | ||||
|       background: #FFFFFF; | ||||
|  | ||||
|       .left-item { | ||||
|         padding: 0 20px; | ||||
|  | ||||
|         &:last-child { | ||||
|           padding-bottom: 20px; | ||||
|         } | ||||
|  | ||||
|         .left-item__title { | ||||
|           display: flex; | ||||
|           align-items: baseline; | ||||
|           margin-bottom: 20px; | ||||
|  | ||||
|           h2 { | ||||
|             color: #222222; | ||||
|             font-size: 14px; | ||||
|             font-weight: 700; | ||||
|           } | ||||
|  | ||||
|           span { | ||||
|             color: #888888; | ||||
|             font-size: 12px; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .left-item { | ||||
|         margin-top: 20px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .left-item__item { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     height: 40px; | ||||
|     margin-bottom: 10px; | ||||
|     width: 100%; | ||||
|     padding: 0 13px; | ||||
|     background: #FFFFFF; | ||||
|     border-radius: 2px; | ||||
|     color: #222222; | ||||
|     font-size: 12px; | ||||
|     border: 1px solid #E4E8EF; | ||||
|     cursor: move; | ||||
|  | ||||
|     &:hover { | ||||
|       border: 1px dashed #2367ff; | ||||
|       color: #2367ff; | ||||
|  | ||||
|       i { | ||||
|         color: #2367ff; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     i { | ||||
|       margin-right: 13px; | ||||
|       font-size: 14px; | ||||
|       color: #8899BB; | ||||
|     } | ||||
|  | ||||
|     &:last-child { | ||||
|       margin-bottom: 0px; | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
| @@ -0,0 +1,196 @@ | ||||
| <template> | ||||
|   <div class="attachment-material"> | ||||
|     <ai-card title="附件材料"> | ||||
|       <template #right> | ||||
|         <span class="iconfont iconAdd rightBtn"></span> | ||||
|         <span class="rightBtn" style="margin-left: 8px;" @click="dialog=true">新增行数</span> | ||||
|       </template> | ||||
|       <template #content> | ||||
|         <el-table | ||||
|           :data="materialList" | ||||
|           stripe | ||||
|           style="width: 100%" | ||||
|           header-cell-class-name="table-header" | ||||
|           align="center" | ||||
|           empty-text="材料列表信息为空,点击标题右侧添加按钮进行添加" | ||||
|         > | ||||
|           <el-table-column align="left" prop="annexName" label="材料名称" width="280"> | ||||
|             <template slot-scope="scope"> | ||||
|               <div class="table-border">{{ scope.row.annexName }}</div> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|           <el-table-column align="center" prop="exampleFileId" label="样例"> | ||||
|             <template slot-scope="{row}"> | ||||
|               <el-upload action :on-exceed="list=>handleUpload({file:list[0]}).then(v=>row.exampleFileId=v)" | ||||
|                          :http-request="args=>handleUpload(args).then(v=>row.exampleFileId=v)" :limit="1" accept=".jpg,.png"> | ||||
|                 <el-button style="width: 102px">{{ row.exampleFileId ? '重新选择图片' : '选择图片文件' }}</el-button> | ||||
|               </el-upload> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|           <el-table-column align="center" prop="emptyFileId" label="空表"> | ||||
|             <template slot-scope="{row}"> | ||||
|               <el-upload action :on-exceed="list=>handleUpload({file:list[0]}).then(v=>row.emptyFileId=v)" | ||||
|                          :http-request="args=>handleUpload(args).then(v=>row.emptyFileId=v)" :limit="1" accept=".doc,.docx"> | ||||
|                 <el-button style="width: 102px">{{ row.emptyFileId ? '重新选择word' : '选择word文件' }}</el-button> | ||||
|               </el-upload> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|           <el-table-column align="center" prop="name" label="是否必填"> | ||||
|             <template slot-scope="scope"> | ||||
|               <el-switch | ||||
|                 v-model="scope.row.mustFill" | ||||
|                 active-value="1" inactive-value="0" | ||||
|                 active-color="#5088FF" | ||||
|                 inactive-color="#D0D4DC"> | ||||
|               </el-switch> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|           <el-table-column align="center" label="操作"> | ||||
|             <template slot-scope="scope"> | ||||
|               <span class="iconfont iconEdit icon-color89B" title="编辑" @click="editInfo(scope.$index)" style="margin-right: 10px;"/> | ||||
|               <span class="iconfont iconDelete icon-color89B" title="删除" @click="deleteInfo(scope.$index)"/> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|         </el-table> | ||||
|       </template> | ||||
|     </ai-card> | ||||
|     <ai-dialog | ||||
|         title="添加附件材料" | ||||
|         :visible.sync="dialog" | ||||
|         @closed="form.annexName='',idAdd=true,index=null" | ||||
|         @onConfirm="onConfirm" | ||||
|         @onCancel="dialog=false" | ||||
|         width="720px"> | ||||
|       <el-form :rules="rules" ref="materialForm" label-width="100px" :model="form"> | ||||
|         <el-form-item label="材料名称:" prop="annexName"> | ||||
|           <el-input v-model.trim="form.annexName" size="small" placeholder="请输入材料名称" show-word-limit :maxlength="32"/> | ||||
|         </el-form-item> | ||||
|       </el-form> | ||||
|     </ai-dialog> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "attachmentMaterial", | ||||
|   inject: ['config'], | ||||
|   props: { | ||||
|     instance: Function, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       materialList: [], | ||||
|       dialog: false, | ||||
|       idAdd: true, | ||||
|       index: null, | ||||
|       form: { | ||||
|         annexName: "" | ||||
|       }, | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     rules() { | ||||
|       return { | ||||
|         annexName: [{required: true, message: '请输入材料名称', trigger: 'blur'}] | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     handleAttachmentMaterial() { | ||||
|       return Promise.resolve(this.materialList) | ||||
|     }, | ||||
|     handleUpload(file) { | ||||
|       let formData = new FormData() | ||||
|       formData.append('file', file.file) | ||||
|       return this.instance.post(`/admin/file/add`, formData).then(res => { | ||||
|         if (res?.code == 0) { | ||||
|           this.$message.success('上传成功') | ||||
|           let data = res.data[0].split(';') | ||||
|           return data[1] | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     /** | ||||
|      * 添加附件材料 | ||||
|      * */ | ||||
|     onConfirm() { | ||||
|       this.$refs['materialForm'].validate(valid => { | ||||
|         if (valid) { | ||||
|           if(this.idAdd){ | ||||
|             this.materialList.push({ | ||||
|               annexName: this.form.annexName, | ||||
|               mustFill: "1", | ||||
|               exampleFileId: "", | ||||
|               emptyFileId: "", | ||||
|             }) | ||||
|           }else { | ||||
|             this.materialList[this.index].annexName = this.form.annexName | ||||
|           } | ||||
|           this.dialog = false | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     /** | ||||
|      * 删除 | ||||
|      */ | ||||
|     deleteInfo(index) { | ||||
|       this.$confirm("是否删除?").then(res => { | ||||
|         this.materialList.splice(index, 1) | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     /** | ||||
|      * 编辑标题 | ||||
|      */ | ||||
|     editInfo(index) { | ||||
|       this.dialog = true | ||||
|       this.idAdd = false | ||||
|       this.index = index | ||||
|       this.form.annexName = JSON.parse(JSON.stringify(this.materialList[index].annexName)) | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   created() { | ||||
|     if (this.config.detailObj?.id) { | ||||
|       this.materialList = JSON.parse(JSON.stringify(this.config.detailObj?.processAnnexDefs)) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .attachment-material { | ||||
|   .rightBtn { | ||||
|     font-size: 14px; | ||||
|     color: #5088FF; | ||||
|     user-select: none; | ||||
|     cursor: pointer; | ||||
|   } | ||||
|  | ||||
|   .table-border { | ||||
|     width: 260px; | ||||
|     height: 32px; | ||||
|     box-sizing: border-box; | ||||
|     padding: 0 14px; | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     border-radius: 2px; | ||||
|     border: 1px solid #D0D4DC; | ||||
|     color: #333333; | ||||
|     overflow: hidden; | ||||
|     text-overflow: ellipsis; | ||||
|     white-space: nowrap; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .el-upload-list { | ||||
|     display: none; | ||||
|   } | ||||
|  | ||||
|   .iconDelete { | ||||
|     user-select: none; | ||||
|     cursor: pointer; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -0,0 +1,154 @@ | ||||
| <template> | ||||
|   <section class="base-info"> | ||||
|     <ai-card title="基本信息"> | ||||
|       <template #content> | ||||
|         <el-form :model="form" :rules="rules" ref="baseInfoForm" label-suffix=":" label-width="100px"> | ||||
|           <el-form-item label="事项名称" prop="processName"> | ||||
|             <el-input v-model.trim="form.processName" size="small" clearable placeholder="请输入事项名称" :maxlength="30" | ||||
|                       show-word-limit/> | ||||
|           </el-form-item> | ||||
|           <el-row type="type" justify="space-between" :gutter="20"> | ||||
|             <el-col :span="12"> | ||||
|               <el-form-item label="所属部门" prop="department"> | ||||
|                 <el-select placeholder="请选择" size="small" v-model="form.department" clearable style="width: 100%;"> | ||||
|                   <el-option | ||||
|                     v-for="(item,i) in dict.getDict('hbDepartment')" :key="i" | ||||
|                     :label="item.dictName" | ||||
|                     :value="item.dictValue"> | ||||
|                   </el-option> | ||||
|                 </el-select> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|             <el-col :span="12"> | ||||
|               <el-form-item label="所属分类" prop="classificationId"> | ||||
|                 <el-select placeholder="请选择" size="small" v-model="form.classificationId" clearable | ||||
|                            style="width: 100%;"> | ||||
|                   <el-option | ||||
|                     v-for="(item,i) in classList" :key="i" | ||||
|                     :label="item.name" | ||||
|                     :value="item.id"> | ||||
|                   </el-option> | ||||
|                 </el-select> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|           </el-row> | ||||
|           <el-form-item label="办结时限" prop="timeLimit"> | ||||
|             <el-input v-model.trim="form.timeLimit" oninput="value=value.replace(/[^\d]/g,'')" size="small" clearable | ||||
|                       placeholder="请输入天数" style="width: 270px;"/> | ||||
|           </el-form-item> | ||||
|           <el-form-item label="办理须知" prop="needToKnow"> | ||||
|             <ai-editor v-model="form.needToKnow" :instance="instance" @validate="v=>valid=!v"/> | ||||
|           </el-form-item> | ||||
|           <el-form-item label="是否启用" prop="processDefStatus"> | ||||
|             <el-switch | ||||
|               v-model="form.processDefStatus" | ||||
|               active-color="#5088FF" | ||||
|               inactive-color="#D0D4DC" active-value="1" inactive-value="0"> | ||||
|             </el-switch> | ||||
|           </el-form-item> | ||||
|         </el-form> | ||||
|       </template> | ||||
|     </ai-card> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|  | ||||
|   export default { | ||||
|     name: "baseInfo", | ||||
|     inject: ['config'], | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|     }, | ||||
|     data() { | ||||
|       const validTimeLimit = (rule, value, callback) => { | ||||
|         if (!value) { | ||||
|           return callback(new Error('请输入办结时限')); | ||||
|         } else { | ||||
|           if (+value <= 0) { | ||||
|             return callback(new Error('最小值为1')); | ||||
|           } | ||||
|           callback(); | ||||
|         } | ||||
|       } | ||||
|       return { | ||||
|         form: { | ||||
|           processName: "", | ||||
|           department: "", | ||||
|           classificationId: "", | ||||
|           timeLimit: "", | ||||
|           needToKnow: "", | ||||
|           processDefStatus: "1", | ||||
|         }, | ||||
|         valid:true, | ||||
|         classList: [], | ||||
|         rules: { | ||||
|           processName: [{required: true, message: '请输入事项名称', trigger: 'blur'}], | ||||
|           department: [{required: true, message: '请选择所属部门', trigger: 'change'}], | ||||
|           classificationId: [{required: true, message: '请选择所属分类', trigger: 'change'}], | ||||
|           timeLimit: [{required: true, validator: validTimeLimit, trigger: 'blur'}], | ||||
|           needToKnow: [ | ||||
|             {required: true, message: '请输入办理须知', trigger: 'blur'}, | ||||
|             { | ||||
|               validator: (r, v, cb) => { | ||||
|                 if (this.valid) { | ||||
|                   cb() | ||||
|                 } else { | ||||
|                   cb('字数超过限制') | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ], | ||||
|           processDefStatus: [{required: true, message: '请选择是否启用', trigger: 'change'}], | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     methods: { | ||||
|       banseInfoForm() { | ||||
|         return new Promise((resolve, reject) => { | ||||
|           this.$refs['baseInfoForm'].validate(valid => { | ||||
|             if (valid) { | ||||
|               resolve(this.form) | ||||
|             } else { | ||||
|               reject(false) | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|       /** | ||||
|        * 获取分类 | ||||
|        */ | ||||
|       getClassification() { | ||||
|         this.instance.post(`/app/zwspapprovalclassification/list`, null, { | ||||
|          params: { | ||||
|            current: 1, | ||||
|            status: 1, | ||||
|            size: 9999 | ||||
|          } | ||||
|         }).then(res => { | ||||
|           if (res?.data) { | ||||
|             this.classList = res.data.records | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|     created() { | ||||
|       this.getClassification() | ||||
|       if (this.config.detailObj?.id) { | ||||
|         this.$nextTick(_=>{ | ||||
|           Object.keys(this.form).map(e => this.form[e] = this.config.detailObj[e]) | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .base-info { | ||||
|     .iconAudit { | ||||
|       font-size: 36px; | ||||
|       color: #3D94FB; | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
| @@ -0,0 +1,203 @@ | ||||
| export const components = [ | ||||
| 	{ | ||||
| 		type: 'info', | ||||
| 		tips: '(可重复添加)', | ||||
| 		label: '信息', | ||||
| 		children: [ | ||||
| 			{ | ||||
| 				type: 'name', | ||||
| 				fieldName: '姓名', | ||||
| 				fieldTips: '请输入姓名', | ||||
| 				fixedLabel: '姓名', | ||||
| 				disable: '0', | ||||
| 				grid: 1, | ||||
| 				fieldDataType: '1', | ||||
| 				defaultValue: '', | ||||
| 				icon: 'icontext_box', | ||||
| 				mustFill: '1', | ||||
| 				fieldLength: 20 | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'idNumber', | ||||
| 				fieldName: '身份证号', | ||||
| 				fixedLabel: '身份证号', | ||||
| 				fieldTips: '请输入身份证号', | ||||
| 				defaultValue: '', | ||||
| 				icon: 'icontext_area', | ||||
| 				mustFill: '1', | ||||
| 				fieldLength: 20, | ||||
| 				disable: '0', | ||||
| 				grid: 1, | ||||
| 				fieldDataType: '1', | ||||
| 				verifyType: 0 | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'phone', | ||||
| 				fieldName: '联系方式', | ||||
| 				fixedLabel: '联系方式', | ||||
| 				fieldTips: '请输入联系方式', | ||||
| 				defaultValue: '', | ||||
| 				icon: 'icontext_area', | ||||
| 				mustFill: '1', | ||||
| 				fieldLength: 11, | ||||
| 				disable: '0', | ||||
| 				grid: 1, | ||||
| 				fieldDataType: '1', | ||||
| 				verifyType: 1 | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	{ | ||||
| 		type: 'options', | ||||
| 		tips: '(可重复添加)', | ||||
| 		label: '选项', | ||||
| 		children: [ | ||||
| 			{ | ||||
| 				type: 'radio', | ||||
| 				fieldName: '单选', | ||||
| 				fixedLabel: '单选', | ||||
| 				fieldTips: '请选择', | ||||
| 				grid: 1, | ||||
| 				icon: 'iconradio', | ||||
| 				mustFill: '1', | ||||
| 				disable: '0', | ||||
| 				fieldDataType: '4', | ||||
| 				defaultValue: '', | ||||
| 				options: [ | ||||
| 					{ | ||||
| 						label: '选项1', | ||||
| 						value: '' | ||||
| 					}, | ||||
| 					{ | ||||
| 						label: '选项2', | ||||
| 						value: '' | ||||
| 					} | ||||
| 				], | ||||
| 				title: '' | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'checkbox', | ||||
| 				fieldName: '多选', | ||||
| 				fixedLabel: '多选', | ||||
| 				fieldTips: '请选择', | ||||
| 				icon: 'iconcheck_box', | ||||
| 				fieldDataType: '5', | ||||
| 				mustFill: '1', | ||||
| 				grid: 1, | ||||
| 				disable: '0', | ||||
| 				defaultValue: [], | ||||
| 				options: [ | ||||
| 					{ | ||||
| 						label: '选项1', | ||||
| 						value: '' | ||||
| 					}, | ||||
| 					{ | ||||
| 						label: '选项2', | ||||
| 						value: '' | ||||
| 					} | ||||
| 				], | ||||
| 				title: '' | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'select', | ||||
| 				fieldName: '单下拉框', | ||||
| 				fixedLabel: '单下拉框', | ||||
| 				grid: 1, | ||||
| 				fieldTips: '请选择', | ||||
| 				icon: 'iconSelect', | ||||
| 				mustFill: '1', | ||||
| 				defaultValue: '', | ||||
| 				fieldDataType: '9', | ||||
| 				disable: '0', | ||||
| 				options: [ | ||||
| 					{ | ||||
| 						label: '选项1', | ||||
| 						value: '' | ||||
| 					}, | ||||
| 					{ | ||||
| 						label: '选项2', | ||||
| 						value: '' | ||||
| 					} | ||||
| 				], | ||||
| 				title: '' | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'date', | ||||
| 				fieldName: '日期', | ||||
| 				fixedLabel: '日期', | ||||
| 				grid: 1, | ||||
| 				fieldDataType: '3', | ||||
| 				datetimePattern: 'yyyy-MM-dd', | ||||
| 				fieldTips: '请选择日期', | ||||
| 				icon: 'iconSelect', | ||||
| 				mustFill: '1', | ||||
| 				disable: '0', | ||||
| 				title: '' | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'datetime', | ||||
| 				fieldName: '日期时间', | ||||
| 				fixedLabel: '日期时间', | ||||
| 				grid: 1, | ||||
| 				fieldDataType: '8', | ||||
| 				datetimePattern: 'yyyy-MM-dd HH:mm:ss', | ||||
| 				fieldTips: '请选择日期时间', | ||||
| 				icon: 'iconSelect', | ||||
| 				mustFill: '1', | ||||
| 				disable: '0', | ||||
| 				title: '' | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	{ | ||||
| 		type: 'input', | ||||
| 		tips: '(可重复添加)', | ||||
| 		label: '填空', | ||||
| 		children: [ | ||||
| 			{ | ||||
| 				type: 'input', | ||||
| 				fieldName: '单行填空', | ||||
| 				fieldTips: '请输入', | ||||
| 				fixedLabel: '单行填空', | ||||
| 				disable: '0', | ||||
| 				grid: 1, | ||||
| 				fieldDataType: '1', | ||||
| 				defaultValue: '', | ||||
| 				icon: 'icontext_box', | ||||
| 				mustFill: '1', | ||||
| 				fieldLength: 50 | ||||
| 			}, | ||||
| 			{ | ||||
| 				type: 'number', | ||||
| 				fieldName: '数字输入', | ||||
| 				fixedLabel: '数字输入', | ||||
| 				fieldTips: '请输入数字', | ||||
| 				defaultValue: '', | ||||
| 				icon: 'icontext_area', | ||||
| 				mustFill: '1', | ||||
| 				maxValue: 10000, | ||||
| 				decimalPlaces: 0, | ||||
| 				fieldDataType: '0', | ||||
| 				minValue: 0, | ||||
| 				fieldLength: 50, | ||||
| 				disable: '0', | ||||
| 				grid: 1, | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	{ | ||||
| 		type: 'layout', | ||||
| 		tips: '(可重复添加)', | ||||
| 		label: '分组', | ||||
| 		children: [ | ||||
| 			{ | ||||
| 				type: 'group', | ||||
| 				fieldName: '卡片', | ||||
| 				fixedLabel: '卡片', | ||||
| 				icon: 'iconpic', | ||||
| 				groupName: '分组标题', | ||||
| 				column: [] | ||||
| 			} | ||||
| 		] | ||||
| 	} | ||||
| ]; | ||||
| @@ -0,0 +1,214 @@ | ||||
| <template> | ||||
|   <div class="config-list"> | ||||
|     <ai-list isTabs> | ||||
|       <template #content> | ||||
|         <ai-search-bar> | ||||
|           <template #left> | ||||
|             <el-select v-model="search.department" placeholder="请选择所属部门" @change="page.current=1,getList()" | ||||
|                        size="small" clearable> | ||||
|               <el-option | ||||
|                 v-for="(item,i) in dict.getDict('hbDepartment')" :key="i" | ||||
|                 :label="item.dictName" | ||||
|                 :value="item.dictValue"> | ||||
|               </el-option> | ||||
|             </el-select> | ||||
|             <el-select v-model="search.classificationId" placeholder="请选择所属分类" @change="page.current=1,getList()" | ||||
|                        size="small" clearable> | ||||
|               <el-option | ||||
|                 v-for="(item,i) in classList" :key="i" | ||||
|                 :label="item.name" | ||||
|                 :value="item.id"> | ||||
|               </el-option> | ||||
|             </el-select> | ||||
|           </template> | ||||
|           <template #right> | ||||
|             <el-input | ||||
|               v-model="search.processName" | ||||
|               size="small" | ||||
|               placeholder="事项名称/创建人" | ||||
|               @clear="search={},page.current=1,getList()" | ||||
|               v-throttle="() => {page.current = 1, getList()}" | ||||
|               clearable | ||||
|               suffix-icon="iconfont iconSearch"/> | ||||
|           </template> | ||||
|         </ai-search-bar> | ||||
|         <ai-search-bar> | ||||
|           <template #left> | ||||
|             <el-button type="primary" icon="iconfont iconAdd" @click="goPage(tab.value==0 ? 'addConfig':'guidance')">添加{{tab.value==0?'事项':'办事指南'}}</el-button> | ||||
|           </template> | ||||
|         </ai-search-bar> | ||||
|         <ai-table | ||||
|           :tableData="tableData" | ||||
|           :col-configs="colConfigs" | ||||
|           :header-cell-style="{fontWeight:'bold',color:'#333'}" | ||||
|           :total="page.total" | ||||
|           :current.sync="page.current" | ||||
|           :size.sync="page.size" | ||||
|           @getList="getList"> | ||||
|           <el-table-column label="是否启用" slot="processDefStatus" align="center" width="150"> | ||||
|             <template v-slot="{row}"> | ||||
|               <el-switch | ||||
|                 v-model="row.processDefStatus" | ||||
|                 @change="onChange(row)" active-value="1" inactive-value="0" | ||||
|                 active-color="#5088FF" | ||||
|                 inactive-color="#D0D4DC"> | ||||
|               </el-switch> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|           <el-table-column label="操作" slot="options" align="center" width="150"> | ||||
|             <template v-slot="{row}"> | ||||
|               <div class="table-options"> | ||||
|                 <el-button type="text" title="编辑" @click="goPage(tab.value==0 ? 'addConfig':'guidance',row)">编辑</el-button> | ||||
|                 <el-button type="text" title="删除" @click="delInfo(row)">删除</el-button> | ||||
|               </div> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|         </ai-table> | ||||
|       </template> | ||||
|     </ai-list> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import day from 'dayjs' | ||||
|  | ||||
|   export default { | ||||
|     name: "configList", | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       permissions: Function, | ||||
|       tab: Object, | ||||
|     }, | ||||
|     data() { | ||||
|       return { | ||||
|         search: { | ||||
|           department: "", | ||||
|           classificationId: "", | ||||
|           processName: "", | ||||
|         }, | ||||
|         page: {current: 1, size: 10}, | ||||
|         total: 0, | ||||
|         row: {}, | ||||
|         tableData: [], | ||||
|         classList: [], | ||||
|       } | ||||
|     }, | ||||
|     computed: { | ||||
|       colConfigs() { | ||||
|         return [ | ||||
|           { | ||||
|             prop: 'processName', | ||||
|             align: 'left', | ||||
|             label: '事项名称', | ||||
|           }, | ||||
|           { | ||||
|             prop: 'department', | ||||
|             align: 'left', | ||||
|             label: '所属部门', | ||||
|             render: (h, {row}) => [ < span > {this.dict.getLabel('hbDepartment', row.department)} < /span>] | ||||
|           }, | ||||
|           { | ||||
|             prop: 'classificationName', | ||||
|             align: 'center', | ||||
|             label: '所属分类', | ||||
|           }, | ||||
|           { | ||||
|             prop: 'timeLimit', | ||||
|             align: 'center', | ||||
|             label: '办结时限(日)', | ||||
|           }, | ||||
|           { | ||||
|             prop: 'createUserName', | ||||
|             align: 'center', | ||||
|             label: '创建人', | ||||
|           }, | ||||
|           { | ||||
|             prop: 'createTime', | ||||
|             align: 'center', | ||||
|             label: '最后修改时间', | ||||
|             render: (h, {row}) => [ < span > {day(row.createTime | ||||
|       ). | ||||
|         format("YYYY-MM-DD HH:mm") | ||||
|       }< | ||||
|         /span>] | ||||
|       }, | ||||
|         {slot: 'processDefStatus', align:'center', label:'是否启用',}, | ||||
|         { slot: 'options',align:'center',label:'操作',}, | ||||
|       ].filter(e=>this.tab.value==0 ? true : (e.prop!="timeLimit")) | ||||
|       }, | ||||
|     }, | ||||
|     methods: { | ||||
|       goPage(comp, row = {}) { | ||||
|         this.$emit("goPage", {comp, row}) | ||||
|       }, | ||||
|       /** | ||||
|        * 获取分类 | ||||
|        */ | ||||
|       getClassification() { | ||||
|         this.instance.post(`/app/zwspapprovalclassification/list`, null, { | ||||
|           params:{ | ||||
|             current: 1, | ||||
|             status: 1, | ||||
|             size: 9999 | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res && res.data) { | ||||
|             this.classList = res.data.records | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       /** | ||||
|        * 删除 | ||||
|        * */ | ||||
|       delInfo({id}) { | ||||
|         this.$confirm("是否删除").then(() => { | ||||
|           this.instance.post(`/app/approval-process-def/delete?id=${id}`).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.$message.success("删除成功") | ||||
|               this.getList() | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|       /** | ||||
|        * 启用,停用 | ||||
|        */ | ||||
|       onChange({id, processDefStatus}) { | ||||
|         this.instance.post(`/app/approval-process-def/enable-disable`, null, { | ||||
|           params: {id} | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.$message.success(processDefStatus == 0 ? "不启用" : "已启用") | ||||
|             this.getList() | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       getList() { | ||||
|         this.instance.post(`/app/approval-process-def/list`, null, { | ||||
|           params: { | ||||
|             ...this.page, | ||||
|             ...this.search, | ||||
|             processType: this.tab.value | ||||
|           }, | ||||
|         }).then(res => { | ||||
|           if (res?.data) { | ||||
|             this.tableData = res.data.records | ||||
|             this.page.total = res.data.total; | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|     }, | ||||
|     mounted() { | ||||
|       this.getList() | ||||
|       this.getClassification() | ||||
|     }, | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .config-list { | ||||
|     height: 100%; | ||||
|   } | ||||
| </style> | ||||
| @@ -0,0 +1,219 @@ | ||||
| <template> | ||||
|   <div class="guidance"> | ||||
|     <ai-detail> | ||||
|       <ai-title slot="title" :title="detailTitle" isShowBack isShowBottomBorder @onBackClick="handleBack"/> | ||||
|       <template #content> | ||||
|         <ai-card title="基本信息"> | ||||
|           <template #content> | ||||
|             <el-form :model="form" :rules="rules" ref="baseInfoForm" label-suffix=":" label-width="100px"> | ||||
|               <el-form-item label="事项名称" prop="processName"> | ||||
|                 <el-input v-model.trim="form.processName" size="small" clearable placeholder="请输入事项名称" :maxlength="30" | ||||
|                           show-word-limit/> | ||||
|               </el-form-item> | ||||
|               <el-row type="type" justify="space-between" :gutter="20"> | ||||
|                 <el-col :span="12"> | ||||
|                   <el-form-item label="所属部门" prop="department"> | ||||
|                     <el-select placeholder="请选择" size="small" v-model="form.department" clearable style="width: 100%;"> | ||||
|                       <el-option | ||||
|                         v-for="(item,i) in dict.getDict('hbDepartment')" :key="i" | ||||
|                         :label="item.dictName" | ||||
|                         :value="item.dictValue"> | ||||
|                       </el-option> | ||||
|                     </el-select> | ||||
|                   </el-form-item> | ||||
|                 </el-col> | ||||
|                 <el-col :span="12"> | ||||
|                   <el-form-item label="所属分类" prop="classificationId"> | ||||
|                     <el-select placeholder="请选择" size="small" v-model="form.classificationId" clearable | ||||
|                                style="width: 100%;"> | ||||
|                       <el-option | ||||
|                         v-for="(item,i) in classList" :key="i" | ||||
|                         :label="item.name" | ||||
|                         :value="item.id"> | ||||
|                       </el-option> | ||||
|                     </el-select> | ||||
|                   </el-form-item> | ||||
|                 </el-col> | ||||
|               </el-row> | ||||
|               <el-form-item label="办理须知" prop="needToKnow"> | ||||
|                 <ai-editor v-model.trim="form.needToKnow" :instance="instance"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="是否启用" prop="processDefStatus"> | ||||
|                 <el-switch | ||||
|                   v-model="form.processDefStatus" | ||||
|                   active-color="#5088FF" | ||||
|                   inactive-color="#D0D4DC" active-value="1" inactive-value="0"> | ||||
|                 </el-switch> | ||||
|               </el-form-item> | ||||
|             </el-form> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|       </template> | ||||
|       <template #footer> | ||||
|         <el-button class="btn" @click="handleBack">取消</el-button> | ||||
|         <el-button class="btn" type="primary" @click="save">保存</el-button> | ||||
|       </template> | ||||
|     </ai-detail> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|  | ||||
|   export default { | ||||
|     name: "addConfig", | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       row: Object, | ||||
|       processType: String | ||||
|     }, | ||||
|     data() { | ||||
|       return { | ||||
|         form: { | ||||
|           processName: "", | ||||
|           department: "", | ||||
|           classificationId: "", | ||||
|           needToKnow: "", | ||||
|           processDefStatus: "1", | ||||
|         }, | ||||
|         classList: [], | ||||
|       } | ||||
|     }, | ||||
|     computed: { | ||||
|       rules() { | ||||
|         return { | ||||
|           processName: [{required: true, message: '请输入事项名称', trigger: 'blur'}], | ||||
|           department: [{required: true, message: '请选择所属部门', trigger: 'change'}], | ||||
|           classificationId: [{required: true, message: '请选择所属分类', trigger: 'change'}], | ||||
|           needToKnow: [{required: true, message: '请输入办理须知', trigger: 'blur'}], | ||||
|           processDefStatus: [{required: true, message: '请选择是否启用', trigger: 'change'}], | ||||
|         } | ||||
|       }, | ||||
|       detailTitle() { | ||||
|         return this.row?.id ? "编辑办事指南" : "添加办事指南" | ||||
|       } | ||||
|     }, | ||||
|     methods: { | ||||
|       /** | ||||
|        * 获取分类 | ||||
|        */ | ||||
|       getClassification() { | ||||
|         this.instance.post(`/app/zwspapprovalclassification/list`, null, { | ||||
|           params: { | ||||
|             current: 1, | ||||
|             status: 1, | ||||
|             size: 9999 | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res?.data) { | ||||
|             this.classList = res.data.records | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       /** | ||||
|        * 保存 | ||||
|        */ | ||||
|       save() { | ||||
|         this.$refs["baseInfoForm"].validate(valid => { | ||||
|           if (valid) { | ||||
|             this.instance.post(`/app/approval-process-def/add-update`, { | ||||
|               ...this.form, | ||||
|               id: this.row.id, | ||||
|               processType: this.processType | ||||
|             }).then(res => { | ||||
|               if (res.code == 0) { | ||||
|                 this.$message.success("保存成功") | ||||
|                 this.$router.push({query: {}}) | ||||
|               } | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       getDetail(id) { | ||||
|         this.instance.post(`/app/approval-process-def/info-id`, null, {params: {id}}).then(res => { | ||||
|           if (res?.data) { | ||||
|             Object.keys(this.form).map(e => this.form[e] = res.data[e]) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       handleBack() { | ||||
|         this.$router.push({query: {}}) | ||||
|       } | ||||
|     }, | ||||
|     created() { | ||||
|       this.getClassification() | ||||
|       if (this.row?.id) { | ||||
|         this.getDetail(this.row?.id) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .add-config { | ||||
|     height: 100%; | ||||
|  | ||||
|     .step { | ||||
|       width: 100%; | ||||
|       height: 72px; | ||||
|       font-size: 14px; | ||||
|  | ||||
|       .el-steps { | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         height: 72px; | ||||
|         padding: 0 calc(50% - 380px); | ||||
|  | ||||
|  | ||||
|         ::v-deep .el-step { | ||||
|           font-weight: bold; | ||||
|  | ||||
|           ::v-deep .el-step__icon { | ||||
|             width: 24px; | ||||
|             height: 24px; | ||||
|             background: #fff; | ||||
|  | ||||
|             .iconfont { | ||||
|               font-size: 24px; | ||||
|             } | ||||
|           } | ||||
|  | ||||
|           ::v-deep .el-step__main { | ||||
|             display: flex; | ||||
|             align-items: center; | ||||
|  | ||||
|             .el-step__arrow { | ||||
|               background: #D0D4DC; | ||||
|               margin: 0 8px; | ||||
|               height: 2px; | ||||
|  | ||||
|               &:before, &:after { | ||||
|                 display: none; | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|  | ||||
|           .is-process { | ||||
|             color: #2266FF; | ||||
|           } | ||||
|  | ||||
|           .is-wait { | ||||
|             color: #666; | ||||
|             border-color: #D0D4DC; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|       } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     .btn { | ||||
|       width: 92px; | ||||
|       height: 32px; | ||||
|  | ||||
|       &:nth-child(2) { | ||||
|         margin-left: 24px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
| @@ -0,0 +1,4 @@ | ||||
| export {default as baseInfo} from './baseInfo' | ||||
| export {default as applyForm} from './applyForm' | ||||
| export {default as attachmentMaterial} from './attachmentMaterial' | ||||
| export {default as processApproval} from './processApproval' | ||||
| @@ -0,0 +1,482 @@ | ||||
| <template> | ||||
|   <div class="process-approval"> | ||||
|     <ai-card title="流程设置"> | ||||
|       <template #right> | ||||
|         <span class="iconfont iconAdd rightBtn"></span> | ||||
|         <span class="rightBtn" style="margin-left: 8px;" @click="addAppStep(1)">添加审批步骤</span> | ||||
|       </template> | ||||
|       <template #content> | ||||
|         <el-steps direction="vertical"> | ||||
|           <el-step v-for="(item,index) in form.processNodeList" :key="index"> | ||||
|             <div slot="title" class="step_title"> | ||||
|               <p>{{ item.nodeName }}({{ dict.getLabel('nodeType', item.nodeType) }})</p> | ||||
|               <div class="peraoBtn"> | ||||
|                 <el-button type="text" :disabled="index==0" class="iconfont iconMoveUp" | ||||
|                            @click="form.processNodeList[index] = form.processNodeList.splice(index-1, 1,form.processNodeList[index])[0]"> | ||||
|                   上移 | ||||
|                 </el-button> | ||||
|                 <el-button type="text" :disabled="index==(form.processNodeList.length-1)" class="iconfont iconMoveDown" | ||||
|                            @click="form.processNodeList[index] = form.processNodeList.splice(index+1, 1,form.processNodeList[index])[0]"> | ||||
|                   下移 | ||||
|                 </el-button> | ||||
|                 <el-button type="text" class="iconfont iconEdit" @click="addAppStep(2,item,index)"> | ||||
|                   编辑 | ||||
|                 </el-button> | ||||
|                 <el-button type="text" class="iconfont iconDelete" @click="deleteInfo(index)"> | ||||
|                   删除 | ||||
|                 </el-button> | ||||
|               </div> | ||||
|             </div> | ||||
|             <div slot="description" class="step_desc"> | ||||
|               <div class="desc_style"> | ||||
|                 <p> | ||||
|                   选人方式:<span>{{ dict.getLabel('candidateApproverType', item.candidateApproverType) }}</span> | ||||
|                 </p> | ||||
|               </div> | ||||
|               <div class="desc_person" v-if="item.scopeCandidates==1||item.candidateApproverType==1"> | ||||
|                 <p class="desc_p">指定人员:</p> | ||||
|                 <div class="desc_div"> | ||||
|                   <el-tag type="info" closable v-for="(value,i) in item.candidateList" :key="i" | ||||
|                           @close="item.candidateList.splice(i,1)"> | ||||
|                     {{ value.name }} | ||||
|                   </el-tag> | ||||
|                   <el-button v-if="item.candidateList.length>0" type="text" @click="item.candidateList=[]">清空 | ||||
|                   </el-button> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <ai-wechat-selecter slot="append" :instance="instance" :props="{id:'wxUserId',label:'name'}" | ||||
|                                     v-model="item.candidateList" v-if="item.candidateApproverType==1"> | ||||
|                 <el-button size="mini" type="primary">选择指定人员</el-button> | ||||
|               </ai-wechat-selecter> | ||||
|             </div> | ||||
|           </el-step> | ||||
|         </el-steps> | ||||
|       </template> | ||||
|     </ai-card> | ||||
|     <el-dialog :title="titleType" class="editStyle" :visible.sync="isAddStep" width="575px" height="380px" | ||||
|                :close-on-click-modal="false"> | ||||
|       <el-form :model="nodeObj" label-width="120px" ref="addForm" :rules="addRules"> | ||||
|         <el-form-item label="审批步骤名称:" prop="nodeName"> | ||||
|           <el-input size="small" v-model="nodeObj.nodeName" placeholder="如:部门主管审批(限10个字)" :maxLength="10" | ||||
|                     clearable></el-input> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="审批方式:" prop="nodeType"> | ||||
|           <el-radio-group v-model="nodeObj.nodeType"> | ||||
|             <section style="position: relative;top: 10px;margin-bottom: 30px;"> | ||||
|               <el-radio :label="2">或签 | ||||
|                 <el-popover | ||||
|                     placement="top-start" | ||||
|                     width="200" | ||||
|                     trigger="click" | ||||
|                     content="或签是指该节点指定多名负责人审批时,其中任何一人完成审批即可。适合一个事项只需要某个岗位任何一人审批即可的业务场景。"> | ||||
|                   <el-button class="el-icon-warning" slot="reference" | ||||
|                              style="padding:0;height:14px;border:0;"></el-button> | ||||
|                 </el-popover> | ||||
|               </el-radio> | ||||
|               <el-radio :label="3">抄送 | ||||
|                 <el-popover | ||||
|                     placement="top-start" | ||||
|                     width="200" | ||||
|                     trigger="click" | ||||
|                     content="抄送是指一个事项审批完成后,抄送给需要知晓的单位或个人,被抄送的对象可以查阅该事项内容,无需审批。适合一个事项无需对方审批,但审批完成后需要通知对方知晓的业务场景。"> | ||||
|                   <el-button class="el-icon-warning" slot="reference" | ||||
|                              style="padding:0;height:14px;border:0;"></el-button> | ||||
|                 </el-popover> | ||||
|               </el-radio> | ||||
|             </section> | ||||
|           </el-radio-group> | ||||
|         </el-form-item> | ||||
|       </el-form> | ||||
|       <div slot="footer" style="text-align: center;"> | ||||
|         <el-button style="width: 92px;" size="small" @click="isAddStep = false">取消</el-button> | ||||
|         <el-button style="width: 92px;" size="small" type="primary" @click="saveAddProgress('addForm')">确认 | ||||
|         </el-button> | ||||
|       </div> | ||||
|     </el-dialog> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapState} from "vuex"; | ||||
|  | ||||
| export default { | ||||
|   name: "processApproval", | ||||
|   inject: ['config'], | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     approvalSteps: String | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       form: { | ||||
|         processNodeList: [], | ||||
|       }, | ||||
|       areaId: "", | ||||
|       isAddStep: false, | ||||
|       isSelectImg: false, | ||||
|       isSelectUnit: false, | ||||
|       isSelectPerson: false, | ||||
|       nodeObj: { | ||||
|         candidateApproverType: '1', | ||||
|         candidateList: [], | ||||
|         nodeIndex: '', | ||||
|         nodeName: '', | ||||
|         nodeType: '', | ||||
|         scopeCandidates: '' | ||||
|       }, | ||||
|       indexType: '', | ||||
|       titleType: '', | ||||
|       bomIndex: '', | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     addRules() { | ||||
|       return { | ||||
|         nodeName: [ | ||||
|           {required: true, message: '请输入审批节点名称', trigger: 'change'} | ||||
|         ], | ||||
|         nodeType: [ | ||||
|           {required: true, message: '请选择审批方式', trigger: 'change'} | ||||
|         ], | ||||
|         candidateApproverType: [ | ||||
|           {required: true, message: '请选择选人方式', trigger: 'change'} | ||||
|         ], | ||||
|         scopeCandidates: [ | ||||
|           {required: true, message: '请选择选人范围', trigger: 'change'} | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|     ...mapState(['user']) | ||||
|   }, | ||||
|   methods: { | ||||
|     handleProcessApproval() { | ||||
|       return Promise.resolve(this.form) | ||||
|     }, | ||||
|     /** | ||||
|      *删除 | ||||
|      * */ | ||||
|     deleteInfo(index) { | ||||
|       this.$confirm("是否删除").then(() => { | ||||
|         this.form.processNodeList.splice(index, 1) | ||||
|       }) | ||||
|     }, | ||||
|     /** | ||||
|      * 添加流程 | ||||
|      * @param index | ||||
|      * @param item | ||||
|      * @param i | ||||
|      */ | ||||
|     addAppStep(index, item, i) { | ||||
|       this.isAddStep = true; | ||||
|       this.bomIndex = i; | ||||
|       this.indexType = index; | ||||
|       if (index == 2) { | ||||
|         this.titleType = '编辑审批步骤'; | ||||
|         item.nodeType = item.nodeType * 1; | ||||
|         item.candidateApproverType = item.candidateApproverType * 1; | ||||
|         item.scopeCandidates = item.scopeCandidates * 1; | ||||
|         this.nodeObj = JSON.parse(JSON.stringify(item)); | ||||
|       } else { | ||||
|         this.titleType = '添加审批步骤'; | ||||
|         if (this.form.processNodeList.length > 0) { | ||||
|           this.init(); | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     // 确定添加审批步骤 | ||||
|     saveAddProgress(formName) { | ||||
|       this.$refs[formName].validate((valid) => { | ||||
|         if (valid) { | ||||
|           if (this.nodeObj.scopeCandidates == 0) this.nodeObj.candidateList = []; | ||||
|           if (this.indexType == 1) { | ||||
|             this.form.processNodeList.push(JSON.parse(JSON.stringify(this.nodeObj))); | ||||
|           } else { | ||||
|             this.form.processNodeList.splice(this.bomIndex, 1, JSON.parse(JSON.stringify(this.nodeObj))); | ||||
|           } | ||||
|           this.$refs[formName].resetFields(); | ||||
|           this.isAddStep = false; | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     init() { | ||||
|       this.nodeObj = { | ||||
|         candidateApproverType: '1', | ||||
|         candidateList: [], | ||||
|         nodeIndex: '', | ||||
|         nodeName: '', | ||||
|         nodeType: '', | ||||
|         scopeCandidates: '' | ||||
|       }; | ||||
|       this.$refs['addForm'].resetFields(); | ||||
|     }, | ||||
|   }, | ||||
|   created() { | ||||
|     this.areaId = this.user.info.areaId.substring(0, 6) + '000000' | ||||
|     if (this.config.detailObj?.id) { | ||||
|  | ||||
|       Object.keys(this.form).map(e => this.form[e] = this.config.detailObj[e]) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .process-approval { | ||||
|   .rightBtn { | ||||
|     font-size: 14px; | ||||
|     color: #5088FF; | ||||
|     user-select: none; | ||||
|     cursor: pointer; | ||||
|   } | ||||
|  | ||||
|   .step_title { | ||||
|     font-weight: 700; | ||||
|     height: 32px; | ||||
|     line-height: 32px; | ||||
|     display: flex; | ||||
|     padding: 0 8px; | ||||
|     justify-content: space-between; | ||||
|     color: #333; | ||||
|  | ||||
|     p { | ||||
|       font-size: 14px; | ||||
|     } | ||||
|  | ||||
|     div { | ||||
|       span { | ||||
|         margin-left: 16px; | ||||
|         font-size: 12px; | ||||
|         cursor: pointer; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .step_desc { | ||||
|     font-size: 14px; | ||||
|     padding: 8px; | ||||
|     color: #999; | ||||
|     margin-bottom: 20px; | ||||
|  | ||||
|     .desc_style { | ||||
|       display: flex; | ||||
|       margin-bottom: 16px; | ||||
|  | ||||
|       p { | ||||
|         margin-right: 80px; | ||||
|       } | ||||
|  | ||||
|       span { | ||||
|         color: #333; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .desc_person { | ||||
|       display: flex; | ||||
|       margin-bottom: 12px; | ||||
|  | ||||
|       .desc_p { | ||||
|         position: relative; | ||||
|         top: 4px; | ||||
|         width: 70px; | ||||
|       } | ||||
|  | ||||
|       .desc_div { | ||||
|         flex: 1; | ||||
|       } | ||||
|  | ||||
|       .el-tag { | ||||
|         margin-right: 8px; | ||||
|         margin-bottom: 8px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .add_btn { | ||||
|     position: absolute; | ||||
|     bottom: 0; | ||||
|     left: 0; | ||||
|     height: 64px; | ||||
|     line-height: 64px; | ||||
|     background: #F3F6F9; | ||||
|     width: 100%; | ||||
|     text-align: center; | ||||
|  | ||||
|     .el-button { | ||||
|       width: 92px; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .select_per { | ||||
|     width: 640px; | ||||
|     height: 400px; | ||||
|     box-sizing: border-box; | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     align-items: center; | ||||
|     margin: auto; | ||||
|  | ||||
|     .add_item { | ||||
|       width: 310px; | ||||
|       height: 400px; | ||||
|       background: rgba(252, 252, 252, 1); | ||||
|       border-radius: 2px; | ||||
|       border: 1px solid rgba(208, 212, 220, 1); | ||||
|       position: relative; | ||||
|       overflow: auto; | ||||
|  | ||||
|       .add_top { | ||||
|         width: 100%; | ||||
|         height: 40px; | ||||
|         background: rgba(245, 245, 245, 1); | ||||
|         border-bottom: 1px solid rgba(208, 212, 220, 1); | ||||
|         padding: 0 8px; | ||||
|         box-sizing: border-box; | ||||
|         display: flex; | ||||
|         justify-content: space-between; | ||||
|         align-items: center; | ||||
|       } | ||||
|  | ||||
|       .tree_list { | ||||
|         width: 100%; | ||||
|         height: 360px; | ||||
|         overflow: auto; | ||||
|       } | ||||
|  | ||||
|       .add_buttom { | ||||
|         position: absolute; | ||||
|         left: 0; | ||||
|         bottom: 0; | ||||
|         font-size: 12px; | ||||
|         width: 310px; | ||||
|         height: 32px; | ||||
|         line-height: 32px; | ||||
|         z-index: 10000; | ||||
|         background: rgba(245, 246, 247, 1); | ||||
|         color: rgba(51, 51, 51, 1); | ||||
|         box-shadow: 0px 1px 0px 0px rgba(216, 220, 227, 1); | ||||
|         display: flex; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         cursor: pointer; | ||||
|       } | ||||
|  | ||||
|       .add_tag { | ||||
|         width: 310px; | ||||
|         height: 360px; | ||||
|         overflow-y: auto; | ||||
|  | ||||
|         .el-tag { | ||||
|           margin: 8px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .icon { | ||||
|     width: 48px; | ||||
|     height: 48px; | ||||
|     border: 1px solid #ddd; | ||||
|     border-radius: 4px; | ||||
|     margin-right: 16px; | ||||
|     margin-bottom: 16px; | ||||
|     cursor: pointer; | ||||
|   } | ||||
|  | ||||
|   .icon_style { | ||||
|     display: flex; | ||||
|     flex-wrap: wrap; | ||||
|  | ||||
|     .icon:hover { | ||||
|       border-color: #5088FF; | ||||
|     } | ||||
|  | ||||
|     .icon_color { | ||||
|       border-color: #5088FF; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .dia_per_content { | ||||
|     width: 640px; | ||||
|     height: 400px; | ||||
|     box-sizing: border-box; | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     align-items: center; | ||||
|     margin: auto; | ||||
|  | ||||
|     .add_item { | ||||
|       width: 310px; | ||||
|       height: 400px; | ||||
|       background: rgba(252, 252, 252, 1); | ||||
|       border-radius: 2px; | ||||
|       border: 1px solid rgba(208, 212, 220, 1); | ||||
|       position: relative; | ||||
|       overflow: auto; | ||||
|  | ||||
|       .add_top { | ||||
|         width: 100%; | ||||
|         height: 40px; | ||||
|         background: rgba(245, 245, 245, 1); | ||||
|         border-bottom: 1px solid rgba(208, 212, 220, 1); | ||||
|         padding: 0 8px; | ||||
|         box-sizing: border-box; | ||||
|         display: flex; | ||||
|         justify-content: space-between; | ||||
|         align-items: center; | ||||
|       } | ||||
|  | ||||
|       .tree_list { | ||||
|         width: 100%; | ||||
|         height: 360px; | ||||
|         overflow: auto; | ||||
|       } | ||||
|  | ||||
|       .add_buttom { | ||||
|         position: absolute; | ||||
|         left: 0; | ||||
|         bottom: 0; | ||||
|         font-size: 12px; | ||||
|         width: 310px; | ||||
|         height: 32px; | ||||
|         line-height: 32px; | ||||
|         z-index: 10000; | ||||
|         background: rgba(245, 246, 247, 1); | ||||
|         color: rgba(51, 51, 51, 1); | ||||
|         box-shadow: 0px 1px 0px 0px rgba(216, 220, 227, 1); | ||||
|         display: flex; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         cursor: pointer; | ||||
|       } | ||||
|  | ||||
|       .add_tag { | ||||
|         width: 310px; | ||||
|         height: 360px; | ||||
|         overflow-y: auto; | ||||
|  | ||||
|         .el-tag { | ||||
|           margin: 8px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .peraoBtn { | ||||
|     .el-button--text { | ||||
|       color: #333; | ||||
|       font-size: 12px; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ::v-deep .el-step__icon.is-text { | ||||
|     border: 2px solid #2266FF; | ||||
|     background: #2266FF; | ||||
|     color: #FFFFFF; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .el-step__line { | ||||
|     background-color: #D0D4DC; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -0,0 +1,365 @@ | ||||
| <template> | ||||
|   <section class="personal-signature"> | ||||
|     <ai-list v-if="!showPhonePage"> | ||||
|       <ai-title slot="title" title="个人签名" :isShowBottomBorder="false"/> | ||||
|       <template #custom> | ||||
|         <div class="signaturePane"> | ||||
|           <div class="signatureCard" v-for="(op,i) in signatures" :key="i"> | ||||
|             <div class="default" v-if="op.isDefault==1">默认</div> | ||||
|             <div class="body"> | ||||
|               <el-image :src="`data:image/png;base64,${op.signSealData}`"/> | ||||
|             </div> | ||||
|             <div class="footer"> | ||||
|               <el-button type="text" :disabled="op.isDefault==1" @click.stop="handleSetDefault(op.id)">设为默认</el-button> | ||||
|               <hr/> | ||||
|               <el-button type="text" :disabled="op.isDefault==1||op.signType>0" @click.stop="handleDelete(op.id)">删除 | ||||
|               </el-button> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="signatureCard add" @click="dialog=true"> | ||||
|             <ai-icon icon="iconAdd" size="32px"/> | ||||
|             <span>点击添加签名</span> | ||||
|           </div> | ||||
|         </div> | ||||
|       </template> | ||||
|     </ai-list> | ||||
|     <ai-dialog :visible.sync="dialog" v-bind="dialogConf" @onConfirm="handleSubmit" | ||||
|                @closed="form={},drawPlaceholder=true,qrCode=null,showQRCode=false,getSignatures()"> | ||||
|       <ai-drawer v-if="hasAuthed" :seal.sync="sealData" ref="aiDrawer"> | ||||
|         <template #tools> | ||||
|           <el-popover trigger="manual" v-model="showQRCode"> | ||||
|             <el-image :src="qrCode"/> | ||||
|             <div class="writeInPhone" slot="reference" @click.stop="showQR"> | ||||
|               <ai-icon icon="iconEwm"/> | ||||
|               <span>手机签名</span> | ||||
|             </div> | ||||
|           </el-popover> | ||||
|         </template> | ||||
|       </ai-drawer> | ||||
|       <el-form size="small" :model="form" ref="authForm" :rules="rules" class="authZone" v-else label-suffix=":" | ||||
|                label-width="100px"> | ||||
|         <el-alert type="warning" title="第一次添加个人签名,需先进行实名认证" show-icon :closable="false"/> | ||||
|         <el-form-item label="姓名" prop="personName"> | ||||
|           <el-input v-model="form.personName" clearable placeholder="姓名"/> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="身份证号" prop="idNumber"> | ||||
|           <el-input v-model="form.idNumber" clearable placeholder="身份证号"/> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="手机号码" prop="signPhone"> | ||||
|           <el-input v-model="form.signPhone" clearable placeholder="手机号码"/> | ||||
|         </el-form-item> | ||||
|       </el-form> | ||||
|     </ai-dialog> | ||||
|     <draw-in-phone v-if="showPhonePage"/> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapState} from "vuex"; | ||||
| import DrawInPhone from "./drawInPhone"; | ||||
|  | ||||
| export default { | ||||
|   name: "AppPersonalSignature", | ||||
|   label: "个人签名", | ||||
|   components: {DrawInPhone}, | ||||
|   provide() { | ||||
|     return { | ||||
|       signature: this | ||||
|     } | ||||
|   }, | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|     hasAuthed() { | ||||
|       return this.signatures.length > 0 | ||||
|     }, | ||||
|     dialogConf() { | ||||
|       return this.hasAuthed ? { | ||||
|         title: "手写签名", | ||||
|         width: '720px' | ||||
|       } : { | ||||
|         title: "实名认证", | ||||
|         width: '520px' | ||||
|       } | ||||
|     }, | ||||
|     rules() { | ||||
|       return { | ||||
|         personName: [{required: true, message: "请填写姓名"}], | ||||
|         signPhone: [ | ||||
|           {required: true, message: "请填写手机号码"}, | ||||
|           {pattern: /^1[3456789]\d{9}$/, message: "手机号码格式有误"} | ||||
|         ], | ||||
|         idNumber: [ | ||||
|           {required: true, message: "请填写身份证号码"}, | ||||
|           {validator: (r, v, cb) => cb(this.idCardNoUtil.checkIdCardNo(v) ? undefined : "身份证号码格式有误")} | ||||
|         ], | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       signatures: [], | ||||
|       dialog: false, | ||||
|       form: {}, | ||||
|       sealData: null, | ||||
|       qrCode: null, | ||||
|       showQRCode: false, | ||||
|       showPhonePage: false, | ||||
|       loading: false, | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     if (this.$route.query.userId && this.$route.hash == "#phone") { | ||||
|       this.showPhonePage = true | ||||
|     } else { | ||||
|       this.getSignatures() | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     getSignatures() { | ||||
|       this.instance.post("/app/syssignaccount/list", null, { | ||||
|         params: { | ||||
|           size: 999 | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res?.data) { | ||||
|           this.signatures = res.data.records | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     handleSubmit() { | ||||
|       if (this.loading) return | ||||
|       if (this.hasAuthed && this.$refs['aiDrawer'].drawPlaceholder) return this.$message.error("请签名") | ||||
|       this.loading = true | ||||
|       if (this.hasAuthed) { | ||||
|         let sealData = this.sealData?.replace(/data:image\/png;base64,/, '') | ||||
|         sealData && this.instance({ | ||||
|           url: '/app/syssignaccount/upload-sealdata', | ||||
|           headers: {"Content-Type": "application/json"}, | ||||
|           method: 'post', | ||||
|           params: {userId: this.user.info.id}, | ||||
|           data: sealData | ||||
|         }).then(res => { | ||||
|           this.loading = false | ||||
|           if (res?.code == 0) { | ||||
|             this.dialog = false | ||||
|             this.$message.success("添加成功!") | ||||
|             this.getSignatures() | ||||
|           } | ||||
|         }).catch(() => { | ||||
|           this.loading = false | ||||
|         }) | ||||
|       } else { | ||||
|         this.$refs.authForm.validate(v => { | ||||
|           if (v) { | ||||
|             this.instance.post("/app/syssignaccount/register", { | ||||
|               signPhone: this.form.signPhone, | ||||
|               signType: 1, | ||||
|               userType: 0, | ||||
|               registerInfo: {...this.form}, | ||||
|               style: {personTemplateType: 'RECTANGLE', sealColor: 'RED'} | ||||
|             }).then(res => { | ||||
|               this.loading = false | ||||
|               if (res?.code == 0) { | ||||
|                 this.dialog = false | ||||
|                 this.$message.success("认证成功!") | ||||
|                 this.getSignatures() | ||||
|               } | ||||
|             }).catch(() => { | ||||
|               this.loading = false | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|     handleSetDefault(id) { | ||||
|       this.$confirm("是否设置该签名为默认签名?").then(() => { | ||||
|         this.instance.post("/app/syssignaccount/default", null, {params: {id, listType: 0}}).then(res => { | ||||
|           if (res?.code == 0) { | ||||
|             this.$message.success("设置成功!") | ||||
|             this.getSignatures() | ||||
|           } | ||||
|         }).catch(() => 0) | ||||
|       }) | ||||
|     }, | ||||
|     handleDelete(ids) { | ||||
|       this.$confirm("是否删除该签名?").then(() => { | ||||
|         this.instance.post("/app/syssignaccount/delete", null, {params: {ids}}).then(res => { | ||||
|           if (res?.code == 0) { | ||||
|             this.$message.success("删除成功!") | ||||
|             this.getSignatures() | ||||
|           } | ||||
|         }).catch(() => 0) | ||||
|       }) | ||||
|     }, | ||||
|     showQR() { | ||||
|       if (!this.qrCode) { | ||||
|         let url = `${location.href}?userId=${this.user.info.id}#phone` | ||||
|         this.instance.post("/app/syssignaccount/draw-qrcode", null, { | ||||
|           params: {url} | ||||
|         }).then(res => { | ||||
|           if (res?.data) { | ||||
|             this.showQRCode = true | ||||
|             this.qrCode = res.data | ||||
|           } | ||||
|         }) | ||||
|       } else { | ||||
|         this.showQRCode = !this.showQRCode | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .personal-signature { | ||||
|   height: 100%; | ||||
|   background: #f3f6f9; | ||||
|   overflow: auto; | ||||
|  | ||||
|   ::v-deep .signaturePane { | ||||
|     display: flex; | ||||
|     gap: 16px; | ||||
|     flex-wrap: wrap; | ||||
|     padding: 16px; | ||||
|  | ||||
|     .signatureCard { | ||||
|       width: 290px; | ||||
|       height: 258px; | ||||
|       background: #FFFFFF; | ||||
|       border-radius: 4px; | ||||
|       position: relative; | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       overflow: hidden; | ||||
|  | ||||
|       &.add { | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         color: #666666; | ||||
|         cursor: pointer; | ||||
|  | ||||
|         .AiIcon { | ||||
|           width: 32px; | ||||
|           height: 32px; | ||||
|           font-size: 32px; | ||||
|         } | ||||
|  | ||||
|         & > span { | ||||
|           font-size: 12px; | ||||
|           line-height: 16px; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .default { | ||||
|         position: absolute; | ||||
|         width: 56px; | ||||
|         height: 24px; | ||||
|         background: #3573FF; | ||||
|         border-radius: 0 0 4px 0; | ||||
|         top: 0; | ||||
|         left: 0; | ||||
|         text-align: center; | ||||
|         line-height: 24px; | ||||
|         font-size: 12px; | ||||
|         color: #FFF; | ||||
|       } | ||||
|  | ||||
|       .body { | ||||
|         min-height: 0; | ||||
|         flex: 1; | ||||
|         display: flex; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         padding: 25px; | ||||
|         pointer-events: none; | ||||
|  | ||||
|         .el-image { | ||||
|           width: 100%; | ||||
|           height: 100% | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .footer { | ||||
|         flex-shrink: 0; | ||||
|         height: 40px; | ||||
|         background: rgba(#30426F, .5); | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         padding: 8px 0; | ||||
|         box-sizing: border-box; | ||||
|  | ||||
|         hr { | ||||
|           height: 100%; | ||||
|           border-color: rgba(#fff, .5); | ||||
|         } | ||||
|  | ||||
|         & > .el-button { | ||||
|           flex: 1; | ||||
|           color: #fff; | ||||
|  | ||||
|           &[disabled] { | ||||
|             color: rgba(#fff, .5); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   ::v-deep .writeInPhone { | ||||
|     position: absolute; | ||||
|     width: 100px; | ||||
|     height: 32px; | ||||
|     background: rgba(#000, .5); | ||||
|     border-radius: 16px; | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     justify-content: center; | ||||
|     gap: 4px; | ||||
|     color: rgba(#fff, .6); | ||||
|     cursor: pointer; | ||||
|     left: 16px; | ||||
|     top: 16px; | ||||
|  | ||||
|     .AiIcon { | ||||
|       width: auto; | ||||
|       height: auto; | ||||
|     } | ||||
|  | ||||
|     &:hover { | ||||
|       color: #fff; | ||||
|     } | ||||
|   } | ||||
|   ::v-deep .ai-dialog__wrapper { | ||||
|     .ai-dialog__content--wrapper { | ||||
|       padding-right: 0 !important; | ||||
|     } | ||||
|  | ||||
|     .el-dialog__body { | ||||
|       padding: 24px 0; | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     .authZone { | ||||
|       padding: 0 16px 24px; | ||||
|       width: 100%; | ||||
|       box-sizing: border-box; | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       gap: 24px; | ||||
|  | ||||
|       .el-alert { | ||||
|         border: 1px solid #FF8822; | ||||
|       } | ||||
|  | ||||
|       .el-form-item { | ||||
|         margin-bottom: 0; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -0,0 +1,110 @@ | ||||
| <template> | ||||
|   <section class="drawInPhone" @touchmove.prevent> | ||||
|     <div class="endPage" v-if="finished">操作结束请关闭页面</div> | ||||
|     <ai-drawer :seal.sync="sealData" placeholder="请签名" :width="device.width" :height="device.height"> | ||||
|       <template #tools> | ||||
|         <div class="writeInPhone" slot="reference" @click.stop="handleSubmit"> | ||||
|           <ai-icon icon="iconPublish"/> | ||||
|           <span>提交</span> | ||||
|         </div> | ||||
|       </template> | ||||
|     </ai-drawer> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "drawInPhone", | ||||
|   inject: ['signature'], | ||||
|   data() { | ||||
|     return { | ||||
|       sealData: null, | ||||
|       device: {width: 0, height: 0}, | ||||
|       finished: false | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.device.width = document.body.clientWidth | ||||
|     this.device.height = document.body.clientHeight | ||||
|     window.onresize = () => { | ||||
|       this.device.width = document.body.clientWidth | ||||
|       this.device.height = document.body.clientHeight | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     handleSubmit() { | ||||
|       let sealData = this.sealData?.replace(/data:image\/png;base64,/, ''), | ||||
|           {userId} = this.$route.query | ||||
|       if (!userId) return alert("缺少必要参数") | ||||
|       sealData && this.signature.instance({ | ||||
|         url: '/app/syssignaccount/upload-sealdata', | ||||
|         headers: {"Content-Type": "application/json"}, | ||||
|         method: 'post', | ||||
|         params: {userId}, | ||||
|         data: sealData, | ||||
|         withoutToken: true | ||||
|       }).then(res => { | ||||
|         if (res?.code == 0) { | ||||
|           alert("添加成功!") | ||||
|           this.finished = true | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .drawInPhone { | ||||
|   position: fixed; | ||||
|   left: 0; | ||||
|   right: 0; | ||||
|   top: 0; | ||||
|   bottom: 0; | ||||
|   z-index: 20210205932; | ||||
|  | ||||
|   .endPage { | ||||
|     position: fixed; | ||||
|     left: 0; | ||||
|     right: 0; | ||||
|     top: 0; | ||||
|     bottom: 0; | ||||
|     z-index: 20210205933; | ||||
|     background: rgba(#000, .8); | ||||
|     color: #999; | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|     align-items: center; | ||||
|     font-size: 32px; | ||||
|   } | ||||
|  | ||||
|   .AiDrawer { | ||||
|     margin: 0; | ||||
|   } | ||||
|  | ||||
|   .writeInPhone { | ||||
|     position: absolute; | ||||
|     width: 72px; | ||||
|     height: 32px; | ||||
|     background: rgba(#000, .5); | ||||
|     border-radius: 16px; | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     justify-content: center; | ||||
|     gap: 4px; | ||||
|     color: rgba(#fff, .6); | ||||
|     cursor: pointer; | ||||
|     left: 16px; | ||||
|     top: 16px; | ||||
|  | ||||
|     .AiIcon { | ||||
|       width: auto; | ||||
|       height: auto; | ||||
|     } | ||||
|  | ||||
|     &:hover { | ||||
|       color: #fff; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
		Reference in New Issue
	
	Block a user