迁移
This commit is contained in:
		
							
								
								
									
										60
									
								
								project/biaopin/AppGeneralElection/AppGeneralElection.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								project/biaopin/AppGeneralElection/AppGeneralElection.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="AppGeneralElection"> | ||||||
|  |     <keep-alive :include="['electionList']"> | ||||||
|  |       <component ref="component" :is="component" :instance="instance" :params="params" :dict="dict" @change="onChange"/> | ||||||
|  |     </keep-alive> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import electionList from "./components/electionList.vue"; | ||||||
|  | import electionAdd from "./components/electionAdd.vue"; | ||||||
|  | import Statistics from "./components/Statistics.vue"; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "AppGeneralElection", | ||||||
|  |   label: "换届选举", | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |   }, | ||||||
|  |   components: {electionAdd, electionList,Statistics}, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       component: "electionList", | ||||||
|  |       params: {}, | ||||||
|  |       include: [], | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     onChange(data) { | ||||||
|  |       if (data.type === "electionAdd") { | ||||||
|  |         this.component = "electionAdd"; | ||||||
|  |         this.params = data.params; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if (data.type === "Statistics") { | ||||||
|  |         this.component = "Statistics"; | ||||||
|  |         this.params = data.params; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if (data.type === "electionList") { | ||||||
|  |         this.component = "electionList"; | ||||||
|  |         this.params = data.params; | ||||||
|  |  | ||||||
|  |         this.$nextTick(() => { | ||||||
|  |           if (data.isRefresh) { | ||||||
|  |             this.$refs.component.getList(); | ||||||
|  |           } | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .AppGeneralElection { | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										152
									
								
								project/biaopin/AppGeneralElection/components/Statistics.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								project/biaopin/AppGeneralElection/components/Statistics.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,152 @@ | |||||||
|  | <template> | ||||||
|  |   <section> | ||||||
|  |     <ai-detail class="Statistics"> | ||||||
|  |       <template slot="title"> | ||||||
|  |         <ai-title title="投票实况" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title> | ||||||
|  |       </template> | ||||||
|  |       <template slot="content"> | ||||||
|  |         <ai-title title="本届任职" isShowBottomBorder></ai-title> | ||||||
|  |         <div class="basicinfo-box"> | ||||||
|  |           <div><span>已投人数:</span><span>{{ data.alreadyCount || 0 }}</span></div> | ||||||
|  |           <div><span>未投人数:</span><span>{{ data.notYetCount || 0 }}</span></div> | ||||||
|  |           <div><span>日期:</span><span>{{ data.dateTime || '' }}</span></div> | ||||||
|  |         </div> | ||||||
|  |  | ||||||
|  |         <ai-title title="候选人选票统计" isShowBottomBorder></ai-title> | ||||||
|  |  | ||||||
|  |         <div class="echarts-box"> | ||||||
|  |           <div id="echarts-bar"></div> | ||||||
|  |           <!-- <ai-empty class="empty"></ai-empty> --> | ||||||
|  |         </div> | ||||||
|  |       </template> | ||||||
|  |     </ai-detail> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import * as echarts from 'echarts'; | ||||||
|  | export default { | ||||||
|  |   name: "Statistics", | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |     params: Object, | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       data: {}, | ||||||
|  |       myChart: null, | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.getStatistics() | ||||||
|  |   }, | ||||||
|  |   mounted() { | ||||||
|  |     this.getStaBar() | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     cancel (isRefresh) { | ||||||
|  |       this.$emit('change', { | ||||||
|  |         type: 'electionList', | ||||||
|  |         isRefresh: !!isRefresh | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     getStatistics() { | ||||||
|  |       this.instance.post(`/app/appgeneralelectioninfo/statistics?id=${this.params.id}`).then(res=> { | ||||||
|  |         if(res?.data) { | ||||||
|  |           this.data = res.data | ||||||
|  |           this.statistics = res.data.statistics | ||||||
|  |           let xData = res.data.statistics.map(e=> e.candidate_user_name) | ||||||
|  |           let yData1 = res.data.statistics.map(e=> e.c1) | ||||||
|  |           let yData2 = res.data.statistics.map(e=> e.c2) | ||||||
|  |           let yData3 = res.data.statistics.map(e=> e.c3) | ||||||
|  |           this.getStaBar(xData,yData1,yData2,yData3) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     getStaBar(xData,yData1,yData2,yData3) { | ||||||
|  |       let chartDom = document.getElementById('echarts-bar') | ||||||
|  |       this.myChart = echarts.init(chartDom); | ||||||
|  |       this.myChart.setOption({ | ||||||
|  |         dataZoom: [ | ||||||
|  |           { | ||||||
|  |             type: "slider", | ||||||
|  |             xAxisIndex: [0], | ||||||
|  |             filterMode: "filter", | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |         legend: { | ||||||
|  |           data: ['支持', '反对', '弃票'] | ||||||
|  |         }, | ||||||
|  |         xAxis: { | ||||||
|  |           type: 'category', | ||||||
|  |           data: xData, | ||||||
|  |         }, | ||||||
|  |         yAxis: { | ||||||
|  |           type: 'value', | ||||||
|  |           alignTicks: true, | ||||||
|  |         }, | ||||||
|  |         series: [    // 支持、反对、弃票 | ||||||
|  |           { | ||||||
|  |             name: '支持', | ||||||
|  |             data: yData1, | ||||||
|  |             type: 'bar', | ||||||
|  |              | ||||||
|  |             showBackground: true, | ||||||
|  |             backgroundStyle: { | ||||||
|  |               color: 'rgba(180, 180, 180, 0.2)' | ||||||
|  |             }, | ||||||
|  |             barWidth: 22, | ||||||
|  |             barGap: '20%', | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             name: '反对', | ||||||
|  |             data: yData2, | ||||||
|  |             type: 'bar', | ||||||
|  |              | ||||||
|  |             showBackground: true, | ||||||
|  |             backgroundStyle: { | ||||||
|  |               color: 'rgba(180, 180, 180, 0.2)' | ||||||
|  |             }, | ||||||
|  |             barWidth: 22, | ||||||
|  |             barGap: '20%', | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             name: '弃票', | ||||||
|  |             data: yData3, | ||||||
|  |             type: 'bar', | ||||||
|  |              | ||||||
|  |             showBackground: true, | ||||||
|  |             backgroundStyle: { | ||||||
|  |               color: 'rgba(180, 180, 180, 0.2)' | ||||||
|  |             }, | ||||||
|  |             barWidth: 22, | ||||||
|  |             barGap: '20%', | ||||||
|  |           } | ||||||
|  |         ] | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .Statistics { | ||||||
|  |   .basicinfo-box { | ||||||
|  |     display: flex; | ||||||
|  |     margin: 20px 0; | ||||||
|  |     div { | ||||||
|  |       flex: 1; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   .echarts-box { | ||||||
|  |     // width: 100%; | ||||||
|  |  | ||||||
|  |     #echarts-bar { | ||||||
|  |       width: 1200px; | ||||||
|  |       height: 400px; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										284
									
								
								project/biaopin/AppGeneralElection/components/electionAdd.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										284
									
								
								project/biaopin/AppGeneralElection/components/electionAdd.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,284 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="electionAdd"> | ||||||
|  |     <ai-detail v-show="id && !isEdit"> | ||||||
|  |       <template slot="title"> | ||||||
|  |         <ai-title title="换届选举详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title> | ||||||
|  |       </template> | ||||||
|  |       <template slot="content"> | ||||||
|  |         <ai-card :title="info.title"> | ||||||
|  |           <template #right> | ||||||
|  |             <span style="color:#2266FF;cursor: pointer;font-size: 12px;" class="iconfont iconEdit" v-if="isEdit==false && info.status==0" @click="update">修改</span> | ||||||
|  |           </template> | ||||||
|  |           <template #content v-if="isEdit == false"> | ||||||
|  |             <ai-wrapper> | ||||||
|  |               <ai-info-item label="投票说明" :value="info.votingInstructions"></ai-info-item> | ||||||
|  |               <ai-info-item label="单位名称" :value="info.organizationName"></ai-info-item> | ||||||
|  |               <ai-info-item label="选举方式"> | ||||||
|  |                 {{ info.electionMethod==0? '等额':'差额'}} | ||||||
|  |                 <el-tooltip class="item" effect="dark" content="差额选举:候选人数多于应选人数的选举方式; | ||||||
|  |                   等额选举:候选人数与应选人数相等的选举方式。" placement="top"> | ||||||
|  |                   <i class="el-icon-info" style="margin-right: 8px"></i> | ||||||
|  |                 </el-tooltip> | ||||||
|  |               </ai-info-item> | ||||||
|  |               <ai-info-item label="应选人数" :value="info.candidatesNumber"></ai-info-item> | ||||||
|  |               <ai-info-item label="投票日期" :value="info.votingDate"></ai-info-item> | ||||||
|  |             </ai-wrapper> | ||||||
|  |           </template> | ||||||
|  |         </ai-card> | ||||||
|  |         <ai-card title="参会人员信息"> | ||||||
|  |           <template #content v-if="isEdit == false"> | ||||||
|  |             <ai-wrapper> | ||||||
|  |               <ai-info-item label="候选人" isLine> | ||||||
|  |                 <span v-for="(item,index) in candidateUsersList" :key="index"> | ||||||
|  |                   {{ item }} | ||||||
|  |                   <span v-if="index < candidateUsersList.length - 1">、</span> | ||||||
|  |                 </span> | ||||||
|  |               </ai-info-item> | ||||||
|  |               <ai-info-item label="投票人" isLine> | ||||||
|  |                 <span v-for="(item,index) in voteUsersList" :key="index"> | ||||||
|  |                   {{ item }} | ||||||
|  |                   <span v-if="index < voteUsersList.length - 1">、</span> | ||||||
|  |                 </span> | ||||||
|  |               </ai-info-item> | ||||||
|  |             </ai-wrapper> | ||||||
|  |           </template> | ||||||
|  |         </ai-card> | ||||||
|  |       </template> | ||||||
|  |     </ai-detail> | ||||||
|  |     <ai-detail v-show="!id || isEdit==true"> | ||||||
|  |       <ai-title slot="title" :title="id? '编辑换届选举':'添加换届选举'" isShowBottomBorder isShowBack @onBackClick="cancel(true)"/> | ||||||
|  |       <template slot="content"> | ||||||
|  |         <ai-card title="基本信息"> | ||||||
|  |           <template #content> | ||||||
|  |             <div class="tips" v-if="!id"><i class="el-icon-warning"></i>换届选举仅采取不记名(匿名)投票</div> | ||||||
|  |             <div class="add-form"> | ||||||
|  |               <el-form ref="form" :model="form" :rules="formRules" size="small"  label-width="150px"> | ||||||
|  |  | ||||||
|  |                 <el-form-item label="标题" prop="title"> | ||||||
|  |                   <el-input v-model="form.title" placeholder="请输入" show-word-limit maxlength="100"></el-input> | ||||||
|  |                 </el-form-item> | ||||||
|  |  | ||||||
|  |                 <el-form-item label="投票说明"> | ||||||
|  |                   <el-input type="textarea" :rows="5" v-model="form.votingInstructions" placeholder="请输入" show-word-limit maxlength="500"></el-input> | ||||||
|  |                 </el-form-item> | ||||||
|  |  | ||||||
|  |                 <el-form-item label="单位名称" prop="organizationName"> | ||||||
|  |                   <el-input size="small" disabled placeholder="请选择所属党组织" v-model="form.organizationName"> | ||||||
|  |                     <template slot="append"> | ||||||
|  |                       <ai-party :instance="instance" size="small" :value="form.partyOrgId" @origin="handlePartyOrgSelect"/> | ||||||
|  |                     </template> | ||||||
|  |                   </el-input> | ||||||
|  |                 </el-form-item> | ||||||
|  |  | ||||||
|  |                 <el-form-item label="选举方式" prop="electionMethod"> | ||||||
|  |                   <el-tooltip class="item" effect="dark" content="差额选举:候选人数多于应选人数的选举方式; | ||||||
|  |                    等额选举:候选人数与应选人数相等的选举方式。" placement="top"> | ||||||
|  |                     <i class="el-icon-info" style="margin-right: 8px"></i> | ||||||
|  |                   </el-tooltip> | ||||||
|  |  | ||||||
|  |                   <el-radio v-model="form.electionMethod" label="0">等额</el-radio> | ||||||
|  |                   <el-radio v-model="form.electionMethod" label="1">差额</el-radio> | ||||||
|  |                 </el-form-item> | ||||||
|  |  | ||||||
|  |                 <el-row type="flex"> | ||||||
|  |                   <el-col :span="20"> | ||||||
|  |                     <el-form-item label="应选人数" prop="chooseNumber"> | ||||||
|  |                       <el-input type="number" v-model="form.chooseNumber" placeholder="请输入"></el-input> | ||||||
|  |                     </el-form-item> | ||||||
|  |                   </el-col> | ||||||
|  |                   <el-col :span="20"> | ||||||
|  |                     <el-form-item label="投票日期" prop="votingDate"> | ||||||
|  |                       <el-date-picker v-model="form.votingDate" value-format="yyyy-MM-dd HH:mm:ss" type="date" placeholder="选择日期" style="width:338px"> | ||||||
|  |                       </el-date-picker> | ||||||
|  |                     </el-form-item> | ||||||
|  |                   </el-col> | ||||||
|  |                 </el-row> | ||||||
|  |  | ||||||
|  |                 <el-form-item label="候选人" prop="candidateUsers"> | ||||||
|  |                   <ai-person-select :instance="instance" :customClicker="true" :chooseUserList="chooseCandidateList" | ||||||
|  |                       :url="`/app/appparty/list?partyOrgId=${form.partyOrgId}`" headerTitle="党员列表" | ||||||
|  |                       :isMultiple="true" dialogTitle="选择" @selectPerson="selectCandidate" class="aipersonselect"> | ||||||
|  |                     <template name="option" v-slot:option="{ item }"> | ||||||
|  |                       <span class="iconfont iconProlife">{{ item.name }}</span> | ||||||
|  |                       <span>{{ item.phone }}</span> | ||||||
|  |                       <span>{{ item}}</span> | ||||||
|  |                     </template> | ||||||
|  |                   </ai-person-select> | ||||||
|  |                 </el-form-item> | ||||||
|  |  | ||||||
|  |                 <el-form-item label="投票人" prop="voteUsers"> | ||||||
|  |                   <ai-person-select :instance="instance" :customClicker="true" :chooseUserList="chooseVoteList" | ||||||
|  |                       :url="`/app/appparty/list?partyOrgId=${form.partyOrgId}`" headerTitle="党员列表" | ||||||
|  |                       :isMultiple="true" dialogTitle="选择" @selectPerson="selectVote" class="aipersonselect"> | ||||||
|  |                     <template name="option" v-slot:option="{ item }"> | ||||||
|  |                       <span class="iconfont iconProlife">{{ item.name }}</span> | ||||||
|  |                       <ai-id mode="show" :show-eyes="false" :value="item.idNumber"/> | ||||||
|  |                     </template> | ||||||
|  |                   </ai-person-select> | ||||||
|  |                 </el-form-item> | ||||||
|  |               </el-form> | ||||||
|  |             </div> | ||||||
|  |           </template> | ||||||
|  |         </ai-card> | ||||||
|  |       </template> | ||||||
|  |       <template #footer> | ||||||
|  |         <el-button class="delete-btn footer-btn" @click="cancel(false)">取消</el-button> | ||||||
|  |         <el-button class="footer-btn" type="primary" @click="confirm()">保存</el-button> | ||||||
|  |       </template> | ||||||
|  |     </ai-detail> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: "electionAdd", | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |     params: Object, | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  |   data() { | ||||||
|  |     let validCandidate = (rule, value, callback) => { | ||||||
|  |       if (!value.length) { | ||||||
|  |         return callback(new Error('请选择候选人')); | ||||||
|  |       } else { | ||||||
|  |         callback(); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |     let validVote = (rule, value, callback) => { | ||||||
|  |       if (!value.length) { | ||||||
|  |         return callback(new Error('请选择投票人')); | ||||||
|  |       } else { | ||||||
|  |         callback(); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |     return { | ||||||
|  |       form: { | ||||||
|  |         title: '', | ||||||
|  |         votingInstructions: '', | ||||||
|  |         organizationName: '', | ||||||
|  |         electionMethod: '', | ||||||
|  |         chooseNumber: '', | ||||||
|  |         votingDate: '', | ||||||
|  |         candidateUsers: [], | ||||||
|  |         voteUsers: [], | ||||||
|  |         partyOrganizations: [], | ||||||
|  |         partyOrgId: '' | ||||||
|  |       }, | ||||||
|  |       formRules: { | ||||||
|  |         title: [{required: true, message: "请输入标题", trigger: "blur"}], | ||||||
|  |         organizationName: [{required: true, message: "请选择党组织", trigger: "blur"}], | ||||||
|  |         electionMethod: [{required: true, message: "请选择选举方式", trigger: "blur"}], | ||||||
|  |         chooseNumber: [{required: true, message: "请输入应选人数", trigger: "blur"}], | ||||||
|  |         votingDate: [{required: true, message: "请选择投票日期", trigger: "blur"}], | ||||||
|  |         candidateUsers: [{required: true,validator: validCandidate, trigger: "blur"}], | ||||||
|  |         voteUsers: [{required: true,validator: validVote, trigger: "blur"}], | ||||||
|  |       }, | ||||||
|  |       id: '', | ||||||
|  |       isEdit: false, | ||||||
|  |       info: {}, | ||||||
|  |       candidateUsersList: '', | ||||||
|  |       voteUsersList: '', | ||||||
|  |       chooseCandidateList: [], | ||||||
|  |       chooseVoteList: [], | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     if(this.params && this.params.id) { | ||||||
|  |       this.id = this.params.id | ||||||
|  |       this.getDetail() | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     cancel (isRefresh) { | ||||||
|  |       this.$emit('change', { | ||||||
|  |         type: 'electionList', | ||||||
|  |         isRefresh: !!isRefresh | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     update() { | ||||||
|  |       this.isEdit = true | ||||||
|  |       this.getDetail() | ||||||
|  |     }, | ||||||
|  |     getDetail() { | ||||||
|  |       this.instance.post(`/app/appgeneralelectioninfo/queryDetailById`,null, { | ||||||
|  |         params: {id:this.id} | ||||||
|  |       }).then((res) => { | ||||||
|  |         if(res?.data) { | ||||||
|  |           this.form = res.data | ||||||
|  |           this.form.organizationName = res.data.partyOrganizations[0].name | ||||||
|  |           this.info = res.data | ||||||
|  |           this.candidateUsersList = res.data.candidateUsers.map(v=> v.name) | ||||||
|  |           this.voteUsersList = res.data.voteUsers.map(v=> v.name) | ||||||
|  |           this.chooseCandidateList = res.data.candidateUsers | ||||||
|  |           this.chooseVoteList = res.data.voteUsers | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     selectCandidate(v) { | ||||||
|  |       this.form.candidateUsers = v | ||||||
|  |     }, | ||||||
|  |     selectVote(e) { | ||||||
|  |       this.form.voteUsers = e | ||||||
|  |     }, | ||||||
|  |     handlePartyOrgSelect(v) { | ||||||
|  |       if(v) { | ||||||
|  |         this.form.organizationName = v[0]?.name | ||||||
|  |         this.form.partyOrganizations = [v[0]] | ||||||
|  |         this.form.partyOrgId = v[0]?.id | ||||||
|  |       } else { | ||||||
|  |         this.form.organizationName = this.chooseUserList[0]?.name | ||||||
|  |         this.form.partyOrganizations = this.chooseUserList | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     confirm() { | ||||||
|  |       this.$refs.form.validate((valid) => { | ||||||
|  |           if (valid) { | ||||||
|  |             if(this.form.electionMethod == 0) { | ||||||
|  |               if(this.form.chooseNumber != this.form.candidateUsers.length) { | ||||||
|  |                 return this.$message.error('候选人数与应选人数应相等') | ||||||
|  |               } | ||||||
|  |             } else if(this.form.electionMethod == 1) { | ||||||
|  |               if(this.form.chooseNumber >= this.form.candidateUsers.length) { | ||||||
|  |                 return this.$message.error('候选人数应多于应选人数') | ||||||
|  |               } | ||||||
|  |             } | ||||||
|  |             this.instance.post(`/app/appgeneralelectioninfo/addOrUpdate`,{ | ||||||
|  |               ...this.form | ||||||
|  |             }).then(res => { | ||||||
|  |               if(res.code == 0) { | ||||||
|  |                 this.$message.success(this.id ? '编辑成功' : '新增成功') | ||||||
|  |                 this.cancel(true) | ||||||
|  |               } | ||||||
|  |             }).catch((err) => { | ||||||
|  |               console.log(err); | ||||||
|  |             }) | ||||||
|  |           } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scope> | ||||||
|  | .electionAdd { | ||||||
|  |   height: 100%; | ||||||
|  |  | ||||||
|  |   :deep( .el-date-editor .el-input ){ | ||||||
|  |     width: 100%; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .tips { | ||||||
|  |     width: 100%; | ||||||
|  |     border: 1px solid #f82; | ||||||
|  |     background-color: #fff3e9; | ||||||
|  |     color: #f82; | ||||||
|  |     padding: 8px 16px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     border-radius: 4px; | ||||||
|  |     margin-bottom: 32px; | ||||||
|  |     font-size: 13px; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										148
									
								
								project/biaopin/AppGeneralElection/components/electionList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								project/biaopin/AppGeneralElection/components/electionList.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="electionList"> | ||||||
|  |     <ai-list> | ||||||
|  |       <ai-title slot="title" title="换届选举" isShowBottomBorder /> | ||||||
|  |       <template #content> | ||||||
|  |         <ai-search-bar> | ||||||
|  |           <template #left> | ||||||
|  |             <el-button size="small" type="primary" icon="iconfont iconAdd" @click="toAdd('')" >添加</el-button> | ||||||
|  |             <ai-select v-model="search.status" @change=";(page.current = 1), getList()" placeholder="请选择状态" :selectList="dict.getDict('electionStatus')"></ai-select> | ||||||
|  |           </template> | ||||||
|  |           <template #right> | ||||||
|  |             <el-input v-model="search.title" class="search-input" size="small" v-throttle="() => {(page.current = 1), getList()} " placeholder="标题" clearable @change="getList" @clear="page.current = 1, (search.title = ''), getList()" suffix-icon="iconfont iconSearch"> | ||||||
|  |             </el-input> | ||||||
|  |           </template> | ||||||
|  |         </ai-search-bar> | ||||||
|  |         <ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size" @getList="getList" :col-configs="colConfigs" :dict="dict"> | ||||||
|  |           <el-table-column slot="options" label="操作" fixed="right" align="center"> | ||||||
|  |             <template slot-scope="{ row }"> | ||||||
|  |               <el-button type="text" @click.native="toAdd(row.id)">详情</el-button> | ||||||
|  |               <el-button type="text" v-show="row.status!=2" :disabled="row.status==2" @click.native="startEnd(row.id, row.status)">{{row.status == 0? '开启':'结束'}}</el-button> | ||||||
|  |               <el-button type="text" v-show="row.status != 0" @click.native="toStatistics(row.id)">统计</el-button> | ||||||
|  |               <el-button type="text" @click.native="handleDelete(row.id)">删除</el-button> | ||||||
|  |             </template> | ||||||
|  |           </el-table-column> | ||||||
|  |         </ai-table> | ||||||
|  |       </template> | ||||||
|  |     </ai-list> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: 'electionList', | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object | ||||||
|  |   }, | ||||||
|  |   data () { | ||||||
|  |     return { | ||||||
|  |       search: { | ||||||
|  |         status: '',  // 0、未开始;1、进行中;2、已结束 | ||||||
|  |         title: '', | ||||||
|  |       }, | ||||||
|  |       page: { | ||||||
|  |         current: 1, | ||||||
|  |         size: 10, | ||||||
|  |         total: 0, | ||||||
|  |       }, | ||||||
|  |       tableData: [], | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created () { | ||||||
|  |     this.$dict.load('electionStatus', 'electionMethod').then(()=> { | ||||||
|  |       this.getList() | ||||||
|  |     }) | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     colConfigs() { | ||||||
|  |       return [ | ||||||
|  |         {prop: "title", label: "标题", align: "left", showOverflowTooltip: true}, | ||||||
|  |         {prop: "organizationName", label: "所属支部", align: "center"}, | ||||||
|  |         {prop: "electionMethod", label: "选举方式", align: "center",dict:"electionMethod"}, | ||||||
|  |         {prop: "chooseNumber", label: "应选人数", align: "center"}, | ||||||
|  |         {prop: "status", label: "状态", align: "center",width: "180px", dict: "electionStatus"}, | ||||||
|  |         { slot: "options", }, | ||||||
|  |       ] | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     getList() { | ||||||
|  |       this.instance.post(`/app/appgeneralelectioninfo/list`,null,{ | ||||||
|  |         params: { | ||||||
|  |           ...this.page, | ||||||
|  |           ...this.search, | ||||||
|  |         } | ||||||
|  |       }).then(res=> { | ||||||
|  |         if(res?.data) { | ||||||
|  |           this.tableData = res.data.records | ||||||
|  |           this.page.total = res.data.total | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     toAdd(id) { | ||||||
|  |       this.$emit('change', { | ||||||
|  |         type: 'electionAdd', | ||||||
|  |         params: { | ||||||
|  |           id: id || '', | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     handleDelete(id) { | ||||||
|  |       this.$confirm('确定删除该数据?').then(() => { | ||||||
|  |         this.instance.post(`/app/appgeneralelectioninfo/delete?ids=${id}`).then(res=>{ | ||||||
|  |           if(res.code == 0) { | ||||||
|  |             this.$message.success('删除成功!') | ||||||
|  |             this.getList() | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     reset() { | ||||||
|  |       this.search = { | ||||||
|  |         status: '', | ||||||
|  |         title: '', | ||||||
|  |       } | ||||||
|  |       this.getList() | ||||||
|  |     }, | ||||||
|  |     // 开启、结束 | ||||||
|  |     startEnd(id, status) { | ||||||
|  |       let title = '' | ||||||
|  |       let bool = null | ||||||
|  |       let tips = '' | ||||||
|  |       if(status == 0) { | ||||||
|  |         title = '未到投票开始时间,确定要提前开始吗?' | ||||||
|  |         bool = true | ||||||
|  |         tips = '开启成功' | ||||||
|  |       } else if(status == 1) { | ||||||
|  |         title = '投票正在进行中,确定要提前结束吗?' | ||||||
|  |         bool = false | ||||||
|  |         tips = '结束成功' | ||||||
|  |       } | ||||||
|  |       this.$confirm(title).then(() => { | ||||||
|  |         this.instance.post(`/app/appgeneralelectioninfo/start-end?id=${id}&start=${bool}`).then(res=>{ | ||||||
|  |           if(res.code == 0) { | ||||||
|  |             this.$message.success(tips) | ||||||
|  |             this.getList() | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     // 统计 | ||||||
|  |     toStatistics(id) { | ||||||
|  |       this.$emit('change', { | ||||||
|  |         type: 'Statistics', | ||||||
|  |         params: { | ||||||
|  |           id: id || '', | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .electionList { | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @@ -0,0 +1,59 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="AppOrganizationChange"> | ||||||
|  |     <keep-alive :include="['List']"> | ||||||
|  |       <component :is="currentPage" :instance="instance" :selected.sync="selected" :params="params" :dict="dict" @change="onChange"/> | ||||||
|  |     </keep-alive> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import {mapState} from "vuex"; | ||||||
|  | import List from "./components/List.vue"; | ||||||
|  | import organizationSetting from "./components/organizationSetting.vue"; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "AppOrganizationChange", | ||||||
|  |   label: "组织换届", | ||||||
|  |   provide() { | ||||||
|  |     return { | ||||||
|  |       ...this.$props | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |     permissions: Function | ||||||
|  |   }, | ||||||
|  |   components: { | ||||||
|  |     List, | ||||||
|  |     organizationSetting, | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     ...mapState(['user']), | ||||||
|  |     currentPage() { | ||||||
|  |       const {hash} = this.$route | ||||||
|  |       if (["#add","#makeup"].includes(hash)) { | ||||||
|  |         return organizationSetting | ||||||
|  |       } else return List | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       params: {}, | ||||||
|  |       include: [], | ||||||
|  |       selected: {}, | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     onChange(data) { | ||||||
|  |       this.params = data.params; | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .AppOrganizationChange { | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								project/biaopin/AppOrganizationChange/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								project/biaopin/AppOrganizationChange/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | |||||||
|  | <template> | ||||||
|  |   <ai-detail list class="List"> | ||||||
|  |     <template slot="title"> | ||||||
|  |       <ai-title title="组织换届" isShowBottomBorder> | ||||||
|  |         <template #rightBtn> | ||||||
|  |           <el-button size="small" type="primary" @click="toAdd(selected.id)" v-if="hasConfig&&permissions('app_apporganizationchangeconfig')">换届设置 | ||||||
|  |           </el-button> | ||||||
|  |         </template> | ||||||
|  |       </ai-title> | ||||||
|  |     </template> | ||||||
|  |     <el-row slot="content" type="flex"> | ||||||
|  |       <ai-tree-menu title="组织目录" searchPlaceholder="请输入组织名称" @search="onSearch"> | ||||||
|  |         <ai-party-tree | ||||||
|  |             :filter-node-method="filterNode" | ||||||
|  |             ref="tree" | ||||||
|  |             :instance="instance" | ||||||
|  |             :root="user.info.organizationId" | ||||||
|  |             :current-node-key="selected.id" | ||||||
|  |             @select="onTreeChange"/> | ||||||
|  |       </ai-tree-menu> | ||||||
|  |       <el-scrollbar class="fill mar-l16 mainContent"> | ||||||
|  |         <ai-card title="当前届次"> | ||||||
|  |           <moment slot="content" :selected="selected" v-on="$listeners" :hasConfig.sync="hasConfig"/> | ||||||
|  |         </ai-card> | ||||||
|  |         <ai-card title="历史届次" v-if="hasConfig"> | ||||||
|  |           <history slot="content" :selected="selected" v-on="$listeners"/> | ||||||
|  |         </ai-card> | ||||||
|  |       </el-scrollbar> | ||||||
|  |     </el-row> | ||||||
|  |   </ai-detail> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import {mapState} from 'vuex' | ||||||
|  | import moment from './moment.vue' | ||||||
|  | import history from './history.vue' | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: 'List', | ||||||
|  |   inject: ['permissions', 'instance', 'dict'], | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       tabs: [ | ||||||
|  |         {label: '当前届次', name: 'moment', comp: moment, permission: ''}, | ||||||
|  |         {label: '历史届次', name: 'history', comp: history, permission: ''} | ||||||
|  |       ], | ||||||
|  |       currIndex: '0', | ||||||
|  |       selected: null, | ||||||
|  |       hasConfig: false | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   components: { | ||||||
|  |     moment, | ||||||
|  |     history, | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     ...mapState(['user']), | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     onTreeChange(e) { | ||||||
|  |       this.selected = e | ||||||
|  |     }, | ||||||
|  |     onSearch(v) { | ||||||
|  |       this.$refs.tree?.$refs?.partyTree?.filter(v) | ||||||
|  |     }, | ||||||
|  |     filterNode(value, data) { | ||||||
|  |       if (!value) return true | ||||||
|  |       return data.name.indexOf(value) !== -1 | ||||||
|  |     }, | ||||||
|  |     toAdd(oid) { | ||||||
|  |       this.$router.push({hash: "#add", query: {oid}}) | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     const {organizationId: id, organizationName: name} = this.user.info | ||||||
|  |     this.selected = {id, name} | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .List { | ||||||
|  |   position: relative; | ||||||
|  |  | ||||||
|  |   :deep(.ai-detail__content--wrapper ){ | ||||||
|  |     height: 100%; | ||||||
|  |  | ||||||
|  |     & > * { | ||||||
|  |       height: inherit; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .mainContent { | ||||||
|  |       .el-scrollbar__wrap { | ||||||
|  |         overflow-x: hidden; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .AiTreeMenu { | ||||||
|  |       min-width: 300px; | ||||||
|  |       box-shadow: 0 4px 6px -2px rgb(15 15 21 / 15%); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   :deep( .is-current > .el-tree-node__content ){ | ||||||
|  |     width: 100% !important; | ||||||
|  |     padding-right: 16px !important; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										157
									
								
								project/biaopin/AppOrganizationChange/components/detailPanel.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								project/biaopin/AppOrganizationChange/components/detailPanel.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,157 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="detailPanel"> | ||||||
|  |     <ai-title :title="`本届任职${!disabled?'(必填)':''}`"> | ||||||
|  |       <template #rightBtn v-if="!disabled"> | ||||||
|  |         <el-button type="text" icon="iconfont iconAdd" @click="showDialog({type:0})">添加任职人员</el-button> | ||||||
|  |       </template> | ||||||
|  |     </ai-title> | ||||||
|  |     <el-table :data="serveList" border size="small"> | ||||||
|  |       <el-table-column label="职位" width="180px" prop="position"/> | ||||||
|  |       <el-table-column label="姓名" prop="name"/> | ||||||
|  |       <el-table-column label="操作" width="200px" align="center" v-if="!disabled"> | ||||||
|  |         <div slot-scope="{row,$index}" class="table-operation"> | ||||||
|  |           <el-button type="text" @click="showDialog(row,$index)">编辑</el-button> | ||||||
|  |           <el-button type="text" @click="deleteItem($index,0)">删除</el-button> | ||||||
|  |         </div> | ||||||
|  |       </el-table-column> | ||||||
|  |     </el-table> | ||||||
|  |     <ai-title title="本届候选人"> | ||||||
|  |       <template #rightBtn v-if="!disabled"> | ||||||
|  |         <el-button type="text" icon="iconfont iconAdd" @click="showDialog({type:1})">添加候选人</el-button> | ||||||
|  |       </template> | ||||||
|  |     </ai-title> | ||||||
|  |     <el-table :data="candidateList" border size="small"> | ||||||
|  |       <el-table-column label="职位" width="180px" prop="position"/> | ||||||
|  |       <el-table-column label="候选人" prop="name"/> | ||||||
|  |       <el-table-column label="操作" width="200px" align="center" v-if="!disabled"> | ||||||
|  |         <div slot-scope="{row,$index}" class="table-operation"> | ||||||
|  |           <el-button type="text" @click="showDialog(row,$index)">编辑</el-button> | ||||||
|  |           <el-button type="text" @click="deleteItem($index,1)">删除</el-button> | ||||||
|  |         </div> | ||||||
|  |       </el-table-column> | ||||||
|  |     </el-table> | ||||||
|  |     <ai-dialog :visible.sync="visible" width="520px" :title="dialog.title" class="editStyle" | ||||||
|  |                @closed="dialog={}" @onConfirm="submitAdd"> | ||||||
|  |       <el-form ref="editListItemForm" size="small" :model="dialog" :rules="rules" label-width="100px" | ||||||
|  |                :validate-on-rule-change="false"> | ||||||
|  |         <el-form-item label="职位:" prop="position"> | ||||||
|  |           <el-input v-model="dialog.position" placeholder="请输入..."/> | ||||||
|  |         </el-form-item> | ||||||
|  |         <el-form-item :label="currentList.name+':'" prop="name"> | ||||||
|  |           <el-input v-if="dialog.type==0" v-model="dialog.name" placeholder="请输入..."/> | ||||||
|  |           <div v-else> | ||||||
|  |             <el-input type="textarea" :rows="3" v-model="dialog.name" placeholder="请输入..."/> | ||||||
|  |             <span style="color:#999;font-size: 12px">输入候选人姓名,用空格隔开</span> | ||||||
|  |           </div> | ||||||
|  |         </el-form-item> | ||||||
|  |       </el-form> | ||||||
|  |     </ai-dialog> | ||||||
|  |   </section> | ||||||
|  |  | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: "detailPanel", | ||||||
|  |   props: { | ||||||
|  |     candidateList: {default: () => []}, | ||||||
|  |     serveList: {default: () => []}, | ||||||
|  |     disabled: Boolean | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       visible: false, | ||||||
|  |       dialog: { | ||||||
|  |         title: "", | ||||||
|  |         name: "", | ||||||
|  |         changeTime: "" | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     currentList() { | ||||||
|  |       let initData = { | ||||||
|  |         0: {name: "姓名", dialogTitle: "本届任职人", list: "serveList"}, | ||||||
|  |         1: {name: "候选人", dialogTitle: "本届候选人", list: "candidateList"} | ||||||
|  |       } | ||||||
|  |       return initData[this.dialog.type || 0] | ||||||
|  |     }, | ||||||
|  |     rules() { | ||||||
|  |       return { | ||||||
|  |         name: [{required: true, message: "请输入" + this.currentList.name, trigger: "change"}], | ||||||
|  |         position: [{required: true, message: "请输入职位", trigger: "change"}], | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     showDialog(v, rowIndex) { | ||||||
|  |       this.dialog = {...this.dialog, ...v, rowIndex} | ||||||
|  |       this.dialog.title = (this.dialog.rowIndex == 0 ? "编辑" : "添加") + this.currentList.dialogTitle | ||||||
|  |       this.visible = true | ||||||
|  |     }, | ||||||
|  |     submitAdd() { | ||||||
|  |       this.$refs.editListItemForm.validate(v => { | ||||||
|  |         if (v) { | ||||||
|  |           this.handleData(this.currentList.list, list => { | ||||||
|  |             if (this.dialog.rowIndex > -1) { | ||||||
|  |               list.splice(this.dialog.rowIndex, 1, this.dialog) | ||||||
|  |             } else list.push(this.dialog) | ||||||
|  |           }) | ||||||
|  |           this.visible = false | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     handleData(prop, cb) { | ||||||
|  |       const list = this.$copy(this.$props[prop]) || [] | ||||||
|  |       cb(list) | ||||||
|  |       this.$emit("update:" + prop, list) | ||||||
|  |     }, | ||||||
|  |     deleteItem(index, type) { | ||||||
|  |       this.$confirm(`是否要删除该${type == 0 ? '本届任职人' : '本届候选人'}`, {type: "error"}).then(() => { | ||||||
|  |         this.handleData(type == 0 ? "serveList" : "candidateList", list => { | ||||||
|  |           list.splice(index, 1) | ||||||
|  |         }) | ||||||
|  |       }).catch(() => { | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .detailPanel { | ||||||
|  |   .itemTitle + .el-table { | ||||||
|  |     margin-top: 16px; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .el-table + .itemTitle { | ||||||
|  |     margin-top: 24px; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   :deep( .table-header ){ | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     border-right: 1px solid #d0d4dc !important; | ||||||
|  |  | ||||||
|  |     .cell { | ||||||
|  |       padding-left: 32px; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     &.is-center > .cell { | ||||||
|  |       padding-left: 10px !important; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   :deep( .table-cell ){ | ||||||
|  |     height: 44px; | ||||||
|  |     color: #333; | ||||||
|  |  | ||||||
|  |     .cell { | ||||||
|  |       padding-left: 32px; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     &.is-center > .cell { | ||||||
|  |       padding-left: 10px !important; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										93
									
								
								project/biaopin/AppOrganizationChange/components/history.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								project/biaopin/AppOrganizationChange/components/history.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="history"> | ||||||
|  |     <ai-search-bar> | ||||||
|  |       <template #left> | ||||||
|  |         <el-button type="primary" icon="iconfont iconEdit" @click="$router.push({hash:'#makeup',query:{oid}})">补录</el-button> | ||||||
|  |       </template> | ||||||
|  |       <template #right> | ||||||
|  |         <el-input size="small" placeholder="请输入届次" v-model="search.sessionTime" clearable @change="getList"/> | ||||||
|  |       </template> | ||||||
|  |     </ai-search-bar> | ||||||
|  |     <ai-table :tableData="tableData" :col-configs="colConfigs" :isShowPagination="false" @getList="getList"> | ||||||
|  |       <el-table-column slot="options" label="操作" align="center"> | ||||||
|  |         <template slot-scope="{ row }"> | ||||||
|  |           <el-button type="text" @click="handleEdit(row.id)">编辑</el-button> | ||||||
|  |           <el-button type="text" @click="handleDelete(row.id)">删除</el-button> | ||||||
|  |         </template> | ||||||
|  |       </el-table-column> | ||||||
|  |     </ai-table> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: "history", | ||||||
|  |   inject: { | ||||||
|  |     permissions: {}, | ||||||
|  |     instance: {}, | ||||||
|  |     dict: {} | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       search: {sessionTime: null}, | ||||||
|  |       tableData: [] | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     colConfigs() { | ||||||
|  |       return [ | ||||||
|  |         {prop: 'sessionTime', label: '届次', align: 'left'}, | ||||||
|  |         {prop: 'changeTime', label: '换届日期', align: 'center'}, | ||||||
|  |         {prop: 'createTime', label: '操作时间', align: 'center'}, | ||||||
|  |         {prop: 'createUserName', label: '操作人', align: 'center'}, | ||||||
|  |         {slot: 'options'}, | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     oid: v => v.$attrs.selected.id | ||||||
|  |   }, | ||||||
|  |   watch: { | ||||||
|  |     oid: { | ||||||
|  |       immediate: true, | ||||||
|  |       handler() { | ||||||
|  |         this.search.sessionTime = null | ||||||
|  |         this.getList() | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     handleEdit(id) { | ||||||
|  |       this.$router.push({hash: "#makeup", query: {id}}) | ||||||
|  |     }, | ||||||
|  |     handleDelete(id) { | ||||||
|  |       this.$confirm("是否要删除该条届次记录?").then(() => { | ||||||
|  |         this.instance.post("/app/apporganizationgeneralelection/delete", null, { | ||||||
|  |           params: {id} | ||||||
|  |         }).then(res => { | ||||||
|  |           if (res?.code == 0) { | ||||||
|  |             this.$message.success("删除成功!") | ||||||
|  |             this.getList() | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       }).catch(() => 0) | ||||||
|  |     }, | ||||||
|  |     getList() { | ||||||
|  |       const {oid: organizationId} = this | ||||||
|  |       organizationId && this.instance.post("/app/apporganizationgeneralelection/list", null, { | ||||||
|  |         throttle: 500, | ||||||
|  |         params: {...this.search, organizationId} | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.tableData = res.data | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scope> | ||||||
|  | .history { | ||||||
|  |   padding-top: 0 !important; | ||||||
|  |   background-color: #FFF !important; | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										82
									
								
								project/biaopin/AppOrganizationChange/components/moment.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								project/biaopin/AppOrganizationChange/components/moment.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="moment"> | ||||||
|  |     <template v-if="detail.id"> | ||||||
|  |       <ai-title :title="detail.organizationName||'基本信息'" class="mar-b8"/> | ||||||
|  |       <ai-wrapper> | ||||||
|  |         <ai-info-item label="本届换届时间" :value="detail.changeTime"/> | ||||||
|  |         <ai-info-item label="换届类型" :value="dict.getLabel('organizationChangeType',detail.type)"/> | ||||||
|  |         <ai-info-item label="下届换届时间" :value="detail.nextChangeTime"/> | ||||||
|  |         <ai-info-item label="当前届次" :value="detail.sessionTime"/> | ||||||
|  |       </ai-wrapper> | ||||||
|  |       <detail-panel :candidate-list="detail.candidateList" :serve-list="detail.serveList" disabled/> | ||||||
|  |     </template> | ||||||
|  |     <ai-empty v-else> | ||||||
|  |       <div>暂无换届信息</div> | ||||||
|  |       <el-row type="flex" justify="center" class="mar-t8"> | ||||||
|  |         <ai-highlight content="请点击【@v】完善基础内容后,再进行后续操作" value="开始设置"/> | ||||||
|  |       </el-row> | ||||||
|  |       <el-button class="mar-t32" type="primary" @click="$router.push({hash:'#add',query:{oid,new:1}})">开始设置</el-button> | ||||||
|  |     </ai-empty> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import DetailPanel from "./detailPanel"; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "moment", | ||||||
|  |   components: {DetailPanel}, | ||||||
|  |   inject: ['permissions', 'instance', 'dict'], | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       detail: {}, | ||||||
|  |       tableData: [], | ||||||
|  |       totalJob: 0, | ||||||
|  |       current: 1, | ||||||
|  |       size: 10, | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     colConfigs() { | ||||||
|  |       return [ | ||||||
|  |         {prop: 'content', label: '职位'}, | ||||||
|  |         {prop: 'content', label: '姓名'}, | ||||||
|  |         {slot: 'options'}, | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     oid: v => v.$attrs.selected.id | ||||||
|  |   }, | ||||||
|  |   watch: { | ||||||
|  |     oid: { | ||||||
|  |       immediate: true, | ||||||
|  |       handler() { | ||||||
|  |         this.getDetail() | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     getDetail() { | ||||||
|  |       const {oid: organizationId} = this | ||||||
|  |       this.detail = {} | ||||||
|  |       organizationId && this.instance.post(`/app/apporganizationgeneralelection/queryDetailByOrganizationId`, null, { | ||||||
|  |         pureBack:true, | ||||||
|  |         params: {organizationId} | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.detail = res.data | ||||||
|  |         } | ||||||
|  |       }).finally(() => this.$emit("update:hasConfig", !!this.detail.id)) | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.dict.load("organizationChangeType") | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scope> | ||||||
|  | .moment { | ||||||
|  |   padding-top: 0 !important; | ||||||
|  |   background-color: #FFF !important; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @@ -0,0 +1,195 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="organizationSetting"> | ||||||
|  |     <ai-detail> | ||||||
|  |       <ai-title slot="title" :title="pageTitle" isShowBottomBorder isShowBack @onBackClick="cancel(true)"/> | ||||||
|  |       <template slot="content"> | ||||||
|  |         <el-form ref="SettingForm" :model="form" :rules="formRules" size="small" label-width="150px"> | ||||||
|  |           <ai-card title="基本信息" v-if="!isMakeUp"> | ||||||
|  |             <template #content> | ||||||
|  |               <div class="tips"> | ||||||
|  |                 <i class="el-icon-warning"></i> | ||||||
|  |                 系统将在下次换届时间开始前,对“换届提醒人”进行提醒。提醒方式包括平台消息推送、短信提醒。 | ||||||
|  |               </div> | ||||||
|  |               <el-form-item label="单位名称">{{ org.name }}</el-form-item> | ||||||
|  |               <el-form-item label="成立时间">{{ $dateFormat(org.createTime) }}</el-form-item> | ||||||
|  |               <el-form-item label="换届类型" prop="type"> | ||||||
|  |                 <el-radio v-model="form.type" label="0">三年换届</el-radio> | ||||||
|  |                 <el-radio v-model="form.type" label="1">五年换届</el-radio> | ||||||
|  |               </el-form-item> | ||||||
|  |               <el-form-item label="换届提醒人" prop="userList"> | ||||||
|  |                 <ai-person-select :instance="instance" :customClicker="true" :chooseUserList="form.userList" | ||||||
|  |                                   :url="`/app/appparty/list?partyOrgId=${org.id}`" headerTitle="党员列表" | ||||||
|  |                                   :isMultiple="true" dialogTitle="选择抄送人" @selectPerson="selectUser" class="aipersonselect"> | ||||||
|  |                   <template name="option" v-slot:option="{ item }"> | ||||||
|  |                     <span class="iconfont iconProlife">{{ item.name }}</span> | ||||||
|  |                   </template> | ||||||
|  |                 </ai-person-select> | ||||||
|  |               </el-form-item> | ||||||
|  |             </template> | ||||||
|  |           </ai-card> | ||||||
|  |           <ai-card title="当前届次"> | ||||||
|  |             <template #content> | ||||||
|  |               <div flex class="wrap"> | ||||||
|  |                 <el-form-item class="w50" label="本届换届时间" prop="changeTime"> | ||||||
|  |                   <el-date-picker v-model="form.changeTime" @change="getNextChangeTime" value-format="yyyy-MM-dd" placeholder="本届换届时间"/> | ||||||
|  |                 </el-form-item> | ||||||
|  |                 <el-form-item class="w50" label="下届换届时间" prop="nextChangeTime" v-if="!isMakeUp"> | ||||||
|  |                   <el-date-picker disabled v-model="form.nextChangeTime" placeholder="根据换届设置信息自动计算"/> | ||||||
|  |                 </el-form-item> | ||||||
|  |                 <el-form-item label="届次" prop="sessionTime" class="w50"> | ||||||
|  |                   <el-input type="number" v-model="form.sessionTime" placeholder="请输入..."/> | ||||||
|  |                 </el-form-item> | ||||||
|  |               </div> | ||||||
|  |               <detail-panel :serve-list.sync="form.serveList" :candidate-list.sync="form.candidateList"/> | ||||||
|  |             </template> | ||||||
|  |           </ai-card> | ||||||
|  |         </el-form> | ||||||
|  |       </template> | ||||||
|  |       <template slot="footer" class="footer"> | ||||||
|  |         <el-button class="delete-btn footer-btn" @click="cancel(false)">取消</el-button> | ||||||
|  |         <el-button class="footer-btn" type="primary" @click="confirm()">保存</el-button> | ||||||
|  |       </template> | ||||||
|  |     </ai-detail> | ||||||
|  |  | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import {mapState} from 'vuex' | ||||||
|  | import DetailPanel from "./detailPanel"; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "organizationSetting", | ||||||
|  |   components: {DetailPanel}, | ||||||
|  |   inject: ['permissions', 'instance', 'dict'], | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       form: { | ||||||
|  |         type: "", | ||||||
|  |         userList: [], | ||||||
|  |         sessionTime: "", | ||||||
|  |         changeTime: "", | ||||||
|  |         nextChangeTime: "", | ||||||
|  |         serveList: [], | ||||||
|  |         candidateList: [] | ||||||
|  |       }, | ||||||
|  |       formRules: { | ||||||
|  |         type: [{required: true, message: "请选择换届类型", trigger: "change"}], | ||||||
|  |         sessionTime: [{required: true, message: "请输入届次", trigger: "blur"}], | ||||||
|  |         userList: [{required: true, message: "请选择换届提醒人", trigger: "change"}], | ||||||
|  |         changeTime: [{required: true, message: "请选择本次换届时间", trigger: "blur"}], | ||||||
|  |         nextChangeTime: [{required: true, message: "请选择下次换届时间", trigger: "change"}] | ||||||
|  |       }, | ||||||
|  |       org: {} | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     ...mapState(['user']), | ||||||
|  |     isMakeUp: v => v.$route.hash == "#makeup", | ||||||
|  |     pageTitle: v => v.isMakeUp ? "补录换届" : "换届设置", | ||||||
|  |     oid: v => v.$route.query.oid | ||||||
|  |   }, | ||||||
|  |   watch: { | ||||||
|  |     'form.type'() { | ||||||
|  |       this.getNextChangeTime() | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     if (!!this.oid) { | ||||||
|  |       this.org = new this.MODEL.PartyOrg(this.oid) | ||||||
|  |     } | ||||||
|  |     !!this.isMakeUp ? this.getSession() : this.getDetail() | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     cancel() { | ||||||
|  |       this.$router.back() | ||||||
|  |     }, | ||||||
|  |     getNextChangeTime() { | ||||||
|  |       const {type, changeTime} = this.form, sessionPeriod = {0: 3, 1: 5}[type] | ||||||
|  |       this.form.nextChangeTime = type && changeTime ? this.$dateFormat(this.$moment(changeTime).add(sessionPeriod, "years")) : "" | ||||||
|  |     }, | ||||||
|  |     getSession() { | ||||||
|  |       //根据id获取对应届次信息 | ||||||
|  |       const {id} = this.$route.query | ||||||
|  |       id && this.instance.post(`/app/apporganizationgeneralelection/queryDetailById`, null, { | ||||||
|  |         pureBack: true, | ||||||
|  |         params: {id} | ||||||
|  |       }).then((res) => { | ||||||
|  |         if (res?.data && res?.code == '0') { | ||||||
|  |           this.form = res.data | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     getDetail() { | ||||||
|  |       //获取到当前届次信息 | ||||||
|  |       const {oid: organizationId} = this.$route.query | ||||||
|  |       this.instance.post(`/app/apporganizationgeneralelection/queryDetailByOrganizationId`, null, { | ||||||
|  |         pureBack: true, | ||||||
|  |         params: {organizationId} | ||||||
|  |       }).then((res) => { | ||||||
|  |         if (res?.data && res?.code == '0') { | ||||||
|  |           this.form = res.data | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     selectUser(v) { | ||||||
|  |       this.form.userList = v.map(e => ({ | ||||||
|  |         name: e.name, | ||||||
|  |         organizationId: e.partyOrgId, | ||||||
|  |         partyId: e.id, | ||||||
|  |         phone: e.phone | ||||||
|  |       })) | ||||||
|  |     }, | ||||||
|  |     confirm() { | ||||||
|  |       // 换届设置 | ||||||
|  |       this.$refs.SettingForm.validate(v => { | ||||||
|  |         if (v) { | ||||||
|  |           const {id: organizationId, name: organizationName} = this.org | ||||||
|  |           let action | ||||||
|  |           if (this.isMakeUp) {//补录 | ||||||
|  |             action = `/app/apporganizationgeneralelection/${!!this.form.id ? 'update' : 'add'}` | ||||||
|  |           } else {//换届设置 | ||||||
|  |             action = `/app/${!!this.form.id ? "apporganizationgeneralelection/updateAll" : 'apporganizationchangeconfig/add'}` | ||||||
|  |           } | ||||||
|  |           const addOrMakeup = !this.isMakeUp | ||||||
|  |           this.instance.post(action, { | ||||||
|  |             organizationId, organizationName, | ||||||
|  |             ...this.form, addOrMakeup | ||||||
|  |           }).then(res => { | ||||||
|  |             if (res.code == 0) { | ||||||
|  |               this.$message.success('提交成功') | ||||||
|  |               this.cancel(true) | ||||||
|  |             } | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scope> | ||||||
|  | .organizationSetting { | ||||||
|  |   height: 100%; | ||||||
|  |  | ||||||
|  |   .el-date-editor, .el-input { | ||||||
|  |     width: 100% !important; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .w50 { | ||||||
|  |     width: 50%; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .tips { | ||||||
|  |     width: 100%; | ||||||
|  |     border: 1px solid #f82; | ||||||
|  |     background-color: #fff3e9; | ||||||
|  |     color: #f82; | ||||||
|  |     padding: 8px 16px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     border-radius: 4px; | ||||||
|  |     margin-bottom: 32px; | ||||||
|  |     font-size: 13px; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @@ -0,0 +1,67 @@ | |||||||
|  | <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: 'AppVillageAuxiliarPolice', | ||||||
|  |     label: '驻村干部', | ||||||
|  |  | ||||||
|  |     props: { | ||||||
|  |       instance: Function, | ||||||
|  |       dict: Object, | ||||||
|  |       menuName: {default: '驻村干部'} | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     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> | ||||||
							
								
								
									
										126
									
								
								project/biaopin/AppVillageAuxiliarPolice/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								project/biaopin/AppVillageAuxiliarPolice/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | |||||||
|  | <template> | ||||||
|  |   <ai-detail> | ||||||
|  |     <template slot="title"> | ||||||
|  |       <ai-title :title="params.id ? '编辑' : '添加'" isShowBack isShowBottomBorder @onBackClick="cancel(false)"> | ||||||
|  |       </ai-title> | ||||||
|  |     </template> | ||||||
|  |     <template slot="content"> | ||||||
|  |       <ai-card title="基本信息"> | ||||||
|  |         <template #content> | ||||||
|  |           <el-form ref="form" class="ai-form" :model="form" label-width="110px" label-position="right"> | ||||||
|  |             <el-form-item label="服务区域" style="width: 100%;" prop="codeName"> | ||||||
|  |               <span style="color: #666;">{{ form.areaName }}</span> | ||||||
|  |             </el-form-item> | ||||||
|  |             <el-form-item style="width: 100%" label="姓名" prop="name" :rules="[{ required: true, message: '请输入姓名', trigger: 'blur' }]"> | ||||||
|  |               <el-input size="small" placeholder="请输入姓名" v-model="form.name"></el-input> | ||||||
|  |             </el-form-item> | ||||||
|  |             <el-form-item style="width: 100%" label="电话" prop="phone" :rules="[{ required: true, message: '请输入电话', trigger: 'blur' }]"> | ||||||
|  |               <el-input size="small" placeholder="请输入电话" maxlength="20" v-model="form.phone"></el-input> | ||||||
|  |             </el-form-item> | ||||||
|  |             <el-form-item style="width: 100%;" label="是否公开" prop="isPublic" :rules="[{ required: true, message: '请选择是否公开', trigger: 'change' }]"> | ||||||
|  |               <el-radio-group v-model="form.isPublic"> | ||||||
|  |                 <el-radio label="1">是</el-radio> | ||||||
|  |                 <el-radio label="0">否</el-radio> | ||||||
|  |               </el-radio-group> | ||||||
|  |             </el-form-item> | ||||||
|  |             <el-form-item label="图片" style="width: 100%;" prop="picture"> | ||||||
|  |               <ai-uploader | ||||||
|  |                 :instance="instance" | ||||||
|  |                 isShowTip | ||||||
|  |                 v-model="form.picture" | ||||||
|  |                 :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: '', | ||||||
|  |           name: '', | ||||||
|  |           areaName: '', | ||||||
|  |           phone: '', | ||||||
|  |           picture: [], | ||||||
|  |           isPublic: '1' | ||||||
|  |         }, | ||||||
|  |         id: '' | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     created () { | ||||||
|  |       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/appvillageauxiliarypolice/queryDetailById?id=${id}`).then(res => { | ||||||
|  |           if (res.code === 0) { | ||||||
|  |             this.form = res.data | ||||||
|  |             this.form.picture = res.data.picture ? [{url: res.data.picture}] : [] | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       onClose () { | ||||||
|  |         this.form.explain = '' | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       confirm () { | ||||||
|  |         this.$refs.form.validate((valid) => { | ||||||
|  |           if (valid) { | ||||||
|  |             this.instance.post(`/app/appvillageauxiliarypolice/addOrUpdate`, { | ||||||
|  |               ...this.form, | ||||||
|  |               id: this.params.id || '', | ||||||
|  |               picture: this.form.picture.length ? this.form.picture[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> | ||||||
							
								
								
									
										426
									
								
								project/biaopin/AppVillageAuxiliarPolice/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										426
									
								
								project/biaopin/AppVillageAuxiliarPolice/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,426 @@ | |||||||
|  | <template> | ||||||
|  |   <ai-list class="villagecode"> | ||||||
|  |     <template slot="title"> | ||||||
|  |       <ai-title :title="menuName" 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" | ||||||
|  |               clearable | ||||||
|  |               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" icon="iconfont iconAdd" @click="toAdd('')">添加</el-button> | ||||||
|  |         </template> | ||||||
|  |         <template slot="right"> | ||||||
|  |           <el-input | ||||||
|  |             v-model="search.name" | ||||||
|  |             class="search-input" | ||||||
|  |             size="small" | ||||||
|  |             v-throttle="() => {search.current = 1, getList()}" | ||||||
|  |             placeholder="请输入姓名/电话" | ||||||
|  |             clearable | ||||||
|  |             @change="getList" | ||||||
|  |             @clear="search.current = 1, search.name = '', getList()" | ||||||
|  |             suffix-icon="iconfont iconSearch"> | ||||||
|  |           </el-input> | ||||||
|  |         </template> | ||||||
|  |       </ai-search-bar> | ||||||
|  |       <ai-table | ||||||
|  |         :tableData="tableData" | ||||||
|  |         :col-configs="colConfigs" | ||||||
|  |         :total="total" | ||||||
|  |         style="margin-top: 6px;" | ||||||
|  |         :current.sync="search.current" | ||||||
|  |         :size.sync="search.size" | ||||||
|  |         @getList="getList"> | ||||||
|  |         <el-table-column slot="isPublic" label="是否公开"> | ||||||
|  |           <template slot-scope="{ row }"> | ||||||
|  |             <el-switch | ||||||
|  |               v-model="row.isPublic" | ||||||
|  |               active-value="1" | ||||||
|  |               @change="e => onChange(row.id, e)" | ||||||
|  |               inactive-value="0"> | ||||||
|  |             </el-switch> | ||||||
|  |           </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-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, | ||||||
|  |       menuName: String | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     data() { | ||||||
|  |       return { | ||||||
|  |         search: { | ||||||
|  |           current: 1, | ||||||
|  |           size: 10, | ||||||
|  |           name: '', | ||||||
|  |           areaId: '' | ||||||
|  |         }, | ||||||
|  |         defaultExpanded: [], | ||||||
|  |         defaultChecked: [], | ||||||
|  |         areaTree: [], | ||||||
|  |         defaultProps: { | ||||||
|  |           children: 'children', | ||||||
|  |           label: 'name' | ||||||
|  |         }, | ||||||
|  |         currIndex: -1, | ||||||
|  |         total: 10, | ||||||
|  |         colConfigs: [ | ||||||
|  |           {prop: 'name', label: '姓名', align: 'left'}, | ||||||
|  |           {prop: 'phone', label: '联系方式', align: 'center'}, | ||||||
|  |           {prop: 'areaName', label: '服务区域', align: 'center'}, | ||||||
|  |           {prop: 'createTime', label: '创建时间', align: 'center'}, | ||||||
|  |           {slot: 'isPublic', label: '是否公开', align: 'center'}, | ||||||
|  |           {slot: 'options', label: '操作'} | ||||||
|  |         ], | ||||||
|  |         areaName: '', | ||||||
|  |         unitName: '', | ||||||
|  |         tableData: [] | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     computed: { | ||||||
|  |       ...mapState(['user']) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     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.getList() | ||||||
|  |  | ||||||
|  |       this.$nextTick(() => { | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     methods: { | ||||||
|  |       getList() { | ||||||
|  |         this.instance.post(`/app/appvillageauxiliarypolice/list`, null, { | ||||||
|  |           params: { | ||||||
|  |             ...this.search | ||||||
|  |           } | ||||||
|  |         }).then(res => { | ||||||
|  |           if (res.code == 0) { | ||||||
|  |             this.tableData = res.data.records | ||||||
|  |             this.total = res.data.total | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       onChange (id) { | ||||||
|  |         this.instance.post(`/app/appvillageauxiliarypolice/enable?id=${id}`).then(res => { | ||||||
|  |           if (res.code == 0) { | ||||||
|  |             this.$message.success('修改成功') | ||||||
|  |             this.getList() | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       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)) | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       remove(id) { | ||||||
|  |         this.$confirm('确定删除该数据?').then(() => { | ||||||
|  |           this.instance.post(`/app/appvillageauxiliarypolice/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; | ||||||
|  |         :deep( input ){ | ||||||
|  |           width: 100%; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       .el-button { | ||||||
|  |         width: 84px; | ||||||
|  |         flex-shrink: 1; | ||||||
|  |         margin-right: 8px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     span { | ||||||
|  |       color: #222222; | ||||||
|  |       font-size: 14px; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     :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; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   :deep( .ai-list__content--left ){ | ||||||
|  |     margin-right: 2px; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .villagecode-left { | ||||||
|  |     width: 100%; | ||||||
|  |     height: auto; | ||||||
|  |     background: #FAFAFB; | ||||||
|  |  | ||||||
|  |     .villagecode-left__title { | ||||||
|  |       display: flex; | ||||||
|  |       align-items: center; | ||||||
|  |       height: 40px; | ||||||
|  |       padding: 0 16px; | ||||||
|  |       background: #fff; | ||||||
|  |  | ||||||
|  |       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; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   :deep( .ai-list__content--right ){ | ||||||
|  |  | ||||||
|  |     .ai-list__content--right-wrapper { | ||||||
|  |       min-height: 100%; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .message-info__img { | ||||||
|  |   font-size: 0; | ||||||
|  |   width: 144px; | ||||||
|  |   height: 144px; | ||||||
|  | } | ||||||
|  | </style> | ||||||
		Reference in New Issue
	
	Block a user