调整工程目录
This commit is contained in:
		
							
								
								
									
										379
									
								
								src/sass/AppNotification/AppNotification.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										379
									
								
								src/sass/AppNotification/AppNotification.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,379 @@ | ||||
| <template> | ||||
|   <div class="notification"> | ||||
|     <template v-if="showList"> | ||||
|       <AiTopFixed> | ||||
|         <u-tabs :list="tabs" :is-scroll="false" height="96" :current="index" bar-width="192" @change="change"></u-tabs> | ||||
|       </AiTopFixed> | ||||
|       <div class="body" v-if="dataList.length"> | ||||
|         <div class="card" v-for="(item,idx) in dataList" :key="idx" @click="handeClick(item)"> | ||||
|           <template v-if="!item.imgUrl"> | ||||
|             <label> | ||||
|               <span class="status" v-if="index==0 && item.readStatus==0">未读</span> | ||||
|               <span class="status read" v-if="index==0 && item.readStatus!=0">已读</span> | ||||
|               <div class="tag" v-if="index==1" :style="color(item.status)"> | ||||
|                 {{ $dict.getLabel("announcementStatus", item.status) }} | ||||
|               </div> | ||||
|               {{ item.title }} | ||||
|             </label> | ||||
|             <u-gap height="16"></u-gap> | ||||
|             <span class="info"> | ||||
|             <AiOpenData type="userName" :openid="item.releaseUserId"></AiOpenData> | ||||
|             <text>{{ item.releaseTime }}</text> | ||||
|           </span> | ||||
|           </template> | ||||
|           <template v-else> | ||||
|             <div class="has-pic"> | ||||
|               <div class="left"> | ||||
|                 <label> | ||||
|                   <span class="status" v-if="index==0 && item.readStatus==0">未读</span> | ||||
|                   <span class="status read" v-if="index==0 && item.readStatus!=0">已读</span> | ||||
|                   <div class="tag" v-if="index==1" :style="color(item.status)"> | ||||
|                     {{ $dict.getLabel("announcementStatus", item.status) }} | ||||
|                   </div> | ||||
|                   {{ item.title }} | ||||
|                 </label> | ||||
|                 <u-gap height="16"></u-gap> | ||||
|                 <span class="info"> | ||||
|                 <AiOpenData type="userName" :openid="item.releaseUserId"></AiOpenData> | ||||
|                 <text>{{ item.releaseTime }}</text> | ||||
|               </span> | ||||
|               </div> | ||||
|               <img :src="item.imgUrl" alt=""> | ||||
|             </div> | ||||
|           </template> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <AiEmpty v-else/> | ||||
|       <u-loadmore :status="status" v-if="dataList.length"/> | ||||
|       <AiAdd @add="handleAdd"/> | ||||
|       <u-popup v-model="show" mode="bottom"> | ||||
|         <div class="popup-wrap"> | ||||
|           <u-row justify="between"> | ||||
|             <div class="colum" v-for="(item,index) in optList" :key="index" @click="handleOpt(item)"> | ||||
|               <u-icon :name="item.icon" size="100" :custom-style="{backgroundColor:'#fff',borderRadius:'8px'}"></u-icon> | ||||
|               <u-gap height="16"></u-gap> | ||||
|               {{ item.name }} | ||||
|             </div> | ||||
|           </u-row> | ||||
|           <div class="btn" @click="show=false">关闭</div> | ||||
|         </div> | ||||
|       </u-popup> | ||||
|       <u-modal v-model="modal" :content="'是否确定' + content + '该公告?'" title="" show-confirm-button | ||||
|                show-cancel-button confirm-text="确定" cancel-text="取消" | ||||
|                @confirm="confirm" @cancel="modal=false"></u-modal> | ||||
|     </template> | ||||
|     <component :is="comp" v-else :params="params"></component> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import add from "./add"; | ||||
| import detail from "./detail"; | ||||
| import read from "./read"; | ||||
| import {mapActions} from "vuex"; | ||||
|  | ||||
| export default { | ||||
|   name: "AppNotification", | ||||
|   appName: "通知公告", | ||||
|   components: {add, detail, read}, | ||||
|   data() { | ||||
|     return { | ||||
|       index: 0, | ||||
|       show: false, | ||||
|       modal: false, | ||||
|       content: "", | ||||
|       current: 1, | ||||
|       dataList: [], | ||||
|       detail: {}, | ||||
|       showList: true, | ||||
|       comp: "", | ||||
|       params: null, | ||||
|       status: "加载更多", | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   computed: { | ||||
|     tabs() { | ||||
|       return [{name: "最新公告"}, {name: "公告管理"}]; | ||||
|     }, | ||||
|     optList() { | ||||
|       return [ | ||||
|         { | ||||
|           name: "详情", | ||||
|           icon: this.$cdn + "notice/yl.png", | ||||
|           val: 0, | ||||
|           show: true, | ||||
|         }, | ||||
|         { | ||||
|           name: "撤回", | ||||
|           icon: this.$cdn + "notice/ch.png", | ||||
|           val: 1, | ||||
|           show: this.detail?.status == 1, | ||||
|         }, | ||||
|         { | ||||
|           name: "发布", | ||||
|           icon: this.$cdn + "notice/fb.png", | ||||
|           val: 2, | ||||
|           show: this.detail?.status == 0, | ||||
|         }, | ||||
|         { | ||||
|           name: "编辑", | ||||
|           icon: this.$cdn + "notice/bj.png", | ||||
|           val: 3, | ||||
|           show: this.detail?.status == 0 || this.detail?.status == 3, | ||||
|         }, { | ||||
|           name: "删除", | ||||
|           icon: this.$cdn + "notice/sc.png", | ||||
|           val: 4, | ||||
|           show: true, | ||||
|         } | ||||
|       ].filter(e => e.show) | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   onShow() { | ||||
|     this.current = 1; | ||||
|     document.title = "通知公告"; | ||||
|     this.$dict.load("announcementStatus"); | ||||
|     this.injectJWeixin(['sendChatMessage']).then(() => { | ||||
|       this.getList(); | ||||
|     }) | ||||
|   }, | ||||
|  | ||||
|   onReachBottom() { | ||||
|     this.current++; | ||||
|     this.getList(); | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     ...mapActions(['injectJWeixin']), | ||||
|     changeState() { | ||||
|       this.$http.post(this.content == '删除' ? '/app/appannouncement/delete' : "/app/appannouncement/update-status", null, { | ||||
|         params: { | ||||
|           [this.content == '删除' ? 'ids' : 'id']: this.detail.id | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.$u.toast(this.content + "成功"); | ||||
|           this.modal = false; | ||||
|           this.getList(); | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     confirm() { | ||||
|       this.show = false; | ||||
|       this.changeState(); | ||||
|     }, | ||||
|     handleOpt(item) { | ||||
|       this.content = { | ||||
|         1: "撤回", | ||||
|         2: "发布", | ||||
|         4: "删除", | ||||
|       }[item.val]; | ||||
|  | ||||
|       if (item.val == 0) { | ||||
|         this.show = false; | ||||
|         return uni.navigateTo({ | ||||
|           url: "/apps/AppNotification/detail?id=" + this.detail.id | ||||
|         }); | ||||
|       } | ||||
|  | ||||
|       if ([1, 2, 4].includes(item.val)) { | ||||
|         return this.modal = true; | ||||
|       } | ||||
|  | ||||
|       if (item.val == 3) { | ||||
|         this.show = false; | ||||
|         return uni.navigateTo({ | ||||
|           url: "/apps/AppNotification/add?id=" + this.detail.id + "&flag=" + false | ||||
|         }); | ||||
|       } | ||||
|     }, | ||||
|     color(status) { | ||||
|       return [ | ||||
|         {backgroundColor: "rgba(255,136,34,0.1)", color: "#FF8822"}, | ||||
|         {backgroundColor: "rgba(34,102,255,0.1)", color: "#2266FF"}, | ||||
|         {backgroundColor: "rgba(102,102,102,0.1)", color: "#666666"}, | ||||
|         {backgroundColor: "rgba(255,136,34,0.1)", color: "#FF8822"} | ||||
|       ][status]; | ||||
|     }, | ||||
|     handeClick(item) { | ||||
|       this.detail = item; | ||||
|       if (this.index == 1) { | ||||
|         this.show = true; | ||||
|       } else { | ||||
|         uni.navigateTo({ | ||||
|           url: "/apps/AppNotification/detail?id=" + this.detail.id + "&flag=" + true | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|     handleAdd() { | ||||
|       uni.navigateTo({ | ||||
|         url: "/apps/AppNotification/add" | ||||
|       }) | ||||
|     }, | ||||
|     change(val) { | ||||
|       this.index = val; | ||||
|       this.current = 1; | ||||
|       this.dataList = []; | ||||
|       this.getList(); | ||||
|     }, | ||||
|     getList() { | ||||
|       this.$http.post(this.index == 0 ? "/app/appannouncement/list-latest" : "/app/appannouncement/list-mgr", null, { | ||||
|         params: { | ||||
|           size: 10, | ||||
|           current: this.current | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res && res.data) { | ||||
|           if (this.current > 1 && this.current > res.data.pages) { | ||||
|             this.status = "已经到底啦" | ||||
|           } | ||||
|           this.dataList = this.current > 1 ? [...this.dataList, ...res.data.records] : res.data.records | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .notification { | ||||
|   min-height: 100%; | ||||
|   background-color: #F5F5F5; | ||||
|   padding-bottom: 32px; | ||||
|  | ||||
|   ::v-deep .content { | ||||
|     padding: 0 !important; | ||||
|   } | ||||
|  | ||||
|   .body { | ||||
|     box-sizing: border-box; | ||||
|     padding: 32px; | ||||
|  | ||||
|     .card { | ||||
|       height: 255px; | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       justify-content: space-between; | ||||
|       box-sizing: border-box; | ||||
|       padding: 32px; | ||||
|       border-radius: 8px; | ||||
|       background-color: #ffffff; | ||||
|       margin-bottom: 32px; | ||||
|  | ||||
|       &:last-child { | ||||
|         margin-bottom: 0; | ||||
|       } | ||||
|  | ||||
|       & > label { | ||||
|         font-size: 32px; | ||||
|         overflow: hidden; | ||||
|         text-overflow: ellipsis; | ||||
|         display: -webkit-box; | ||||
|         -webkit-box-orient: vertical; | ||||
|         -webkit-line-clamp: 2; | ||||
|         color: #333333; | ||||
|         line-height: 44px; | ||||
|       } | ||||
|  | ||||
|       .tag { | ||||
|         width: 96px; | ||||
|         height: 44px; | ||||
|         display: inline-block; | ||||
|         border-radius: 8px; | ||||
|         margin-right: 16px; | ||||
|         font-size: 26px; | ||||
|         font-weight: 400; | ||||
|         line-height: 46px; | ||||
|         text-align: center; | ||||
|       } | ||||
|  | ||||
|       .info { | ||||
|         font-size: 28px; | ||||
|         color: #999999; | ||||
|         line-height: 40px; | ||||
|  | ||||
|         & > text:first-child { | ||||
|           margin-right: 32px; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       & > .has-pic { | ||||
|         display: flex; | ||||
|         justify-content: space-between; | ||||
|  | ||||
|         & > .left { | ||||
|           display: flex; | ||||
|           flex-direction: column; | ||||
|           justify-content: space-between; | ||||
|  | ||||
|           & > label { | ||||
|             overflow: hidden; | ||||
|             text-overflow: ellipsis; | ||||
|             display: -webkit-box; | ||||
|             -webkit-box-orient: vertical; | ||||
|             -webkit-line-clamp: 2; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         & > img { | ||||
|           width: 192px; | ||||
|           height: 144px; | ||||
|           flex-shrink: 0; | ||||
|           margin-left: 32px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .status { | ||||
|       display: inline-block; | ||||
|       width: 88px; | ||||
|       height: 36px; | ||||
|       font-size: 26px; | ||||
|       color: #FF8822; | ||||
|       background: rgba(255, 136, 34, .1); | ||||
|       line-height: 36px; | ||||
|       text-align: center; | ||||
|       margin-right: 4px; | ||||
|     } | ||||
|  | ||||
|     .read { | ||||
|       background: rgba(102, 102, 102, .1); | ||||
|       color: #666666; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .popup-wrap { | ||||
|     height: 368px; | ||||
|     background-color: #F7F7F7; | ||||
|  | ||||
|     .btn { | ||||
|       height: 96px; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|       font-size: 30px; | ||||
|       font-weight: 500; | ||||
|       color: #333333; | ||||
|       background-color: #ffffff; | ||||
|     } | ||||
|  | ||||
|     & > .u-row { | ||||
|       height: 272px; | ||||
|       box-sizing: border-box; | ||||
|       padding: 0 46px; | ||||
|  | ||||
|       & > .colum { | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|         align-items: center; | ||||
|         justify-content: center; | ||||
|         font-size: 26px; | ||||
|         color: #666666; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										367
									
								
								src/sass/AppNotification/add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								src/sass/AppNotification/add.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,367 @@ | ||||
| <template> | ||||
|   <div class="add-meeting"> | ||||
|     <div v-if="!userSelect"> | ||||
|       <div class="card"> | ||||
|         <header><em>*</em>公告标题</header> | ||||
|         <input v-model="form.title" placeholder="请输入" :maxlength="30"> | ||||
|       </div> | ||||
|  | ||||
|       <div class="card"> | ||||
|         <header><em>*</em>公告内容</header> | ||||
|         <textarea v-model="form.content" placeholder="请输入" :maxlength="500"></textarea> | ||||
|       </div> | ||||
|  | ||||
|       <div class="card"> | ||||
|         <AiUploader :multiple="true" type="image" :limit="9" placeholder="上传图片" @list="fileList" :def="form.files" | ||||
|                     action="/admin/file/add2"></AiUploader> | ||||
|       </div> | ||||
|  | ||||
|       <div class="card item-wrap"> | ||||
|         <u-row justify="between" class="item" style="border-bottom: 1px solid #eeeeee" @click="handleSelectUser"> | ||||
|           <header><em>*</em>发送对象</header> | ||||
|           <div class="right"> | ||||
|             <template v-if="!form.persons.length"> | ||||
|               <span>请选择</span> | ||||
|             </template> | ||||
|             <template v-else> | ||||
|               已选择<em>{{ form.persons.map(e => e.name).slice(0, 2).join("、") }}</em>等<em>{{ form.persons.length }}</em>人 | ||||
|             </template> | ||||
|             <div class="right-arrow"></div> | ||||
|           </div> | ||||
|         </u-row> | ||||
|  | ||||
|         <u-row justify="between" class="item" @click="userSelect=true"> | ||||
|           <header><em>*</em>发送时间</header> | ||||
|         </u-row> | ||||
|         <u-row justify="between"> | ||||
|           <div class="type" :class="[index==0 && 'active']" @click="index=0,form.releaseTime=null">立即发送 | ||||
|             <img :src="$cdn + 'notice/jiaobiao.png'" alt="" v-show="index==0"> | ||||
|           </div> | ||||
|           <div class="type" :class="[index==1 && 'active']" @click="index=1">定时发送 | ||||
|             <img :src="$cdn + 'notice/jiaobiao.png'" alt="" v-show="index==1"> | ||||
|           </div> | ||||
|         </u-row> | ||||
|         <u-gap height="38"></u-gap> | ||||
|         <u-row justify="between" class="item" style="box-shadow: none;" @click="show=true" v-show="index==1"> | ||||
|           <header><em>*</em>定时发送时间</header> | ||||
|           <div class="right"> | ||||
|             <template v-if="!form.releaseTime"> | ||||
|               <span>请选择</span> | ||||
|             </template> | ||||
|             <template v-else> | ||||
|               <span>{{ form.releaseTime }}</span> | ||||
|             </template> | ||||
|             <div class="right-arrow"></div> | ||||
|           </div> | ||||
|         </u-row> | ||||
|       </div> | ||||
|  | ||||
|       <div class="footer"> | ||||
|         <div @click="add(0)">保存草稿</div> | ||||
|         <div @click="add(1)">立即发布</div> | ||||
|       </div> | ||||
|     </div> | ||||
|     <AiBack ref="aiBack" v-if="!userSelect"/> | ||||
|     <u-picker v-model="show" mode="time" :params="options" @confirm="confirm"></u-picker> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapActions} from "vuex"; | ||||
|  | ||||
| export default { | ||||
|   name: "add", | ||||
|   data() { | ||||
|     return { | ||||
|       show: false, | ||||
|       index: 0, | ||||
|       list: [], | ||||
|       form: { | ||||
|         id: null, | ||||
|         title: "", | ||||
|         content: "", | ||||
|         persons: [], | ||||
|         releaseTime: null, | ||||
|         files: [], | ||||
|       }, | ||||
|       userSelect: false, | ||||
|       flag: null, | ||||
|       options: { | ||||
|         year: true, | ||||
|         month: true, | ||||
|         day: true, | ||||
|         hour: true, | ||||
|         minute: true, | ||||
|         second: true, | ||||
|         timestamp: true, | ||||
|       }, | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   onLoad(opt) { | ||||
|     if (opt.id) { | ||||
|       this.form.id = opt.id; | ||||
|       this.flag = opt.flag; | ||||
|       this.getDetail(); | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     ...mapActions(['selectEnterpriseContact']), | ||||
|     handleSelectUser() { | ||||
|       this.selectEnterpriseContact({ | ||||
|         fromDepartmentId: 0, | ||||
|         type: ["user"], | ||||
|         selectedUserIds: this.form.persons?.map(e => e.id) | ||||
|       }).then(res => { | ||||
|         this.form.persons = res?.userList || [] | ||||
|       }) | ||||
|     }, | ||||
|     confirm(e) { | ||||
|       if (e.timestamp < (Date.now() / 1000) || 0) { | ||||
|         return this.$u.toast("发送时间不能小于当前时间"); | ||||
|       } | ||||
|       this.form.releaseTime = `${e.year}-${e.month}-${e.day} ${e.hour}:${e.minute}:${e.second}`; | ||||
|     }, | ||||
|     fileList(e) { | ||||
|       this.form.files = e | ||||
|     }, | ||||
|     change(e) { | ||||
|       this.form.persons = e | ||||
|     }, | ||||
|     getDetail() { | ||||
|       this.$http.post("/app/appannouncement/detail", null, { | ||||
|         params: { | ||||
|           id: this.form.id, | ||||
|           detail: this.flag | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res && res.data) { | ||||
|           this.form.releaseTime = res.data.releaseTime; | ||||
|           Object.keys(this.form).map(e => { | ||||
|             this.form[e] = res.data[e]; | ||||
|           }) | ||||
|           this.index = res.data.releaseTime ? 1 : 0; | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     add(status) { | ||||
|       // if(status==1){ | ||||
|       if (!this.form.title) return this.$u.toast("请输入公告标题") | ||||
|  | ||||
|       if (!this.form.content) return this.$u.toast("请输入公告内容") | ||||
|  | ||||
|       if (!this.form.persons.length) return this.$u.toast("请选择发送对象") | ||||
|  | ||||
|       if (this.index == 1 && !this.form.releaseTime) return this.$u.toast("请选择定时发送时间") | ||||
|  | ||||
|       if (this.form.releaseTime && new Date(this.form.releaseTime).getTime() < Date.now()) return this.$u.toast("发送时间不能小于当前时间"); | ||||
|       // } | ||||
|  | ||||
|       this.$http.post("/app/appannouncement/addOrUpdate", { | ||||
|         ...this.form, | ||||
|         status, | ||||
|       }).then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.$u.toast(status == 1 ? "发布成功" : "保存成功"); | ||||
|           this.$refs["aiBack"].back(); | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|   }, | ||||
|  | ||||
|   onShow() { | ||||
|     document.title = "新增公告"; | ||||
|   }, | ||||
|   computed: { | ||||
|     background() { | ||||
|       return `url(${this.$cdn}/notice/jiaobiao.png) no-repeat; background-size: 46px 48px;position: absolute;bottom: 0;right: 0;` | ||||
|     }, | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .add-meeting { | ||||
|   min-height: 100%; | ||||
|   background: #F5F5F5; | ||||
|   padding-bottom: 140px; | ||||
|  | ||||
|   .card { | ||||
|     background-color: #FFFFFF; | ||||
|     box-sizing: border-box; | ||||
|     padding: 32px; | ||||
|     margin-top: 16px; | ||||
|  | ||||
|     header { | ||||
|       font-size: 32px; | ||||
|       font-weight: 400; | ||||
|       color: #333333; | ||||
|  | ||||
|       em { | ||||
|         font-style: normal; | ||||
|         font-size: 32px; | ||||
|         color: #FF4466; | ||||
|         margin-right: 8px; | ||||
|         vertical-align: middle; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     input { | ||||
|       margin: 32px 0 16px; | ||||
|       box-sizing: border-box; | ||||
|       padding: 0 16px; | ||||
|     } | ||||
|  | ||||
|     textarea { | ||||
|       width: 100%; | ||||
|       height: 160px; | ||||
|       margin: 32px 0 16px; | ||||
|       box-sizing: border-box; | ||||
|       padding: 0 16px; | ||||
|     } | ||||
|  | ||||
|     .u-row { | ||||
|       margin-top: 34px; | ||||
|  | ||||
|       .time { | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|  | ||||
|         & > span:first-child { | ||||
|           font-size: 60px; | ||||
|           font-weight: 600; | ||||
|           color: #333333; | ||||
|           line-height: 84px; | ||||
|         } | ||||
|  | ||||
|         & > span:last-child { | ||||
|           font-size: 22px; | ||||
|           color: #333333; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .arrow { | ||||
|         width: 28px; | ||||
|         height: 68px; | ||||
|         overflow: hidden; | ||||
|         position: relative; | ||||
|         transform: rotate(180deg); | ||||
|  | ||||
|         &:before, &:after { | ||||
|           content: ""; | ||||
|           width: 50px; | ||||
|           height: 50px; | ||||
|           position: absolute; | ||||
|           transform: scaleY(1.3) translate(30%, -40px) rotate(45deg); | ||||
|         } | ||||
|  | ||||
|         &:before { | ||||
|           top: 59px; | ||||
|           background-color: #CCCCCC; | ||||
|         } | ||||
|  | ||||
|         &:after { | ||||
|           left: 7px; | ||||
|           top: 59px; | ||||
|           background-color: #FFFFFF; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .type { | ||||
|         width: 320px; | ||||
|         height: 112px; | ||||
|         background: #F5F5F5; | ||||
|         color: #333333; | ||||
|         border-radius: 4px; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         justify-content: center; | ||||
|         font-size: 30px; | ||||
|         font-weight: 500; | ||||
|         letter-spacing: 1px; | ||||
|         position: relative; | ||||
|  | ||||
|         & > img { | ||||
|           width: 46px; | ||||
|           height: 48px; | ||||
|           position: absolute; | ||||
|           right: 0; | ||||
|           bottom: 0; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .active { | ||||
|         background-color: #E7F1FE; | ||||
|         color: #1174FE; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .item { | ||||
|       height: 112px; | ||||
|       box-shadow: 0px -1px 0px 0px #D8DDE6; | ||||
|       margin-top: 0; | ||||
|  | ||||
|       .right { | ||||
|         font-size: 28px; | ||||
|         color: #999999; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|  | ||||
|         em { | ||||
|           font-style: normal; | ||||
|           color: #1365DD; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .right-arrow { | ||||
|         width: 16px; | ||||
|         height: 16px; | ||||
|         display: inline-block; | ||||
|         border-top: 5px solid #CCCCCC; | ||||
|         border-right: 5px solid #CCCCCC; | ||||
|         transform: rotate(45deg); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .item-wrap { | ||||
|     padding: 0 32px; | ||||
|   } | ||||
|  | ||||
|   .footer { | ||||
|     height: 112px; | ||||
|     width: 100%; | ||||
|     position: fixed; | ||||
|     left: 0; | ||||
|     bottom: 0; | ||||
|     background-color: #FFFFFF; | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|  | ||||
|     & > div { | ||||
|       font-size: 36px; | ||||
|       color: #333333; | ||||
|     } | ||||
|  | ||||
|     & > div:first-child { | ||||
|       width: 270px; | ||||
|       height: 100%; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|     } | ||||
|  | ||||
|     & > div:last-child { | ||||
|       width: calc(100% - 270px); | ||||
|       height: 100%; | ||||
|       color: #FFFFFF; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|       background-color: #1365DD; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										360
									
								
								src/sass/AppNotification/detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										360
									
								
								src/sass/AppNotification/detail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,360 @@ | ||||
| <template> | ||||
|   <div class="detail" v-if="pageShow"> | ||||
|     <template v-if="detailObj.status!=2"> | ||||
|       <div class="card"> | ||||
|         <header>{{ detailObj.title }}</header> | ||||
|         <u-gap height="16"></u-gap> | ||||
|         <u-row> | ||||
|           <span>发布人:</span> | ||||
|           <span v-if="detailObj.createUserId"> | ||||
|             <AiOpenData type="userName" :openid="detailObj.createUserId"></AiOpenData> | ||||
|           </span> | ||||
|         </u-row> | ||||
|         <u-gap height="8"></u-gap> | ||||
|         <u-row> | ||||
|           <span>发布部门:</span> | ||||
|           <span v-if="detailObj.unitName"> | ||||
|             <AiOpenData type="departmentName" :openid="detailObj.unitName"></AiOpenData> | ||||
|           </span> | ||||
|         </u-row> | ||||
|         <u-gap height="8"></u-gap> | ||||
|         <u-row> | ||||
|           <span>发布日期:</span> | ||||
|           <span>{{ detailObj.releaseTime }}</span> | ||||
|         </u-row> | ||||
|         <u-gap height="8"></u-gap> | ||||
|       </div> | ||||
|  | ||||
|       <div class="card"> | ||||
|         <div class="label">公告内容</div> | ||||
|         <u-parse :html="detailObj.content"></u-parse> | ||||
|       </div> | ||||
|  | ||||
|       <div class="card" style="padding-top: 0" v-if="detailObj.files && detailObj.files.length"> | ||||
|         <div class="label">相关附件</div> | ||||
|         <div class="file" v-for="(item,index) in detailObj.files" :key="index" @click="preFile(item)"> | ||||
|           <u-row justify="between"> | ||||
|             <label class="left"> | ||||
|               <img :src="$cdn + 'common/appendix.png'" alt=""> | ||||
|               <span>{{ item.name }}.{{ item.postfix }}</span> | ||||
|             </label> | ||||
|             <span>{{ (item.size / 1024).toFixed(2) }}KB</span> | ||||
|           </u-row> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <div class="card" @click="handleClick"> | ||||
|         <u-row justify="between" class="item"> | ||||
|           <span>接收对象</span> | ||||
|           <div class="right"> | ||||
|             <em>{{ detailObj.readNum }}人</em>已读 | ||||
|             <em>{{ detailObj.unReadNum }}人</em>未读 | ||||
|             <div class="arrow"></div> | ||||
|           </div> | ||||
|         </u-row> | ||||
|       </div> | ||||
|     </template> | ||||
|     <AiEmpty description="该通知已撤回" v-else/> | ||||
|     <AiBack/> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapActions} from "vuex"; | ||||
|  | ||||
| export default { | ||||
|   name: "detail", | ||||
|   data() { | ||||
|     return { | ||||
|       detailObj: {}, | ||||
|       id: null, | ||||
|       pageShow: false, | ||||
|       flag: false, | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   onLoad(opt) { | ||||
|     this.id = opt.id; | ||||
|     this.flag = opt.flag; | ||||
|   }, | ||||
|  | ||||
|   created() { | ||||
|     this.injectJWeixin(['sendChatMessage']).then(() => { | ||||
|       this.getDetail() | ||||
|     }) | ||||
|   }, | ||||
|  | ||||
|   onShow() { | ||||
|     document.title = "公告详情"; | ||||
|     wx.hideOptionMenu(); | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     ...mapActions(['previewFile', 'injectJWeixin']), | ||||
|     preFile(e) { | ||||
|       if ([".jpg", ".png", ".gif"].includes(e.postfix.toLowerCase())) { | ||||
|         uni.previewImage({ | ||||
|           current: e.url, | ||||
|           urls: [e.url] | ||||
|         }) | ||||
|       } else { | ||||
|         this.previewFile({...e}) | ||||
|       } | ||||
|     }, | ||||
|     getDetail() { | ||||
|       this.$http.post("/app/appannouncement/detail", null, { | ||||
|         params: { | ||||
|           id: this.id, | ||||
|           detail: this.flag | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res && res.data) { | ||||
|           this.detailObj = res.data; | ||||
|           this.pageShow = true | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     handleClick() { | ||||
|       uni.navigateTo({ | ||||
|         url: "/apps/AppNotification/read?id=" + this.id, | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .detail { | ||||
|   min-height: 100%; | ||||
|   background-color: #F5F5F5; | ||||
|   padding-bottom: 140px; | ||||
|  | ||||
|   ::v-deep .content { | ||||
|     padding: 0; | ||||
|   } | ||||
|  | ||||
|   .card { | ||||
|     background-color: #FFFFFF; | ||||
|     margin-bottom: 8px; | ||||
|     box-sizing: border-box; | ||||
|     padding: 16px 32px; | ||||
|  | ||||
|     header { | ||||
|       font-size: 40px; | ||||
|       font-weight: 600; | ||||
|       color: #333333; | ||||
|       line-height: 64px; | ||||
|       letter-spacing: 1px; | ||||
|     } | ||||
|  | ||||
|     .u-row { | ||||
|       & > div { | ||||
|         border-radius: 50%; | ||||
|         text-align: center; | ||||
|         font-size: 22px; | ||||
|         font-weight: bold; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         justify-content: center; | ||||
|       } | ||||
|  | ||||
|       & > span { | ||||
|         font-size: 30px; | ||||
|         color: #343D65; | ||||
|         line-height: 48px; | ||||
|       } | ||||
|  | ||||
|       & > span:last-child { | ||||
|         font-size: 30px; | ||||
|         /*color: #343D65;*/ | ||||
|         /*margin-left: 16px;*/ | ||||
|         line-height: 48px; | ||||
|       } | ||||
|  | ||||
|       .title { | ||||
|         width: 490px; | ||||
|         height: 112px; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         font-size: 32px; | ||||
|         color: #333333; | ||||
|         overflow: hidden; | ||||
|         text-overflow: ellipsis; | ||||
|         white-space: nowrap; | ||||
|       } | ||||
|  | ||||
|       .right { | ||||
|         font-size: 28px; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         color: #666666; | ||||
|  | ||||
|         .arrow { | ||||
|           width: 16px; | ||||
|           height: 16px; | ||||
|           border-top: 3px solid #CCCCCC; | ||||
|           border-right: 3px solid #CCCCCC; | ||||
|           transform: rotate(45deg); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .item { | ||||
|       position: relative; | ||||
|       height: 80px; | ||||
|  | ||||
|       &:after { | ||||
|         width: 100%; | ||||
|         height: 1px; | ||||
|         background-color: rgba(216, 221, 230, 0.5); | ||||
|         content: ""; | ||||
|         position: absolute; | ||||
|         left: 0; | ||||
|         bottom: 0; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     & > span { | ||||
|       font-size: 32px; | ||||
|       color: #333333; | ||||
|       line-height: 48px; | ||||
|       letter-spacing: 1px; | ||||
|       display: inline-block; | ||||
|     } | ||||
|  | ||||
|     .label { | ||||
|       height: 80px; | ||||
|       font-size: 32px; | ||||
|       color: #333333; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       margin-bottom: 16px; | ||||
|  | ||||
|       & > em { | ||||
|         font-style: normal; | ||||
|         font-size: 32px; | ||||
|         color: #1365DD; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .file { | ||||
|       height: 128px; | ||||
|       background: #FFFFFF; | ||||
|       border-radius: 8px; | ||||
|       border: 1px solid #CCCCCC; | ||||
|       box-sizing: border-box; | ||||
|       padding: 0 16px; | ||||
|       margin-bottom: 32px; | ||||
|  | ||||
|       & > .u-row { | ||||
|         height: 100%; | ||||
|  | ||||
|         .left { | ||||
|           width: 476px; | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           word-break: break-all; | ||||
|  | ||||
|           & > img { | ||||
|             flex-shrink: 0; | ||||
|             width: 96px; | ||||
|             height: 96px; | ||||
|           } | ||||
|  | ||||
|           & > span { | ||||
|             font-size: 32px; | ||||
|             color: #333333; | ||||
|             display: inline-block; | ||||
|             line-height: 44px; | ||||
|             overflow: hidden; | ||||
|             text-overflow: ellipsis; | ||||
|             display: -webkit-box; | ||||
|             -webkit-box-orient: vertical; | ||||
|             -webkit-line-clamp: 2; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         & > span { | ||||
|           font-size: 28px; | ||||
|           color: #999999; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .active { | ||||
|       background-color: #F3F6F9; | ||||
|     } | ||||
|  | ||||
|     & > text { | ||||
|       width: 100%; | ||||
|       display: inline-block; | ||||
|       font-size: 30px; | ||||
|       color: #649EFD; | ||||
|       text-align: center; | ||||
|     } | ||||
|  | ||||
|     .progress { | ||||
|       height: 12px; | ||||
|       background: #F2F4FC; | ||||
|       border-radius: 12px; | ||||
|       position: relative; | ||||
|       margin: 16px 0 64px 0; | ||||
|  | ||||
|       .pro-active { | ||||
|         height: 12px; | ||||
|         background: #639EFD; | ||||
|         border-radius: 12px; | ||||
|         position: absolute; | ||||
|         left: 0; | ||||
|         top: 0; | ||||
|       } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     em { | ||||
|       font-style: normal; | ||||
|       font-size: 28px; | ||||
|       color: #1365DD; | ||||
|     } | ||||
|  | ||||
|     ::v-deep .u-collapse { | ||||
|       position: relative; | ||||
|  | ||||
|       &:after { | ||||
|         content: ""; | ||||
|         width: 718px; | ||||
|         height: 1px; | ||||
|         background-color: rgba(216, 221, 230, 0.5); | ||||
|         position: absolute; | ||||
|         left: 0; | ||||
|         bottom: 0; | ||||
|       } | ||||
|  | ||||
|       .u-collapse-head { | ||||
|         padding: 40px 0; | ||||
|       } | ||||
|  | ||||
|       .u-collapse-content { | ||||
|         font-size: 32px; | ||||
|         color: #333333; | ||||
|         line-height: 48px; | ||||
|         letter-spacing: 1px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .footer { | ||||
|     height: 112px; | ||||
|     width: 100%; | ||||
|     position: fixed; | ||||
|     left: 0; | ||||
|     bottom: 0; | ||||
|     background: #1365DD; | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     justify-content: center; | ||||
|     font-size: 36px; | ||||
|     color: #FFFFFF; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										99
									
								
								src/sass/AppNotification/read.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/sass/AppNotification/read.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| <template> | ||||
|   <div class="read"> | ||||
|     <AiTopFixed> | ||||
|       <u-tabs :list="tabs" :is-scroll="false" height="96" bar-width="192" :current="current" @change="change"></u-tabs> | ||||
|     </AiTopFixed> | ||||
|     <div class="body"> | ||||
|       <div class="item" v-for="(item,index) in (current==0 ? list.read : list.unRead)" :key="index"> | ||||
|         <u-avatar :src="item.avatar" mode="square" size="76" style="margin-right: 8px;"></u-avatar> | ||||
|         <AiOpenData type="userName" :openid="item.id"></AiOpenData> | ||||
|       </div> | ||||
|     </div> | ||||
|     <AiBack/> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapActions} from "vuex"; | ||||
|  | ||||
| export default { | ||||
|   name: "read", | ||||
|   data() { | ||||
|     return { | ||||
|       current: 0, | ||||
|       list: [], | ||||
|       id: null, | ||||
|     } | ||||
|   }, | ||||
|   onLoad(opt) { | ||||
|     this.id = opt.id; | ||||
|     this.getList(); | ||||
|   }, | ||||
|   created() { | ||||
|     document.title = "接收对象"; | ||||
|     this.injectJWeixin().then(() => { | ||||
|       this.getList(); | ||||
|     }) | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapActions(['previewFile', 'injectJWeixin']), | ||||
|     getList() { | ||||
|       this.$http.post("/app/appannouncementreader/list-unread", null, { | ||||
|         params: { | ||||
|           id: this.id | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res && res.data) { | ||||
|           this.list = res.data; | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     change(val) { | ||||
|       this.current = val; | ||||
|       this.list = []; | ||||
|       this.getList(); | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     tabs() { | ||||
|       return [ | ||||
|         {name: (this.list?.read?.length || 0) + "人已读"}, | ||||
|         {name: (this.list?.unRead?.length || 0) + "人未读"}, | ||||
|       ]; | ||||
|     } | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .read { | ||||
|   min-height: 100%; | ||||
|   background-color: #F5F5F5; | ||||
|  | ||||
|   ::v-deep .content { | ||||
|     padding: 0 !important; | ||||
|   } | ||||
|  | ||||
|   .body { | ||||
|     padding: 16px 0; | ||||
|  | ||||
|     .item { | ||||
|       height: 120px; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       box-sizing: border-box; | ||||
|       padding: 0 50px; | ||||
|       background-color: #ffffff; | ||||
|       border-bottom: 1px solid #eeeeee; | ||||
|  | ||||
|       & > .name { | ||||
|         font-size: 36px; | ||||
|         font-weight: 600; | ||||
|         color: #333333; | ||||
|         line-height: 50px; | ||||
|         margin-left: 32px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
		Reference in New Issue
	
	Block a user