初始化
This commit is contained in:
		
							
								
								
									
										81
									
								
								packages/wechat/AppNotification/AppNotification.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								packages/wechat/AppNotification/AppNotification.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| <template> | ||||
|   <section style="height: 100%;"> | ||||
|     <ai-list v-if="!showDetail"> | ||||
|       <template slot="title"> | ||||
|         <ai-title title="通知公告"></ai-title> | ||||
|       </template> | ||||
|       <template slot="tabs"> | ||||
|         <el-tabs v-model="currIndex"> | ||||
|           <el-tab-pane v-for="(tab,i) in tabs" :key="i" :label="tab.label" :name="String(i)"> | ||||
|             <component :is="tab.comp" v-if="currIndex==i" :ref="currIndex" :instance="instance" :dict="dict" | ||||
|                         @goPage="goPage"/> | ||||
|           </el-tab-pane> | ||||
|         </el-tabs> | ||||
|       </template> | ||||
|     </ai-list> | ||||
|     <component v-else :is="currentComp" :instance="instance" :dict="dict" :detail="detailRow" @gotoEdit="gotoAdd" ></component> | ||||
|   </section> | ||||
| </template> | ||||
| <script> | ||||
|   import add from './components/add'; | ||||
|   import detail from './components/detail' | ||||
|   import manageDetail from './components/manageDetail' | ||||
|   import recentNotice from './components/recentNotice' | ||||
|   import noticeManage from './components/noticeManage' | ||||
|  | ||||
|   export default { | ||||
|     name: 'AppNotification', | ||||
|     label: "通知公告", | ||||
|     components: {add, detail, recentNotice,noticeManage,manageDetail}, | ||||
|     provide() { | ||||
|       return { | ||||
|         top: this | ||||
|       } | ||||
|     }, | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|     }, | ||||
|     data() { | ||||
|       return { | ||||
|         currIndex: "0", | ||||
|         currentComp: "", | ||||
|         showDetail: false, | ||||
|         detailRow: {}, | ||||
|       } | ||||
|     }, | ||||
|     computed: { | ||||
|       tabs() { | ||||
|         return [ | ||||
|           {label: "最新公告", name: "recentNotice", comp: recentNotice, detail: detail}, | ||||
|           {label: "公告管理", name: "noticeManage", comp: noticeManage, detail: manageDetail}, | ||||
|         ] | ||||
|       }, | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       goPage(params) { | ||||
|         params.row && (this.detailRow = params.row) | ||||
|         this.currentComp = params.comp | ||||
|  | ||||
|         if (params.comp == 'detail' || params.comp == 'add' || params.comp == "manageDetail") { | ||||
|           this.showDetail = true | ||||
|         } | ||||
|       }, | ||||
|       goBack() { | ||||
|         this.showDetail = false; | ||||
|       }, | ||||
|       gotoAdd(obj) { | ||||
|         this.showDetail = true | ||||
|         this.detailRow = obj | ||||
|         this.currentComp = 'add' | ||||
|       }, | ||||
|     }, | ||||
|   } | ||||
| </script> | ||||
| <style lang="scss" scoped> | ||||
|   ::v-deep .ai-list__content--right-wrapper { | ||||
|     background-color: transparent !important; | ||||
|     box-shadow: none !important; | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										183
									
								
								packages/wechat/AppNotification/components/add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								packages/wechat/AppNotification/components/add.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,183 @@ | ||||
| <template> | ||||
|   <ai-detail> | ||||
|     <template slot="title"> | ||||
|       <ai-title :title="detail.id ? '编辑公告' : '创建公告'" isShowBack isShowBottomBorder @onBackClick="$parent.goBack"></ai-title> | ||||
|     </template> | ||||
|     <template #content> | ||||
|       <ai-card title="基本信息"> | ||||
|         <template #content> | ||||
|           <el-form ref="form" :model="form" :rules="rules" label-width="80px"> | ||||
|             <el-form-item label="公告标题" prop="title"> | ||||
|               <el-input v-model="form.title" size="small" placeholder="请输入" show-word-limit maxlength="30"></el-input> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="公告内容" prop="content"> | ||||
|               <ai-editor v-model="form.content" :instance="instance"/> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="附件"> | ||||
|               <ai-uploader :instance="instance" v-model="form.files" fileType="file" isShowTip></ai-uploader> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="发送对象" prop="persons"> | ||||
|               <el-row type="flex" align="middle"> | ||||
|                 <div class="text-area"> | ||||
|                    <ai-open-data type="userName" :openid="item.name"  v-for="(item,index) in persons.slice(0,2)" :key="index"></ai-open-data> | ||||
|                    <span v-if="persons.length">等{{persons.length}}人</span> | ||||
|                 </div> | ||||
|                 <ai-wechat-selecter v-model="form.persons" :instance="instance" @change="onChange"> | ||||
|                   <el-button type="info">选择</el-button> | ||||
|                 </ai-wechat-selecter> | ||||
|               </el-row> | ||||
|             </el-form-item> | ||||
|             <el-row type="flex"> | ||||
|               <el-form-item label="发送时间" prop="type"> | ||||
|                 <el-radio-group v-model="form.type" @change="form.releaseTime = null"> | ||||
|                   <el-radio :label="0">立即发送</el-radio> | ||||
|                   <el-radio :label="1">定时发送</el-radio> | ||||
|                 </el-radio-group> | ||||
|               </el-form-item> | ||||
|               <el-form-item prop="releaseTime" class="picker" v-if="form.type==1"> | ||||
|                 <el-date-picker | ||||
|                   v-model="form.releaseTime" | ||||
|                   style="margin-left: 10px;" | ||||
|                   value-format="yyyy-MM-dd HH:mm:ss" | ||||
|                   size="small" | ||||
|                   type="datetime" | ||||
|                   placeholder="请选择"> | ||||
|                 </el-date-picker> | ||||
|               </el-form-item> | ||||
|             </el-row> | ||||
|           </el-form> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|     </template> | ||||
|     <template #footer> | ||||
|       <el-button @click="$parent.goBack">取消</el-button> | ||||
|       <el-button type="primary" @click="confim(0)">保存</el-button> | ||||
|       <el-button type="primary" @click="confim(1)">发布</el-button> | ||||
|     </template> | ||||
|   </ai-detail> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   export default { | ||||
|     name: "add", | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       detail: Object, | ||||
|     }, | ||||
|     data() { | ||||
|       return { | ||||
|         form: { | ||||
|           id: null, | ||||
|           title: "", | ||||
|           content: "", | ||||
|           files: [], | ||||
|           persons: [], | ||||
|           type: 0, | ||||
|           releaseTime: null, | ||||
|         }, | ||||
|         persons:[], | ||||
|       } | ||||
|     }, | ||||
|     computed: { | ||||
|       rules() { | ||||
|         return { | ||||
|           title: [ | ||||
|             {required: true, message: '请输入公告标题'}, | ||||
|           ], | ||||
|           content: [ | ||||
|             {required: true, message: '请输入公告内容'}, | ||||
|           ], | ||||
|           persons: [ | ||||
|             {required: true, message: '请选择发送对象'}, | ||||
|           ], | ||||
|           type: [ | ||||
|             {required: true}, | ||||
|           ], | ||||
|           releaseTime: [ | ||||
|             {required: true, message: '请选择发送时间'}, | ||||
|           ], | ||||
|         }; | ||||
|       } | ||||
|     }, | ||||
|     methods: { | ||||
|       onChange(e){ | ||||
|         this.form.persons = e; | ||||
|         this.persons = e; | ||||
|         this.$refs["form"].validateField("persons"); | ||||
|       }, | ||||
|       confim(e) { | ||||
|         this.$refs["form"].validate(v => { | ||||
|           if (v) { | ||||
|             if(this.form.releaseTime && (new Date(this.form.releaseTime).getTime() <= Date.now())){ | ||||
|               return this.$message.error("发送时间要大于当前时间") | ||||
|             } | ||||
|             this.instance.post("/app/appannouncement/addOrUpdate", { | ||||
|               ...this.form, | ||||
|               status: e | ||||
|             }).then(res => { | ||||
|               if (res.code == 0) { | ||||
|                 this.$message.success(e==0?"保存成功":"发布成功"); | ||||
|                 this.$parent.goBack(); | ||||
|               } | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       getDetail(){ | ||||
|         this.instance.post("/app/appannouncement/detail",null,{ | ||||
|           params:{ | ||||
|             id:this.detail.id | ||||
|           } | ||||
|         }).then(res=>{ | ||||
|           if(res && res.data){ | ||||
|             Object.keys(this.form).map(e=>this.form[e] = res.data[e]); | ||||
|             this.form.type = res.data.releaseTime ? 1 : 0; | ||||
|             this.$initWxOpenData() | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|     }, | ||||
|     mounted(){ | ||||
|       if(this.detail?.id){ | ||||
|         this.getDetail(); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   ::v-deep .picker { | ||||
|     width: 300px; | ||||
|  | ||||
|     .el-form-item__content { | ||||
|       margin-left: 0 !important; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .text-area{ | ||||
|     width:995px; | ||||
|     height:32px; | ||||
|     background-color:#F5F5F5; | ||||
|     border: 1px solid #d0d4dc; | ||||
|     border-radius: 2px; | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     box-sizing: border-box; | ||||
|     padding:0 6px; | ||||
|     color: #666666; | ||||
|     text-overflow: ellipsis; | ||||
|     overflow: hidden; | ||||
|     white-space: nowrap; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .AiOpenData{ | ||||
|     height:auto !important; | ||||
|     &:after{ | ||||
|       content:"、"; | ||||
|     } | ||||
|     &:nth-child(2):after{ | ||||
|       content:""; | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										94
									
								
								packages/wechat/AppNotification/components/detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								packages/wechat/AppNotification/components/detail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| <template> | ||||
|   <ai-detail> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="公告详情" isShowBack isShowBottomBorder @onBackClick="$parent.goBack"></ai-title> | ||||
|     </template> | ||||
|     <template #content> | ||||
|       <ai-card :title="detailObj.title" class="title"> | ||||
|         <template #content> | ||||
|           <el-row type="flex" justify="space-between" class="info"> | ||||
|             <span>时间:{{detailObj.releaseTime}}</span> | ||||
|             <span style="display:flex">发布单位: | ||||
|              <ai-open-data type="departmentName"  :openid="detailObj.unitName"></ai-open-data> | ||||
|             </span> | ||||
|             <span style="display:flex">发布人: | ||||
|              <ai-open-data type="userName"  :openid="detailObj.releaseUserName"></ai-open-data> | ||||
|             </span> | ||||
|           </el-row> | ||||
|           <div v-html="detailObj.content" style="margin: 20px 0;"></div> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|       <ai-card title="附件" v-if="detailObj.files && detailObj.files.length"> | ||||
|         <template #content> | ||||
|           <el-row type="flex" justify="space-between" class="file" v-for="(item,index) in detailObj.files" :key="index" @click.native="open(item)"> | ||||
|             <span>{{item.fileName}}</span> | ||||
|             <span>{{(item.size/1024).toFixed(2)}}KB</span> | ||||
|           </el-row> | ||||
|         </template> | ||||
|       </ai-card> | ||||
|     </template> | ||||
|   </ai-detail> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   export default { | ||||
|     name: "detail", | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       detail: Object | ||||
|     }, | ||||
|     data() { | ||||
|       return { | ||||
|         detailObj: {}, | ||||
|       } | ||||
|     }, | ||||
|     methods: { | ||||
|       open(item) { | ||||
|         window.open(item.url); | ||||
|       } | ||||
|     }, | ||||
|     mounted() { | ||||
|       this.instance.post("/app/appannouncement/detail", null, { | ||||
|         params: { | ||||
|           id: this.detail.id | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res && res.data) { | ||||
|           this.detailObj = res.data; | ||||
|           this.$initWxOpenData() | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   ::v-deep .title { | ||||
|     .aibar-left { | ||||
|       width: 100%; | ||||
|       text-align: center; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .file { | ||||
|     height: 40px; | ||||
|     line-height: 40px; | ||||
|     padding: 0 8px; | ||||
|     font-size: 14px; | ||||
|     color: #333; | ||||
|     background: #fff; | ||||
|     border-radius: 4px; | ||||
|     border: 1px solid #d0d4dc; | ||||
|     margin-bottom: 16px; | ||||
|     cursor: pointer; | ||||
|   } | ||||
|  | ||||
|   .info { | ||||
|     & > span { | ||||
|       font-size: 14px; | ||||
|       color: #333; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| </style> | ||||
							
								
								
									
										202
									
								
								packages/wechat/AppNotification/components/manageDetail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								packages/wechat/AppNotification/components/manageDetail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,202 @@ | ||||
| <template> | ||||
|   <ai-detail> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="公告详情" isShowBack isShowBottomBorder @onBackClick="$parent.goBack"></ai-title> | ||||
|     </template> | ||||
|     <template #content> | ||||
|       <ai-sidebar v-model="index" :tabTitle="tabTitle" @change="onChange"></ai-sidebar> | ||||
|       <template v-if="index==0"> | ||||
|         <ai-card :title="detailObj.title" class="title"> | ||||
|           <template #content> | ||||
|             <el-row type="flex" justify="space-between" class="info"> | ||||
|               <span>时间:{{detailObj.releaseTime}}</span> | ||||
|               <span style="display:flex">发布单位: | ||||
|                 <ai-open-data type="departmentName"  :openid="detailObj.unitName"></ai-open-data> | ||||
|               </span> | ||||
|               <span style="display:flex">发布人: | ||||
|                 <ai-open-data type="userName"  :openid="detailObj.releaseUserName"></ai-open-data> | ||||
|               </span> | ||||
|             </el-row> | ||||
|             <div v-html="detailObj.content" style="margin: 20px 0;"></div> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|         <ai-card title="附件" v-if="detailObj.files && detailObj.files.length"> | ||||
|           <template #right> | ||||
|             <span class="Edit" @click="downFileAll"><i class="iconfont iconDownload"></i>下载全部</span> | ||||
|           </template> | ||||
|           <template #content> | ||||
|             <ai-file-list :fileList="detailObj.files" :fileOps="{ name: 'fileName', size: 'size' }" ></ai-file-list> | ||||
|           </template> | ||||
|         </ai-card> | ||||
|       </template> | ||||
|       <template v-else> | ||||
|         <ai-list> | ||||
|           <template #content> | ||||
|             <ai-search-bar> | ||||
|               <template #left> | ||||
|                 <ai-select | ||||
|                   v-model="search.readStatus" | ||||
|                   @change="search.current=1,getList()" | ||||
|                   placeholder="查阅状态" | ||||
|                   :selectList="dict.getDict('announcementReadStatus')" | ||||
|                 ></ai-select> | ||||
|               </template> | ||||
|               <template #right> | ||||
|                 <el-input v-model="search.readUserName" @keyup.enter.native="getList()" placeholder="姓名" | ||||
|                           size="small" suffix-icon="iconfont iconSearch" clearable @clear="search.current=1,getList()"></el-input> | ||||
|               </template> | ||||
|             </ai-search-bar> | ||||
|             <ai-table | ||||
|               :tableData="tableData" | ||||
|               :col-configs="colConfigs" | ||||
|               :total="total" | ||||
|               :current.sync="search.current" | ||||
|               :size.sync="search.size" | ||||
|               @getList="getList"> | ||||
|               <el-table-column slot="readUserName" label="姓名" align="center"> | ||||
|                 <template slot-scope="{ row }"> | ||||
|                   <ai-open-data type="userName"  :openid="row.readUserName"></ai-open-data> | ||||
|                 </template> | ||||
|               </el-table-column> | ||||
|               <el-table-column slot="unitName" label="所属部门" align="center"> | ||||
|                 <template slot-scope="{ row }"> | ||||
|                   <ai-open-data type="departmentName"  :openid="row.unitName"></ai-open-data> | ||||
|                 </template> | ||||
|               </el-table-column> | ||||
|             </ai-table> | ||||
|           </template> | ||||
|         </ai-list> | ||||
|       </template> | ||||
|     </template> | ||||
|   </ai-detail> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   export default { | ||||
|     name: "manageDetail", | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|       detail:Object | ||||
|     }, | ||||
|     data() { | ||||
|       return { | ||||
|         index: 0, | ||||
|         tableData: [], | ||||
|         total: 0, | ||||
|         detailObj: {}, | ||||
|         search: { | ||||
|           current: 1, | ||||
|           size: 10 | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     computed: { | ||||
|       tabTitle() { | ||||
|         return ["公告详情", "查询情况"]; | ||||
|       }, | ||||
|       colConfigs(){ | ||||
|         return [ | ||||
|           {slot:"readUserName"}, | ||||
|           {prop:"readUserPhone",label:"手机号",align:"center"}, | ||||
|           {slot:"unitName"}, | ||||
|           { | ||||
|             prop:"readStatus",label:"查阅状态",align:"center", | ||||
|             render:(h,{row})=>[<span style={{color:this.dict.getColor("announcementReadStatus",row.readStatus)}}>{this.dict.getLabel("announcementReadStatus",row.readStatus)}</span>] | ||||
|           }, | ||||
|         ]; | ||||
|       } | ||||
|     }, | ||||
|     methods: { | ||||
|       downFileAll () { | ||||
|         if (this.detailObj.files.length > 0) { | ||||
|           this.instance.post('/app/appannouncement/downLoadAllFileForDetail', null, { | ||||
|             responseType: 'blob', | ||||
|             params: { | ||||
|               id: this.detailObj.id | ||||
|             } | ||||
|           }).then((res) => { | ||||
|             const link = document.createElement('a') | ||||
|             let blob = new Blob([res], { type: 'application/octet-stream' }) | ||||
|             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('暂无附件提供下载') | ||||
|         } | ||||
|       }, | ||||
|       onChange(val){ | ||||
|         if(val==0){ | ||||
|           this.getDetail(); | ||||
|         }else { | ||||
|           this.getList(); | ||||
|         } | ||||
|       }, | ||||
|       getDetail() { | ||||
|         this.instance.post("/app/appannouncement/detail", null, { | ||||
|           params: { | ||||
|             id: this.detail.id | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res && res.data) { | ||||
|             this.detailObj = res.data; | ||||
|             this.$initWxOpenData() | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       getList() { | ||||
|         this.instance.post("/app/appannouncementreader/list", null, { | ||||
|           params: { | ||||
|             announcementId: this.detail.id, | ||||
|             ...this.search | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res && res.data) { | ||||
|             this.tableData = res.data.records; | ||||
|             this.total = res.data.total; | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|     }, | ||||
|     created() { | ||||
|       this.dict.load("announcementReadStatus").then(this.getDetail); | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   ::v-deep .title { | ||||
|     .aibar-left { | ||||
|       width: 100%; | ||||
|       text-align: center; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .file { | ||||
|     height: 40px; | ||||
|     line-height: 40px; | ||||
|     padding: 0 8px; | ||||
|     font-size: 14px; | ||||
|     color: #333; | ||||
|     background: #fff; | ||||
|     border-radius: 4px; | ||||
|     border: 1px solid #d0d4dc; | ||||
|     margin-bottom: 16px; | ||||
|     cursor: pointer; | ||||
|   } | ||||
|  | ||||
|   .info { | ||||
|     & > span { | ||||
|       font-size: 14px; | ||||
|       color: #333; | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										264
									
								
								packages/wechat/AppNotification/components/noticeManage.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										264
									
								
								packages/wechat/AppNotification/components/noticeManage.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,264 @@ | ||||
| <template> | ||||
|   <section style="height: 100%;"> | ||||
|     <ai-list isTabs> | ||||
|       <template slot="content"> | ||||
|         <ai-search-bar> | ||||
|           <template #left> | ||||
|             <ai-select v-model="search.status" placeholder="发布状态" :selectList="dict.getDict('announcementStatus')" | ||||
|                        @change="search.current = 1, getList()"></ai-select> | ||||
|             <el-date-picker | ||||
|               type="daterange" | ||||
|               size="small" | ||||
|               v-model="date" | ||||
|               @change="search.current = 1,getList()" | ||||
|               range-separator="至" | ||||
|               value-format="yyyy-MM-dd" | ||||
|               start-placeholder="开始日期" | ||||
|               end-placeholder="结束日期"> | ||||
|             </el-date-picker> | ||||
|           </template> | ||||
|           <template slot="right"> | ||||
|             <el-input | ||||
|               v-model="search.title" | ||||
|               size="small" | ||||
|               @keyup.enter.native="search.current = 1, getList()" | ||||
|               placeholder="标题" | ||||
|               clearable | ||||
|               @clear="search.current = 1, search.title = '', getList()" | ||||
|               suffix-icon="iconfont iconSearch"> | ||||
|             </el-input> | ||||
|           </template> | ||||
|         </ai-search-bar> | ||||
|         <ai-search-bar> | ||||
|           <template #left> | ||||
|             <el-button icon="iconfont iconAdd" type="primary" @click="add">创建公告</el-button> | ||||
|           </template> | ||||
|         </ai-search-bar> | ||||
|         <ai-table | ||||
|           :tableData="tableData" | ||||
|           :col-configs="colConfigs" | ||||
|           :total="total" | ||||
|           :current.sync="search.current" | ||||
|           :size.sync="search.size" | ||||
|           @getList="getList"> | ||||
|           <el-table-column slot="releaseUserName" label="发布人" align="center"> | ||||
|             <template slot-scope="{ row }"> | ||||
|               <ai-open-data type="userName"  :openid="row.releaseUserName"></ai-open-data> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|           <el-table-column slot="unitName" label="发布部门" align="center"> | ||||
|             <template slot-scope="{ row }"> | ||||
|               <ai-open-data type="departmentName"  :openid="row.unitName"></ai-open-data> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|  | ||||
|           <el-table-column slot="options" width="250" label="操作" align="center"> | ||||
|             <template slot-scope="{ row }"> | ||||
|               <el-button type="text" @click="toDetail(row)">详情</el-button> | ||||
|               <el-button type="text" v-if="row.status==0" @click="publish(row,0)">发布</el-button> | ||||
|               <el-button type="text" v-if="row.status==1" @click="publish(row,1)">撤回</el-button> | ||||
|               <el-button type="text" @click="toEdit(row)" v-if="row.status==0 || row.status==3">编辑</el-button> | ||||
|               <el-button type="text" @click="handleDel(row)">删除</el-button> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|         </ai-table> | ||||
|       </template> | ||||
|     </ai-list> | ||||
|     <ai-dialog | ||||
|       title="查阅状态" | ||||
|       :visible.sync="visible" | ||||
|       @closed="row={},readList=[]" | ||||
|       :customFooter="true" | ||||
|       width="800px"> | ||||
|       <template v-if="readObj.read && readObj.read.length"> | ||||
|         <header>已读人员</header> | ||||
|         <div class="wrap"> | ||||
|           <div class="item" v-for="(item,index) in readObj.read" :key="index"> | ||||
|             <img :src="item.avatar" alt=""> | ||||
|             <ai-open-data type="userName"  :openid="item.name"></ai-open-data> | ||||
|           </div> | ||||
|         </div> | ||||
|       </template> | ||||
|  | ||||
|       <template v-if="readObj.unRead && readObj.unRead.length"> | ||||
|         <header>未读人员</header> | ||||
|         <div class="wrap"> | ||||
|           <div class="item" v-for="(item,index) in readObj.unRead" :key="index"> | ||||
|             <img :src="item.avatar" alt=""> | ||||
|             <ai-open-data type="userName"  :openid="item.name"></ai-open-data> | ||||
|           </div> | ||||
|         </div> | ||||
|       </template> | ||||
|     </ai-dialog> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   export default { | ||||
|     name: "noticeManage", | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object | ||||
|     }, | ||||
|     data() { | ||||
|       return { | ||||
|         search: { | ||||
|           title: "", | ||||
|           status: "", | ||||
|           size: 10, | ||||
|           current: 1, | ||||
|         }, | ||||
|         date: [], | ||||
|         tableData: [], | ||||
|         total: 0, | ||||
|         visible: false, | ||||
|         row: {}, | ||||
|         readObj:{}, | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       colConfigs() { | ||||
|         return [ | ||||
|           {prop: 'title', label: '标题'}, | ||||
|           { | ||||
|             prop: 'readNum', label: '查询状态', align: 'center', | ||||
|             render:(h,{row})=>[<span class='status' onClick={this.showDialog.bind(this,row)}>{row.readNum}人已读,</span>,<span class='status' onClick={this.showDialog.bind(this,row)}>{row.unReadNum}人未读</span>] | ||||
|           }, | ||||
|           {slot: 'releaseUserName'}, | ||||
|           {slot: 'unitName'}, | ||||
|           {prop: 'releaseTime', label: '发布时间', align: 'center'}, | ||||
|           { | ||||
|             prop: 'status', label: '发布状态', align: 'center', | ||||
|             render:(h,{row})=>[<span style={{color:this.dict.getColor("announcementStatus",row.status)}}>{this.dict.getLabel("announcementStatus",row.status)}</span>] | ||||
|           }, | ||||
|           {slot: 'options'}, | ||||
|         ]; | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       showDialog(row) { | ||||
|         this.row = row; | ||||
|         this.getReadList(); | ||||
|       }, | ||||
|       toDetail(row){ | ||||
|         this.$emit('goPage', { | ||||
|           comp: 'manageDetail', | ||||
|           row | ||||
|         }); | ||||
|       }, | ||||
|       toEdit(row){ | ||||
|         this.$emit('goPage', { | ||||
|           comp: 'add', | ||||
|           row | ||||
|         }); | ||||
|       }, | ||||
|       publish(row,status){ | ||||
|         this.$confirm(`是否要${status==0?'发布':'撤回'}该公告?`).then(()=>{ | ||||
|           this.instance.post("/app/appannouncement/update-status",null,{ | ||||
|             params: { | ||||
|               id:row.id | ||||
|             } | ||||
|           }).then(res=>{ | ||||
|             if(res.code==0){ | ||||
|               this.$message.success(status==0?'发布成功':'撤回成功'); | ||||
|               this.getList(); | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|       handleDel(row){ | ||||
|         this.$confirm("是否要删除该公布?").then(()=>{ | ||||
|           this.instance.post("/app/appannouncement/delete",null,{ | ||||
|             params:{ | ||||
|               ids:row.id | ||||
|             } | ||||
|           }).then(res=>{ | ||||
|             if(res.code==0){ | ||||
|               this.$message.success("删除成功"); | ||||
|               this.getList(); | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       }, | ||||
|       add(){ | ||||
|         this.$emit('goPage', { | ||||
|           comp: 'add', | ||||
|           row: {}, | ||||
|         }); | ||||
|       }, | ||||
|       getReadList(){ | ||||
|         this.instance.post("/app/appannouncementreader/list-unread",null,{ | ||||
|           params:{ | ||||
|             id:this.row.id | ||||
|           } | ||||
|         }).then(res=>{ | ||||
|           if(res && res.data){ | ||||
|             this.readObj = res.data; | ||||
|             this.visible = true; | ||||
|             this.$initWxOpenData() | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       getList() { | ||||
|         this.instance.post("/app/appannouncement/list-mgr",null,{ | ||||
|           params:{ | ||||
|             ...this.search, | ||||
|             startTime: this.date?.length ? this.date[0] : null, | ||||
|             endTime: this.date?.length ? this.date[1] : null, | ||||
|           } | ||||
|         }).then(res=>{ | ||||
|           if(res && res.data){ | ||||
|             this.tableData = res.data.records; | ||||
|             this.total = res.data.total; | ||||
|             this.$initWxOpenData() | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|     created() { | ||||
|       this.dict.load("announcementStatus").then(this.getList) | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   ::v-deep .status { | ||||
|     color: rgba(41, 107, 251, 100); | ||||
|     cursor: pointer; | ||||
|   } | ||||
|  | ||||
|   header{ | ||||
|     font-size: 14px; | ||||
|     color: #333333; | ||||
|     margin-bottom: 10px; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .wrap { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     flex-wrap: wrap; | ||||
|  | ||||
|     .item { | ||||
|       width: 50px; | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       justify-content: center; | ||||
|       margin-right: 22px; | ||||
|       margin-bottom: 22px; | ||||
|  | ||||
|       img { | ||||
|         width: 100%; | ||||
|         height: 50px; | ||||
|         border-radius: 50%; | ||||
|       } | ||||
|  | ||||
|       span{ | ||||
|         font-size: 14px; | ||||
|         color: #333333; | ||||
|         text-align: center; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										217
									
								
								packages/wechat/AppNotification/components/recentNotice.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								packages/wechat/AppNotification/components/recentNotice.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,217 @@ | ||||
| <template> | ||||
|   <ai-list isTabs> | ||||
|     <template #content> | ||||
|       <ai-search-bar> | ||||
|         <template #left> | ||||
|           <ai-select | ||||
|             v-model="search.readStatus" | ||||
|             @change="getList()" | ||||
|             placeholder="查阅状态" | ||||
|             :selectList="dict.getDict('announcementReadStatus')" | ||||
|           ></ai-select> | ||||
|           <el-date-picker | ||||
|             v-model="date" | ||||
|             @change="search.current = 1,getList()" | ||||
|             type="daterange" | ||||
|             size="small" | ||||
|             value-format="yyyy-MM-dd" | ||||
|             range-separator="至" | ||||
|             start-placeholder="开始日期" | ||||
|             end-placeholder="结束日期"> | ||||
|           </el-date-picker> | ||||
|         </template> | ||||
|         <template #right> | ||||
|           <el-input v-model="search.title" @keyup.enter.native="getList()" placeholder="标题" | ||||
|                     size="small" suffix-icon="iconfont iconSearch" clearable | ||||
|                     @clear="search.current=1,getList()"></el-input> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <div class="body"> | ||||
|         <ul v-if="tableData.length"> | ||||
|           <li v-for="(item,index) in tableData" :key="index" @click="goDetail(item)"> | ||||
|             <label> | ||||
|               <!--              <em v-if="item.readStatus==0"></em>--> | ||||
|               <div class="status" v-if="item.readStatus==0">未读</div> | ||||
|               <div class="status read" v-else>已读</div> | ||||
|               {{item.title}}</label> | ||||
|             <el-row type="flex" justify="space-between" class="row"> | ||||
|               <span style="display:flex"> | ||||
|                 <b>发布人:</b> | ||||
|                 <ai-open-data type="userName"  :openid="item.releaseUserName"></ai-open-data> | ||||
|               </span> | ||||
|               <span style="display:flex"> | ||||
|                 <b>发布部门:</b> | ||||
|                 <ai-open-data type="departmentName"  :openid="item.unitName"></ai-open-data> | ||||
|               </span> | ||||
|               <span> | ||||
|                 <b>发布日期:</b> | ||||
|                 {{item.releaseTime}}</span> | ||||
|             </el-row> | ||||
|           </li> | ||||
|         </ul> | ||||
|         <div class="no-data" style="height:160px;" v-else></div> | ||||
|       </div> | ||||
|       <div class="pagination" v-if="tableData.length>0"> | ||||
|         <el-pagination | ||||
|           @current-change="handleCurrentChange" | ||||
|           @size-change="handleSizeChange" | ||||
|           background | ||||
|           :current-page.sync="search.current" | ||||
|           :page-sizes="[5, 10, 50, 100,200]" | ||||
|           :page-size="search.size" | ||||
|           layout="slot,->,prev, pager, next,sizes,jumper" | ||||
|           :total="total"> | ||||
|           <div class="page" style="text-align: left">共 | ||||
|             <em>{{total}}</em> | ||||
|             条记录 | ||||
|           </div> | ||||
|         </el-pagination> | ||||
|       </div> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   export default { | ||||
|     name: "recentNotice", | ||||
|     props: { | ||||
|       instance: Function, | ||||
|       dict: Object, | ||||
|     }, | ||||
|     data() { | ||||
|       return { | ||||
|         search: { | ||||
|           readStatus: "", | ||||
|           title: "", | ||||
|           current: 1, | ||||
|           size: 10, | ||||
|         }, | ||||
|         date: [], | ||||
|         tableData: [], | ||||
|         total: 0, | ||||
|       } | ||||
|     }, | ||||
|     methods: { | ||||
|       pickerChange(e) { | ||||
|         console.log(e); | ||||
|       }, | ||||
|       goDetail(item) { | ||||
|         this.$emit('goPage', { | ||||
|           row: item, | ||||
|           comp: 'detail' | ||||
|         }); | ||||
|       }, | ||||
|       getList() { | ||||
|         this.instance.post(`/app/appannouncement/list-latest`, null, { | ||||
|           params: { | ||||
|             ...this.search, | ||||
|             startTime: this.date?.length ? this.date[0] : null, | ||||
|             endTime: this.date?.length ? this.date[1] : null, | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res && res.data) { | ||||
|             this.tableData = res.data.records; | ||||
|             this.total = res.data.total; | ||||
|             this.$initWxOpenData() | ||||
|           } | ||||
|         }); | ||||
|       }, | ||||
|       handleCurrentChange(val) { | ||||
|         this.search.current = val; | ||||
|         this.getList(); | ||||
|       }, | ||||
|       handleSizeChange(val) { | ||||
|         this.search.size = val; | ||||
|         this.getList(); | ||||
|       }, | ||||
|     }, | ||||
|     created() { | ||||
|       this.dict.load("announcementReadStatus").then(_ => this.getList()) | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .body { | ||||
|  | ||||
|     ul { | ||||
|       overflow: hidden; | ||||
|       padding: 0; | ||||
|       margin: 0; | ||||
|  | ||||
|       li { | ||||
|         height: 86px; | ||||
|         background: #FFFFFF; | ||||
|         border-radius: 4px; | ||||
|         box-sizing: border-box; | ||||
|         padding: 16px 215px 16px 32px; | ||||
|         margin-top: 10px; | ||||
|         cursor: pointer; | ||||
|         overflow: hidden; | ||||
|         text-overflow: ellipsis; | ||||
|         white-space: nowrap; | ||||
|  | ||||
|         label { | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           position: relative; | ||||
|           font-size: 16px; | ||||
|           color: #222222; | ||||
|  | ||||
|           .status { | ||||
|             width: 40px; | ||||
|             height: 20px; | ||||
|             background: #FEF4E5; | ||||
|             color: #F79300; | ||||
|             border-radius: 4px; | ||||
|             font-size: 12px; | ||||
|             font-weight: bold; | ||||
|             display: flex; | ||||
|             align-items: center; | ||||
|             justify-content: center; | ||||
|             margin-right: 4px; | ||||
|           } | ||||
|  | ||||
|           .read{ | ||||
|             background: #EEEEEE; | ||||
|             color: #999999; | ||||
|           } | ||||
|  | ||||
|           em { | ||||
|             width: 8px; | ||||
|             height: 8px; | ||||
|             background: #ff4422; | ||||
|             border-radius: 50%; | ||||
|             position: absolute; | ||||
|             left: -16px; | ||||
|             top: 4px; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       ::v-deep .row { | ||||
|         margin-top: 10px; | ||||
|  | ||||
|         span { | ||||
|           font-size: 14px; | ||||
|           color: #222222; | ||||
|  | ||||
|           b { | ||||
|             font-size: 14px; | ||||
|             color: #888888; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ::v-deep .page { | ||||
|     font-size: 12px; | ||||
|     color: #555555; | ||||
|  | ||||
|     em { | ||||
|       font-style: normal; | ||||
|       color: rgb(34, 102, 255); | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
		Reference in New Issue
	
	Block a user