村民圈
This commit is contained in:
		| @@ -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/shandong/AppDispatchManagement/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										388
									
								
								packages/shandong/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/shandong/AppDispatchManagement/components/Detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										563
									
								
								packages/shandong/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> | ||||
							
								
								
									
										310
									
								
								packages/shandong/AppDispatchManagement/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										310
									
								
								packages/shandong/AppDispatchManagement/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,310 @@ | ||||
| <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" | ||||
|                     @change="(page.current = 1), getList()" | ||||
|                     clearable | ||||
|                     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: "操作"}, | ||||
|       ]; | ||||
|     }, | ||||
|   }, | ||||
|   mounted() { | ||||
|     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> | ||||
| @@ -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/shandong/AppVillageCode/AppVillageCode.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								packages/shandong/AppVillageCode/AppVillageCode.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: 'AppVillageCode', | ||||
|     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> | ||||
							
								
								
									
										135
									
								
								packages/shandong/AppVillageCode/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								packages/shandong/AppVillageCode/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | ||||
| <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> | ||||
|           <el-form class="ai-form" ref="form" :model="form" label-width="110px" label-position="right"> | ||||
|             <el-form-item label="地区" style="width: 100%;" prop="codeName"> | ||||
|               <span style="color: #666;">{{ form.areaName }}</span> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="二维码名称" prop="codeName" :rules="[{ required: true, message: '请输入二维码名称', trigger: 'blur' }]"> | ||||
|               <el-input size="small" placeholder="请输入二维码名称" style="width: 328px;" v-model="form.codeName"></el-input> | ||||
|             </el-form-item> | ||||
|             <el-form-item style="width: 100%;" label="二维码类型" prop="type" :rules="[{ required: true, message: '请选择二维码类型', trigger: 'change' }]"> | ||||
|               <el-radio-group v-model="form.type"> | ||||
|                 <el-radio label="0">群二维码</el-radio> | ||||
|                 <el-radio label="1">个人二维码</el-radio> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="上传二维码" prop="codeUrl" style="width: 100%;" :rules="[{ required: true, message: '请上传二维码', trigger: 'change' }]"> | ||||
|               <ai-uploader :instance="instance" v-model="form.codeUrl" :limit="1"></ai-uploader> | ||||
|             </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> | ||||
|   export default { | ||||
|     name: 'Add', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       params: Object | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         info: {}, | ||||
|         form: { | ||||
|           areaId: '', | ||||
|           codeName: '', | ||||
|           areaName: '', | ||||
|           code: '', | ||||
|           codeUrl: [], | ||||
|           type: '', | ||||
|         }, | ||||
|         id: '', | ||||
|         areaList: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       this.getAreaList() | ||||
|  | ||||
|       if (this.params && this.params.areaId && !this.params.id) { | ||||
|         this.form.areaId = this.params.areaId | ||||
|         this.form.areaName = this.params.areaName | ||||
|       } | ||||
|  | ||||
|       if (this.params && this.params.id) { | ||||
|         this.id = this.params.id | ||||
|         this.getInfo(this.params.id) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getInfo (id) { | ||||
|         this.instance.post(`/app/appeveryvillagecode/queryDetailById?id=${id}`).then(res => { | ||||
|           if (res.code === 0) { | ||||
|             this.form = res.data | ||||
|             this.form.codeUrl = [{ | ||||
|               url: res.data.codeUrl | ||||
|             }] | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       getAreaList() { | ||||
|         this.instance.post(`/admin/area/queryAreaByParentId?id=341021104000`).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.areaList = res.data.map(item => { | ||||
|               item.dictName = item.name | ||||
|               item.dictValue = item.id | ||||
|  | ||||
|               return item | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       onClose () { | ||||
|         this.form.explain = '' | ||||
|       }, | ||||
|  | ||||
|       confirm () { | ||||
|         this.$refs.form.validate((valid) => { | ||||
|           if (valid) { | ||||
|             this.instance.post(`/app/appeveryvillagecode/addOrUpdate`, { | ||||
|               ...this.form, | ||||
|               codeUrl: this.form.codeUrl[0].url | ||||
|             }).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> | ||||
							
								
								
									
										422
									
								
								packages/shandong/AppVillageCode/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										422
									
								
								packages/shandong/AppVillageCode/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,422 @@ | ||||
| <template> | ||||
|   <ai-list class="villagecode"> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="一村一码" isShowBottomBorder></ai-title> | ||||
|     </template> | ||||
|     <template #left> | ||||
|       <div class="villagecode-left"> | ||||
|         <div class="villagecode-left__title"> | ||||
|           <h2>村列表</h2> | ||||
|         </div> | ||||
|         <div class="addressBook-left__list"> | ||||
|           <div class="addressBook-left__list--title"> | ||||
|             <el-input | ||||
|               class="addressBook-left__list--search" | ||||
|               size="mini" | ||||
|               placeholder="请输入地区名称" | ||||
|               v-model="unitName" | ||||
|               suffix-icon="iconfont iconSearch"> | ||||
|             </el-input> | ||||
|           </div> | ||||
|           <el-tree | ||||
|             :filter-node-method="filterNode" | ||||
|             ref="tree" | ||||
|             :props="defaultProps" | ||||
|             node-key="id" | ||||
|             :data="areaTree" | ||||
|             highlight-current | ||||
|             :current-node-key="search.areaId" | ||||
|             :default-expanded-keys="defaultExpanded" | ||||
|             :default-checked-keys="defaultChecked" | ||||
|             @current-change="onTreeChange"> | ||||
|           </el-tree> | ||||
|         </div> | ||||
|       </div> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-search-bar class="search-bar"> | ||||
|         <template #left> | ||||
|           <el-button size="small" type="primary" :disabled="isShowAdd" icon="iconfont iconAdd" @click="toAdd('')">添加活码</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="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="180px" fixed="right" label="操作" align="center"> | ||||
|           <template slot-scope="{ row }"> | ||||
|             <div class="table-options"> | ||||
|               <el-popover | ||||
|                   placement="bottom" | ||||
|                   width="160" | ||||
|                   :visible-arrow="false" | ||||
|                   popper-class="wechat-message__container" | ||||
|                   trigger="hover"> | ||||
|                 <el-button type="text" slot="reference">二维码</el-button> | ||||
|                 <div style="font-size: 0;"> | ||||
|                   <img class="message-info__img" :src="row.codeUrl"> | ||||
|                 </div> | ||||
|               </el-popover> | ||||
|               <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, | ||||
|           status: 0, | ||||
|           title: '', | ||||
|           areaId: '' | ||||
|         }, | ||||
|         defaultExpanded: [], | ||||
|         defaultChecked: [], | ||||
|         areaTree: [], | ||||
|         defaultProps: { | ||||
|           children: 'children', | ||||
|           label: 'name' | ||||
|         }, | ||||
|         currIndex: -1, | ||||
|         areaList: [], | ||||
|         total: 10, | ||||
|         colConfigs: [ | ||||
|           {prop: 'codeName', label: '名称', align: 'left'}, | ||||
|           {prop: 'type', label: '二维码类型', align: 'left', formart: v => v === '0' ? '群二维码' : '个人二维码'}, | ||||
|           {prop: 'createUserName', label: '创建人'}, | ||||
|           {prop: 'createTime', label: '创建时间'}, | ||||
|           {slot: 'options', label: '操作'} | ||||
|         ], | ||||
|         areaName: '', | ||||
|         unitName: '', | ||||
|         tableData: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       ...mapState(['user']), | ||||
|  | ||||
|       isShowAdd () { | ||||
|         const str = this.search.areaId.substr(this.search.areaId.length - 3) | ||||
|  | ||||
|         return str === '000' | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     watch: { | ||||
|       unitName (val) { | ||||
|         this.$refs.tree.filter(val) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     mounted() { | ||||
|       this.search.areaId = this.user.info.areaId | ||||
|       this.areaName = this.user.info.areaName | ||||
|       this.getTree() | ||||
|       this.getAreaList() | ||||
|       this.getList() | ||||
|  | ||||
|       this.$nextTick(() => { | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getList() { | ||||
|         this.instance.post(`/app/appeveryvillagecode/list`, null, { | ||||
|           params: { | ||||
|             ...this.search | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.tableData = res.data.records | ||||
|             this.total = res.data.total | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       filterNode(value, data) { | ||||
|         if (!value) return true | ||||
|         return data.name.indexOf(value) !== -1 | ||||
|       }, | ||||
|  | ||||
|       onTreeChange (e) { | ||||
|         this.search.areaId = e.id | ||||
|         this.areaName = e.name | ||||
|         this.search.current = 1 | ||||
|  | ||||
|         this.$nextTick(() => { | ||||
|           this.getList() | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       getTree () { | ||||
|         this.instance.post(`/admin/area/queryAllArea?id=${this.user.info.areaId}`).then(res => { | ||||
|           if (res.code === 0) { | ||||
|             let parent = res.data.map(v => { | ||||
|               v.label = v.name | ||||
|               v.children = [] | ||||
|  | ||||
|               return v | ||||
|             }).filter(e => !e.parentid)[0] | ||||
|             this.defaultExpanded = [parent.id] | ||||
|             this.defaultChecked = [parent.id] | ||||
|             this.search.areaId = parent.id | ||||
|             this.addChild(parent, res.data) | ||||
|             this.areaTree = [parent] | ||||
|  | ||||
|             this.$nextTick(() => { | ||||
|               this.$refs.tree.setCurrentKey(parent.id) | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       addChild (parent, list) { | ||||
|         for (let i = 0; i < list.length; i++) { | ||||
|           if (list[i].parentId === parent.id) { | ||||
|             parent.children.push(list[i]) | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         if (list.length > 0) { | ||||
|           parent['children'].map(v => this.addChild(v, list)) | ||||
|         } | ||||
|       }, | ||||
|  | ||||
|       getAreaList() { | ||||
|         this.instance.post(`/admin/area/queryAreaByParentId?id=341021104000`).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.areaList = res.data | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       remove(id) { | ||||
|         this.$confirm('确定删除该数据?').then(() => { | ||||
|           this.instance.post(`/app/appeveryvillagecode/delete?ids=${id}`).then(res => { | ||||
|             if (res.code == 0) { | ||||
|               this.$message.success('删除成功!') | ||||
|               this.getList() | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       toAdd(id) { | ||||
|         this.$emit('change', { | ||||
|           type: 'Add', | ||||
|           params: { | ||||
|             areaName: this.areaName, | ||||
|             id: id || '', | ||||
|             areaId: this.search.areaId | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .villagecode { | ||||
|   .table-tags { | ||||
|     .el-tag { | ||||
|       margin-right: 8px; | ||||
|  | ||||
|       &:last-child { | ||||
|         margin-right: 0; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .addressBook-left__list { | ||||
|     height: calc(100% - 40px); | ||||
|     padding: 8px 8px; | ||||
|     overflow: auto; | ||||
|  | ||||
|     .addressBook-left__tags--item { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: space-between; | ||||
|       height: 40px; | ||||
|       padding: 0 8px 0 16px; | ||||
|       color: #222222; | ||||
|  | ||||
|       &.addressBook-left__tags--item-active, &:hover { | ||||
|         background: #E8EFFF; | ||||
|         color: #2266FF; | ||||
|  | ||||
|         i, span { | ||||
|           color: #2266FF; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       span { | ||||
|         font-size: 14px; | ||||
|       } | ||||
|  | ||||
|       i { | ||||
|         cursor: pointer; | ||||
|         color: #8e9ebf; | ||||
|         font-size: 16px; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .addressBook-left__list--title { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       margin-bottom: 8px; | ||||
|  | ||||
|       .addressBook-left__list--search { | ||||
|         flex: 1; | ||||
|         ::v-deep input { | ||||
|           width: 100%; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .el-button { | ||||
|         width: 84px; | ||||
|         flex-shrink: 1; | ||||
|         margin-right: 8px; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     span { | ||||
|       color: #222222; | ||||
|       font-size: 14px; | ||||
|     } | ||||
|  | ||||
|     ::v-deep .el-tree { | ||||
|       background: transparent; | ||||
|  | ||||
|       .el-tree-node__expand-icon.is-leaf { | ||||
|         color: transparent!important; | ||||
|       } | ||||
|  | ||||
|       .el-tree-node__content > .el-tree-node__expand-icon { | ||||
|         padding: 4px; | ||||
|       } | ||||
|  | ||||
|       .el-tree-node__content { | ||||
|         height: 32px; | ||||
|       } | ||||
|  | ||||
|       .el-tree__empty-text { | ||||
|         color: #222; | ||||
|         font-size: 14px; | ||||
|       } | ||||
|  | ||||
|       .el-tree-node__children .el-tree-node__content { | ||||
|         height: 32px; | ||||
|       } | ||||
|  | ||||
|       .el-tree-node__content:hover { | ||||
|         background: #E8EFFF; | ||||
|         color: #222222; | ||||
|         border-radius: 2px; | ||||
|       } | ||||
|  | ||||
|       .is-current > .el-tree-node__content { | ||||
|         &:hover { | ||||
|           background: #2266FF; | ||||
|           color: #fff; | ||||
|         } | ||||
|  | ||||
|         background: #2266FF; | ||||
|          | ||||
|         span { | ||||
|           color: #fff; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .villagecode-left { | ||||
|     width: 100%; | ||||
|     height: auto; | ||||
|     background: #FAFAFB; | ||||
|  | ||||
|     .villagecode-left__title { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       height: 40px; | ||||
|       padding: 0 16px; | ||||
|       background: #E5E5E5; | ||||
|  | ||||
|       h2 { | ||||
|         color: #222; | ||||
|         font-size: 14px; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .villagecode-left__list { | ||||
|       height: calc(100% - 40px); | ||||
|       padding: 8px 0; | ||||
|       overflow: auto; | ||||
|  | ||||
|       span { | ||||
|         display: block; | ||||
|         height: 40px; | ||||
|         line-height: 40px; | ||||
|         padding: 0 24px; | ||||
|         color: #222222; | ||||
|         font-size: 14px; | ||||
|         cursor: pointer; | ||||
|         border-right: 2px solid transparent; | ||||
|         background: transparent; | ||||
|  | ||||
|         &:hover { | ||||
|           color: #2266FF; | ||||
|           background: #E8EFFF; | ||||
|         } | ||||
|  | ||||
|         &.left-active { | ||||
|           color: #2266FF; | ||||
|           border-color: #2266FF; | ||||
|           background: #E8EFFF; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ::v-deep .ai-list__content--right { | ||||
|  | ||||
|     .ai-list__content--right-wrapper { | ||||
|       min-height: 100%; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
|  | ||||
| .message-info__img { | ||||
|   font-size: 0; | ||||
|   width: 144px; | ||||
|   height: 144px; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										66
									
								
								packages/shandong/AppVillagersCircle/AppVillagersCircle.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								packages/shandong/AppVillagersCircle/AppVillagersCircle.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: 'AppVillagersCircle', | ||||
|     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> | ||||
							
								
								
									
										105
									
								
								packages/shandong/AppVillagersCircle/components/Detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								packages/shandong/AppVillagersCircle/components/Detail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| <template> | ||||
|   <ai-detail> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="村民圈详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)"> | ||||
|       </ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-card title="基础信息"> | ||||
|         <ai-wrapper slot="content"> | ||||
|           <ai-info-item label="主题" :value="info.content" isLine></ai-info-item> | ||||
|           <ai-info-item label="发布地区" :value="info.areaName" isLine></ai-info-item> | ||||
|           <ai-info-item label="议事截止时间" :value="info.discussDeadline"></ai-info-item> | ||||
|           <ai-info-item label="公示截止时间" :value="info.publicityDeadline"></ai-info-item> | ||||
|           <ai-info-item label="议事类型" :value="dict.getLabel('discussType', info.type)" isLine></ai-info-item> | ||||
|           <ai-info-item label="是否匿名投票" v-if="info.type === '1'" :value="info.anonymous === '1' ? '是' : '否'"></ai-info-item> | ||||
|           <ai-info-item label="投票方式" v-if="info.type === '1'" :value="info.voteType === '0' ? '单选' : '多选'"></ai-info-item> | ||||
|           <ai-info-item label="图片" isLine> | ||||
|             <ai-uploader | ||||
|               :instance="instance" | ||||
|               disabled | ||||
|               v-model="info.images" | ||||
|               :limit="9"> | ||||
|             </ai-uploader> | ||||
|           </ai-info-item> | ||||
|         </ai-wrapper> | ||||
|       </ai-card> | ||||
|       <ai-dialog | ||||
|         :visible.sync="isShowAdd" | ||||
|         width="680px" | ||||
|         height="580px" | ||||
|         title="发表意见" | ||||
|         @close="onClose" | ||||
|         @onConfirm="onConfirm"> | ||||
|         <el-form ref="form" class="ai-form" :model="form" label-width="110px" label-position="right"> | ||||
|           <el-form-item label="发表意见" prop="content" style="width: 100%;" :rules="[{ required: true, message: '请发表你的观点和意见', trigger: 'blur' }]"> | ||||
|             <el-input size="small" type="textarea" :rows="5" show-word-limit :maxlength="140" placeholder="请发表你的观点和意见" v-model="form.content"></el-input> | ||||
|           </el-form-item> | ||||
|         </el-form> | ||||
|       </ai-dialog> | ||||
|     </template> | ||||
|   </ai-detail> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   import { mapState } from 'vuex' | ||||
|   export default { | ||||
|     name: 'Detail', | ||||
|  | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       params: Object | ||||
|     }, | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         info: {}, | ||||
|         id: '', | ||||
|         search: { | ||||
|           current: 1, | ||||
|           size: 10 | ||||
|         }, | ||||
|         isShowAdd: false, | ||||
|         form: { | ||||
|           content: '' | ||||
|         }, | ||||
|         type: '' | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       ...mapState(['user']) | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       this.getInfo(this.params.id) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getInfo (id) { | ||||
|         this.instance.post(`/app/appvillagediscuss/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.type = res.data.type | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       onClose () { | ||||
|         this.form.content = '' | ||||
|       }, | ||||
|  | ||||
|       cancel (isRefresh) { | ||||
|         this.$emit('change', { | ||||
|           type: 'list', | ||||
|           isRefresh: !!isRefresh | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| </style> | ||||
							
								
								
									
										173
									
								
								packages/shandong/AppVillagersCircle/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								packages/shandong/AppVillagersCircle/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| <template> | ||||
|   <ai-list class="notice"> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="村民圈" isShowBottomBorder isShowArea v-model="search.areaId" :instance="instance" @change="search.current = 1, getList()"></ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-search-bar class="search-bar"> | ||||
|         <template #left> | ||||
|           <ai-select placeholder="请选择状态" v-model="search.type" clearable @change="search.current = 1, getList()" :selectList="dict.getDict('discussType')"></ai-select> | ||||
|           <ai-select placeholder="请选择话题" v-model="search.status" clearable @change="search.current = 1, getList()" :selectList="dict.getDict('discussStatus')"></ai-select> | ||||
|         </template> | ||||
|         <template #right> | ||||
|           <el-input | ||||
|             v-model="search.title" | ||||
|             class="search-input" | ||||
|             size="small" | ||||
|             @keyup.enter.native="search.current = 1, search.title, getList()" | ||||
|             placeholder="请输入发布人姓名" | ||||
|             clearable | ||||
|             @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: 6px;" | ||||
|         :current.sync="search.current" | ||||
|         :size.sync="search.size" | ||||
|         @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="160px" fixed="right" label="操作" align="center"> | ||||
|           <template slot-scope="{ row }"> | ||||
|             <div class="table-options"> | ||||
|               <el-button type="text" title="详情" @click="toDetail(row.id)">详情</el-button> | ||||
|               <el-button type="text" title="取消公示" @click="changeStatus(row)" :disabled="row.status !== '1'">结束公示</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, | ||||
|           status: '', | ||||
|           type: '', | ||||
|           title: '', | ||||
|           areaId: '' | ||||
|         }, | ||||
|         currIndex: -1, | ||||
|         areaList: [], | ||||
|         total: 10, | ||||
|         colConfigs: [ | ||||
|           { prop: 'content',  label: '议事主题', align: 'left', width: '200px' }, | ||||
|           { prop: 'type', label: '议事类型', align: 'center', formart: v => this.dict.getLabel('discussType', v) }, | ||||
|           { prop: 'createUserName', label: '话事人', align: 'center' }, | ||||
|           { prop: 'msgCountTotal', label: '观点数量', align: 'center', formart: v => v === 0 ? '-' : v }, | ||||
|           { prop: 'voteCount', label: '投票数量', align: 'center', formart: v => v === 0 ? '-' : v }, | ||||
|           { prop: 'status', label: '发布状态', align: 'center', formart: v => this.dict.getLabel('discussStatus', v) }, | ||||
|           { prop: 'createTime', label: '发布时间', align: 'center' }, | ||||
|           { slot: 'options', label: '操作', align: 'center' } | ||||
|         ], | ||||
|         areaName: '', | ||||
|         unitName: '', | ||||
|         tableData: [] | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       ...mapState(['user']) | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       this.search.areaId = this.user.info.areaId | ||||
|       this.dict.load(['discussType', 'discussStatus']).then(() => { | ||||
|         this.getList() | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       getList() { | ||||
|         this.instance.post(`/app/appvillagediscuss/listUp`, null, { | ||||
|           params: { | ||||
|             type: 0, | ||||
|             ...this.search | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.tableData = res.data.records.map(v => { | ||||
|               return { | ||||
|                 ...v, | ||||
|                 content: v.content || v.title | ||||
|               } | ||||
|             }) | ||||
|             this.total = res.data.total | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       changeStatus (item) { | ||||
|         this.$confirm('是否要结束公示', {type: 'warning'}).then(() => { | ||||
|           this.instance.post('/app/appvillagediscuss/finishPublic', { | ||||
|             status: '2', | ||||
|             id: item.id | ||||
|           }).then(res => { | ||||
|             if (res && res.code == 0) { | ||||
|               this.$message.success('结束公示成功') | ||||
|               this.getList() | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|  | ||||
|       remove(id) { | ||||
|         this.$confirm('确定删除该数据?').then(() => { | ||||
|           this.instance.post(`/app/appvillagediscuss/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> | ||||
|   .notice { | ||||
|   } | ||||
| </style> | ||||
		Reference in New Issue
	
	Block a user