协同宣发1.1 慧治理
| @@ -0,0 +1,495 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="AppCooperationPropaganda"> | ||||||
|  |     <AiTopFixed> | ||||||
|  |       <div class="tab-select"> | ||||||
|  |         <div class="item" :class="tabIndex == index ? 'active' : ''" v-for="(item, index) in tabs" :key="index" @click="tabClick(item,index)">{{ item.name }}<span></span></div> | ||||||
|  |       </div> | ||||||
|  |       <div class="search"> | ||||||
|  |         <div class="searchBox"> | ||||||
|  |           <u-search placeholder="请输入任务名称" v-model="taskTitle" clearabled @search="searchBtn" @clear="taskTitle='',getList()" :show-action="false"></u-search> | ||||||
|  |         </div> | ||||||
|  |         <div class="filterBtn" @click="filterShow = true"><img src="./images/shaixuan.png" alt="">筛选</div> | ||||||
|  |       </div> | ||||||
|  |     </AiTopFixed> | ||||||
|  |     <div class="resident_list" v-if="list.length"> | ||||||
|  |       <div class="card" @click="toDetail(item)" v-for="(item,index) in list" :key="index"> | ||||||
|  |         <div class="card_title"> | ||||||
|  |           <div class="card_left">{{ item.taskTitle }}</div> | ||||||
|  |           <div class="card_right"><span :class="item.status==0? 'status0': item.status==1? 'status1': item.status==2? 'status2': | ||||||
|  |            item.status == 3? 'status3':item.status==4? 'status4': 'status5'"></span>{{ $dict.getLabel('mstStatus', item.status) }}</div> | ||||||
|  |         </div> | ||||||
|  |         <div>群发时间:<span>{{ item.choiceTime }}</span></div> | ||||||
|  |         <div>共需<span class="num">{{ item.groupOwnerCount || 0 }}</span>名成员完成群发,目前已完成<span class="num">{{ item.completionRate || 0 }}%</span></div> | ||||||
|  |         <div> | ||||||
|  |           创建部门: | ||||||
|  |           <span v-if="item.createUserDeptName">{{ item.createUserDeptName }}</span> | ||||||
|  |           <!-- <span v-if="item.createUserSecondDept"><AiOpenData type="departmentName" :openid="item.createUserSecondDept" style="display: inline-block" /></span> --> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |     <AiEmpty description="暂无数据" v-if="!list.length"/> | ||||||
|  |  | ||||||
|  |     <div class="btn"> | ||||||
|  |       <div class="addBtn" @click="toAdd">新增群发{{tabIndex==0? '居民群': tabIndex==1? '居民':'朋友圈'}}</div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <u-popup v-model="filterShow" mode="bottom" border-radius="14"> | ||||||
|  |       <div class="popup"> | ||||||
|  |         <div class="tips"></div> | ||||||
|  |         <div class="title"> | ||||||
|  |           <div | ||||||
|  |             class="cancel" | ||||||
|  |             @click.stop="(filterShow = false), (timeSelect = 0)" | ||||||
|  |           > | ||||||
|  |             取消 | ||||||
|  |           </div> | ||||||
|  |           <p>筛选条件</p> | ||||||
|  |           <div class="confirm" @click.stop="selectConfirm">确定</div> | ||||||
|  |         </div> | ||||||
|  |         <scroll-view class="select-content" scroll-y="true"> | ||||||
|  |           <div class="type-list"> | ||||||
|  |             <div class="type-title">创建人</div> | ||||||
|  |             <AiPagePicker type="custom" :selected.sync="userIdList" nodeKey="createUserId" :ops="{url:`./selectUser`,label: 'id'}"> | ||||||
|  |               <div class="page_picker"> | ||||||
|  |                 <span class="label" v-if="userIdList.length">已选择</span> | ||||||
|  |                 <span v-else style="color:#999;">请选择</span> | ||||||
|  |                 <u-icon name="arrow-right" color="#303133" size="24" style="margin-left:8px;"/> | ||||||
|  |               </div>  | ||||||
|  |             </AiPagePicker> | ||||||
|  |           </div> | ||||||
|  |           <div class="type-list"> | ||||||
|  |             <div class="type-title">任务状态</div> | ||||||
|  |             <div class="items"> | ||||||
|  |               <AiSelect dict="mstStatus" v-model="status"></AiSelect> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |           <div class="type-list"> | ||||||
|  |             <div class="type-title">群发时间</div> | ||||||
|  |             <div class="item"> | ||||||
|  |               <div>开始时间</div> | ||||||
|  |               <div style="display: flex;"> | ||||||
|  |                 <u-input v-model="startTime" disabled placeholder="请选择开始时间" @click="showStart = true" /> | ||||||
|  |                 <u-icon name="arrow-right"></u-icon> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |             <div class="item"> | ||||||
|  |               <div>结束时间</div> | ||||||
|  |               <div style="display: flex;"> | ||||||
|  |                 <u-input v-model="endTime" disabled placeholder="请选择结束时间" @click="showEnd = true" /> | ||||||
|  |                 <u-icon name="arrow-right"></u-icon> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |         </scroll-view> | ||||||
|  |         <u-picker mode="time" v-model="showStart" @confirm="confirmStart"></u-picker> | ||||||
|  |         <u-picker mode="time" v-model="showEnd" @confirm="confirmEnd"></u-picker> | ||||||
|  |         <div class="popBtn"> | ||||||
|  |           <div @click="reset">重置</div> | ||||||
|  |           <div @click="selectConfirm">确认</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </u-popup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: 'AppCooperationPropaganda', | ||||||
|  |   appName: '协同宣发', | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       tabs: [ | ||||||
|  |         { | ||||||
|  |           name: '群发居民群', | ||||||
|  |           value: 'ResidentsGroup' | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           name: '群发居民', | ||||||
|  |           value: 'Residents' | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           name: '群发朋友圈', | ||||||
|  |           value: 'CircleOfFriends' | ||||||
|  |         }, | ||||||
|  |       ], | ||||||
|  |       tabIndex: 0, | ||||||
|  |       current: 1, | ||||||
|  |       name: '', | ||||||
|  |       list: [], | ||||||
|  |       filterShow: false, | ||||||
|  |       startTime: '', | ||||||
|  |       endTime: '', | ||||||
|  |       start: "", | ||||||
|  |       end: "", | ||||||
|  |       showStart: false, | ||||||
|  |       showEnd: false, | ||||||
|  |       taskTitle: '', | ||||||
|  |       createUserId: '', | ||||||
|  |       userList: [], | ||||||
|  |       userIdList: [], | ||||||
|  |       status: '', | ||||||
|  |       sendType: '', | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     tabClick(item,index) { | ||||||
|  |       this.tabIndex = index; | ||||||
|  |       this.sendType = item.value | ||||||
|  |       uni.clearStorageSync('userSelect') | ||||||
|  |       uni.clearStorageSync('wxGroupsUser') | ||||||
|  |       uni.clearStorageSync('girdSelect') | ||||||
|  |       uni.clearStorageSync('deptList') | ||||||
|  |       uni.clearStorageSync('sendScope') | ||||||
|  |       uni.clearStorageSync('ResidentTags') | ||||||
|  |       uni.clearStorageSync('ResidentTagsRemove') | ||||||
|  |       uni.clearStorageSync('circleTags') | ||||||
|  |       uni.clearStorageSync('circleTagsRemove') | ||||||
|  |       this.$dict.load('mstStatus').then(() => { | ||||||
|  |         this.getList() | ||||||
|  |       }) | ||||||
|  |        | ||||||
|  |     }, | ||||||
|  |     toDetail(item) { | ||||||
|  |       if(this.tabIndex == 0) { | ||||||
|  |         uni.navigateTo({url: `./cooperationDetail?id=${item.id}&time=${item.createTime}`}) | ||||||
|  |       } else { | ||||||
|  |         alert('hhh') | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |     }, | ||||||
|  |     searchBtn() { | ||||||
|  |       this.current = 1 | ||||||
|  |       this.list = [], | ||||||
|  |       this.getList() | ||||||
|  |     }, | ||||||
|  |     getList() { | ||||||
|  |       let url = '' | ||||||
|  |       let data = { | ||||||
|  |         current: this.current, | ||||||
|  |         taskTitle: this.taskTitle, | ||||||
|  |         startTime: this.start, | ||||||
|  |         endTime: this.end, | ||||||
|  |         createUserId: this.createUserId, | ||||||
|  |         status: this.status, | ||||||
|  |       } | ||||||
|  |       if(this.tabIndex==0) { | ||||||
|  |         url = `/app/appmasssendingtask/list` | ||||||
|  |       } else if(this.tabIndex==1 || this.tabIndex==2) { | ||||||
|  |         url = `/app/whchatmomentstask/list` | ||||||
|  |         data = { | ||||||
|  |           ...data, | ||||||
|  |           taskType: this.tabIndex == 0? '': this.tabIndex==1? 1:0 | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       this.$http.post(url,null, {params:{...data}}).then(res=> { | ||||||
|  |         if(res?.data) { | ||||||
|  |           this.list = this.current == 1?  res.data.records : [...this.list,...res.data.records] | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     reset() { | ||||||
|  |       this.start = '', | ||||||
|  |       this.end = '', | ||||||
|  |       this.startTime = '', | ||||||
|  |       this.endTime = '' | ||||||
|  |       this.userIdList = [] | ||||||
|  |       this.createUserId = '' | ||||||
|  |       uni.setStorageSync('userSelect', []) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     selectConfirm() { | ||||||
|  |       if(this.userIdList.length) { | ||||||
|  |         this.createUserId = this.userIdList?.[0].userId | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       this.start = this.startTime, | ||||||
|  |       this.end = this.endTime | ||||||
|  |       let startTmp = this.start.split("-"); | ||||||
|  |       let endTmp = this.end.split("-"); | ||||||
|  |       let stT = new Date(startTmp[0], startTmp[1], startTmp[2]); | ||||||
|  |       let edT = new Date(endTmp[0], endTmp[1], endTmp[2]); | ||||||
|  |       if (stT.getTime() > edT.getTime()) { | ||||||
|  |         this.$u.toast("开始日期不能大于结束日期!"); | ||||||
|  |         this.filterShow = true | ||||||
|  |         return | ||||||
|  |       } | ||||||
|  |       this.filterShow = false | ||||||
|  |       this.current = 1 | ||||||
|  |       this.list = [] | ||||||
|  |       this.getList() | ||||||
|  |     }, | ||||||
|  |     confirmStart(val) { | ||||||
|  |       this.startTime = val.year + '-' + val.month + '-' + val.day | ||||||
|  |     }, | ||||||
|  |     confirmEnd(val) { | ||||||
|  |       this.endTime = val.year + '-' + val.month + '-' + val.day | ||||||
|  |     }, | ||||||
|  |     toAdd() { | ||||||
|  |       uni.navigateTo({url: `./addPropaganda?type=${this.sendType}`}) | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   onShow() { | ||||||
|  |     document.title = '协同宣发' | ||||||
|  |     this.$dict.load('mstStatus').then(() => { | ||||||
|  |       this.list = [] | ||||||
|  |       this.current = 1 | ||||||
|  |       this.getList() | ||||||
|  |     }) | ||||||
|  |   }, | ||||||
|  |   onReachBottom() { | ||||||
|  |     this.current ++ | ||||||
|  |     this.getList() | ||||||
|  |   }, | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .AppCooperationPropaganda { | ||||||
|  |  | ||||||
|  |   padding-bottom: 130px; | ||||||
|  |   box-sizing: border-box; | ||||||
|  |  | ||||||
|  |   ::v-deep .AiTopFixed .content { | ||||||
|  |     padding: 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .tab-select { | ||||||
|  |     width: 100%; | ||||||
|  |     height: 96px; | ||||||
|  |     line-height: 96px; | ||||||
|  |     background: #3975c6; | ||||||
|  |     display: flex; | ||||||
|  |  | ||||||
|  |     .item { | ||||||
|  |       flex: 1; | ||||||
|  |       text-align: center; | ||||||
|  |       font-size: 28px; | ||||||
|  |       font-family: PingFangSC-Regular, PingFang SC; | ||||||
|  |       color: #cddcf0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .active { | ||||||
|  |       font-family: PingFangSC-Medium, PingFang SC; | ||||||
|  |       font-weight: 500; | ||||||
|  |       position: relative; | ||||||
|  |       color: #fff; | ||||||
|  |  | ||||||
|  |       span { | ||||||
|  |         width: 48px; | ||||||
|  |         height: 4px; | ||||||
|  |         background: #fff; | ||||||
|  |         position: absolute; | ||||||
|  |         bottom: 14px; | ||||||
|  |         left: 50%; | ||||||
|  |         margin-left: -24px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .search { | ||||||
|  |     display: flex; | ||||||
|  |     height: 100px; | ||||||
|  |     align-items: center; | ||||||
|  |     justify-content: space-between; | ||||||
|  |     padding: 20px 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |  | ||||||
|  |     .searchBox { | ||||||
|  |       width: 562px; | ||||||
|  |     } | ||||||
|  |     .filterBtn { | ||||||
|  |       img { | ||||||
|  |         width: 28px; | ||||||
|  |         height: 28px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   .resident_list { | ||||||
|  |     padding: 24px 32px 20px 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     .card { | ||||||
|  |       background: #FFF; | ||||||
|  |       border-radius: 16px; | ||||||
|  |       padding: 30px; | ||||||
|  |       margin-bottom: 24px; | ||||||
|  |       & > div { | ||||||
|  |         padding: 10px 0; | ||||||
|  |       } | ||||||
|  |       .num { | ||||||
|  |         color: #3AA0FF; | ||||||
|  |       } | ||||||
|  |       .card_title { | ||||||
|  |         display: flex; | ||||||
|  |         justify-content: space-between; | ||||||
|  |         .card_left { | ||||||
|  |           font-size: 32px; | ||||||
|  |           color: #000000; | ||||||
|  |           font-weight: 600; | ||||||
|  |         } | ||||||
|  |         .card_right { | ||||||
|  |           span { | ||||||
|  |             display: inline-block; | ||||||
|  |             width: 16px; | ||||||
|  |             height: 16px; | ||||||
|  |             // background: #3399FF; | ||||||
|  |             border-radius: 50%; | ||||||
|  |             margin-right: 10px; | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           .status0 { | ||||||
|  |             background: #FFA938; | ||||||
|  |           } | ||||||
|  |           .status1 { | ||||||
|  |             background: #FF6758; | ||||||
|  |           } | ||||||
|  |           .status2 { | ||||||
|  |             background: #3399FF; | ||||||
|  |           } | ||||||
|  |           .status3 { | ||||||
|  |             background: #FF6758; | ||||||
|  |           } | ||||||
|  |           .status4 { | ||||||
|  |             background: #3399FF; | ||||||
|  |           } | ||||||
|  |           .status5 { | ||||||
|  |             background: #1CCEB0; | ||||||
|  |           } | ||||||
|  |           .status6 { | ||||||
|  |             background: #666666; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .btn { | ||||||
|  |     position: fixed; | ||||||
|  |     bottom: 0; | ||||||
|  |     left: 0; | ||||||
|  |     background: #FFF; | ||||||
|  |     display: flex; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 128px; | ||||||
|  |     padding: 24px 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |  | ||||||
|  |     .addBtn { | ||||||
|  |       flex: 1; | ||||||
|  |       height: 80px; | ||||||
|  |       line-height: 80px; | ||||||
|  |       text-align: center; | ||||||
|  |       border-radius: 8px; | ||||||
|  |       border: 2px solid #CCCCCC; | ||||||
|  |       background: #1365DD; | ||||||
|  |       color: #FFF; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .popup { | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     // height: 800px; | ||||||
|  |     .tips { | ||||||
|  |       width: 80px; | ||||||
|  |       height: 6px; | ||||||
|  |       background: #dddddd; | ||||||
|  |       border-radius: 4px; | ||||||
|  |       padding: 0 32px; | ||||||
|  |       box-sizing: border-box; | ||||||
|  |       margin: 32px auto 8px auto; | ||||||
|  |     } | ||||||
|  |     .title { | ||||||
|  |       height: 48px; | ||||||
|  |       line-height: 48px; | ||||||
|  |       font-size: 34px; | ||||||
|  |       font-family: PingFangSC-Medium, PingFang SC; | ||||||
|  |       font-weight: 500; | ||||||
|  |       color: #222; | ||||||
|  |       padding: 0 32px; | ||||||
|  |       box-sizing: border-box; | ||||||
|  |       padding-bottom: 32px; | ||||||
|  |       .cancel { | ||||||
|  |         display: inline-block; | ||||||
|  |         width: 200px; | ||||||
|  |         color: #aaa; | ||||||
|  |       } | ||||||
|  |       .confirm { | ||||||
|  |         display: inline-block; | ||||||
|  |         width: 200px; | ||||||
|  |         text-align: right; | ||||||
|  |         color: #333; | ||||||
|  |       } | ||||||
|  |       p { | ||||||
|  |         display: inline-block; | ||||||
|  |         width: calc(100% - 400px); | ||||||
|  |         text-align: center; | ||||||
|  |         font-size: 28px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     .select-content { | ||||||
|  |       height: calc(100% - 100px); | ||||||
|  |       overflow-y: scroll; | ||||||
|  |     } | ||||||
|  |     .type-list { | ||||||
|  |       padding: 0 32px; | ||||||
|  |       box-sizing: border-box; | ||||||
|  |       margin-bottom: 32px; | ||||||
|  |       .type-title { | ||||||
|  |         line-height: 108px; | ||||||
|  |         font-size: 32px; | ||||||
|  |         font-family: PingFangSC-Medium, PingFang SC; | ||||||
|  |         font-weight: 500; | ||||||
|  |         color: #333; | ||||||
|  |       } | ||||||
|  |       .item { | ||||||
|  |         display: flex; | ||||||
|  |         justify-content: space-between; | ||||||
|  |         & > div:last-child { | ||||||
|  |           ::v-deep .uni-input-input, | ||||||
|  |           ::v-deep .uni-input-placeholder { | ||||||
|  |             text-align: right; | ||||||
|  |           } | ||||||
|  |         }         | ||||||
|  |       } | ||||||
|  |       .items { | ||||||
|  |         ::v-deep .AiSelect .display { | ||||||
|  |           justify-content: space-between; | ||||||
|  |           width: 100%; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       .active { | ||||||
|  |         background: #1365dd; | ||||||
|  |         color: #fff; | ||||||
|  |       } | ||||||
|  |       .user { | ||||||
|  |         display: flex; | ||||||
|  |         justify-content: space-between; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     .popBtn { | ||||||
|  |       display: flex; | ||||||
|  |       height: 98px; | ||||||
|  |       line-height: 98px; | ||||||
|  |       div { | ||||||
|  |         width: 50%; | ||||||
|  |         border: 2px solid #3399ff; | ||||||
|  |         text-align: center; | ||||||
|  |       } | ||||||
|  |       div:first-child { | ||||||
|  |         color: #3399ff; | ||||||
|  |       } | ||||||
|  |       div:last-child { | ||||||
|  |         color: #fff; | ||||||
|  |         background: #3399ff; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   ::v-deep .uicon-arrow-right::before { | ||||||
|  |     color: #606266 !important; | ||||||
|  |   } | ||||||
|  |   .page_picker { | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: space-between; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										847
									
								
								src/project/huizhili/AppCooperationPropaganda/addPropaganda.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,847 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="addPropaganda"> | ||||||
|  |     <div class="task_name"> | ||||||
|  |       <div><span class="color_red">*</span><span class="title">任务名称</span></div> | ||||||
|  |       <u-input v-model="form.taskTitle" type="text" placeholder="请输入" maxlength="15" class="inpt"/> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <div class="send_scope"> | ||||||
|  |       <div><span class="color_red">*</span><span class="title">发送范围</span></div> | ||||||
|  |       <div @click="toSleectScoped"> | ||||||
|  |         <span> | ||||||
|  |           <span class="color_gray" v-if="!form.sendScope || sum==0">请选择</span> | ||||||
|  |           <span v-if="type=='ResidentsGroup' && form.wxGroups.length">预计送达{{ form.wxGroups.length }}名成员</span> | ||||||
|  |           <span v-if="type!='ResidentsGroup' && sum != 0">预计送达{{ sum }}名成员</span> | ||||||
|  |           <u-icon name="arrow-right" color="#CCD0D3"></u-icon> | ||||||
|  |         </span> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <div class="send_content"> | ||||||
|  |       <div class="content_title"> | ||||||
|  |         <div><span class="color_red">*</span><span class="title">发送内容</span></div> | ||||||
|  |         <div style="color: #3399FF;" @click="preview">预览</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="content_text"> | ||||||
|  |         <u-input v-model="content" type="textarea" height="372" :auto-height="true" placeholder="请输入政策、活动、节日问候等内容" maxlength="1300"/> | ||||||
|  |       </div> | ||||||
|  |       <div class="content_fodder"> | ||||||
|  |         <div class="fodder_alls"> | ||||||
|  |           <div class="fodder_add" @click="showUpload = true"><u-icon name="plus" color="#CCD0D3" size="32"></u-icon></div> | ||||||
|  |           <div class="fodder_title">添加素材</div> | ||||||
|  |           <!-- <AiUploader :def.sync="files" placeholder="添加素材" type="file" :limit="9" multiple action="/app/wxcp/upload/uploadFile" :mediaId.sync="midiaIds"></AiUploader> --> | ||||||
|  |         </div> | ||||||
|  |         <div class="fodder_file" v-for="(item, index) in files" :key="index"> | ||||||
|  |           <div class="item"> | ||||||
|  |             <div class="images"> | ||||||
|  |               <img src="	https://cdn.cunwuyun.cn/dvcp/h5/file.png" alt=""> | ||||||
|  |             </div> | ||||||
|  |             <div class="info"> | ||||||
|  |               <div class="name">{{ item.name }}</div> | ||||||
|  |               <div class="size">{{ item.fileSizeStr }}</div> | ||||||
|  |             </div> | ||||||
|  |             <div class="remove" @click="remove" style="color: #f72c27">删除</div> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <div class="isExamine"> | ||||||
|  |       <div class="examineChange"> | ||||||
|  |         <div>宣发需要审批</div> | ||||||
|  |         <u-switch v-model="enableExamine" size="40" @change="enableExamine = !!enableExamine"></u-switch> | ||||||
|  |       </div> | ||||||
|  |       <div class="examine_person" v-if="enableExamine == true"> | ||||||
|  |         <div><span class="color_red">*</span><span class="title">审批人</span></div> | ||||||
|  |         <div @click="getDeptUser"> | ||||||
|  |           <span v-if="!userList.length" class="color_gray">请选择人员<u-icon name="arrow-right" color="#CCD0D3"></u-icon></span> | ||||||
|  |           <div v-if="userList.length"> | ||||||
|  |             <AiOpenData type="departmentName" :openid="departmentId"/> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div class="examineChange"> | ||||||
|  |         <div>定时发送</div> | ||||||
|  |         <u-switch v-model="isTimedTask" size="40" @change="isTimedTask = !!isTimedTask"></u-switch> | ||||||
|  |       </div> | ||||||
|  |       <div class="examine_person" v-if="isTimedTask == true"> | ||||||
|  |         <div><span class="color_red">*</span><span class="title">发送时间</span></div> | ||||||
|  |         <div @click="showTaskTime = true"> | ||||||
|  |           <span class="color_gray" v-if="!form.choiceTime.length">请选择</span> | ||||||
|  |           <span v-if="form.choiceTime.length">{{ form.choiceTime }}</span> | ||||||
|  |           <u-icon name="arrow-right" color="#CCD0D3"/> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <u-picker v-model="showTaskTime" :params="params" mode="time" @confirm="choiceTime"></u-picker> | ||||||
|  |  | ||||||
|  |     <div class="mask" v-show="showPopup" @tap="showPopup = false"> | ||||||
|  |       <div class="noticeModal" @tap.stop> | ||||||
|  |         <div class="body"> | ||||||
|  |  | ||||||
|  |           <div class="text_content" v-if="content.length"> | ||||||
|  |             <img class="text_left" src="https://cdn.cunwuyun.cn/dvcp/announce/avatar.png" /> | ||||||
|  |             <div class="text_right">{{ content }}</div> | ||||||
|  |           </div> | ||||||
|  |          | ||||||
|  |           <div class="file_content" v-for="item in files" :key="item.id"> | ||||||
|  |             <img class="text_left" src="https://cdn.cunwuyun.cn/dvcp/announce/avatar.png" /> | ||||||
|  |             <img class="only_pic" :src="item.url" alt="" v-if="['.jpg', '.jpeg','.png'].indexOf(getExtension(item.name)) !== -1"> | ||||||
|  |             <video controls class="only_video" :src="item.url" v-if="getExtension(item.name) == '.mp4'"></video> | ||||||
|  |             <div class="text_right file_right"  | ||||||
|  |             v-if="['.jpg', '.jpeg','.png','.mp4'].indexOf(getExtension(item.name)) === -1"> | ||||||
|  |               <div class="cont_left"> | ||||||
|  |                 <h4>{{ item.name }}</h4> | ||||||
|  |                 <p>{{ item.fileSizeStr }}</p> | ||||||
|  |               </div> | ||||||
|  |               <div class="cont_right"> | ||||||
|  |                 <img :src="fileIcon(item.name)" alt=""> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |  | ||||||
|  |         </div> | ||||||
|  |         <div class="footer"> | ||||||
|  |           <div class="exit" @click="showPopup = false">退出预览</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <u-popup v-model="showUpload" mode="bottom" border-radius="24"> | ||||||
|  | 			<div class="uploadPopup"> | ||||||
|  |         <div class="upload_card" v-for="(item,index) in upload" :key="index"> | ||||||
|  |           <div class="upload_item">{{ item.title }}</div> | ||||||
|  |           <div class="upload_list"> | ||||||
|  |             <div class="list_item" v-for="(e, i) in item.list" :key="i" @click="uploadBtn(e.msgType)"> | ||||||
|  |               <img :src="e.icon" alt=""> | ||||||
|  |               <span>{{ e.name }}</span> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <div class="btnCancel" @click="showUpload = false">取消</div> | ||||||
|  |       </div> | ||||||
|  | 		</u-popup> | ||||||
|  |  | ||||||
|  |      | ||||||
|  |     <div class="btn"> | ||||||
|  |       <div class="submitBtn" @click="confirm">通知成员发送</div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import { mapActions } from "vuex"; | ||||||
|  | export default { | ||||||
|  |   name: "addPropaganda", | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       type: '', | ||||||
|  |       form: { | ||||||
|  |         taskTitle: '', | ||||||
|  |         contents: [], // 发送内容 | ||||||
|  |         enableExamine: '0', // 是否需要审批  0否 1是 | ||||||
|  |         examines: [], // 审批人 | ||||||
|  |         choiceTime: '', // 定时发送时间 | ||||||
|  |         sendScope: '', // 0:全部居民群、1:按部门选择、2:按网格选择 | ||||||
|  |         sendType: '0', // 0:立即发送、1:定时发送 | ||||||
|  |         wxGroups: [  // 发送范围 | ||||||
|  |           // { | ||||||
|  |           //   corpId: "ww596787bb70f08288", | ||||||
|  |           //   errorCode: null, | ||||||
|  |           //   errorMsg: null, | ||||||
|  |           //   groupCount: 1, | ||||||
|  |           //   groupIds: "wrytYEDgAAA5MGVJ3Ttb6ycbmxJ2Zv-Q", | ||||||
|  |           //   groupNames: "111", | ||||||
|  |           //   groupOwnerId: "d41d8cd98f00b204e9800998ecf8427e", | ||||||
|  |           //   groupOwnerName: "张硕", | ||||||
|  |           //   id: null, | ||||||
|  |           //   msgId: null, | ||||||
|  |           //   sendStatus: null, | ||||||
|  |           //   sendTime: null, | ||||||
|  |           //   taskId: null, | ||||||
|  |           // }, | ||||||
|  |           // { | ||||||
|  |           //   corpId: "ww596787bb70f08288", | ||||||
|  |           //   errorCode: null, | ||||||
|  |           //   errorMsg: null, | ||||||
|  |           //   groupCount: 4, | ||||||
|  |           //   groupIds: "wrytYEDgAA-Llt9H1jr40WT1_RfOstWQ,wrytYEDgAADava7QSJGicwZg09nG_GXg,wrytYEDgAAKG6qd39fHWFkrTiT9vsSQQ,wrytYEDgAAPxVpqyzf4kwzwvtdE0nqbQ", | ||||||
|  |           //   groupNames: "慧政务需求沟通,临汾市政法委企微项目沟通,淄博企微项目沟通群,未命名群聊", | ||||||
|  |           //   groupOwnerId: "XieJin", | ||||||
|  |           //   groupOwnerName: "谢晋", | ||||||
|  |           //   id: null, | ||||||
|  |           //   msgId: null, | ||||||
|  |           //   sendStatus: null, | ||||||
|  |           //   sendTime: null, | ||||||
|  |           //   taskId: null, | ||||||
|  |           // } | ||||||
|  |         ],  // 送达居民群 | ||||||
|  |         filterCriteria: '' | ||||||
|  |       }, | ||||||
|  |       forms: { | ||||||
|  |         taskTitle: '', | ||||||
|  |         taskType: '', | ||||||
|  |         executorList: [], // 任务执行人集合(群发朋友圈的执行人) | ||||||
|  |         groupList: [],  // 添加人集合 | ||||||
|  |         contents: [], // 发送内容 | ||||||
|  |         enableExamine: '0', // 是否需要审批  0否 1是 | ||||||
|  |         examines: [], // 审批人 | ||||||
|  |         choiceTime: '', // 定时发送时间 | ||||||
|  |         sendScope: '', // 0:全部居民群、1:按部门选择、2:按网格选择 | ||||||
|  |         sendType: '0', // 0:立即发送、1:定时发送 | ||||||
|  |         gender: '', // 性别:0-女、1-男、2-全部 | ||||||
|  |         filterCriteria: '' | ||||||
|  |       }, | ||||||
|  |       enableExamine: false, | ||||||
|  |       isTimedTask: false, | ||||||
|  |       content: '', | ||||||
|  |       files: [],  | ||||||
|  |       showTaskTime: false, | ||||||
|  |       userList: [], | ||||||
|  |       showPopup: false, | ||||||
|  |       showFodder: false, | ||||||
|  |       showUpload: false, | ||||||
|  |       params: { | ||||||
|  |         year: true, | ||||||
|  |         month: true, | ||||||
|  |         day: true, | ||||||
|  |         hour: true, | ||||||
|  |         minute: true, | ||||||
|  |         second: true, | ||||||
|  |         timestamp: false, | ||||||
|  |       }, | ||||||
|  |       flag: false, | ||||||
|  |       uploadList: [ | ||||||
|  |         {  | ||||||
|  |           title: '从本地上传',  | ||||||
|  |           list: [ | ||||||
|  |             { | ||||||
|  |               icon: 'https://cdn.cunwuyun.cn/dvcp/announce/img.png',  | ||||||
|  |               name: '图片',  | ||||||
|  |               msgType: 'image' | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |               icon: 'https://cdn.cunwuyun.cn/dvcp/announce/video.png',  | ||||||
|  |               name: '视频', | ||||||
|  |               msgType: 'video' | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |               icon: 'https://cdn.cunwuyun.cn/dvcp/announce/folder.png',  | ||||||
|  |               name: '文件', | ||||||
|  |               msgType: 'file' | ||||||
|  |             } | ||||||
|  |           ] | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       uploadCircle: [ | ||||||
|  |         {  | ||||||
|  |           title: '从本地上传',  | ||||||
|  |           list: [ | ||||||
|  |             { | ||||||
|  |               icon: 'https://cdn.cunwuyun.cn/dvcp/announce/img.png',  | ||||||
|  |               name: '图片',  | ||||||
|  |               msgType: 'image' | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |               icon: 'https://cdn.cunwuyun.cn/dvcp/announce/video.png',  | ||||||
|  |               name: '视频', | ||||||
|  |               msgType: 'video' | ||||||
|  |             }, | ||||||
|  |           ] | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       upload: [], | ||||||
|  |       midiaIds: [], | ||||||
|  |       sum: '', | ||||||
|  |       girdListIds: [], | ||||||
|  |       deptListIds: [], | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     ...mapActions(['selectEnterpriseContact']), | ||||||
|  |  | ||||||
|  |     // 发送范围 | ||||||
|  |     toSleectScoped() { | ||||||
|  |       uni.navigateTo({url: `./sendScoped?type=${this.type}`}) | ||||||
|  |     }, | ||||||
|  |     // 预览 | ||||||
|  |     preview() { | ||||||
|  |       this.showPopup = true; | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     fileIcon(name) { | ||||||
|  |       if (['.zip', '.rar','.mp4'].indexOf(this.getExtension(name)) !== -1) { | ||||||
|  |         return 'https://cdn.cunwuyun.cn/dvcp/announce/zip.png' | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if (['.doc', '.docx'].indexOf(this.getExtension(name)) !== -1) { | ||||||
|  |         return 'https://cdn.cunwuyun.cn/dvcp/announce/world.png' | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if (['.xls', '.xlsx'].indexOf(this.getExtension(name)) !== -1) { | ||||||
|  |         return 'https://cdn.cunwuyun.cn/dvcp/announce/xls.png' | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if (['.txt'].indexOf(this.getExtension(name)) !== -1) { | ||||||
|  |         return 'https://cdn.cunwuyun.cn/dvcp/announce/txt.png' | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if (['.pdf'].indexOf(this.getExtension(name)) !== -1) { | ||||||
|  |         return 'https://cdn.cunwuyun.cn/dvcp/announce/pdf.png' | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if (['.ppt', '.pptx'].indexOf(this.getExtension(name)) !== -1) { | ||||||
|  |         return 'https://cdn.cunwuyun.cn/dvcp/announce/ppt.png' | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     getExtension(name) { | ||||||
|  |       return name.substring(name.lastIndexOf('.')) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     uploadBtn(type) { | ||||||
|  |       let count = 9 - (this.files?.length || 0) | ||||||
|  |       if(count > 0){ | ||||||
|  |         let params = { | ||||||
|  |           count, | ||||||
|  |           sizeType: ['compressed'], | ||||||
|  |           sourceType: ['album', 'camera'], | ||||||
|  |           success: (res) => { | ||||||
|  |             let count = this.files?.length + (res.tempFiles?.length || res.tempFile ? 1 : 0) | ||||||
|  |             if (count > 9) { | ||||||
|  |               return this.$u.toast(`不能超过9个`) | ||||||
|  |             } | ||||||
|  |             if (res.tempFiles) { | ||||||
|  |               res.tempFiles?.map((item) => { | ||||||
|  |                 this.uploadFile(item,type) | ||||||
|  |               }) | ||||||
|  |             } else if (res?.tempFile) { | ||||||
|  |               this.uploadFile(res.tempFile,type) | ||||||
|  |             } | ||||||
|  |           }, | ||||||
|  |         } | ||||||
|  |         if (type == 'image') { | ||||||
|  |           uni.chooseImage(params) | ||||||
|  |         } else if (type == 'video') { | ||||||
|  |           uni.chooseVideo(params) | ||||||
|  |         } else if(type == 'file') { | ||||||
|  |           uni.chooseFile(params) | ||||||
|  |         } | ||||||
|  |       } else { | ||||||
|  |         this.$u.toast(`不能超过9个`) | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     uploadFile(img,type) { | ||||||
|  |       uni.showLoading({title: '上传中'}) | ||||||
|  |       let formData = new FormData() | ||||||
|  |       formData.append('file', img) | ||||||
|  |       formData.append('type', type) | ||||||
|  |       let url = '' | ||||||
|  |       if(this.type=='Residents' || this.type=='ResidentsGroup') { | ||||||
|  |         url = `/app/wxcp/upload/uploadFile` | ||||||
|  |       } else if(this.type=='CircleOfFriends') { | ||||||
|  |         url = `/app/wxcp/upload/uploadAttachment?attachmentType=1&mediaType=${type}` | ||||||
|  |       } | ||||||
|  |       this.$http.post(url, formData,{ | ||||||
|  |         withCredentials: false | ||||||
|  |       }).then((res) => { | ||||||
|  |         uni.hideLoading() | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.$u.toast('上传成功!') | ||||||
|  |           this.showUpload = false | ||||||
|  |           this.files.push({ | ||||||
|  |             ...res.data.file, | ||||||
|  |             media: res.data.media, | ||||||
|  |             msgType: type, | ||||||
|  |             sysFileId: res.data.file.id, | ||||||
|  |             imgPicUrl: res.data.file.url, | ||||||
|  |             mediaId: res.data.media.mediaId | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       }).catch(res => { | ||||||
|  |         this.$u.toast(res) | ||||||
|  |         uni.hideLoading() | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     remove(index) { | ||||||
|  |       this.files.splice(index, 1) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     choiceTime(e) { | ||||||
|  |       this.form.choiceTime = e.year + '-' + e.month + '-' + e.day + ' ' + e.hour + ':' + e.minute + ':' + e.second | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     confirm() { | ||||||
|  |       if(this.flag) return | ||||||
|  |       this.form.contents = [] | ||||||
|  |       // 文本 | ||||||
|  |       const firstContent = [ | ||||||
|  |         {  | ||||||
|  |           content: this.content, | ||||||
|  |           msgType: '0' | ||||||
|  |         }, | ||||||
|  |       ] | ||||||
|  |       this.form.contents.push(...firstContent) | ||||||
|  |       // 图片 | ||||||
|  |       const picUrl = this.files.filter(i=> ['.jpg','.jpeg','.png'].indexOf(this.getExtension(i.name)) !== -1).map(e=>{ | ||||||
|  |         return { | ||||||
|  |           imgPicUrl: e.url,  | ||||||
|  |           msgType: '1', | ||||||
|  |           mediaId: e.mediaId | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |       this.form.contents.push(...picUrl) | ||||||
|  |       // 视频 | ||||||
|  |       const video = this.files.filter(i=> ['.mp4'].indexOf(this.getExtension(i.name)) !== -1).map(e=>{ | ||||||
|  |         return { | ||||||
|  |           imgPicUrl: e.url,  | ||||||
|  |           msgType: '2', | ||||||
|  |           mediaId: e.mediaId | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |       this.form.contents.push(...video) | ||||||
|  |       // 文件 | ||||||
|  |       const files = this.files.filter(i=> ['.mp4','.jpg','.jpeg','.png'].indexOf(this.getExtension(i.name)) == -1).map(e=>{ | ||||||
|  |         return { | ||||||
|  |           imgPicUrl: e.url,  | ||||||
|  |           msgType: '3', | ||||||
|  |           mediaId: e.mediaId | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |       this.form.contents.push(...files) | ||||||
|  |  | ||||||
|  |       if(this.type=='Residents' || this.type=='CircleOfFriends') { | ||||||
|  |         this.forms.contents = this.form.contents | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |       if(!this.form.taskTitle) { | ||||||
|  |         return this.$u.toast('请输入任务名称') | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if(!this.form.sendScope) { | ||||||
|  |         return this.$u.toast('请选择发送范围') | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if(!this.form.contents.length) { | ||||||
|  |         return this.$u.toast("请输入发送内容") | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if(this.enableExamine) { // 是否需要审批,0:否、1:是 | ||||||
|  |         if(!this.form.examines.length) { | ||||||
|  |           return this.$u.toast("请选择审批人") | ||||||
|  |         } else { | ||||||
|  |           this.form.examineList = this.form.examineList | ||||||
|  |         } | ||||||
|  |         this.form.enableExamine = 1 | ||||||
|  |         this.forms.enableExamine = 1  | ||||||
|  |       } else { | ||||||
|  |         this.form.enableExamine = 0 | ||||||
|  |         this.forms.enableExamine = 0  | ||||||
|  |         this.form.examineList = [] | ||||||
|  |         this.form.examineList = [] | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if(this.isTimedTask) {   // 发送类型,0:立即发送、1:定时发送 | ||||||
|  |         this.form.sendType = 1 | ||||||
|  |         this.forms.sendType = 1 | ||||||
|  |         if(!this.form.choiceTime.length) { | ||||||
|  |           return this.$u.toast("请选择发送时间") | ||||||
|  |         } else if (new Date(this.form.choiceTime).getTime() < Date.now()) { | ||||||
|  |           return this.$u.toast('定时发送时间不得早于当前时间') | ||||||
|  |         } | ||||||
|  |         this.forms.choiceTime = this.form.choiceTime | ||||||
|  |       } else { | ||||||
|  |         this.form.sendType = 0 | ||||||
|  |         this.forms.sendType = 0 | ||||||
|  |         this.forms.choiceTime = '' | ||||||
|  |         this.form.choiceTime = '' | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       this.flag = true | ||||||
|  |  | ||||||
|  |       let formData = {} | ||||||
|  |       let url = '' | ||||||
|  |       if(this.type=='Residents') { | ||||||
|  |         url = `/app/whchatmomentstask/addOrUpdate` | ||||||
|  |         this.forms.filterCriteria = this.girdListIds.toString() || this.deptListIds.toString() || '' | ||||||
|  |         this.forms.filterTags = '' | ||||||
|  |         this.forms.excludeFilterTags = '剔除标签' | ||||||
|  |         formData = this.forms | ||||||
|  |       } else if(this.type=='CircleOfFriends') { | ||||||
|  |         url = `/app/whchatmomentstask/addOrUpdate` | ||||||
|  |         this.forms.filterCriteria = this.girdListIds.toString() || this.deptListIds.toString() || '' | ||||||
|  |         this.forms.filterTags = '过滤标签' | ||||||
|  |         this.forms.excludeFilterTags = '剔除标签' | ||||||
|  |         formData = this.forms | ||||||
|  |       } else if(this.type=='ResidentsGroup') { | ||||||
|  |         url = `/app/appmasssendingtask/addOrUpdate` | ||||||
|  |         this.form.filterCriteria = this.girdListIds.toString() || this.deptListIds.toString() || '' | ||||||
|  |         formData = this.form | ||||||
|  |       }  | ||||||
|  |       this.$http.post(url, { ...formData }).then(res=>{ | ||||||
|  |         if(res?.code == 0) { | ||||||
|  |           this.flag = false | ||||||
|  |           this.$u.toast("新增成功") | ||||||
|  |           setTimeout(() => { | ||||||
|  |             navigateBack() | ||||||
|  |           }, 600) | ||||||
|  |         } | ||||||
|  |       }).catch((err)=>{ | ||||||
|  |         this.flag = false | ||||||
|  |         this.$u.toast(err) | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     getDeptUser() { | ||||||
|  |       this.selectEnterpriseContact({ | ||||||
|  |         fromDepartmentId: 0, | ||||||
|  |         mode: "multi", | ||||||
|  |         type: ["user"], | ||||||
|  |         selectedUserIds: this.form.examineList?.map(e => e.id) | ||||||
|  |       }).then((res)=>{ | ||||||
|  |           if(res?.userList) { | ||||||
|  |             this.form.examineList = res.userList | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       ).catch((err) => { | ||||||
|  |         console.log(err); | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   onLoad(o) { | ||||||
|  |     this.type = o.type; | ||||||
|  |     document.title = this.type=='ResidentsGroup'? "群发居民群": this.type=='Residents'? "群发居民": "群发朋友圈" | ||||||
|  |     if(this.type=='Residents') { | ||||||
|  |       this.forms.taskType = 1 | ||||||
|  |     } else if(this.type=='CircleOfFriends') { | ||||||
|  |       this.forms.taskType = 0 | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   onShow() { | ||||||
|  |     this.form.wxGroups = uni.getStorageSync('wxGroupsUser') || [] | ||||||
|  |     this.form.sendScope = uni.getStorageSync('sendScope') | ||||||
|  |     if(this.type=='Residents') { | ||||||
|  |       this.forms.taskType = 1 | ||||||
|  |       this.forms.sendScope = this.form.sendScope | ||||||
|  |       this.forms.groupList = this.form.wxGroups | ||||||
|  |       this.sum = this.form.wxGroups.reduce((pre, cur) => pre + cur.customerCount, 0) | ||||||
|  |       this.upload = this.uploadList | ||||||
|  |     } else if(this.type=='CircleOfFriends') { | ||||||
|  |       this.forms.taskType = 0 | ||||||
|  |       this.forms.sendScope = this.form.sendScope | ||||||
|  |       this.forms.executorList = this.form.wxGroups | ||||||
|  |       this.sum = this.form.wxGroups.reduce((pre, cur) => pre + cur.customerCount, 0) | ||||||
|  |       this.upload = this.uploadCircle | ||||||
|  |     } else if(this.type == 'ResidentsGroup') { | ||||||
|  |       this.upload = this.uploadList | ||||||
|  |     } | ||||||
|  |     this.forms.taskTitle = this.form.taskTitle | ||||||
|  |     const girdArr = uni.getStorageSync('girdSelect') | ||||||
|  |     if(girdArr.length) { | ||||||
|  |       this.girdListIds = girdArr.map(e=>e.id) | ||||||
|  |     } | ||||||
|  |     const deptArr = uni.getStorageSync('deptList') | ||||||
|  |     if(deptArr.length) { | ||||||
|  |       this.deptListIds = deptArr.map(v=>v.id) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .addPropaganda { | ||||||
|  |   font-size: 32px !important; | ||||||
|  |   padding-bottom: 140px; | ||||||
|  |   box-sizing: border-box; | ||||||
|  |   .task_name, | ||||||
|  |   .send_scope, | ||||||
|  |   .send_content { | ||||||
|  |     background: #FFF; | ||||||
|  |     padding: 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     margin-bottom: 16px; | ||||||
|  |     box-shadow: inset 0px -1px 0px 0px #DDDDDD; | ||||||
|  |     .title { | ||||||
|  |       font-weight: 400; | ||||||
|  |       font-size: 32px; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .send_scope { | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: space-between; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .send_content { | ||||||
|  |     .content_title { | ||||||
|  |       display: flex; | ||||||
|  |       justify-content: space-between; | ||||||
|  |     } | ||||||
|  |     .content_text { | ||||||
|  |       margin-top: 12px; | ||||||
|  |       border-bottom: 1px solid #DDD; | ||||||
|  |     } | ||||||
|  |     .content_fodder { | ||||||
|  |       margin-top: 16px; | ||||||
|  |        | ||||||
|  |       .fodder_alls { | ||||||
|  |         display: flex; | ||||||
|  |         margin-top: 16px; | ||||||
|  |         align-items: center; | ||||||
|  |         .fodder_add { | ||||||
|  |           border: 2px solid #DBDCDF; | ||||||
|  |           padding: 20px 24px; | ||||||
|  |           box-sizing: border-box; | ||||||
|  |           border-radius: 8px; | ||||||
|  |         } | ||||||
|  |         .fodder_title { | ||||||
|  |           color: #8E8F91; | ||||||
|  |           margin-left: 20px; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       .fodder_file { | ||||||
|  |         margin-top: 16px; | ||||||
|  |         width: 100%; | ||||||
|  |         .item { | ||||||
|  |           display: flex; | ||||||
|  |           .images { | ||||||
|  |             margin-right: 32px; | ||||||
|  |             img { | ||||||
|  |               width: 80px; | ||||||
|  |               height: 80px; | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |           .info { | ||||||
|  |             width: calc(100% - 200px); | ||||||
|  |             .name { | ||||||
|  |               overflow: hidden;  | ||||||
|  |               text-overflow: ellipsis; | ||||||
|  |               display: -webkit-box; | ||||||
|  |               -webkit-box-orient: vertical; | ||||||
|  |               -webkit-line-clamp: 2; | ||||||
|  |             } | ||||||
|  |             .size { | ||||||
|  |               color: #9b9b9b; | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |           .reUpload { | ||||||
|  |             color:  #1365DD; | ||||||
|  |             margin-left: 20px; | ||||||
|  |           } | ||||||
|  |           .remove { | ||||||
|  |             color: #f72c27; | ||||||
|  |             margin-left: 20px; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .isExamine { | ||||||
|  |     background: #FFF; | ||||||
|  |     padding: 0px 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     box-shadow: inset 0px -1px 0px 0px #DDDDDD; | ||||||
|  |      | ||||||
|  |     .examineChange, | ||||||
|  |     .examine_person { | ||||||
|  |       display: flex; | ||||||
|  |       justify-content: space-between; | ||||||
|  |       padding: 26px 0px; | ||||||
|  |       box-sizing: border-box; | ||||||
|  |       border-top: 2px solid #DDD; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .examine_person { | ||||||
|  |        | ||||||
|  |       // padding: 26px 0 0 0; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   .color_red { | ||||||
|  |     color: #FF4466; | ||||||
|  |   } | ||||||
|  |   .color_gray { | ||||||
|  |     color: #CCD0D3; | ||||||
|  |   } | ||||||
|  |   .inpt { | ||||||
|  |     margin-left: 14px; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .mask { | ||||||
|  |     position: fixed; | ||||||
|  |     top: 0; | ||||||
|  |     bottom: 0; | ||||||
|  |     margin: 0; | ||||||
|  |     left: 0; | ||||||
|  |     right: 0; | ||||||
|  |     background: rgba(#000, 0.6); | ||||||
|  |     z-index: 202103021409; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 100%; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ::v-deep .noticeModal { | ||||||
|  |     position: fixed; | ||||||
|  |     left: 50%; | ||||||
|  |     top: 45%; | ||||||
|  |     transform: translate(-50%, -50%); | ||||||
|  |     width: 90%; | ||||||
|  |     height: 85%; | ||||||
|  |  | ||||||
|  |     .body { | ||||||
|  |       background: #EBECF0; | ||||||
|  |       border-radius: 16px 16px 0 0; | ||||||
|  |       padding: 32px; | ||||||
|  |       box-sizing: border-box; | ||||||
|  |       height: 100%; | ||||||
|  |       overflow-y: auto; | ||||||
|  |       font-size: 28px; | ||||||
|  |       font-weight: 400; | ||||||
|  |       color: #333; | ||||||
|  |       line-height: 48px; | ||||||
|  |  | ||||||
|  |       .text_content, | ||||||
|  |       .file_content { | ||||||
|  |         display: flex; | ||||||
|  |         margin-bottom: 32px; | ||||||
|  |         .text_left {  | ||||||
|  |           margin-right: 32px; | ||||||
|  |           width: 84px; | ||||||
|  |           height: 84px; | ||||||
|  |         } | ||||||
|  |         .only_pic { | ||||||
|  |           max-width: 206px; | ||||||
|  |           max-height: 200px; | ||||||
|  |         } | ||||||
|  |         .only_video { | ||||||
|  |           max-width: 284px; | ||||||
|  |           max-height: 160px; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .text_right { | ||||||
|  |           width: calc(100% - 116px); | ||||||
|  |           background: #FFF; | ||||||
|  |           border-radius: 10px; | ||||||
|  |           padding: 24px; | ||||||
|  |           box-sizing: border-box; | ||||||
|  |           position: relative; | ||||||
|  |  | ||||||
|  |           &::before { | ||||||
|  |             position: absolute; | ||||||
|  |             content: ""; | ||||||
|  |             width: 0; | ||||||
|  |             height: 0; | ||||||
|  |             top: 18px; | ||||||
|  |             left: 0; | ||||||
|  |             border-top: 12px solid transparent; | ||||||
|  |             border-bottom: 12px solid transparent; | ||||||
|  |             border-left: 12px solid transparent; | ||||||
|  |             border-right: 12px solid #fff; | ||||||
|  |             transform: translate(-100%, 0%); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         .file_right { | ||||||
|  |           display: flex; | ||||||
|  |           .cont_left { | ||||||
|  |             width: calc(100% - 90px); | ||||||
|  |             h4 {  | ||||||
|  |               overflow: hidden; | ||||||
|  |               text-overflow: ellipsis; | ||||||
|  |               white-space: nowrap; | ||||||
|  |               font-weight: normal; | ||||||
|  |             } | ||||||
|  |             p { | ||||||
|  |               color: #888888; | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |           .cont_right { | ||||||
|  |             width: 84px; | ||||||
|  |             height: 84px; | ||||||
|  |             img { | ||||||
|  |               width: 100%; | ||||||
|  |               height: 100%; | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .footer { | ||||||
|  |       width: 100%; | ||||||
|  |       height: 112px; | ||||||
|  |       line-height: 112px; | ||||||
|  |       text-align: center; | ||||||
|  |       background: #FFF; | ||||||
|  |       border-radius: 0 0 16px 16px; | ||||||
|  |       border-top: 2px solid #EEEEEE; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .uploadPopup { | ||||||
|  |      | ||||||
|  |     background: #F7F7F7; | ||||||
|  |     .upload_card { | ||||||
|  |       padding: 32px 32px 0 32px; | ||||||
|  |       box-sizing: border-box; | ||||||
|  |       overflow-x: scroll; | ||||||
|  |  | ||||||
|  |       .upload_item { | ||||||
|  |         margin-bottom: 32px; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       .upload_list { | ||||||
|  |         overflow-x: scroll; | ||||||
|  |         display: flex; | ||||||
|  |         .list_item { | ||||||
|  |           text-align: center; | ||||||
|  |           width: 106px; | ||||||
|  |           height: 130px; | ||||||
|  |           margin-right: 48px; | ||||||
|  |           img { | ||||||
|  |             display: inline-block; | ||||||
|  |             width: 84px; | ||||||
|  |             height: 84px; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     .btnCancel { | ||||||
|  |       width: 100%; | ||||||
|  |       height: 120px; | ||||||
|  |       line-height: 120px; | ||||||
|  |       text-align: center; | ||||||
|  |       border-top: 2px solid #DDDDDD; | ||||||
|  |       margin-top: 80px; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   .btn { | ||||||
|  |     position: fixed; | ||||||
|  |     bottom: 0; | ||||||
|  |     left: 0; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 128px; | ||||||
|  |     padding: 24px 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     background: #FFF; | ||||||
|  |     .submitBtn { | ||||||
|  |       background: #1365DD; | ||||||
|  |       width: 100%; | ||||||
|  |       height: 80px; | ||||||
|  |       line-height: 80px; | ||||||
|  |       text-align: center; | ||||||
|  |       color: #FFF; | ||||||
|  |       border-radius: 8px; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										482
									
								
								src/project/huizhili/AppCooperationPropaganda/circleDetail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,482 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="circleDetail"> | ||||||
|  |     <!-- <AiTopFixed> | ||||||
|  |       <div class="tab-select"> | ||||||
|  |         <div | ||||||
|  |           class="item" | ||||||
|  |           :class="tabIndex == index ? 'active' : ''" | ||||||
|  |           v-for="(item, index) in tabs" | ||||||
|  |           :key="index" | ||||||
|  |           @click="tabClick(index)" | ||||||
|  |         > | ||||||
|  |           {{ item }}<span></span> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </AiTopFixed> --> | ||||||
|  |  | ||||||
|  |     <div class="content"> | ||||||
|  |       <div class="header"> | ||||||
|  |         <div class="header_left"> | ||||||
|  |           <div>{{ detail.taskTitle }} <span :class="detail.status==0? 'status0': detail.status==1? 'status1': detail.status==2? 'status2': | ||||||
|  |            detail.status == 3? 'status3':detail.status==4? 'status4': 'status5'">{{ $dict.getLabel('mstStatus', detail.status) }}</span></div> | ||||||
|  |           <div> | ||||||
|  |             创建时间: <span>{{ createTime }}</span>  | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <div class="header_right" @click="toDetail">查看详情</div> | ||||||
|  |       </div> | ||||||
|  |  | ||||||
|  |       <div class="pieEcharts"> | ||||||
|  |         <div class="pie_info"> | ||||||
|  |           <div class="tips" v-if="detail.status"> | ||||||
|  |             数据更新于<span>{{ info.remindTime }}</span> | ||||||
|  |           </div> | ||||||
|  |           <div class="pie_card"> | ||||||
|  |             <div id="pieEcharts"></div> | ||||||
|  |             <div class="pie_right"> | ||||||
|  |               <div> | ||||||
|  |                 <span>{{ | ||||||
|  |                   tabIndex == 0 ? "计划执行成员:" : "计划送达居民群:" | ||||||
|  |                 }}</span> | ||||||
|  |                 <span>{{ info.planCount || 0 }}</span> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <span>{{ | ||||||
|  |                   tabIndex == 0 ? "未执行成员:" : "未送达居民群:" | ||||||
|  |                 }}</span> | ||||||
|  |                 <span>{{ info.unExecutedCount || 0 }}</span> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <span>{{ | ||||||
|  |                   tabIndex == 0 ? "已执行成员:" : "已送达居民群:" | ||||||
|  |                 }}</span> | ||||||
|  |                 <span>{{ info.executedCount || 0 }}</span> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <span>{{ | ||||||
|  |                   tabIndex == 0 ? "无法执行成员:" : "无法送达居民群:" | ||||||
|  |                 }}</span> | ||||||
|  |                 <span>{{ info.cannotExecuteCount || 0 }}</span> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |           <div v-if="detail.status == 4" class="btn" @click="remindSend">提醒成员发送</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |  | ||||||
|  |       <div class="list_content"> | ||||||
|  |         <div class="list_card"> | ||||||
|  |           <div class="tab" v-show="update"> | ||||||
|  |             <u-subsection | ||||||
|  |               :list="subsection" | ||||||
|  |               mode="button" | ||||||
|  |               activeColor="#3c9cff" | ||||||
|  |               :current="subIndex" | ||||||
|  |               @change="changeSub" | ||||||
|  |             ></u-subsection> | ||||||
|  |           </div> | ||||||
|  |  | ||||||
|  |           <AiTable | ||||||
|  |             :data="tableData" | ||||||
|  |             :colConfigs="tabIndex == 0 ? colConfigs0 : colConfigs1" | ||||||
|  |             v-if="tableData.length"/> | ||||||
|  |           <AiEmpty v-if="!tableData.length" description="暂无数据"></AiEmpty> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import echarts from "echarts"; | ||||||
|  | export default { | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       tabs: ["成员统计", "居民群统计"], | ||||||
|  |       tabIndex: 0, | ||||||
|  |       pieEcharts: null, | ||||||
|  |       subIndex0: 0, | ||||||
|  |       subIndex1: 0, | ||||||
|  |       tableData: [], | ||||||
|  |       createTime: "", | ||||||
|  |       id: "", | ||||||
|  |       info: {}, | ||||||
|  |       current: 1, | ||||||
|  |       firstClickTime: "", | ||||||
|  |       currentClickTime: "", | ||||||
|  |       detail: {}, | ||||||
|  |  | ||||||
|  |       subsection: [ | ||||||
|  |         { name: "未执行" }, | ||||||
|  |         { name: "已执行" }, | ||||||
|  |         { name: "无法执行" }, | ||||||
|  |       ], | ||||||
|  |       update: true, | ||||||
|  |     }; | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     colConfigs0() { | ||||||
|  |       return [ | ||||||
|  |         { prop: "groupOwnerName", label: "成员" }, | ||||||
|  |         { label: "预计送达居民", prop: "groupCount" }, | ||||||
|  |       ]; | ||||||
|  |     }, | ||||||
|  |     colConfigs1() { | ||||||
|  |       return [ | ||||||
|  |         { label: "居民群", prop: "groupName" }, | ||||||
|  |         { label: "群人数", prop: "memberCount" }, | ||||||
|  |         { slot: "groupOwnerId", label: "群主" }, | ||||||
|  |       ]; | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   onLoad(o) { | ||||||
|  |     this.id = o.id; | ||||||
|  |     this.createTime = o.time; | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     tabClick(index) { | ||||||
|  |       this.tabIndex = index; | ||||||
|  |       if(this.tabIndex == 0) { | ||||||
|  |           this.subsection = [ | ||||||
|  |           { name: "未执行" }, | ||||||
|  |           { name: "已执行" }, | ||||||
|  |           { name: "无法执行" }, | ||||||
|  |         ] | ||||||
|  |         this.update0 = true | ||||||
|  |         this.update1 = false | ||||||
|  |         this.$forceUpdate() | ||||||
|  |       } else if(this.tabIndex == 1) { | ||||||
|  |           this.subsection = [ | ||||||
|  |           { name: "未送达" }, | ||||||
|  |           { name: "已送达" }, | ||||||
|  |           { name: "无法送达" }, | ||||||
|  |         ] | ||||||
|  |         this.update0 = false | ||||||
|  |         this.update1 = true | ||||||
|  |         this.$forceUpdate() | ||||||
|  |       } | ||||||
|  |       this.getStatistics(); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     getDetail() { | ||||||
|  |       this.$http | ||||||
|  |         .post(`/app/appmasssendingtask/queryDetailById?id=${this.id}`) | ||||||
|  |         .then((res) => { | ||||||
|  |           if (res?.data) { | ||||||
|  |             this.detail = res.data; | ||||||
|  |           } | ||||||
|  |         }); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     toDetail() { | ||||||
|  |       uni.navigateTo({ url: `./detail?id=${this.id}` }); | ||||||
|  |     }, | ||||||
|  |     // 提醒发送 | ||||||
|  |     remindSend() { | ||||||
|  |       uni.getSystemInfo({ | ||||||
|  |         success: (res)=>{ | ||||||
|  |           if(res.platform == "ios") { | ||||||
|  |             this.firstClickTime = new Date(this.detail.remindTime.replace(/-/g, "/")).getTime() || 0 | ||||||
|  |           } else { | ||||||
|  |             this.firstClickTime = new Date(this.detail.remindTime).getTime() || 0 | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |       this.currentClickTime = +new Date(); | ||||||
|  |       let time = this.currentClickTime - this.firstClickTime; | ||||||
|  |       if (time >= 3600000) { | ||||||
|  |         this.$http.post("/app/appmasssendingtask/remindSend", null, { | ||||||
|  |             params: { | ||||||
|  |               id: this.id, | ||||||
|  |             }, | ||||||
|  |           }) | ||||||
|  |           .then((res) => { | ||||||
|  |             if (res?.code == 0) { | ||||||
|  |               this.$u.toast("已提醒成员发送"); | ||||||
|  |               this.getDetail() | ||||||
|  |             } | ||||||
|  |           }) | ||||||
|  |           .catch(() => {}); | ||||||
|  |       } else { | ||||||
|  |         time = 3600000 - time; | ||||||
|  |         const min = Math.floor(time / 60000); // 分钟 | ||||||
|  |         let second = Math.floor(time / 1000); // 秒 | ||||||
|  |         second %= 60; | ||||||
|  |         let msg = ``; | ||||||
|  |         if (min > 0 && second > 0) { | ||||||
|  |           msg = `${min}分钟${second}秒后可以再次点击`; | ||||||
|  |         } else if (min > 0 && second <= 0) { | ||||||
|  |           msg = `${min}分钟后可以再次点击`; | ||||||
|  |         } else if (min <= 0 && second > 0) { | ||||||
|  |           msg = `${second}秒后可以再次点击`; | ||||||
|  |         } | ||||||
|  |         this.$u.toast(msg); | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     // 切换分段器 | ||||||
|  |     changeSub(index) { | ||||||
|  |       this.subIndex = index; | ||||||
|  |       this.getStatistics(); | ||||||
|  |     }, | ||||||
|  |     // 获取数据 | ||||||
|  |     getStatistics() { | ||||||
|  |       this.$http | ||||||
|  |         .post(`/app/appmasssendingtask/detailStatistics`, null, { | ||||||
|  |           params: { | ||||||
|  |             type: this.tabIndex, | ||||||
|  |             sendStatus: this.tabIndex==0? this.subIndex0: this.subIndex1, | ||||||
|  |             taskId: this.id, | ||||||
|  |             current: this.current, | ||||||
|  |             size: 3000, | ||||||
|  |           }, | ||||||
|  |         }) | ||||||
|  |         .then((res) => { | ||||||
|  |           if (res?.data) { | ||||||
|  |             this.info = res.data; | ||||||
|  |             this.tableData = res.data.executedList.records; | ||||||
|  |             setTimeout(()=>{ | ||||||
|  |               this.getPieEcharts(); | ||||||
|  |             }, 1000) | ||||||
|  |           } | ||||||
|  |         }); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     // 饼图 | ||||||
|  |     getPieEcharts() { | ||||||
|  |       this.pieEcharts = echarts.init(document.getElementById("pieEcharts")); | ||||||
|  |       this.pieEcharts.setOption({ | ||||||
|  |         tooltip: { | ||||||
|  |           show: false, | ||||||
|  |         }, | ||||||
|  |         color: ["#1684fc", "#ccc"], | ||||||
|  |         series: [ | ||||||
|  |           { | ||||||
|  |             name: this.tabIndex == 0 ? "任务完成率" : "群发送达率", | ||||||
|  |             type: "pie", | ||||||
|  |             radius: ["50%", "70%"], | ||||||
|  |             avoidLabelOverlap: false, | ||||||
|  |             label: { | ||||||
|  |               normal: { | ||||||
|  |                 show: false, | ||||||
|  |                 position: "center", | ||||||
|  |               }, | ||||||
|  |             }, | ||||||
|  |             labelLine: { | ||||||
|  |               show: false, | ||||||
|  |             }, | ||||||
|  |             data: [ | ||||||
|  |               { | ||||||
|  |                 value: this.info.executedCount, | ||||||
|  |                 name: "已执行成员", | ||||||
|  |                 label: { | ||||||
|  |                   normal: { | ||||||
|  |                     show: true, | ||||||
|  |                     formatter: ({ name, value }) => { | ||||||
|  |                       let num = value / this.info.planCount * 100 | ||||||
|  |                       if (this.tabIndex == 0) { | ||||||
|  |                         return num % 1==0? `{name|任务达成率\n\n}{value|${num}%}`: `{name|任务达成率\n\n}{value|${ num.toFixed(1) }%}`; | ||||||
|  |                       } else { | ||||||
|  |                         return num % 1==0? `{name|群发送达率\n\n}{value|${num}%}`: `{name|群发送达率\n\n}{value|${ num.toFixed(1) }%}`; | ||||||
|  |                       } | ||||||
|  |                     }, | ||||||
|  |                     textStyle: { | ||||||
|  |                       fontSize: 16, | ||||||
|  |                     }, | ||||||
|  |                     rich: { | ||||||
|  |                       name: { | ||||||
|  |                         color: "#999", | ||||||
|  |                          | ||||||
|  |                       }, | ||||||
|  |                       value: { | ||||||
|  |                         color: "#000000", | ||||||
|  |                         fontSize: 26, | ||||||
|  |                       }, | ||||||
|  |                     }, | ||||||
|  |                   }, | ||||||
|  |                 }, | ||||||
|  |               }, | ||||||
|  |               {  | ||||||
|  |                 value: this.info.planCount - this.info.executedCount , | ||||||
|  |                 name: "未执行成员" | ||||||
|  |               }, | ||||||
|  |             ], | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |       }); | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   onShow() { | ||||||
|  |     document.title = "群发居民群统计"; | ||||||
|  |     this.$dict.load("mstStatus") | ||||||
|  |     this.getStatistics(); | ||||||
|  |     this.getDetail(); | ||||||
|  |   }, | ||||||
|  |   mounted() { | ||||||
|  |     this.getPieEcharts(); | ||||||
|  |   }, | ||||||
|  | }; | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .circleDetail { | ||||||
|  |   ::v-deep .AiTopFixed .content { | ||||||
|  |     padding: 0; | ||||||
|  |   } | ||||||
|  |   ::v-deep .emptyWrap { | ||||||
|  |     border: 2px solid #d0d4dc; | ||||||
|  |     border-radius: 8px; | ||||||
|  |     padding-bottom: 20px; | ||||||
|  |   } | ||||||
|  |   .tab-select { | ||||||
|  |     width: 100%; | ||||||
|  |     height: 96px; | ||||||
|  |     line-height: 96px; | ||||||
|  |     background: #3975c6; | ||||||
|  |     display: flex; | ||||||
|  |  | ||||||
|  |     .item { | ||||||
|  |       flex: 1; | ||||||
|  |       text-align: center; | ||||||
|  |       font-size: 28px; | ||||||
|  |       font-family: PingFangSC-Regular, PingFang SC; | ||||||
|  |       color: #cddcf0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .active { | ||||||
|  |       font-family: PingFangSC-Medium, PingFang SC; | ||||||
|  |       font-weight: 500; | ||||||
|  |       position: relative; | ||||||
|  |       color: #fff; | ||||||
|  |  | ||||||
|  |       span { | ||||||
|  |         width: 48px; | ||||||
|  |         height: 4px; | ||||||
|  |         background: #fff; | ||||||
|  |         position: absolute; | ||||||
|  |         bottom: 14px; | ||||||
|  |         left: 50%; | ||||||
|  |         margin-left: -24px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .header { | ||||||
|  |     padding: 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     background: #fff; | ||||||
|  |     display: flex; | ||||||
|  |     align-items: center; | ||||||
|  |     .header_left { | ||||||
|  |       width: calc(100% - 120px); | ||||||
|  |       div:first-child { | ||||||
|  |         color: #000000; | ||||||
|  |         font-size: 32px; | ||||||
|  |         font-weight: 600; | ||||||
|  |         margin-bottom: 10px; | ||||||
|  |  | ||||||
|  |         span { | ||||||
|  |           display: inline-block; | ||||||
|  |           padding: 0 8px; | ||||||
|  |           border: 1px solid; | ||||||
|  |           border-radius: 6px; | ||||||
|  |           font-size: 26px; | ||||||
|  |           font-weight: normal; | ||||||
|  |           margin-left: 8px; | ||||||
|  |         } | ||||||
|  |         .status0 { | ||||||
|  |           color: #FFA938 !important; | ||||||
|  |         } | ||||||
|  |         .status1 { | ||||||
|  |           color: #FF6758 !important; | ||||||
|  |         } | ||||||
|  |         .status2 { | ||||||
|  |           color: #3399FF !important; | ||||||
|  |         } | ||||||
|  |         .status3 { | ||||||
|  |           color: #FF6758 !important; | ||||||
|  |         } | ||||||
|  |         .status4 { | ||||||
|  |           color: #3399FF !important; | ||||||
|  |         } | ||||||
|  |         .status5 { | ||||||
|  |           color: #1CCEB0 !important; | ||||||
|  |         } | ||||||
|  |         .status6 { | ||||||
|  |           color: #666666 !important; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       div:last-child { | ||||||
|  |         color: #666666; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     .header_right { | ||||||
|  |       width: 120px; | ||||||
|  |       color: #5297ff; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .pieEcharts { | ||||||
|  |     width: 100%; | ||||||
|  |     padding: 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     .pie_info { | ||||||
|  |       background: #fff; | ||||||
|  |       border-radius: 16px; | ||||||
|  |       padding-bottom: 20px; | ||||||
|  |       box-sizing: border-box; | ||||||
|  |       .tips { | ||||||
|  |         color: #666666; | ||||||
|  |         padding: 40px 32px 0 32px; | ||||||
|  |         box-sizing: border-box; | ||||||
|  |       } | ||||||
|  |       .pie_card { | ||||||
|  |         display: flex; | ||||||
|  |         width: 100%; | ||||||
|  |         align-items: center; | ||||||
|  |         #pieEcharts { | ||||||
|  |           width: 60%; | ||||||
|  |           height: 400px; | ||||||
|  |         } | ||||||
|  |         ::v-deep .emptyWrap { | ||||||
|  |           width: 60%; | ||||||
|  |         } | ||||||
|  |         .pie_right { | ||||||
|  |           width: 40%; | ||||||
|  |           padding-right: 30px; | ||||||
|  |           box-sizing: border-box; | ||||||
|  |           div { | ||||||
|  |             margin-bottom: 10px; | ||||||
|  |             display: flex; | ||||||
|  |             justify-content: space-between; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       .btn { | ||||||
|  |         margin: 0 auto; | ||||||
|  |         width: 90%; | ||||||
|  |         height: 80px; | ||||||
|  |         line-height: 80px; | ||||||
|  |         text-align: center; | ||||||
|  |         color: #fff; | ||||||
|  |         background: #3aa0ff; | ||||||
|  |         border-radius: 8px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .list_content { | ||||||
|  |     padding: 0 32px 32px 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |  | ||||||
|  |     .list_card { | ||||||
|  |       background: #fff; | ||||||
|  |       border-radius: 16px; | ||||||
|  |       padding: 30px 30px; | ||||||
|  |  | ||||||
|  |       .tab { | ||||||
|  |         margin-bottom: 34px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @@ -0,0 +1,501 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="cooperationDetail"> | ||||||
|  |     <AiTopFixed> | ||||||
|  |       <div class="tab-select"> | ||||||
|  |         <div | ||||||
|  |           class="item" | ||||||
|  |           :class="tabIndex == index ? 'active' : ''" | ||||||
|  |           v-for="(item, index) in tabs" | ||||||
|  |           :key="index" | ||||||
|  |           @click="tabClick(index)" | ||||||
|  |         > | ||||||
|  |           {{ item }}<span></span> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </AiTopFixed> | ||||||
|  |  | ||||||
|  |     <div class="content"> | ||||||
|  |       <div class="header"> | ||||||
|  |         <div class="header_left"> | ||||||
|  |           <div>{{ detail.taskTitle }} <span :class="detail.status==0? 'status0': detail.status==1? 'status1': detail.status==2? 'status2': | ||||||
|  |            detail.status == 3? 'status3':detail.status==4? 'status4': 'status5'">{{ $dict.getLabel('mstStatus', detail.status) }}</span></div> | ||||||
|  |           <div> | ||||||
|  |             创建时间: <span>{{ createTime }}</span>  | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <div class="header_right" @click="toDetail">查看详情</div> | ||||||
|  |       </div> | ||||||
|  |  | ||||||
|  |       <div class="pieEcharts"> | ||||||
|  |         <div class="pie_info"> | ||||||
|  |           <div class="tips" v-if="detail.status"> | ||||||
|  |             数据更新于<span>{{ info.remindTime }}</span> | ||||||
|  |           </div> | ||||||
|  |           <div class="pie_card"> | ||||||
|  |             <div id="pieEcharts"></div> | ||||||
|  |             <div class="pie_right"> | ||||||
|  |               <div> | ||||||
|  |                 <span>{{ | ||||||
|  |                   tabIndex == 0 ? "计划执行成员:" : "计划送达居民群:" | ||||||
|  |                 }}</span> | ||||||
|  |                 <span>{{ info.planCount || 0 }}</span> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <span>{{ | ||||||
|  |                   tabIndex == 0 ? "未执行成员:" : "未送达居民群:" | ||||||
|  |                 }}</span> | ||||||
|  |                 <span>{{ info.unExecutedCount || 0 }}</span> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <span>{{ | ||||||
|  |                   tabIndex == 0 ? "已执行成员:" : "已送达居民群:" | ||||||
|  |                 }}</span> | ||||||
|  |                 <span>{{ info.executedCount || 0 }}</span> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <span>{{ | ||||||
|  |                   tabIndex == 0 ? "无法执行成员:" : "无法送达居民群:" | ||||||
|  |                 }}</span> | ||||||
|  |                 <span>{{ info.cannotExecuteCount || 0 }}</span> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |           <div v-if="detail.status == 4" class="btn" @click="remindSend">提醒成员发送</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |  | ||||||
|  |       <div class="list_content"> | ||||||
|  |         <div class="list_card"> | ||||||
|  |           <div class="tab" v-show="update0"> | ||||||
|  |             <u-subsection | ||||||
|  |               :list="subsection0" | ||||||
|  |               mode="button" | ||||||
|  |               activeColor="#3c9cff" | ||||||
|  |               :current="subIndex0" | ||||||
|  |               @change="changeSub0" | ||||||
|  |             ></u-subsection> | ||||||
|  |           </div> | ||||||
|  |  | ||||||
|  |           <div class="tab" v-show="update1"> | ||||||
|  |             <u-subsection | ||||||
|  |               :list="subsection1" | ||||||
|  |               mode="button" | ||||||
|  |               activeColor="#3c9cff" | ||||||
|  |               :current="subIndex1" | ||||||
|  |               @change="changeSub1" | ||||||
|  |             ></u-subsection> | ||||||
|  |           </div> | ||||||
|  |  | ||||||
|  |           <AiTable | ||||||
|  |             :data="tableData" | ||||||
|  |             :colConfigs="tabIndex == 0 ? colConfigs0 : colConfigs1" | ||||||
|  |             v-if="tableData.length"/> | ||||||
|  |           <AiEmpty v-if="!tableData.length" description="暂无数据"></AiEmpty> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import echarts from "echarts"; | ||||||
|  | export default { | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       tabs: ["成员统计", "居民群统计"], | ||||||
|  |       tabIndex: 0, | ||||||
|  |       pieEcharts: null, | ||||||
|  |       subIndex0: 0, | ||||||
|  |       subIndex1: 0, | ||||||
|  |       tableData: [], | ||||||
|  |       createTime: "", | ||||||
|  |       id: "", | ||||||
|  |       info: {}, | ||||||
|  |       current: 1, | ||||||
|  |       firstClickTime: "", | ||||||
|  |       currentClickTime: "", | ||||||
|  |       detail: {}, | ||||||
|  |  | ||||||
|  |       subsection0: [ | ||||||
|  |         { name: "未执行" }, | ||||||
|  |         { name: "已执行" }, | ||||||
|  |         { name: "无法执行" }, | ||||||
|  |       ], | ||||||
|  |       subsection1: [ | ||||||
|  |         { name: "未送达" }, | ||||||
|  |         { name: "已送达" }, | ||||||
|  |         { name: "无法送达" }, | ||||||
|  |       ], | ||||||
|  |       update0: true, | ||||||
|  |       update1: false, | ||||||
|  |     }; | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     colConfigs0() { | ||||||
|  |       return [ | ||||||
|  |         { prop: "groupOwnerName", label: "成员" }, | ||||||
|  |         { label: "预计送达居民", prop: "groupCount" }, | ||||||
|  |       ]; | ||||||
|  |     }, | ||||||
|  |     colConfigs1() { | ||||||
|  |       return [ | ||||||
|  |         { label: "居民群", prop: "groupName" }, | ||||||
|  |         { label: "群人数", prop: "memberCount" }, | ||||||
|  |         { prop: "groupOwnerName", label: "群主" }, | ||||||
|  |       ]; | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   onLoad(o) { | ||||||
|  |     this.id = o.id; | ||||||
|  |     this.createTime = o.time; | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     tabClick(index) { | ||||||
|  |       this.tabIndex = index; | ||||||
|  |       if(this.tabIndex == 0) { | ||||||
|  |           this.subsection = [ | ||||||
|  |           { name: "未执行" }, | ||||||
|  |           { name: "已执行" }, | ||||||
|  |           { name: "无法执行" }, | ||||||
|  |         ] | ||||||
|  |         this.update0 = true | ||||||
|  |         this.update1 = false | ||||||
|  |         this.$forceUpdate() | ||||||
|  |       } else if(this.tabIndex == 1) { | ||||||
|  |           this.subsection = [ | ||||||
|  |           { name: "未送达" }, | ||||||
|  |           { name: "已送达" }, | ||||||
|  |           { name: "无法送达" }, | ||||||
|  |         ] | ||||||
|  |         this.update0 = false | ||||||
|  |         this.update1 = true | ||||||
|  |         this.$forceUpdate() | ||||||
|  |       } | ||||||
|  |       this.getStatistics(); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     getDetail() { | ||||||
|  |       this.$http | ||||||
|  |         .post(`/app/appmasssendingtask/queryDetailById?id=${this.id}`) | ||||||
|  |         .then((res) => { | ||||||
|  |           if (res?.data) { | ||||||
|  |             this.detail = res.data; | ||||||
|  |           } | ||||||
|  |         }); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     toDetail() { | ||||||
|  |       uni.navigateTo({ url: `./detail?id=${this.id}` }); | ||||||
|  |     }, | ||||||
|  |     // 提醒发送 | ||||||
|  |     remindSend() { | ||||||
|  |       uni.getSystemInfo({ | ||||||
|  |         success: (res)=>{ | ||||||
|  |           if(res.platform == "ios") { | ||||||
|  |             this.firstClickTime = new Date(this.detail.remindTime.replace(/-/g, "/")).getTime() || 0 | ||||||
|  |           } else { | ||||||
|  |             this.firstClickTime = new Date(this.detail.remindTime).getTime() || 0 | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |       this.currentClickTime = +new Date(); | ||||||
|  |       let time = this.currentClickTime - this.firstClickTime; | ||||||
|  |       if (time >= 3600000) { | ||||||
|  |         this.$http.post("/app/appmasssendingtask/remindSend", null, { | ||||||
|  |             params: { | ||||||
|  |               id: this.id, | ||||||
|  |             }, | ||||||
|  |           }) | ||||||
|  |           .then((res) => { | ||||||
|  |             if (res?.code == 0) { | ||||||
|  |               this.$u.toast("已提醒成员发送"); | ||||||
|  |               this.getDetail() | ||||||
|  |             } | ||||||
|  |           }) | ||||||
|  |           .catch(() => {}); | ||||||
|  |       } else { | ||||||
|  |         time = 3600000 - time; | ||||||
|  |         const min = Math.floor(time / 60000); // 分钟 | ||||||
|  |         let second = Math.floor(time / 1000); // 秒 | ||||||
|  |         second %= 60; | ||||||
|  |         let msg = ``; | ||||||
|  |         if (min > 0 && second > 0) { | ||||||
|  |           msg = `${min}分钟${second}秒后可以再次点击`; | ||||||
|  |         } else if (min > 0 && second <= 0) { | ||||||
|  |           msg = `${min}分钟后可以再次点击`; | ||||||
|  |         } else if (min <= 0 && second > 0) { | ||||||
|  |           msg = `${second}秒后可以再次点击`; | ||||||
|  |         } | ||||||
|  |         this.$u.toast(msg); | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     // 切换分段器 | ||||||
|  |     changeSub(index) { | ||||||
|  |       this.subIndex = index; | ||||||
|  |       this.getStatistics(); | ||||||
|  |     }, | ||||||
|  |     // 获取数据 | ||||||
|  |     getStatistics() { | ||||||
|  |       this.$http | ||||||
|  |         .post(`/app/appmasssendingtask/detailStatistics`, null, { | ||||||
|  |           params: { | ||||||
|  |             type: this.tabIndex, | ||||||
|  |             sendStatus: this.tabIndex==0? this.subIndex0: this.subIndex1, | ||||||
|  |             taskId: this.id, | ||||||
|  |             current: this.current, | ||||||
|  |             size: 3000, | ||||||
|  |           }, | ||||||
|  |         }) | ||||||
|  |         .then((res) => { | ||||||
|  |           if (res?.data) { | ||||||
|  |             this.info = res.data; | ||||||
|  |             this.tableData = res.data.executedList.records; | ||||||
|  |             setTimeout(()=>{ | ||||||
|  |               this.getPieEcharts(); | ||||||
|  |             }, 1000) | ||||||
|  |           } | ||||||
|  |         }); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     // 饼图 | ||||||
|  |     getPieEcharts() { | ||||||
|  |       this.pieEcharts = echarts.init(document.getElementById("pieEcharts")); | ||||||
|  |       this.pieEcharts.setOption({ | ||||||
|  |         tooltip: { | ||||||
|  |           show: false, | ||||||
|  |         }, | ||||||
|  |         color: ["#1684fc", "#ccc"], | ||||||
|  |         series: [ | ||||||
|  |           { | ||||||
|  |             name: this.tabIndex == 0 ? "任务完成率" : "群发送达率", | ||||||
|  |             type: "pie", | ||||||
|  |             radius: ["50%", "70%"], | ||||||
|  |             avoidLabelOverlap: false, | ||||||
|  |             label: { | ||||||
|  |               normal: { | ||||||
|  |                 show: false, | ||||||
|  |                 position: "center", | ||||||
|  |               }, | ||||||
|  |             }, | ||||||
|  |             labelLine: { | ||||||
|  |               show: false, | ||||||
|  |             }, | ||||||
|  |             data: [ | ||||||
|  |               { | ||||||
|  |                 value: this.info.executedCount, | ||||||
|  |                 name: "已执行成员", | ||||||
|  |                 label: { | ||||||
|  |                   normal: { | ||||||
|  |                     show: true, | ||||||
|  |                     formatter: ({ name, value }) => { | ||||||
|  |                       let num = value / this.info.planCount * 100 | ||||||
|  |                       if (this.tabIndex == 0) { | ||||||
|  |                         return num % 1==0? `{name|任务达成率\n\n}{value|${num}%}`: `{name|任务达成率\n\n}{value|${ num.toFixed(1) }%}`; | ||||||
|  |                       } else { | ||||||
|  |                         return num % 1==0? `{name|群发送达率\n\n}{value|${num}%}`: `{name|群发送达率\n\n}{value|${ num.toFixed(1) }%}`; | ||||||
|  |                       } | ||||||
|  |                     }, | ||||||
|  |                     textStyle: { | ||||||
|  |                       fontSize: 16, | ||||||
|  |                     }, | ||||||
|  |                     rich: { | ||||||
|  |                       name: { | ||||||
|  |                         color: "#999", | ||||||
|  |                          | ||||||
|  |                       }, | ||||||
|  |                       value: { | ||||||
|  |                         color: "#000000", | ||||||
|  |                         fontSize: 26, | ||||||
|  |                       }, | ||||||
|  |                     }, | ||||||
|  |                   }, | ||||||
|  |                 }, | ||||||
|  |               }, | ||||||
|  |               {  | ||||||
|  |                 value: this.info.planCount - this.info.executedCount , | ||||||
|  |                 name: "未执行成员" | ||||||
|  |               }, | ||||||
|  |             ], | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |       }); | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   onShow() { | ||||||
|  |     document.title = "群发居民群统计"; | ||||||
|  |     this.$dict.load("mstStatus") | ||||||
|  |     this.getStatistics(); | ||||||
|  |     this.getDetail(); | ||||||
|  |   }, | ||||||
|  |   mounted() { | ||||||
|  |     this.getPieEcharts(); | ||||||
|  |   }, | ||||||
|  | }; | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .cooperationDetail { | ||||||
|  |   ::v-deep .AiTopFixed .content { | ||||||
|  |     padding: 0; | ||||||
|  |   } | ||||||
|  |   ::v-deep .emptyWrap { | ||||||
|  |     border: 2px solid #d0d4dc; | ||||||
|  |     border-radius: 8px; | ||||||
|  |     padding-bottom: 20px; | ||||||
|  |   } | ||||||
|  |   .tab-select { | ||||||
|  |     width: 100%; | ||||||
|  |     height: 96px; | ||||||
|  |     line-height: 96px; | ||||||
|  |     background: #3975c6; | ||||||
|  |     display: flex; | ||||||
|  |  | ||||||
|  |     .item { | ||||||
|  |       flex: 1; | ||||||
|  |       text-align: center; | ||||||
|  |       font-size: 28px; | ||||||
|  |       font-family: PingFangSC-Regular, PingFang SC; | ||||||
|  |       color: #cddcf0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .active { | ||||||
|  |       font-family: PingFangSC-Medium, PingFang SC; | ||||||
|  |       font-weight: 500; | ||||||
|  |       position: relative; | ||||||
|  |       color: #fff; | ||||||
|  |  | ||||||
|  |       span { | ||||||
|  |         width: 48px; | ||||||
|  |         height: 4px; | ||||||
|  |         background: #fff; | ||||||
|  |         position: absolute; | ||||||
|  |         bottom: 14px; | ||||||
|  |         left: 50%; | ||||||
|  |         margin-left: -24px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .header { | ||||||
|  |     padding: 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     background: #fff; | ||||||
|  |     display: flex; | ||||||
|  |     align-items: center; | ||||||
|  |     .header_left { | ||||||
|  |       width: calc(100% - 120px); | ||||||
|  |       div:first-child { | ||||||
|  |         color: #000000; | ||||||
|  |         font-size: 32px; | ||||||
|  |         font-weight: 600; | ||||||
|  |         margin-bottom: 10px; | ||||||
|  |  | ||||||
|  |         span { | ||||||
|  |           display: inline-block; | ||||||
|  |           padding: 0 8px; | ||||||
|  |           border: 1px solid; | ||||||
|  |           border-radius: 6px; | ||||||
|  |           font-size: 26px; | ||||||
|  |           font-weight: normal; | ||||||
|  |           margin-left: 8px; | ||||||
|  |         } | ||||||
|  |         .status0 { | ||||||
|  |           color: #FFA938 !important; | ||||||
|  |         } | ||||||
|  |         .status1 { | ||||||
|  |           color: #FF6758 !important; | ||||||
|  |         } | ||||||
|  |         .status2 { | ||||||
|  |           color: #3399FF !important; | ||||||
|  |         } | ||||||
|  |         .status3 { | ||||||
|  |           color: #FF6758 !important; | ||||||
|  |         } | ||||||
|  |         .status4 { | ||||||
|  |           color: #3399FF !important; | ||||||
|  |         } | ||||||
|  |         .status5 { | ||||||
|  |           color: #1CCEB0 !important; | ||||||
|  |         } | ||||||
|  |         .status6 { | ||||||
|  |           color: #666666 !important; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       div:last-child { | ||||||
|  |         color: #666666; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     .header_right { | ||||||
|  |       width: 120px; | ||||||
|  |       color: #5297ff; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .pieEcharts { | ||||||
|  |     width: 100%; | ||||||
|  |     padding: 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     .pie_info { | ||||||
|  |       background: #fff; | ||||||
|  |       border-radius: 16px; | ||||||
|  |       padding-bottom: 20px; | ||||||
|  |       box-sizing: border-box; | ||||||
|  |       .tips { | ||||||
|  |         color: #666666; | ||||||
|  |         padding: 40px 32px 0 32px; | ||||||
|  |         box-sizing: border-box; | ||||||
|  |       } | ||||||
|  |       .pie_card { | ||||||
|  |         display: flex; | ||||||
|  |         width: 100%; | ||||||
|  |         align-items: center; | ||||||
|  |         #pieEcharts { | ||||||
|  |           width: 60%; | ||||||
|  |           height: 400px; | ||||||
|  |         } | ||||||
|  |         ::v-deep .emptyWrap { | ||||||
|  |           width: 60%; | ||||||
|  |         } | ||||||
|  |         .pie_right { | ||||||
|  |           width: 40%; | ||||||
|  |           padding-right: 30px; | ||||||
|  |           box-sizing: border-box; | ||||||
|  |           div { | ||||||
|  |             margin-bottom: 10px; | ||||||
|  |             display: flex; | ||||||
|  |             justify-content: space-between; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       .btn { | ||||||
|  |         margin: 0 auto; | ||||||
|  |         width: 90%; | ||||||
|  |         height: 80px; | ||||||
|  |         line-height: 80px; | ||||||
|  |         text-align: center; | ||||||
|  |         color: #fff; | ||||||
|  |         background: #3aa0ff; | ||||||
|  |         border-radius: 8px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .list_content { | ||||||
|  |     padding: 0 32px 32px 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |  | ||||||
|  |     .list_card { | ||||||
|  |       background: #fff; | ||||||
|  |       border-radius: 16px; | ||||||
|  |       padding: 30px 30px; | ||||||
|  |  | ||||||
|  |       .tab { | ||||||
|  |         margin-bottom: 34px; | ||||||
|  |         ::v-deep .u-subsection uni-view{ | ||||||
|  |           background: #eeef !important; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										318
									
								
								src/project/huizhili/AppCooperationPropaganda/detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,318 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="detail"> | ||||||
|  |     <div class="task"> | ||||||
|  |       <div class="task_title">群发客户群</div> | ||||||
|  |       <div class="task_content"> | ||||||
|  |         <div class="item"> | ||||||
|  |           <span>任务名称</span> | ||||||
|  |           <span>{{ data.taskTitle }}</span> | ||||||
|  |         </div> | ||||||
|  |         <div class="item"> | ||||||
|  |           <span>创建人</span> | ||||||
|  |           <span> | ||||||
|  |             {{ data.createUserName }} | ||||||
|  |           </span> | ||||||
|  |         </div> | ||||||
|  |         <div class="item" v-if="data.enableExamine == 1"> | ||||||
|  |           <span>审批人</span> | ||||||
|  |           <span> | ||||||
|  |             <span v-for="(item, index) in approver" :key="index" style="color: #333;"> | ||||||
|  |               {{ item.examineUserName }} | ||||||
|  |               <span v-show="index < approver.length - 1">、</span> | ||||||
|  |             </span> | ||||||
|  |           </span> | ||||||
|  |         </div> | ||||||
|  |         <div class="item"> | ||||||
|  |           <span>所在部门</span> | ||||||
|  |           <span style="display: flex;"> | ||||||
|  |             <div v-if="data.createUserDeptName">{{ data.createUserDeptName }}</div> | ||||||
|  |           </span> | ||||||
|  |         </div> | ||||||
|  |         <div class="item"> | ||||||
|  |           <span>群发时间</span> | ||||||
|  |           <span>{{ data.choiceTime }}</span> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div class="task_results" v-if="data.enableExamine == 1"> | ||||||
|  |         <img v-if="data.status == 1" src="./images/refuse.png" alt=""> | ||||||
|  |         <img v-if="data.status == 2" src="./images/pass.png" alt=""> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |     <div class="info"> | ||||||
|  |       <div class="scope"> | ||||||
|  |         <span>群发范围</span> | ||||||
|  |         <span v-if="data.sendScope==0">全部{{ data.receiveGroupCount || 0}}个居民群</span> | ||||||
|  |         <span v-if="data.sendScope==1 || data.sendScope==2">按条件筛选的{{ data.receiveGroupCount || 0}}个居民群</span> | ||||||
|  |       </div> | ||||||
|  |       <div class="content"> | ||||||
|  |         <p>群发内容</p> | ||||||
|  |         <div> | ||||||
|  |           <!-- 文本 --> | ||||||
|  |           <div class="textarea" v-show="content.length">{{ content }}</div> | ||||||
|  |           <!-- 图片 --> | ||||||
|  |           <div class="pictures" v-show="picList.length"> | ||||||
|  |             <image v-for="(item, index) in picList" :key="index" :src="item.imgPicUrl" @click.stop="previewImages(picList, item.imgPicUrl)"/> | ||||||
|  |           </div> | ||||||
|  |           <!-- 视频 --> | ||||||
|  |           <div class="video" v-show="videoList.length"> | ||||||
|  |             <video v-for="(item, index) in videoList" :key="index" :src="item.imgPicUrl"/> | ||||||
|  |           </div> | ||||||
|  |           <!-- 文件 --> | ||||||
|  |           <div class="file" v-show="fileList.length"> | ||||||
|  |             <div class="file_item" v-for="(item,index) in fileList" :key="index" @click="prevFile(item.sysFile)"> | ||||||
|  |               <img src="./images/files.png" alt=""> | ||||||
|  |               <div>{{ item.sysFile.name }}</div> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |           <!-- 网页 --> | ||||||
|  |           <div class="webpage" v-show="webpage.length"> | ||||||
|  |             <p>链接地址</p> | ||||||
|  |             <a v-for="(item, index) in webpage" :key="index" :href="item.linkUrl"> | ||||||
|  |               <div v-if="item.linkTitle">{{item.linkTitle}}</div> | ||||||
|  |               <div v-else>{{ item.linkUrl }}</div> | ||||||
|  |             </a> | ||||||
|  |           </div> | ||||||
|  |           <!-- 小程序 --> | ||||||
|  |           <div class="miniapp" v-show="miniapp.length"> | ||||||
|  |             <p>小程序</p> | ||||||
|  |             <div v-for="(item, index) in miniapp" :key="index">{{item.mpTitle}}</div> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |     <div class="btn" v-if="data.status==0 && data.haveExaminPower"> | ||||||
|  |       <div class="refuse" @click="refuseBtn">审核拒绝</div> | ||||||
|  |       <div class="pass" @click="passBtn">审核通过</div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import { mapState ,mapActions } from "vuex"; | ||||||
|  | export default { | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       id: "", | ||||||
|  |       data: {}, | ||||||
|  |       content: '', | ||||||
|  |       picList: [], | ||||||
|  |       videoList: [], | ||||||
|  |       fileList: [], | ||||||
|  |       webpage: [], | ||||||
|  |       miniapp: [], | ||||||
|  |       pictres: [], | ||||||
|  |       options: '', | ||||||
|  |       approver: [],  //审批人 | ||||||
|  |     }  | ||||||
|  |   }, | ||||||
|  |   onLoad(o) { | ||||||
|  |     this.id = o.id | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     ...mapState(['user']) | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     getDetail() { | ||||||
|  |       this.$http.post(`/app/appmasssendingtask/queryDetailById?id=${this.id}`).then(res=> { | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.data = res.data | ||||||
|  |           this.content = res.data.contents.filter(v=> v.msgType == 0)?.[0].content | ||||||
|  |           this.picList = res.data.contents.filter(v=> v.msgType == 1) | ||||||
|  |           this.videoList = res.data.contents.filter(v=> v.msgType == 2) | ||||||
|  |           this.fileList = res.data.contents.filter(v=> v.msgType == 3) | ||||||
|  |           this.webpage = res.data.contents.filter(v=> v.msgType == 4) | ||||||
|  |           this.miniapp = res.data.contents.filter(v=> v.msgType == 5) | ||||||
|  |           this.approver = res.data.examines | ||||||
|  |           // if(res.data.status==1) {  // 拒绝 | ||||||
|  |           //   this.approver = res.data.examines.filter(e=> e.examineStatus == 2) | ||||||
|  |           // } else {  // 通过 | ||||||
|  |           //   this.approver = res.data.examines | ||||||
|  |           // } | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     previewImages(images, img) { | ||||||
|  |       uni.previewImage({ | ||||||
|  |         urls: images.map(v => v.imgPicUrl), | ||||||
|  |         current: img | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     ...mapActions(['previewFile']), | ||||||
|  |     prevFile(file) { | ||||||
|  |       this.$loading() | ||||||
|  |       this.previewFile({ ...file }).then(()=>{ | ||||||
|  |         this.$hideLoading() | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     // 拒绝 | ||||||
|  |     refuseBtn() { | ||||||
|  |       this.pass = 0 | ||||||
|  |       this.$confirm('确认审核拒绝该任务?').then(() => { | ||||||
|  |         this.examine() | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     // 通过 | ||||||
|  |     passBtn() { | ||||||
|  |       this.pass = 1 | ||||||
|  |       this.$confirm('确认审核通过该任务?').then(() => { | ||||||
|  |         this.examine() | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     examine() { | ||||||
|  |       this.$http.post(`/app/appmasssendingtask/examine`,null,{ | ||||||
|  |         params: { | ||||||
|  |           pass: this.pass, | ||||||
|  |           id: this.id, | ||||||
|  |           options: this.options | ||||||
|  |         } | ||||||
|  |       }).then(res => { | ||||||
|  |         if(res?.code == 0) { | ||||||
|  |           if(this.pass == 0) { | ||||||
|  |             this.$u.toast('任务已拒绝') | ||||||
|  |           } else if(this.pass == 1) { | ||||||
|  |             this.$u.toast('任务审核通过') | ||||||
|  |           } | ||||||
|  |           this.getDetail() | ||||||
|  |         } | ||||||
|  |       }).catch(()=> { | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   onShow() { | ||||||
|  |     document.title = "群发审批" | ||||||
|  |     this.getDetail() | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .detail { | ||||||
|  |   padding: 32px 32px 140px 32px; | ||||||
|  |   box-sizing: border-box; | ||||||
|  |   .task { | ||||||
|  |     position: relative; | ||||||
|  |     margin-bottom: 24px; | ||||||
|  |     background: #FFF; | ||||||
|  |     border-radius: 8px; | ||||||
|  |     box-shadow: inset 0px -1px 0px 0px #DDDDDD; | ||||||
|  |     .task_title { | ||||||
|  |       padding: 26px 32px; | ||||||
|  |       box-sizing: border-box; | ||||||
|  |       border-bottom: 2px solid #DDDDDD; | ||||||
|  |     } | ||||||
|  |     .task_content { | ||||||
|  |       padding: 0 32px 26px 32px; | ||||||
|  |       box-sizing: border-box; | ||||||
|  |       .item { | ||||||
|  |         display: flex; | ||||||
|  |         padding-top: 26px; | ||||||
|  |         box-sizing: border-box; | ||||||
|  |         span:first-child { | ||||||
|  |           width: 160px; | ||||||
|  |           color: #999999; | ||||||
|  |         } | ||||||
|  |         span:last-child { | ||||||
|  |           width: calc(100% - 160px); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     .task_results { | ||||||
|  |       position: absolute; | ||||||
|  |       right: 30px; | ||||||
|  |       top: 30px; | ||||||
|  |       img { | ||||||
|  |         width: 160px; | ||||||
|  |         height: 130px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .info { | ||||||
|  |     background: #FFF; | ||||||
|  |     border-radius: 8px; | ||||||
|  |     padding: 26px 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     .scope { | ||||||
|  |       display: flex; | ||||||
|  |       margin-bottom: 16px; | ||||||
|  |       span:first-child { | ||||||
|  |         width: 160px; | ||||||
|  |         color: #999; | ||||||
|  |       } | ||||||
|  |       span:last-child { | ||||||
|  |         width: calc(100% - 160px); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     .content { | ||||||
|  |       p { | ||||||
|  |         color: #999; | ||||||
|  |       } | ||||||
|  |       .textarea, | ||||||
|  |       .pictures, | ||||||
|  |       .video, | ||||||
|  |       .file, | ||||||
|  |       .webpage, | ||||||
|  |       .miniapp { | ||||||
|  |         background: #F9F9F9; | ||||||
|  |         border-radius: 4px; | ||||||
|  |         padding: 20px; | ||||||
|  |         box-sizing: border-box; | ||||||
|  |         margin-top: 26px; | ||||||
|  |       } | ||||||
|  |       .pictures { | ||||||
|  |         margin-top: 16px; | ||||||
|  |         image { | ||||||
|  |           width: 190px; | ||||||
|  |           height: 190px; | ||||||
|  |           margin-right: 4px; | ||||||
|  |           margin-bottom: 4px; | ||||||
|  |         } | ||||||
|  |         image:nth-child(3n) { | ||||||
|  |           margin-right: 0; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       .video { | ||||||
|  |         video { | ||||||
|  |           height: 300px; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       .file { | ||||||
|  |         .file_item { | ||||||
|  |           display: flex; | ||||||
|  |           align-items: center; | ||||||
|  |           img { | ||||||
|  |             width: 96px; | ||||||
|  |             height: 96px; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .btn { | ||||||
|  |     position: fixed; | ||||||
|  |     display: flex; | ||||||
|  |     bottom: 0; | ||||||
|  |     left: 0; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 112px; | ||||||
|  |     line-height: 112px; | ||||||
|  |     font-size: 32px; | ||||||
|  |     z-index: 9; | ||||||
|  |     .refuse { | ||||||
|  |       width: 40%; | ||||||
|  |       height: 100%; | ||||||
|  |       background: #FFF; | ||||||
|  |       color: #FF4466; | ||||||
|  |       text-align: center; | ||||||
|  |     } | ||||||
|  |     .pass { | ||||||
|  |       width: 60%; | ||||||
|  |       height: 100%; | ||||||
|  |       background: #3975C6; | ||||||
|  |       color: #FFF; | ||||||
|  |       text-align: center; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										
											BIN
										
									
								
								src/project/huizhili/AppCooperationPropaganda/images/files.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 955 B | 
| After Width: | Height: | Size: 1.2 KiB | 
| After Width: | Height: | Size: 1.1 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/project/huizhili/AppCooperationPropaganda/images/pass.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 15 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/project/huizhili/AppCooperationPropaganda/images/refuse.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 15 KiB | 
| After Width: | Height: | Size: 373 B | 
| After Width: | Height: | Size: 663 B | 
							
								
								
									
										
											BIN
										
									
								
								src/project/huizhili/AppCooperationPropaganda/images/tx@2x.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.4 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/project/huizhili/AppCooperationPropaganda/images/xz.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.5 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/project/huizhili/AppCooperationPropaganda/images/xzh.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.7 KiB | 
							
								
								
									
										219
									
								
								src/project/huizhili/AppCooperationPropaganda/scopedSelect.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,219 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="scopedSelect"> | ||||||
|  |     <div class="item"> | ||||||
|  |       <div>添加人</div> | ||||||
|  |       <div @click="selectUser"> | ||||||
|  |         <!-- <span v-if="selectedUser.length || deptListArr.length">已选择{{ selectedUser.length || deptListArr.length }} | ||||||
|  |           <span v-if="selectedUser.length">个网格</span><span v-if="deptListArr.length">个部门</span></span> --> | ||||||
|  |         <div v-if="type == 1" style="display: inline-block;"> | ||||||
|  |           <span v-if="deptListArr.length">已选择{{ deptListArr.length }}个部门</span> | ||||||
|  |           <span class="color_gray" v-else>请选择</span> | ||||||
|  |         </div> | ||||||
|  |         <div v-if="type == 2" style="display: inline-block;"> | ||||||
|  |           <span v-if="selectedUser.length">已选择{{ selectedUser.length }}个网格</span> | ||||||
|  |           <span class="color_gray" v-else>请选择</span> | ||||||
|  |         </div> | ||||||
|  |         <u-icon name="arrow-right" color="#CCD0D3"></u-icon> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <div class="item" v-if="['Residents', 'CircleOfFriends'].includes(sendType)"> | ||||||
|  |       <div>包含标签</div> | ||||||
|  |       <div @click="toTagsList(0)"> | ||||||
|  |         <span v-if="circleTags.length || ResidentTags.length">已选择{{ circleTags.length || ResidentTags.length }}个标签</span> | ||||||
|  |         <span class="color_gray" v-else>请选择</span> | ||||||
|  |         <u-icon name="arrow-right" color="#CCD0D3"></u-icon> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <div class="item" v-if="['Residents', 'CircleOfFriends'].includes(sendType)"> | ||||||
|  |       <div>剔除标签</div> | ||||||
|  |       <div @click="toTagsList(1)"> | ||||||
|  |         <span v-if="circleTagsRemove.length || ResidentTagsRemove.length">已剔除{{ circleTagsRemove.length || ResidentTagsRemove.length }}个标签</span> | ||||||
|  |         <span class="color_gray" v-else>请选择</span> | ||||||
|  |         <u-icon name="arrow-right" color="#CCD0D3"></u-icon> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <div class="item" v-if="['Residents'].includes(sendType)"> | ||||||
|  |       <div>添加时间</div> | ||||||
|  |       <div @click="showCalendar = true"> | ||||||
|  |         <span v-if="!startTime.length && !endTime.length" class="color_gray">请选择</span> | ||||||
|  |         <span v-if="startTime.length && endTime.length">{{ startTime }} - {{ endTime }}</span> | ||||||
|  |         <u-icon name="arrow-right" color="#CCD0D3"></u-icon> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <div class="items" v-if="['Residents'].includes(sendType)"> | ||||||
|  |       <div>性别</div> | ||||||
|  |       <div class="sex"> | ||||||
|  |         <span :class="sex == 0? 'active':''" @click="sex = 0">全部</span> | ||||||
|  |         <span :class="sex == 1? 'active':''" @click="sex = 1">男</span> | ||||||
|  |         <span :class="sex == 2? 'active':''" @click="sex = 2">女</span> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <u-calendar v-model="showCalendar" mode="range" @change="selectDate"></u-calendar> | ||||||
|  |  | ||||||
|  |     <div class="btn"> | ||||||
|  |       <div class="submitBtn" @click="submit">确定</div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import { mapActions } from "vuex"; | ||||||
|  | export default { | ||||||
|  |   name: "scopedSelect", | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       type: "", | ||||||
|  |       sendType: '', | ||||||
|  |       showCalendar: false, | ||||||
|  |       startTime: '', | ||||||
|  |       endTime: '', | ||||||
|  |       sex: 0,  // 性别:0-女、1-男、2-全部 | ||||||
|  |       userList: [], | ||||||
|  |       deptListArr: [], | ||||||
|  |       selectedUser: [], | ||||||
|  |       circleTags: [], // 朋友圈包含标签 | ||||||
|  |       circleTagsRemove: [], // 朋友圈剔除标签 | ||||||
|  |       ResidentTags: [],  // 居民包含标签 | ||||||
|  |       ResidentTagsRemove: [],  // 居民剔除标签 | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     ...mapActions(['selectEnterpriseContact']), | ||||||
|  |     // 选人 | ||||||
|  |     selectUser() { | ||||||
|  |       if(this.type == "1") {  // 部门 | ||||||
|  |         this.getDeptUser() | ||||||
|  |       } else if(this.type == "2") {  // 网格 | ||||||
|  |         uni.navigateTo({url: `./selectGridMember`}) | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     getDeptUser() { | ||||||
|  |       this.selectEnterpriseContact({ | ||||||
|  |         fromDepartmentId: 0, | ||||||
|  |         mode: "multi", | ||||||
|  |         type: ["department"], | ||||||
|  |         selectedUserIds: this.deptListArr?.map(e => e.id) | ||||||
|  |       }).then((res)=>{ | ||||||
|  |           if(res?.userList) { | ||||||
|  |             this.deptListArr = res.userList | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       ).catch((err) => { | ||||||
|  |         console.log(err); | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     //  选择包含、剔除的标签 0包含  1剔除 | ||||||
|  |     toTagsList(e) { | ||||||
|  |       uni.navigateTo({url: `./tagsList?type=${e}&sendType=${this.sendType}`}) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     // 选时间范围 | ||||||
|  |     selectDate(e) { | ||||||
|  |       this.startTime = e.startDate | ||||||
|  |       this.endTime = e.endDate | ||||||
|  |     }, | ||||||
|  |     submit() { | ||||||
|  |       uni.setStorageSync('gender',this.sex) | ||||||
|  |       uni.setStorageSync('startTime', this.startTime) | ||||||
|  |       uni.setStorageSync('endTime', this.endTime) | ||||||
|  |       uni.setStorageSync('deptList',this.deptListArr) | ||||||
|  |       uni.navigateBack() | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   onLoad(o) { | ||||||
|  |     this.type = o.type; | ||||||
|  |     this.sendType = o.sendType; | ||||||
|  |     document.title = this.type == 1? '按部门选择':'按网格选择' | ||||||
|  |   }, | ||||||
|  |   onShow() { | ||||||
|  |     // 网格或者部门 | ||||||
|  |     this.selectedUser = uni.getStorageSync('girdSelect') | ||||||
|  |     this.deptListArr = uni.getStorageSync('deptList') | ||||||
|  |     // 添加时间 | ||||||
|  |     this.startTime = uni.getStorageSync('startTime') | ||||||
|  |     this.endTime = uni.getStorageSync('endTime') | ||||||
|  |     // 标签 | ||||||
|  |     if(this.sendType == 'Residents') {  | ||||||
|  |       this.ResidentTags = uni.getStorageSync('ResidentTags') // 居民包含 | ||||||
|  |       this.ResidentTagsRemove = uni.getStorageSync('ResidentTagsRemove') // 居民剔除 | ||||||
|  |     } else if(this.sendType == 'CircleOfFriends') { | ||||||
|  |       this.circleTags = uni.getStorageSync('circleTags') // 朋友圈包含 | ||||||
|  |       this.circleTagsRemove = uni.getStorageSync('circleTagsRemove') // 朋友圈剔除 | ||||||
|  |     } | ||||||
|  |     // 性别 | ||||||
|  |     this.sex = uni.getStorageSync('gender') | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .scopedSelect { | ||||||
|  |   .item { | ||||||
|  |     padding: 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     background: #FFF; | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: space-between; | ||||||
|  |     box-shadow: inset 0px -1px 0px 0px #DDDDDD; | ||||||
|  |     margin-bottom: 8px; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .items { | ||||||
|  |     padding: 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     background: #FFF; | ||||||
|  |     .sex { | ||||||
|  |       margin-top: 32px; | ||||||
|  |       span { | ||||||
|  |         display: inline-block; | ||||||
|  |         width: 30%; | ||||||
|  |         border: 2px solid #CCCCCC; | ||||||
|  |         text-align: center; | ||||||
|  |         padding: 20px 0; | ||||||
|  |         box-sizing: border-box; | ||||||
|  |         margin-right: 16px; | ||||||
|  |         border-radius: 8px; | ||||||
|  |       } | ||||||
|  |       .active { | ||||||
|  |         background: #1365DD; | ||||||
|  |         color: #FFF; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .color_gray { | ||||||
|  |     color: #CCD0D3; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .btn { | ||||||
|  |     position: fixed; | ||||||
|  |     bottom: 0; | ||||||
|  |     left: 0; | ||||||
|  |     background: #FFF; | ||||||
|  |     display: flex; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 128px; | ||||||
|  |     padding: 24px 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |  | ||||||
|  |     .submitBtn { | ||||||
|  |       flex: 1; | ||||||
|  |       height: 80px; | ||||||
|  |       line-height: 80px; | ||||||
|  |       text-align: center; | ||||||
|  |       border-radius: 8px; | ||||||
|  |       border: 2px solid #CCCCCC; | ||||||
|  |       background: #1365DD; | ||||||
|  |       color: #FFF; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @@ -0,0 +1,271 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="selectGridMember"> | ||||||
|  |     <div class="header-middle"> | ||||||
|  |       <div class="hint"> | ||||||
|  |         <span v-for="(item, index) in selectGridPath" :key="index"><span v-if="index" style="margin:0 4px;">/</span><span | ||||||
|  |             style="color:#3F8DF5" @click="girdNameClick(item, index)">{{ item.girdName }}</span></span> | ||||||
|  |       </div> | ||||||
|  |       <div class="cards" v-for="item in treeList" :key="item.id" @click="itemClick(item)"> | ||||||
|  |         <div class="imges"> | ||||||
|  |           <img src="./images/xzh.png" alt="" class="imgselect" v-if="item.isChecked" | ||||||
|  |                @click.stop="girdClick(item)"/> | ||||||
|  |           <img src="./images/xz.png" alt="" class="imgselect" v-else | ||||||
|  |                @click.stop="girdClick(item)"/> | ||||||
|  |           <img src="./images/gird--select-icon.png" alt="" class="avatras"/> | ||||||
|  |         </div> | ||||||
|  |         <div class="rightes"> | ||||||
|  |           <div class="applicationNames">{{ item.girdName }}</div> | ||||||
|  |           <img src="./images/right-icon.png" alt="" class="imgs"/> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <AiEmpty description="暂无数据" v-if="!hasData"/> | ||||||
|  |     </div> | ||||||
|  |     <div class="subBtn" @click="submit"> | ||||||
|  |       <div>确定选择</div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   // 选择网格 | ||||||
|  |   name: "selectGridMember", | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       selected: {}, | ||||||
|  |       allData: null, | ||||||
|  |       treeList: [], | ||||||
|  |       selectGridPath: [], | ||||||
|  |       userList: [], | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     hasData() { | ||||||
|  |       return this.treeList?.length > 0 || this.userList?.length > 0 | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   onLoad() { | ||||||
|  |     this.selected.id = this.$route.query.id | ||||||
|  |     this.getAllGrids() | ||||||
|  |     this.selected = uni.getStorageSync('girdSelect') || [] | ||||||
|  |   }, | ||||||
|  |   onShow() { | ||||||
|  |     document.title = '选择人员' | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     getAllGrids() { | ||||||
|  |       this.$http.post('/app/appgirdinfo/listByInfo').then((res) => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           let parents = res.data.map(e => e.parentGirdId) | ||||||
|  |           this.allData = res.data.map(e => ({...e, hasChildren: parents.includes(e.id)})) | ||||||
|  |           this.gridInit() | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     gridInit() { | ||||||
|  |       this.treeList = this.allData.filter(e => !e.parentGirdId) | ||||||
|  |       this.selectGridPath = [{girdName: "可选范围", id: ''}] | ||||||
|  |     }, | ||||||
|  |     itemClick({id,girdName}) { | ||||||
|  |       this.selectGridPath.push({girdName,id}) | ||||||
|  |       this.getGridsAndUsersByParent(id) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     getGridsAndUsersByParent(id) { | ||||||
|  |       this.treeList = this.allData.filter(e => (e.parentGirdId == id)).map(v=> ({...v,isChecked:this.selected.find(i=>i.id == v.id)})) | ||||||
|  |       this.treeList  | ||||||
|  |       this.$forceUpdate() | ||||||
|  |     }, | ||||||
|  |     girdNameClick(row, index) { | ||||||
|  |       this.userList = [] | ||||||
|  |       if (!index) { //第一级别 | ||||||
|  |         this.gridInit() | ||||||
|  |       } else { | ||||||
|  |         let length = this.selectGridPath.length - index | ||||||
|  |         this.selectGridPath.splice(index, length) | ||||||
|  |         this.getGridsAndUsersByParent(row.id) | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     girdClick(row) { | ||||||
|  |       row.isChecked = !!!row.isChecked | ||||||
|  |       if(row.isChecked) { | ||||||
|  |         this.selected.push(row) | ||||||
|  |       } else { | ||||||
|  |         let index=this.selected.findIndex(item=>row.id===item.id) | ||||||
|  |         index >= 0 && this.selected.splice(index, 1) | ||||||
|  |       } | ||||||
|  |       uni.setStorageSync('girdSelect', this.selected) | ||||||
|  |       this.$forceUpdate() | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     submit() { | ||||||
|  |       if (!this.selected.length) { | ||||||
|  |         return this.$u.toast('请选择网格员') | ||||||
|  |       } else { | ||||||
|  |         uni.navigateBack() | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .selectGridMember { | ||||||
|  |   height: 100%; | ||||||
|  |   background: #fff; | ||||||
|  |  | ||||||
|  |   .header-top { | ||||||
|  |     background: #fff; | ||||||
|  |     padding: 20px 32px; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .header-middle { | ||||||
|  |     padding-bottom: 140px; | ||||||
|  |  | ||||||
|  |     .hint { | ||||||
|  |       padding: 28px 20px 28px 32px; | ||||||
|  |       line-height: 56px; | ||||||
|  |       box-shadow: 0 1px 0 0 #e4e5e6; | ||||||
|  |       font-size: 30px; | ||||||
|  |       font-weight: 500; | ||||||
|  |       // word-break: break-all; | ||||||
|  |       overflow: hidden; | ||||||
|  |       white-space: nowrap; | ||||||
|  |       text-overflow: ellipsis; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .empty-div { | ||||||
|  |       height: 16px; | ||||||
|  |       background: #f5f5f5; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .cards { | ||||||
|  |       display: flex; | ||||||
|  |       align-items: center; | ||||||
|  |       height: 120px; | ||||||
|  |       line-height: 120px; | ||||||
|  |       padding: 0 0 0 32px; | ||||||
|  |  | ||||||
|  |       .imges { | ||||||
|  |         display: flex; | ||||||
|  |         align-items: center; | ||||||
|  |  | ||||||
|  |         .imgselect { | ||||||
|  |           width: 48px; | ||||||
|  |           height: 48px; | ||||||
|  |           vertical-align: middle; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .avatras { | ||||||
|  |           width: 74px; | ||||||
|  |           height: 74px; | ||||||
|  |           border-radius: 8px; | ||||||
|  |           margin-left: 36px; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       img { | ||||||
|  |         width: 74px; | ||||||
|  |         height: 74px; | ||||||
|  |         border-radius: 8px; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       .rightes { | ||||||
|  |         width: calc(100% - 160px); | ||||||
|  |         display: flex; | ||||||
|  |         align-items: center; | ||||||
|  |         margin-left: 32px; | ||||||
|  |         border-bottom: 1px solid #e4e5e6; | ||||||
|  |  | ||||||
|  |         .applicationNames { | ||||||
|  |           flex: 1; | ||||||
|  |           min-width: 0; | ||||||
|  |           font-size: 36px; | ||||||
|  |           font-weight: 500; | ||||||
|  |           color: #333333; | ||||||
|  |           overflow: hidden; | ||||||
|  |           white-space: nowrap; | ||||||
|  |           text-overflow: ellipsis; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .imgs { | ||||||
|  |           width: 40px; | ||||||
|  |           height: 40px; | ||||||
|  |           margin-right: 20px; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .userCards { | ||||||
|  |       display: flex; | ||||||
|  |       align-items: center; | ||||||
|  |       height: 120px; | ||||||
|  |       line-height: 120px; | ||||||
|  |       padding: 0 0 0 32px; | ||||||
|  |  | ||||||
|  |       .imges { | ||||||
|  |         display: flex; | ||||||
|  |         align-items: center; | ||||||
|  |  | ||||||
|  |         .imgselect { | ||||||
|  |           width: 48px; | ||||||
|  |           height: 48px; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .avatras { | ||||||
|  |           width: 74px; | ||||||
|  |           height: 74px; | ||||||
|  |           border-radius: 8px; | ||||||
|  |           margin-left: 36px; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       .rights { | ||||||
|  |         display: flex; | ||||||
|  |         justify-content: space-between; | ||||||
|  |         align-items: center; | ||||||
|  |         margin-left: 32px; | ||||||
|  |         border-bottom: 1px solid #e4e5e6; | ||||||
|  |         padding-right: 40px; | ||||||
|  |         height: inherit; | ||||||
|  |  | ||||||
|  |         .applicationNames { | ||||||
|  |           font-size: 36px; | ||||||
|  |           font-weight: 500; | ||||||
|  |           color: #333333; | ||||||
|  |           overflow: hidden; | ||||||
|  |           white-space: nowrap; | ||||||
|  |           text-overflow: ellipsis; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .idNumbers { | ||||||
|  |           color: #666; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .subBtn { | ||||||
|  |     position: fixed; | ||||||
|  |     bottom: 0; | ||||||
|  |     left: 0; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 118px; | ||||||
|  |     background: #f4f8fb; | ||||||
|  |  | ||||||
|  |     div { | ||||||
|  |       width: 192px; | ||||||
|  |       height: 80px; | ||||||
|  |       line-height: 80px; | ||||||
|  |       text-align: center; | ||||||
|  |       background: #1365dd; | ||||||
|  |       border-radius: 4px; | ||||||
|  |       font-size: 32px; | ||||||
|  |       color: #fff; | ||||||
|  |       margin: 20px 34px 0 0; | ||||||
|  |       float: right; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										235
									
								
								src/project/huizhili/AppCooperationPropaganda/selectUser.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,235 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="selectUser"> | ||||||
|  |     <div class="header-middle"> | ||||||
|  |       <div class="userCards" v-for="e in userList" :key="e.userId"> | ||||||
|  |         <div class="imges"> | ||||||
|  |           <div class="imgselect" :class="{ 'checked': e.isChecked }" @click.stop="itemCheck(e)" /> | ||||||
|  |           <img src="./images/tx@2x.png" alt="" class="avatras"/> | ||||||
|  |         </div> | ||||||
|  |         <div class="rights fill"> | ||||||
|  |           <div class="applicationNames">{{ e.userName }}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <AiEmpty description="暂无数据" v-if="!userList.length"/> | ||||||
|  |     </div> | ||||||
|  |     <div class="subBtn" @click="submit"> | ||||||
|  |       <div>确定选择</div> | ||||||
|  |     </div> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import { mapState } from 'vuex' | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   // 选择创建人 | ||||||
|  |   name: "selectUser", | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       selected: {}, | ||||||
|  |       userList: [], | ||||||
|  |       current: 1, | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     ...mapState(['user']), | ||||||
|  |     hasData() { | ||||||
|  |       return this.userList?.length > 0 | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   onLoad() { | ||||||
|  |     this.selected = uni.getStorageSync('userSelect') || [] | ||||||
|  |     this.getCreateUserList() | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     isSelected(userId) { | ||||||
|  |       return this.selected.userId===userId | ||||||
|  |     }, | ||||||
|  |     getCreateUserList() { | ||||||
|  |       this.userList = [] | ||||||
|  |       this.$http.post(`/app/appmasssendingtask/createUserlist`).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.userList = res.data.map(e => ({ | ||||||
|  |             userId: e.create_user_id, | ||||||
|  |             userName: e.create_user_name,  | ||||||
|  |             isChecked: this.isSelected(e.create_user_id)} | ||||||
|  |           )) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     itemCheck(row) { | ||||||
|  |       this.userList.forEach(e => e.isChecked = false) | ||||||
|  |       const index = this.userList.findIndex(o => { | ||||||
|  |         return row.userId===o.userId | ||||||
|  |       }) | ||||||
|  |       this.userList[index].isChecked = true | ||||||
|  |       this.selected = this.userList[index] | ||||||
|  |     }, | ||||||
|  |     submit() { | ||||||
|  |       if(!this.selected.userId) { | ||||||
|  |         return this.$u.toast('请选择创建人') | ||||||
|  |       } | ||||||
|  |       uni.$emit("pagePicker:custom", [this.selected]) | ||||||
|  |       uni.setStorageSync('userSelect', this.selected) | ||||||
|  |       uni.navigateBack() | ||||||
|  |     }, | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .selectUser { | ||||||
|  |   height: 100%; | ||||||
|  |   background: #fff; | ||||||
|  |  | ||||||
|  |   .header-top { | ||||||
|  |     background: #fff; | ||||||
|  |     padding: 20px 32px; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .header-middle { | ||||||
|  |     padding-bottom: 140px; | ||||||
|  |  | ||||||
|  |     .hint { | ||||||
|  |       padding: 28px 20px 28px 32px; | ||||||
|  |       line-height: 56px; | ||||||
|  |       box-shadow: 0 1px 0 0 #e4e5e6; | ||||||
|  |       font-size: 30px; | ||||||
|  |       font-weight: 500; | ||||||
|  |       word-break: break-all; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .empty-div { | ||||||
|  |       height: 16px; | ||||||
|  |       background: #f5f5f5; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .imges { | ||||||
|  |       display: flex; | ||||||
|  |       align-items: center; | ||||||
|  |  | ||||||
|  |       .imgselect { | ||||||
|  |         width: 48px; | ||||||
|  |         height: 48px; | ||||||
|  |         vertical-align: middle; | ||||||
|  |         background-image: url("./images/xz.png"); | ||||||
|  |         background-position: center; | ||||||
|  |         background-size: 100% 100%; | ||||||
|  |  | ||||||
|  |         &.checked { | ||||||
|  |           background-image: url("./images/xzh.png"); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       .avatras { | ||||||
|  |         width: 74px; | ||||||
|  |         height: 74px; | ||||||
|  |         border-radius: 8px; | ||||||
|  |         margin-left: 36px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .cards { | ||||||
|  |       display: flex; | ||||||
|  |       align-items: center; | ||||||
|  |       height: 120px; | ||||||
|  |       line-height: 120px; | ||||||
|  |       padding: 0 0 0 32px; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |       img { | ||||||
|  |         width: 74px; | ||||||
|  |         height: 74px; | ||||||
|  |         border-radius: 8px; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       .rightes { | ||||||
|  |         width: calc(100% - 160px); | ||||||
|  |         display: flex; | ||||||
|  |         align-items: center; | ||||||
|  |         margin-left: 32px; | ||||||
|  |         border-bottom: 1px solid #e4e5e6; | ||||||
|  |  | ||||||
|  |         .applicationNames { | ||||||
|  |           flex: 1; | ||||||
|  |           min-width: 0; | ||||||
|  |           font-size: 36px; | ||||||
|  |           font-weight: 500; | ||||||
|  |           color: #333333; | ||||||
|  |           overflow: hidden; | ||||||
|  |           white-space: nowrap; | ||||||
|  |           text-overflow: ellipsis; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .imgs { | ||||||
|  |           flex-shrink: 0; | ||||||
|  |           width: 40px; | ||||||
|  |           height: 40px; | ||||||
|  |           margin-right: 20px; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .userCards { | ||||||
|  |       display: flex; | ||||||
|  |       align-items: center; | ||||||
|  |       height: 120px; | ||||||
|  |       line-height: 120px; | ||||||
|  |       padding: 0 0 0 32px; | ||||||
|  |  | ||||||
|  |       .rights { | ||||||
|  |         display: flex; | ||||||
|  |         justify-content: space-between; | ||||||
|  |         align-items: center; | ||||||
|  |         margin-left: 32px; | ||||||
|  |         border-bottom: 1px solid #e4e5e6; | ||||||
|  |         padding-right: 40px; | ||||||
|  |         height: inherit; | ||||||
|  |  | ||||||
|  |         .applicationNames { | ||||||
|  |           font-size: 36px; | ||||||
|  |           font-weight: 500; | ||||||
|  |           color: #333333; | ||||||
|  |           overflow: hidden; | ||||||
|  |           white-space: nowrap; | ||||||
|  |           text-overflow: ellipsis; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .idNumbers { | ||||||
|  |           color: #666; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .subBtn { | ||||||
|  |     position: fixed; | ||||||
|  |     bottom: 0; | ||||||
|  |     left: 0; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 118px; | ||||||
|  |     background: #f4f8fb; | ||||||
|  |  | ||||||
|  |     div { | ||||||
|  |       width: 192px; | ||||||
|  |       height: 80px; | ||||||
|  |       line-height: 80px; | ||||||
|  |       text-align: center; | ||||||
|  |       background: #1365dd; | ||||||
|  |       border-radius: 4px; | ||||||
|  |       font-size: 32px; | ||||||
|  |       color: #fff; | ||||||
|  |       margin: 20px 34px 0 0; | ||||||
|  |       float: right; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .color-3F8DF5 { | ||||||
|  |     color: #3F8DF5; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .mar-h4 { | ||||||
|  |     margin: 0 4px; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										195
									
								
								src/project/huizhili/AppCooperationPropaganda/sendScoped.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,195 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="sendScoped"> | ||||||
|  |     <div class="checkedBox"> | ||||||
|  |       <div class="item" v-for="(item,index) in checkList" :key="index" @click="checkBtn(item)"> | ||||||
|  |         <div class="left"> | ||||||
|  |           <icon type="success" size="18" v-if="item.value == sendScope"/> | ||||||
|  |           <icon type="circle" size="18" v-if="item.value != sendScope" /> | ||||||
|  |           <div class="title">{{ item.name }}</div> | ||||||
|  |         </div> | ||||||
|  |         <div class="right" v-if="item.value != 0"> | ||||||
|  |           <div v-if="item.value == '1' && deptSelect.length">已选择{{ deptSelect.length }}个部门</div> | ||||||
|  |           <div v-if="item.value == '2' && girdSelect.length">已选择{{ girdSelect.length }}个网格</div> | ||||||
|  |           <u-icon name="arrow-right" color="#CCD0D3" ></u-icon> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |     <div class="btn"> | ||||||
|  |       <div class="submitBtn" @click="submit">确定</div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: 'sendScoped', | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       value: '', | ||||||
|  |       checkList: [ | ||||||
|  |         { name: '全部居民群', value: '0'}, | ||||||
|  |         { name: '按部门选择', value: '1'}, | ||||||
|  |         { name: '按网格选择', value: '2'} | ||||||
|  |       ], | ||||||
|  |       showContent: false, | ||||||
|  |       sendType: '', | ||||||
|  |       deptSelect: [], | ||||||
|  |       girdSelect: [], | ||||||
|  |       sendScope: 0, | ||||||
|  |       girdListIds: [], | ||||||
|  |       deptListIds: [], | ||||||
|  |       wxGroups: [],  // 居民群,居民,朋友圈 | ||||||
|  |       sex: '', | ||||||
|  |       ResidentTags: [], | ||||||
|  |       ResidentTagsRemove: [], | ||||||
|  |       startTime: '', | ||||||
|  |       endTime: '', | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     checkBtn(e) { | ||||||
|  |       if(e.value == '1' || e.value == '2') { | ||||||
|  |         uni.navigateTo({url: `./scopedSelect?type=${e.value}&sendType=${this.sendType}`}) | ||||||
|  |       } | ||||||
|  |       this.sendScope = e.value; | ||||||
|  |       uni.setStorageSync('sendScope', this.sendScope) | ||||||
|  |     }, | ||||||
|  |     submit() { | ||||||
|  |       if(this.sendType == 'ResidentsGroup') { | ||||||
|  |         this.getWxGroups().then(()=>{ | ||||||
|  |           setTimeout(() => { | ||||||
|  |             uni.navigateBack() | ||||||
|  |           }, 600) | ||||||
|  |         }) | ||||||
|  |       } else if(this.sendType == 'Residents' || this.sendType == 'CircleOfFriends') { | ||||||
|  |         this.getSendScope().then(()=>{ | ||||||
|  |           setTimeout(() => { | ||||||
|  |             uni.navigateBack() | ||||||
|  |           }, 600) | ||||||
|  |         }) | ||||||
|  |       } | ||||||
|  |       uni.setStorageSync('sendScope', this.sendScope) | ||||||
|  |     }, | ||||||
|  |     // 群发居民群 | ||||||
|  |     getWxGroups() { | ||||||
|  |       this.$http.post(`/app/appmasssendingtask/queryWxGroups?sendScope=${this.sendScope}`, | ||||||
|  |       { | ||||||
|  |         filterCriteria: this.girdListIds.join(',') || this.deptListIds.join(',') || '' | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res.code === 0) { | ||||||
|  |           this.wxGroups = res.data | ||||||
|  |           uni.setStorageSync('wxGroupsUser', this.wxGroups) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     // 群发朋友圈、居民 | ||||||
|  |     getSendScope() { | ||||||
|  |       let formData = {} | ||||||
|  |       if(this.sendScope == 0) { | ||||||
|  |         formData = { | ||||||
|  |           sendScope: this.sendScope, | ||||||
|  |           taskType: this.sendType == 'Residents'? 1:0, | ||||||
|  |         } | ||||||
|  |       } else if(this.sendScope == 1 || this.sendScope == 2) { | ||||||
|  |         formData = { | ||||||
|  |           filterCriteria: this.girdListIds.toString() || this.deptListIds.toString() || '', | ||||||
|  |           sendScope: this.sendScope, | ||||||
|  |           tags: this.ResidentTags.toString() || this.circleTags.toString() || '', | ||||||
|  |           excludeTags: this.ResidentTagsRemove.toString() || this.circleTagsRemove.toString() || '', | ||||||
|  |           addFromTime: this.startTime, | ||||||
|  |           addEndTime: this.endTime, | ||||||
|  |           gender: this.sex, | ||||||
|  |           taskType: this.sendType == 'Residents'? 1:0, | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       this.$http.post(`/app/whchatmomentstask/getSendScope`,{...formData}).then(res => { | ||||||
|  |         if (res.code === 0) { | ||||||
|  |           if(this.sendType == 'Residents') { | ||||||
|  |             this.wxGroups = res.data | ||||||
|  |           } else if(this.sendType == 'CircleOfFriends') { | ||||||
|  |             this.wxGroups = res.data | ||||||
|  |           } | ||||||
|  |           uni.setStorageSync('wxGroupsUser', this.wxGroups) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   onLoad(o) { | ||||||
|  |     this.sendType = o.type; | ||||||
|  |     document.title = "选择发送范围" | ||||||
|  |   }, | ||||||
|  |   onShow() { | ||||||
|  |     this.sendScope = uni.getStorageSync('sendScope') || '' | ||||||
|  |     const girdArr = uni.getStorageSync('girdSelect') | ||||||
|  |     if(girdArr.length) { | ||||||
|  |       this.girdListIds = girdArr.map(e=>e.id) | ||||||
|  |     } | ||||||
|  |     const deptArr = uni.getStorageSync('deptList') | ||||||
|  |     if(deptArr.length) { | ||||||
|  |       this.deptListIds = deptArr.map(v=>v.id) | ||||||
|  |     } | ||||||
|  |     this.sex = uni.getStorageSync('gender') | ||||||
|  |     // 标签 | ||||||
|  |     if(this.sendType == 'Residents') {  | ||||||
|  |       this.ResidentTags = uni.getStorageSync('ResidentTags') // 居民包含 | ||||||
|  |       this.ResidentTagsRemove = uni.getStorageSync('ResidentTagsRemove') // 居民剔除 | ||||||
|  |     } else if(this.sendType == 'CircleOfFriends') { | ||||||
|  |       this.circleTags = uni.getStorageSync('circleTags') // 朋友圈包含 | ||||||
|  |       this.circleTagsRemove = uni.getStorageSync('circleTagsRemove') // 朋友圈剔除 | ||||||
|  |     } | ||||||
|  |     // 时间 | ||||||
|  |     this.startTime = uni.getStorageSync('startTime') | ||||||
|  |     this.endTime = uni.getStorageSync('endTime') | ||||||
|  |      | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .sendScoped { | ||||||
|  |   .checkedBox { | ||||||
|  |     background: #FFF; | ||||||
|  |     padding: 0 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     .item { | ||||||
|  |       display: flex; | ||||||
|  |       justify-content: space-between; | ||||||
|  |       border-bottom: 1px solid #DDD; | ||||||
|  |       padding: 30px 0; | ||||||
|  |       box-sizing: border-box; | ||||||
|  |       .left, | ||||||
|  |       .right { | ||||||
|  |         display: flex; | ||||||
|  |         align-items: center; | ||||||
|  |         .title { | ||||||
|  |           margin-left: 12px; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   .btn { | ||||||
|  |     position: fixed; | ||||||
|  |     bottom: 0; | ||||||
|  |     left: 0; | ||||||
|  |     background: #FFF; | ||||||
|  |     display: flex; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 128px; | ||||||
|  |     padding: 24px 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |  | ||||||
|  |     .submitBtn { | ||||||
|  |       flex: 1; | ||||||
|  |       height: 80px; | ||||||
|  |       line-height: 80px; | ||||||
|  |       text-align: center; | ||||||
|  |       border-radius: 8px; | ||||||
|  |       border: 2px solid #CCCCCC; | ||||||
|  |       background: #1365DD; | ||||||
|  |       color: #FFF; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										167
									
								
								src/project/huizhili/AppCooperationPropaganda/tagsList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,167 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="tagsList"> | ||||||
|  |     <div class="tags-group"> | ||||||
|  |       <div class="tags-list" v-for="items in subTags" :key="items.id"> | ||||||
|  |         <div class="tag_title">{{ items.name }}</div> | ||||||
|  |         <div class="item" | ||||||
|  |           v-for="(item, index) in items.tagList" | ||||||
|  |           :class="[checked.includes(item.id) ? 'active' : '']" | ||||||
|  |           :key="index" | ||||||
|  |           @click="onClick(item.id)"> | ||||||
|  |           {{ item.name }} | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |     <div class="btn" @click="submit"> | ||||||
|  |       <div>确定</div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: "tagsList", | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       sendType: '', | ||||||
|  |       subTags: [], | ||||||
|  |       checked: [], | ||||||
|  |       type: '', | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     getTags() { | ||||||
|  |       this.$http.post(`/app/wxcp/wxcorptag/listAll?current=1&size=3000`).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.subTags = res.data.records | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     onClick(id) { | ||||||
|  |       const index = this.checked.indexOf(id) | ||||||
|  |  | ||||||
|  |       if (index === -1) { | ||||||
|  |         this.checked.push(id) | ||||||
|  |       } else { | ||||||
|  |         this.checked.splice(index, 1) | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     submit() { | ||||||
|  |       // if (!this.checked.length) { | ||||||
|  |       //   return this.$u.toast('请选择标签') | ||||||
|  |       // } | ||||||
|  |  | ||||||
|  |       // const list = this.subTags.filter(v => { | ||||||
|  |       //   return this.checked.includes(v.id) | ||||||
|  |       // }) | ||||||
|  |  | ||||||
|  |       if(this.sendType == 'Residents') { | ||||||
|  |         if(this.type == '0') {  // 居民包含 | ||||||
|  |           uni.setStorageSync('ResidentTags', this.checked) | ||||||
|  |         } else if(this.type == '1') {  // 居民剔除 | ||||||
|  |           uni.setStorageSync('ResidentTagsRemove', this.checked) | ||||||
|  |         } | ||||||
|  |       } else if(this.sendType == 'CircleOfFriends') { | ||||||
|  |         if(this.type == '0') {  // 朋友圈包含 | ||||||
|  |           uni.setStorageSync('circleTags', this.checked) | ||||||
|  |         } else if(this.type == '1') {  // 朋友圈剔除 | ||||||
|  |           uni.setStorageSync('circleTagsRemove', this.checked) | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       uni.navigateBack() | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   onShow() { | ||||||
|  |     this.getTags() | ||||||
|  |     this.checked = [] | ||||||
|  |     if(this.sendType == 'Residents') { | ||||||
|  |       if(this.type == 0) {  // 居民包含 | ||||||
|  |         this.checked = uni.getStorageSync('ResidentTags') || [] | ||||||
|  |       } else {  // 居民剔除 | ||||||
|  |         this.checked = uni.getStorageSync('ResidentTagsRemove') || [] | ||||||
|  |       } | ||||||
|  |     } else if(this.sendType == 'CircleOfFriends') { | ||||||
|  |       if(this.type == 0) {  // 朋友圈包含 | ||||||
|  |         this.checked = uni.getStorageSync('circleTags') || [] | ||||||
|  |       } else {  // 朋友圈剔除 | ||||||
|  |         this.checked = uni.getStorageSync('circleTagsRemove') || [] | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   onLoad(o) { | ||||||
|  |     document.title = o.type ==0? '包含标签': '剔除标签' | ||||||
|  |     this.sendType = o.sendType | ||||||
|  |     this.type = o.type | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .tagsList { | ||||||
|  |   padding-bottom: 120px; | ||||||
|  |   box-sizing: border-box; | ||||||
|  |  | ||||||
|  |   .tags-group { | ||||||
|  |     margin-bottom: 16px; | ||||||
|  |     .tags-list { | ||||||
|  |       display: flex; | ||||||
|  |       flex-wrap: wrap; | ||||||
|  |       line-height: 1; | ||||||
|  |       padding: 0 32px; | ||||||
|  |       box-sizing: border-box; | ||||||
|  |       background: #FFF; | ||||||
|  |       margin-bottom: 16px; | ||||||
|  |  | ||||||
|  |       .tag_title { | ||||||
|  |         width: 100%; | ||||||
|  |         height: 108px; | ||||||
|  |         line-height: 108px; | ||||||
|  |         color: #333333; | ||||||
|  |         font-size: 32px; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       .item { | ||||||
|  |         height: 64px; | ||||||
|  |         line-height: 64px; | ||||||
|  |         margin: 0 16px 16px 0; | ||||||
|  |         padding: 0 32px; | ||||||
|  |         color: #333333; | ||||||
|  |         font-size: 28px; | ||||||
|  |         background: #F3F4F7; | ||||||
|  |         border-radius: 4px; | ||||||
|  |         max-width: 100%; | ||||||
|  |         text-overflow: ellipsis; | ||||||
|  |         overflow: hidden; | ||||||
|  |         white-space: nowrap; | ||||||
|  |  | ||||||
|  |         &.active { | ||||||
|  |           color: #fff; | ||||||
|  |           background: #1365DD; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   .btn { | ||||||
|  |     position: fixed; | ||||||
|  |     bottom: 0; | ||||||
|  |     left: 0; | ||||||
|  |     background: #FFF; | ||||||
|  |     display: flex; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 128px; | ||||||
|  |     padding: 24px 32px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |  | ||||||
|  |     div { | ||||||
|  |       flex: 1; | ||||||
|  |       height: 80px; | ||||||
|  |       line-height: 80px; | ||||||
|  |       text-align: center; | ||||||
|  |       border-radius: 8px; | ||||||
|  |       border: 2px solid #CCCCCC; | ||||||
|  |       background: #1365DD; | ||||||
|  |       color: #FFF; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||