From 60bdd6e881fbefc8c375eb9e9d71009d6c63859d Mon Sep 17 00:00:00 2001 From: hejianhao <15708179461@qq.com> Date: 星期日, 18 五月 2025 16:35:16 +0800 Subject: [PATCH] H5工单列表、工单详情、诉求监督 --- H5/static/home/supervision.png | 0 H5/pages/list/list.vue | 21 H5/pages/supervision/supervision.vue | 416 +++++++++++++++++ H5/static/search.png | 0 H5/pages.json | 53 + H5/pages/supervision/supervision-progress.vue | 378 +++++++++++++++ H5/pages/work-detail/work-detail.vue | 60 ++ H5/store/index.js | 61 ++ H5/static/24gf-playCircle@2x.png | 0 H5/static/tell.png | 0 H5/pages/supervision/service.js | 11 H5/static/Group 2@2x.png | 0 H5/pages/supervision/edit-supervision-progress.vue | 402 ++++++++++++++++ H5/static/pausePlaying.png | 0 H5/pages/progress/progress.vue | 17 H5/pages/index/index.vue | 12 16 files changed, 1,393 insertions(+), 38 deletions(-) diff --git a/H5/pages.json b/H5/pages.json index 7f81f94..10d7eae 100644 --- a/H5/pages.json +++ b/H5/pages.json @@ -100,19 +100,18 @@ } }, { - "path" : "pages/party-member-info/party-member-info", - "style" : - { - "navigationBarTitleText" : "党员信息", + "path": "pages/party-member-info/party-member-info", + "style": { + "navigationBarTitleText": "党员信息", "navigationStyle": "custom" } - },{ + }, { "path": "pages/evaluate/evaluate", "style": { "navigationBarTitleText": "诉求评价", "navigationStyle": "custom" } - },{ + }, { "path": "pages/evaluate/evaluate-detail", "style": { "navigationBarTitleText": "评价详情", @@ -120,26 +119,44 @@ } }, { - "path" : "pages/authentication/authentication", - "style" : - { - "navigationBarTitleText" : "党员认证", + "path": "pages/authentication/authentication", + "style": { + "navigationBarTitleText": "党员认证", "navigationStyle": "custom" } - },{ - "path" : "pages/certificationAudit/certificationAudit", - "style" : - { + }, { + "path": "pages/certificationAudit/certificationAudit", + "style": { "navigationBarTitleText": "党员认证审核", "navigationStyle": "custom" } - },{ - "path" : "pages/statistics/index", - "style" : - { + }, { + "path": "pages/statistics/index", + "style": { "navigationBarTitleText": "统计分析", "navigationStyle": "custom" } + }, + { + "path": "pages/supervision/supervision", + "style": { + "navigationBarTitleText": "诉求监督", + "navigationStyle": "custom" + } + }, + { + "path": "pages/supervision/supervision-progress", + "style": { + "navigationBarTitleText": "办理进度查看", + "navigationStyle": "custom" + } + }, + { + "path": "pages/supervision/edit-supervision-progress", + "style": { + "navigationBarTitleText": "编辑办理进度", + "navigationStyle": "custom" + } } ], "globalStyle": { diff --git a/H5/pages/index/index.vue b/H5/pages/index/index.vue index 0f84781..aafca34 100644 --- a/H5/pages/index/index.vue +++ b/H5/pages/index/index.vue @@ -81,6 +81,11 @@ <image class="w-81 h-77 ml-38" src="/static/home/Group 2@2x.png" mode=""></image> <text class="ml-37 font-bold">党员审核</text> </view> + <view class="pt-38 pb-38 bg1 w-333 br-19 mt-19 flex a-center" @tap.stop="toSupervision" + v-if="showData && userInfo.isAdmin == 1"> + <image class="w-81 h-77 ml-38" src="/static/home/supervision.png" mode=""></image> + <text class="ml-37 font-bold">诉求监督</text> + </view> </view> <view class="flex j-between a-center mt-38"> <!-- <text class="color1">消息通知</text> --> @@ -276,9 +281,14 @@ this.getappletcinfo() }, methods: { + toSupervision() { + uni.navigateTo({ + url: '/pages/supervision/supervision' + }) + }, toStatistics() { uni.navigateTo({ - url:'/pages/statistics/index' + url: '/pages/statistics/index' }) }, // 管理员确认 diff --git a/H5/pages/list/list.vue b/H5/pages/list/list.vue index bd7f56f..8cf89bc 100644 --- a/H5/pages/list/list.vue +++ b/H5/pages/list/list.vue @@ -91,13 +91,17 @@ {{ item.name || '' }} </view> </view> - <view class=""> - <view class="font-bold"> - 联系电话 + <view class="flex a-center"> + <view style="text-align: left;"> + <view class="font-bold"> + 联系电话 + </view> + <view class="mt-10"> + {{ item.contactNumber || '' }} + </view> </view> - <view class="mt-10"> - {{ item.contactNumber || '' }} - </view> + <image @click.stop="callPhone(item.contactNumber)" src="../../static/tell.png" + class="w-58 h-58 shrink0 " /> </view> </view> <view v-if="item.status != '3'" class="fs-27 mt-31 ml-40 mr-40"> @@ -211,6 +215,11 @@ }) }, methods: { + callPhone(phoneNumber) { + uni.makePhoneCall({ + phoneNumber + }); + }, // 去评价 toEvaluate(id) { uni.navigateTo({ diff --git a/H5/pages/progress/progress.vue b/H5/pages/progress/progress.vue index 63f73c0..7c443bd 100644 --- a/H5/pages/progress/progress.vue +++ b/H5/pages/progress/progress.vue @@ -20,9 +20,13 @@ <view class="fs-27 lh-38 font-bold">群众姓名</view> <view class="fs-27 lh-38 mt-10">{{ info.name }}</view> </view> - <view class="flex-column a-center"> - <view class="fs-27 lh-38 font-bold">联系电话</view> - <view class="fs-27 lh-38 mt-10">{{ info.contactNumber }}</view> + <view class="flex a-center"> + <view class="flex-column a-center"> + <view class="fs-27 lh-38 font-bold">联系电话</view> + <view class="fs-27 lh-38 mt-10">{{ info.contactNumber }}</view> + </view> + <image @click.stop="callPhone(info.contactNumber)" src="../../static/tell.png" + class="w-58 h-58 shrink0 " /> </view> </view> </view> @@ -125,6 +129,11 @@ }) }, methods: { + callPhone(phoneNumber) { + uni.makePhoneCall({ + phoneNumber + }); + }, toAdd() { uni.navigateTo({ url: `/pages/add-progress/index?id=${this.id}` @@ -171,7 +180,7 @@ } .bgcolor1 { - background: linear-gradient( 270deg, rgba(255,241,0,0.5) 0%, rgba(255,249,172,0.25) 48%, rgba(255,255,255,0.2) 100%, #FFFFFF 100%); + background: linear-gradient(270deg, rgba(255, 241, 0, 0.5) 0%, rgba(255, 249, 172, 0.25) 48%, rgba(255, 255, 255, 0.2) 100%, #FFFFFF 100%); } .bgcolor2 { diff --git a/H5/pages/supervision/edit-supervision-progress.vue b/H5/pages/supervision/edit-supervision-progress.vue new file mode 100644 index 0000000..4cc0ced --- /dev/null +++ b/H5/pages/supervision/edit-supervision-progress.vue @@ -0,0 +1,402 @@ +<template> + <view class="px-31 pt-38"> + <view v-if="Object.keys(info).length != 0" class="br-19 bs-1 pt-21 pb-35 px-27 bgcolor2"> + <view class="flex a-center j-between fs-23 lh-33 font-bold"> + <view>诉求号:{{ info.serialNumber }}</view> + <view class="color1">{{ ["正在办理", "延期办理", "超时办理", "已办结", "群众撤销", "上报待审核", "上级驳回"][info.status] }}</view> + </view> + <view class="mx-13 mt-33 pt-35 pb-33 px-27 br-19 flex a-center j-between bgcolor1"> + <view class="fs-27 lh-38 color2">{{ info.location }}</view> + <image src="@/static/detailImg/dwei.png" class="w-31 h-31 shrink0" /> + </view> + <view class="flex a-center j-between mt-31 mx-13"> + <view class="flex-column a-center"> + <view class="fs-27 lh-38 font-bold">问题类型</view> + <view class="mt-8 fs-23 lh-42 txt-center px-31 font-w400 color3 bgcolor3 border1"> + {{ info.problemType }} + </view> + </view> + <view class="flex-column a-center"> + <view class="fs-27 lh-38 font-bold">群众姓名</view> + <view class="fs-27 lh-38 mt-10">{{ info.name }}</view> + </view> + <view class="flex-column a-center"> + <view class="fs-27 lh-38 font-bold">联系电话</view> + <view class="fs-27 lh-38 mt-10">{{ info.contactNumber }}</view> + </view> + </view> + </view> + <view class="br-19 mt-38 bs-1 pt-35 pb-33 px-31"> + <view class="fs-27 lh-38 font-bold">办理进度描述</view> + <textarea v-model="describe" class="pt-25 pl-31 mt-27 fs-27 br-8 bgcolor4" + :class="(rulsFlag && !describe) && 'bgcolor-border'" style="height: 365rpx;width: calc(100% - 31rpx);" + placeholder="请输入办理进度描述" /> + <view v-if="rulsFlag && !describe" class="flex a-center mt-19"> + <image src="@/static/noNull.png" class="w-35 h-35 mr-13 shrink0" /> + <view class="fs-23 color99">办理进度描述不能为空</view> + </view> + <view class="fs-27 mt-38 lh-38 font-bold">上传图片</view> + <view class="flex wrap mt-27"> + <view class="relative mr-15" v-for="(item, index) in localImageUrls" :key="index"> + <image v-if="item != 'loading'" :src="item" class="w-140 h-140 shrink0 br-8" /> + <view v-if="item != 'loading'" class="absolute w-140 h-140 bgcolor5 top0 left0 br-8"> + <view class="absolute flex a-center j-between px-34" + style="top: 50%;left: 50%;transform: translate(-50%,-50%);width: calc(100% - 68rpx);"> + <image @tap="viewImage(item)" src="@/static/Appeal/amplify.png" class="w-19 h-19" /> + <image @tap="delImg(item)" src="@/static/Appeal/trash.png" class="w-19 h-19" /> + </view> + </view> + </view> + <view v-if="imgUrls.includes('loading')" class="w-140 h-140 flex a-center j-center mr-15 border2 br-8"> + <u-loading-icon></u-loading-icon> + </view> + <image @tap="uploadImg(1)" src="/static/Appeal/add.png" class="w-140 h-140 shrink0" /> + </view> + <view class="fs-27 mt-37 lh-38 font-bold">上传视频</view> + <view class="flex wrap mt-27"> + <view class="imgOrVedio" v-for="(ite, ind) in video" :key="ind"> + <video v-if="ite != 'loading'" id="myVideo" class="videoImg shrink0" disabled :controls="false" + :show-center-play-btn="false" :src="ite"> + </video> + <view v-if="ite != 'loading'" class="absolute w-140 h-140 bgcolor5 top0 left0 br-8 zIndex999"> + <view class="absolute flex a-center j-between" + style="top: 50%;left: 50%;transform: translate(-50%,-50%);"> + <image @tap="openVideo(ite)" src="@/static/detailImg/open.png" class="w-140 h-140" /> + </view> + <image @tap="delVideo(ite)" src="@/static/Appeal/trash.png" class="absolute w-19 h-19 zIndex999" + style="top: 8rpx;right: 8rpx;" /> + </view> + </view> + <view v-if="video.includes('loading')" class="w-140 h-140 flex a-center j-center mr-15 border2 br-8"> + <u-loading-icon></u-loading-icon> + </view> + <image @tap="uploadImg(2)" src="@/static/Appeal/add.png" class="w-140 h-140 shrink0" /> + </view> + </view> + <view @click.stop="submit" class="mt-38 fs-35 lh-96 br-48 txt-center font-bold bgcolor6 color4 fixed" + style="width: calc(100% - 62rpx);bottom: calc(env(safe-area-inset-bottom) + 10rpx);">确认添加</view> + <view class="btn-box"></view> + <view class="safe-box"></view> + </view> +</template> + +<script> + import { + saveProcess, + getComplaintDetail + } from './service' + import config from '@/config/index.js' + export default { + data() { + return { + complaintId: '', //诉求id + info: {}, //工单详情 + describe: '', //办理进度描述 + localImageUrls: [], //本地回显的图片 + imgUrls: [], //传给后端的url + video: [], + againCklicFlag: true, + rulsFlag: false, + } + }, + onLoad(params) { + this.complaintId = params.id + getComplaintDetail({ + id: params.id + }).then(res => { + this.info = res.data + }) + }, + methods: { + back() { + uni.navigateBack({ + delta: 2 + }) + }, + submit() { + if (!this.describe) { + this.rulsFlag = true + return uni.showToast({ + icon: 'none', + title: '请输入办理进度描述' + }) + } + let obj = { + complaintId: this.complaintId, + describe: this.describe, + imgUrl: this.imgUrls.join(','), + video: this.video.join(',') + } + saveProcess(obj).then(res => { + if (res.code == 200) { + uni.showToast({ + title: '提交成功', + icon: 'success', + mask: true + }) + setTimeout(() => { + uni.navigateBack() + }, 1500) + } else { + uni.showToast({ + title: res.msg, + icon: 'none', + mask: true + }) + } + }) + }, + delImg(item) { + this.localImageUrls = this.localImageUrls.filter(i => i != item) + this.imgUrls = this.imgUrls.filter(i => i != item) + }, + delVideo(item) { + this.video = this.video.filter(i => i != item) + }, + viewImage(item) { + uni.previewImage({ + urls: [item] + }) + }, + uploadImg(type) { + // if (!this.againCklicFlag) return + this.againCklicFlag = false + if (type == 1) { + uni.chooseImage({ + count: 1, + success: (chooseImageRes) => { + this.imgUrls.push('loading') + this.againCklicFlag = true + let imgPathList = chooseImageRes.tempFilePaths; + if (imgPathList.length > 0) { + uni.uploadFile({ + url: config.imageUrl, + filePath: imgPathList[0], + timeout: 1000 * 45, + name: 'file', + header: { + Authorization: uni.getStorageSync('token') + }, + success: (res) => { + if (JSON.parse(res.data).code == 200) { + this.imgUrls = this.imgUrls.filter(item => item != + 'loading') + this.$nextTick(() => { + this.imgUrls.push(JSON.parse(res.data) + .data) + this.localImageUrls.push(imgPathList[0]) + }) + } else { + this.againCklicFlag = true + this.imgUrls = this.imgUrls.filter( + item => item != 'loading') + uni.showToast({ + title: '上传失败,请重新上传', + icon: 'none', + mask: true + }) + } + }, + fail: (err) => { + this.againCklicFlag = true + this.imgUrls = this.imgUrls.filter( + item => item != 'loading') + uni.showToast({ + title: '上传失败,请重新上传', + icon: 'none', + mask: true + }) + } + }) + } + }, + fail: () => { + this.againCklicFlag = true + } + }) + } else { + uni.chooseVideo({ + camera: 'back', + success: (res) => { + const videoExtensions = /\.(mp4|avi|rmvb)$/i; + if (!videoExtensions.test(res.name)) { + uni.showToast({ + title: '请上传mp4, avi, rmvb格式的视频', + icon: 'none', + duration: 3000 + }) + return + } + this.video.push('loading') + this.againCklicFlag = true + const tempFilePath = res.tempFilePath; + uni.uploadFile({ + url: config.imageUrl, + filePath: tempFilePath, + timeout: 1000 * 45, + name: 'file', + header: { + Authorization: cuni.getStorageSync('token') + }, + success: (res) => { + if (JSON.parse(res.data).code == 200) { + this.video = this.video.filter(item => item != + 'loading') + this.$nextTick(() => { + this.video.push(JSON.parse(res.data).data) + }) + } else { + this.againCklicFlag = true + this.video = this.video.filter( + item => item != 'loading') + uni.showToast({ + title: '上传失败,请重新上传', + icon: 'none', + mask: true + }) + } + }, + fail: (err) => { + this.againCklicFlag = true + this.video = this.video.filter( + item => item != 'loading') + uni.showToast({ + title: '上传失败,请重新上传', + icon: 'none', + mask: true + }) + } + }) + }, + fail: () => { + this.againCklicFlag = true + } + }) + } + }, + // 去大屏播放视频 + openVideo(url) { + uni.navigateTo({ + url: `/pages/work-detail/maxVideo?url=${url}` + }) + }, + } + } +</script> + +<style scoped lang="scss"> + .bs-1 { + box-shadow: 0rpx 0rpx 27rpx 0rpx rgba(0, 0, 0, 0.1); + } + + .color1 { + color: #FF4948; + } + + .color2 { + color: rgba(0, 0, 0, .8); + } + + .color3 { + color: #FAAD14; + } + + .color4 { + color: #FFFFFF; + } + + .color99 { + color: #FB9A0E; + } + + .bgcolor-border { + background: rgba(255, 253, 241, 1) !important; + border: 2rpx solid #FFE58F; + } + + .bgcolor1 { + background: linear-gradient(270deg, rgba(255, 241, 0, 0.5) 0%, rgba(255, 249, 172, 0.25) 48%, rgba(255, 255, 255, 0.2) 100%, #FFFFFF 100%); + } + + .bgcolor2 { + background: linear-gradient(180deg, #FFDCDB 0%, rgba(255, 255, 255, 0) 25%); + } + + .bgcolor3 { + background: #FFFBE6; + } + + .bgcolor4 { + background: #F8F8F8; + } + + .bgcolor5 { + background: rgba(0, 0, 0, .23); + } + + .bgcolor6 { + background: linear-gradient(270deg, #FC8D55 0%, #FF4948 100%); + } + + .border1 { + border: 2rpx solid #FFF1B8; + } + + .border2 { + border: 2rpx solid #F8F8F8; + } + + .safe-box { + height: env(safe-area-inset-bottom); + } + + .imgOrVedio { + margin-right: 17rpx; + position: relative; + + .img { + width: 140rpx; + height: 140rpx; + border-radius: 8rpx; + margin-top: 19rpx; + } + + .videoOpen { + position: absolute; + top: 10rpx; + left: 0; + z-index: 99; + width: 140rpx; + height: 140rpx; + border-radius: 8rpx; + display: flex; + align-items: center; + justify-content: center; + + .video { + z-index: 999; + width: 140rpx; + height: 140rpx; + } + } + } + + .videoImg { + width: 140.38rpx; + height: 140.38rpx; + border-radius: 7.69rpx; + position: relative; + } + + #myVideo { + z-index: 1; + } + + .zIndex999 { + z-index: 999; + } + + .btn-box { + height: 120rpx; + } +</style> \ No newline at end of file diff --git a/H5/pages/supervision/service.js b/H5/pages/supervision/service.js new file mode 100644 index 0000000..b9cb14f --- /dev/null +++ b/H5/pages/supervision/service.js @@ -0,0 +1,11 @@ +import request from '@/utils/request.js' + +// 工单列表 +export const getList = (params) => { + return request.post(`/api/huacheng-sangeshenbian/applet/complaint/list`, params) +} + +// 工单详情 +export const getComplaintDetail = (params) => { + return request.get('/api/huacheng-sangeshenbian/applet/complaint/detail', params) +} \ No newline at end of file diff --git a/H5/pages/supervision/supervision-progress.vue b/H5/pages/supervision/supervision-progress.vue new file mode 100644 index 0000000..b0a7520 --- /dev/null +++ b/H5/pages/supervision/supervision-progress.vue @@ -0,0 +1,378 @@ +<template> + <view v-if="Object.keys(info) != 0" class="px-31 pt-38"> + <view v-if="type" class="br-19 bs-1 pt-21 pb-35 px-27 bgcolor2"> + <view class="flex a-center j-between fs-23 lh-33 font-bold"> + <view>诉求号:{{ info.serialNumber }}</view> + <view class="color1">{{ ["正在办理", "延期办理", "超时办理", "已办结", "群众撤销", "上报待审核", "上级驳回"][info.status] }}</view> + </view> + <view class="mx-13 mt-33 pt-35 pb-33 px-27 br-19 flex a-center j-between bgcolor1"> + <view class="fs-27 lh-38 color2">{{ info.location }}</view> + <image src="@/static/detailImg/dwei.png" class="w-31 h-31 shrink0" /> + </view> + <view class="flex a-center j-between mt-31 mx-13"> + <view class="flex-column a-center"> + <view class="fs-27 lh-38 font-bold">问题类型</view> + <view class="mt-8 fs-23 lh-42 txt-center px-31 font-w400 color3 bgcolor3 border1"> + {{ info.problemType }} + </view> + </view> + <view class="flex-column a-center"> + <view class="fs-27 lh-38 font-bold">群众姓名</view> + <view class="fs-27 lh-38 mt-10">{{ info.name }}</view> + </view> + <view class="flex a-center"> + <view class="flex-column a-center"> + <view class="fs-27 lh-38 font-bold">联系电话</view> + <view class="fs-27 lh-38 mt-10">{{ info.contactNumber }}</view> + </view> + <image @click.stop="callPhone(info.contactNumber)" src="../../static/tell.png" + class="w-58 h-58 shrink0 " /> + </view> + </view> + </view> + + <view v-if="info.complaintProgresses.length != 0" class="progress"> + <view class="proCard"> + <view class="proItem" v-for="(item, index) in info.complaintProgresses" :key="item.id"> + <view class="mr-31 flex flex-column a-center"> + <view class="dot"> + <view class="box"></view> + </view> + <view class="proLine"> + </view> + </view> + <view class="flex1"> + <view class="flex a-center j-between mb-10"> + <view class="name">{{ item.createByName }}</view> + <view class="time">{{ item.createTime | formatTime }}</view> + </view> + <view class="context">{{ item.describe }}</view> + <view class="proImg"> + <view v-if="item.imgUrl"> + <view class="imgOrVedio" v-for="(ite, index) in item.imgUrl.split(',')" :key="index"> + <image :src="ite" class="img shrink0" mode="aspectFill" /> + <view + class="absolute mt-19 w-140 h-140 bgcolor5 top0 left0 br-8 flex a-center j-center"> + <image @tap="viewImage(ite)" src="@/static/Appeal/amplify.png" + class="w-19 h-19" /> + </view> + </view> + </view> + <view v-if="item.video"> + <view class="imgOrVedio" v-for="(ite, index) in item.video.split(',')" :key="index"> + <video id="myVideo" class="w-140 h-140 mt-19 shrink0" disabled :controls="false" + :show-center-play-btn="false" :src="ite" /> + <view class="videoOpen" @click.stop="openVideo(ite)"> + <image src="../../static/detailImg/open.png" class="video shrink0" + mode="aspectFill"> + </image> + </view> + </view> + </view> + </view> + <view class="flex a-center j-end fs-25 txt-center"> + <view @click="toEdit(item)" class="lh-58 px-79 mr-38 color10 border3 bgcolor7 br-29">编辑 + </view> + <view @click="toDelete(item)" class="lh-60 px-79 color4 bgcolor6 br-29">删除</view> + </view> + </view> + </view> + </view> + </view> + <view v-if="info.complaintProgresses.length == 0" class="mt-200"> + <image src="../../static/空空如也@2x.png" mode="widthFix" class="w100"></image> + <view class="txt-center mt-94 fs-27 color9"> + 暂无数据 + </view> + </view> + <view v-if="type" @tap="toAdd" class="mt-38 fs-35 lh-96 br-48 txt-center font-bold bgcolor6 color4 fixed" + style="width: calc(100% - 62rpx);bottom: calc(env(safe-area-inset-bottom) + 10rpx);">添加办理进度 + </view> + <CustomPopup ref="customPopup" closeText="取消" @comfirm="deleteProgress"> + <view class="txt-center fs-31 lh-42 mt-50 mb-60 color2">确认删除所选办理进度信息吗?</view> + </CustomPopup> + <view class="btn-box"></view> + <view class="safe-box"></view> + </view> +</template> + +<script> + import dayjs from '../../uni_modules/uview-ui/libs/util/dayjs' + import { + getComplaintDetail + } from './service' + export default { + data() { + return { + id: '', + info: {}, + type: true, + row: {} + } + }, + filters: { + formatTime(val) { + if (!val) return '' + return dayjs(val).format('YYYY-MM-DD HH:mm:ss') + } + }, + onLoad(params) { + if (params.type) { + this.type = false + uni.setNavigationBarTitle({ + title: '办理进度' + }) + } + this.id = params.id + }, + onShow(params) { + getComplaintDetail({ + id: this.id + }).then(res => { + + this.info = { + ...res.data + } + }) + }, + methods: { + deleteProgress() { + + }, + toDelete(item) { + this.row = item + this.$refs.customPopup.show = true + }, + toEdit(item) { + uni.navigateTo({ + url: `/pages/supervision/edit-supervision-progress?id=${this.id}` + }) + }, + callPhone(phoneNumber) { + uni.makePhoneCall({ + phoneNumber + }); + }, + toAdd() { + uni.navigateTo({ + url: `/pages/add-progress/index?id=${this.id}` + }) + }, + viewImage(item) { + uni.previewImage({ + urls: [item] + }) + }, + // 去大屏播放视频 + openVideo(url) { + uni.navigateTo({ + url: `/pages/work-detail/maxVideo?url=${url}` + }) + }, + } + } +</script> + +<style scoped lang="scss"> + .bs-1 { + box-shadow: 0rpx 0rpx 27rpx 0rpx rgba(0, 0, 0, 0.1); + } + + .color1 { + color: #FF4948; + } + + .color2 { + color: rgba(0, 0, 0, .8); + } + + .color3 { + color: #FAAD14; + } + + .color4 { + color: #FFFFFF; + } + + .color9 { + color: #999999; + } + + .color10 { + color: rgba(0, 0, 0, .6); + } + + .bgcolor1 { + background: linear-gradient(270deg, rgba(255, 241, 0, 0.5) 0%, rgba(255, 249, 172, 0.25) 48%, rgba(255, 255, 255, 0.2) 100%, #FFFFFF 100%); + } + + .bgcolor2 { + background: linear-gradient(180deg, #FFDCDB 0%, rgba(255, 255, 255, 0) 25%); + } + + .bgcolor3 { + background: #FFFBE6; + } + + .bgcolor4 { + background: #F8F8F8; + } + + .bgcolor5 { + background: rgba(0, 0, 0, .23); + } + + .bgcolor6 { + background: linear-gradient(270deg, #FC8D55 0%, #FF4948 100%); + } + + .bgcolor7 { + background: #F3F3F3; + } + + .border1 { + border: 2rpx solid #FFF1B8; + } + + .border2 { + border: 2rpx solid #F8F8F8; + } + + .border3 { + border: 2rpx solid #E5E5E5; + box-sizing: border-box; + } + + .safe-box { + height: env(safe-area-inset-bottom); + } + + .progress { + border-radius: 27rpx; + margin-top: 38.46rpx; + background: #FFFFFF; + box-shadow: 0rpx 0rpx 27rpx 0rpx rgba(0, 0, 0, 0.1); + padding: 34rpx 31rpx; + + .title { + font-weight: 600; + font-size: 27rpx; + color: rgba(0, 0, 0, 0.88); + line-height: 38rpx; + text-shadow: 0px 0px 27px rgba(0, 0, 0, 0.1); + margin-bottom: 48rpx; + } + + .proCard { + .proItem { + display: flex; + padding-bottom: 38rpx; + + .dot { + width: 19rpx; + height: 19rpx; + background: linear-gradient(180deg, #FD8D3C 0%, #FA541C 100%); + box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(252, 141, 85, 0.4); + border-radius: 50%; + margin: 10rpx 0; + display: flex; + align-items: center; + justify-content: center; + + .box { + width: 7rpx; + height: 7rpx; + background-color: #fff; + border-radius: 50%; + } + } + + .proLine { + flex: 1; + width: 4rpx; + background: rgba(0, 0, 0, 0.06); + border-radius: 3rpx; + } + + + .name { + font-weight: 400; + font-size: 27rpx; + color: rgba(0, 0, 0, 0.8); + line-height: 38rpx; + } + + .time { + font-weight: 400; + font-size: 23rpx; + color: rgba(0, 0, 0, 0.4); + line-height: 33rpx; + } + + .context { + font-size: 27rpx; + color: rgba(0, 0, 0, 0.8); + line-height: 38rpx; + } + + .proImg { + display: flex; + flex-wrap: wrap; + + .imgOrVedio { + margin-right: 17rpx; + position: relative; + + .img { + width: 140rpx; + height: 140rpx; + border-radius: 8rpx; + margin-top: 19rpx; + } + } + + .videoOpen { + position: absolute; + top: 10rpx; + left: 0; + z-index: 99; + width: 140rpx; + height: 140rpx; + border-radius: 8rpx; + display: flex; + align-items: center; + justify-content: center; + margin-top: 19rpx; + + .video { + z-index: 999; + width: 140rpx; + height: 140rpx; + } + } + } + } + + .proItem:last-child { + .proLine { + display: none; + } + } + } + } + + .videoImg { + width: 140.38rpx; + height: 140.38rpx; + border-radius: 7.69rpx; + position: relative; + } + + #myVideo { + z-index: 1; + } + + .btn-box { + height: 120rpx; + } +</style> \ No newline at end of file diff --git a/H5/pages/supervision/supervision.vue b/H5/pages/supervision/supervision.vue new file mode 100644 index 0000000..a55d20b --- /dev/null +++ b/H5/pages/supervision/supervision.vue @@ -0,0 +1,416 @@ +<template> + <view class="content"> + <view class="bgColor2 shadow1 pb-19" style="position: sticky;top: 0;z-index: 999;"> + <view class="h-96 flex a-center fs-27 j-between txt-center font-w400 color1"> + <view @click="changeType('1')" class="flex1 bgColor2 relative" + :class="searchParams.type == '1' && 'color2 font-bold'"> + <view class="relative zIndex1000"> + 处理记录 + </view> + <view v-if="searchParams.type == '1'" class="bgColor1"></view> + </view> + <view @click="changeType('2')" class="flex1 bgColor2 relative" + :class="searchParams.type == '2' && 'color2 font-bold'"> + <view class="relative zIndex1000"> + 问题驳回池 + </view> + <view v-if="searchParams.type == '2'" class="bgColor1"></view> + </view> + </view> + <view class="flex a-center j-between mx-27 pl-38 border2"> + <view class="flex a-center flex1"> + <image src="../../static/search.png" mode="widthFix" class="w-31 h-31 shrink0 mr-13" /> + <input v-model="searchParams.searchStr" class="fs-27 flex1" placeholder="输入姓名、联系电话关键字搜索" /> + </view> + <view @click="searchList" class="fs-23 lh-69 txt-center px-29 br-48 my-4 mx-4 bgcolor88">搜索</view> + </view> + </view> + <view v-if="list.length == 0 && status == 'noMore'" class="mt-200"> + <image src="../../static/空空如也@2x.png" mode="widthFix" class="w100"></image> + <view class="txt-center mt-94 fs-27 color9"> + 暂无数据 + </view> + </view> + <view v-else class="pl-31 pr-31"> + <view class="mt-31 br-19 bgColor3 shadow2 oh pb-31" v-for="(item,index) in list" :key="item.id" + @click="toDetailProgress(item)"> + <view class="pt-21 pl-27 pr-27 flex a-center j-between fs-27 font-bold"> + <view class=""> + 诉求号:{{ item.serialNumber || '' }} + </view> + <view class="color3 flex a-center"> + <view v-if="status == '2'" + class="fs-23 font-w500 flex a-center pl-10 pr-12 mr-17 bgColor7 h-50 br-8 color8"> + <view class="w-27 h-27 color3 bgColor2 txt-center br-18 fs-20 flex a-center j-center mr-17"> + i + </view> + 已超时{{ item.overTimeDays }}天 + </view> + {{ statusObj[item.status] }} + </view> + </view> + <view v-if="[5,6].includes(item.status)" class="mt-40 fs-23 pl-40 pr-40"> + <view class="flex j-between a-center"> + <view class="color4"> + 上报人:<text class="color5">{{ item.reporter || '' }}</text> + </view> + <view class="color4"> + 所属部门:<text class="color5">{{ item.departmentName || '' }}</text> + </view> + </view> + <view class="mt-15"> + <view class="color4"> + 提交时间:<text class="color5">{{ item.reportTime | formatTime }}</text> + </view> + </view> + </view> + <view class="mt-27 ml-40 mr-40 br-19 bgColor4 pt-34 pb-34 fs-27 pl-27 pr-27 flex a-center j-between"> + <text>{{ item.location || '' }}</text> + <image src="../../static/position@2x.png" class="w-31 h-31 ml-10 shrink0"></image> + </view> + <view class="ml-40 mr-40 mt-31 flex j-between a-center fs-27 txt-center"> + <view class=""> + <view class="font-bold"> + 问题类型 + </view> + <view class="tip"> + {{ item.problemType || '' }} + </view> + </view> + <view class=""> + <view class="font-bold"> + 群众姓名 + </view> + <view class="mt-10"> + {{ item.name || '' }} + </view> + </view> + <view class="flex a-center"> + <view style="text-align: left;"> + <view class="font-bold"> + 联系电话 + </view> + <view class="mt-10"> + {{ item.contactNumber || '' }} + </view> + </view> + <image @click.stop="callPhone(item.contactNumber)" src="../../static/tell.png" + class="w-58 h-58 shrink0 " /> + </view> + </view> + <view class="mt-31 border1"> + <view class="left"></view> + <view class="right"></view> + <view v-if="searchParams.type == '1'"> + <view class="flex a-center j-between lh-38 mt-29 ml-38 mr-23 fs-27"> + <view>添加办理进度数</view> + <view class="font-bold">10</view> + </view> + <view class="flex a-center j-between lh-38 mt-29 ml-38 mr-23 fs-27"> + <view>已下派次数</view> + <view class="font-bold">10</view> + </view> + <view class="flex a-center j-between lh-38 mt-29 ml-38 mr-23 fs-27"> + <view>已上报次数</view> + <view class="font-bold">10</view> + </view> + <view class="flex a-center j-between lh-38 mt-29 ml-38 mr-23 fs-27"> + <view>创建时间</view> + <view class="font-bold">{{ item.createTime | formatTime }}</view> + </view> + </view> + <view v-else> + <view class="flex a-center j-between lh-38 mt-29 ml-38 mr-23 fs-27"> + <view>申请时间</view> + <view class="font-bold">2025-09-09 11:09:09</view> + </view> + <view class="flex a-center j-between lh-38 mt-29 ml-38 mr-23 fs-27"> + <view>申请人</view> + <view class="flex a-center"> + <view class="font-bold">李雷 13987654321</view> + <image @click.stop="callPhone(item.contactNumber)" src="../../static/tell.png" + class="w-58 h-58 shrink0 ml-19" /> + </view> + </view> + <view class="flex a-center j-between lh-38 mt-29 ml-38 mr-23 fs-27"> + <view>审批时间</view> + <view class="font-bold">2025-09-09 11:09:09</view> + </view> + <view class="flex a-center j-between lh-38 mt-29 ml-38 mr-23 fs-27"> + <view>审批人</view> + <view class="flex a-center"> + <view class="font-bold">李雷 13987654321</view> + <image @click.stop="callPhone(item.contactNumber)" src="../../static/tell.png" + class="w-58 h-58 shrink0 ml-19" /> + </view> + </view> + <view class="flex a-center j-between lh-38 mt-29 ml-38 mr-23 fs-27"> + <view class="shrink0">驳回理由</view> + <view style="max-width: 458rpx; text-align: right;font-weight: bold;">不同意当前申请不同意当前申请不同意当前申请 + </view> + </view> + </view> + </view> + </view> + </view> + <view class="safe-b pt-20"></view> + </view> +</template> + +<script> + import dayjs from '@/uni_modules/uview-ui/libs/util/dayjs.js' + import { + getList + } from './service.js' + export default { + data() { + return { + active: 1, + searchParams: { + pageNum: 1, + pageSize: 10, + type: '1', + searchStr: '' + }, + list: [], + status: 'loadMore', + statusObj: { + // 0-正在办理 1-延期办理 2-超时办理 3-已办结 4-群众撤销 5-上报待审核 6-上级驳回 + '0': '正在办理', + '1': '延期办理', + '2': '超时办理', + '3': '已办结', + '4': '群众撤销', + '5': '上报待审核', + '6': '上级驳回', + '7': '延期待审核', + '8': '已办结' + } + } + }, + onReachBottom() { + if (this.status == 'loadMore') { + this.searchParams.pageNum += 1 + this.fetchList(this.searchParams, (e) => { + this.list = [...this.list, ...e.records] + if (this.list.length == e.total) { + this.status = 'noMore' + } else { + this.status = 'loadMore' + } + }) + } + }, + filters: { + formatTime(val) { + if (!val) return '' + return dayjs(val).format('YYYY-MM-DD HH:mm:ss') + } + }, + onShow() { + this.searchParams.pageNum = 1 + this.fetchList(this.searchParams, (e) => { + this.list = e.records || [] + if (this.list.length == e.total) { + this.status = 'noMore' + } else { + this.status = 'loadMore' + } + }) + }, + methods: { + searchList() { + this.searchParams.pageNum = 1 + this.fetchList(this.searchParams, (e) => { + this.list = e.records || [] + if (this.list.length == e.total) { + this.status = 'noMore' + } else { + this.status = 'loadMore' + } + }) + }, + callPhone(phoneNumber) { + uni.makePhoneCall({ + phoneNumber + }); + }, + toDetailProgress(item) { + uni.navigateTo({ + url: `/pages/supervision/supervision-progress?id=${item.id}` + }) + }, + fetchList(params, callback) { + if (this.status == 'loading') return + this.status = 'loading' + getList(params).then(res => { + if (res.code == 200) { + res.data.records.map(item => { + if (item.images) { + item.images = item.images.split(',') + } + }) + callback(res.data) + } + }) + }, + // 切换状态筛选 + changeType(type) { + this.searchParams = { + pageNum: 1, + pageSize: 10, + type, //全部:不传,上报待审核:0,正在办理:1, 办结:2 + } + this.fetchList(this.searchParams, (e) => { + this.list = e.records || [] + if (this.list.length == e.total) { + this.status = 'noMore' + } else { + this.status = 'loadMore' + } + }) + }, + } + } +</script> + +<style scoped lang="scss"> + .border2 { + background: #FFFFFF; + border-radius: 38rpx; + border: 2rpx solid #DADADA; + } + + .bgcolor88 { + background: linear-gradient(270deg, #FC8D55 0%, #FF4948 100%); + color: #fff; + } + + .content { + height: 100%; + background-color: #f7f7f7; + } + + .tip { + height: 40rpx; + background-color: #FFFBE6; + border: 2rpx solid #FFF1B8; + border-radius: 8rpx; + color: #FAAD14; + text-align: center; + line-height: 40rpx; + margin-top: 8rpx; + font-size: 23rpx; + padding: 0 10rpx; + min-width: 88rpx; + } + + .shadow1 { + box-shadow: 0rpx 12rpx 15rpx 0rpx rgba(0, 0, 0, 0.1); + } + + .shadow2 { + box-shadow: 0rpx 0rpx 27rpx 0rpx rgba(0, 0, 0, 0.1); + } + + .color1 { + color: #4C4C4C; + } + + .color2 { + color: #232323; + } + + .color3 { + color: #FF4948; + } + + .color4 { + color: #929191; + } + + .color5 { + color: #000; + } + + .color6 { + color: #666666; + } + + .color7 { + color: #727272; + } + + .color8 { + color: #fff; + } + + .color9 { + color: #999999; + } + + .color10 { + color: #636363; + } + + .bgColor1 { + background: linear-gradient(270deg, #FFB318 0%, #FF330D 100%); + width: 58rpx; + height: 12rpx; + border-radius: 6rpx; + position: absolute; + left: 0; + right: 0; + bottom: -5rpx; + margin: auto; + } + + .bgColor2 { + background-color: #fff; + } + + .bgColor3 { + background: linear-gradient(180deg, #FFDCDB 0%, rgba(255, 255, 255, 0) 138rpx, #fff 100%); + } + + .bgColor4 { + background: linear-gradient(270deg, rgba(255, 241, 0, 0.5) 0%, rgba(255, 249, 172, 0.25) 48%, rgba(255, 255, 255, 0.2) 100%, #FFFFFF 100%); + } + + .bgColor5 { + background: #F3F3F3; + } + + .bgColor6 { + background: linear-gradient(270deg, #FC8D55 0%, #FF4948 100%); + } + + .bgColor7 { + background: #FF4948; + } + + .border1 { + border-top: 2rpx solid #EDEEEF; + position: relative; + + .left { + width: 40rpx; + height: 40rpx; + background-color: #F4F4F4; + border-radius: 50%; + position: absolute; + left: -20rpx; + top: -20rpx; + } + + .right { + width: 40rpx; + height: 40rpx; + background-color: #F4F4F4; + border-radius: 50%; + position: absolute; + right: -20rpx; + top: -20rpx; + } + } +</style> \ No newline at end of file diff --git a/H5/pages/work-detail/work-detail.vue b/H5/pages/work-detail/work-detail.vue index c999127..f0d15bd 100644 --- a/H5/pages/work-detail/work-detail.vue +++ b/H5/pages/work-detail/work-detail.vue @@ -58,7 +58,11 @@ </view> <view class="flex j-between"> <view class="label">联系电话</view> - <view class="value">{{ orderInfo.auditorPhone || '' }}</view> + <view class="flex a-center"> + <view class="value">{{ orderInfo.auditorPhone || '' }}</view> + <image @click.stop="callPhone(orderInfo.contactNumber)" src="../../static/tell.png" + class="w-58 h-58 shrink0 " /> + </view> </view> <view class="flex j-between"> <view class="label">驳回原因</view> @@ -78,7 +82,11 @@ </view> <view class="flex j-between"> <view class="label">联系电话</view> - <view class="value">{{ orderInfo.reporterPhone || '' }}</view> + <view class="flex a-center"> + <view class="value">{{ orderInfo.reporterPhone || '' }}</view> + <image @click.stop="callPhone(orderInfo.contactNumber)" src="../../static/tell.png" + class="w-58 h-58 shrink0 " /> + </view> </view> <view class="flex j-between" v-if="isParty"> <view class="label">所属部门</view> @@ -125,7 +133,11 @@ </view> <view class="flex j-between"> <view class="label"> 联系电话</view> - <view class="value">{{ orderInfo.contactNumber || "" }}</view> + <view class="flex a-center"> + <view class="value">{{ orderInfo.contactNumber || '' }}</view> + <image @click.stop="callPhone(orderInfo.contactNumber)" src="../../static/tell.png" + class="w-58 h-58 shrink0 " /> + </view> </view> <view class="flex j-between"> <view class="label">详细地址</view> @@ -139,7 +151,11 @@ </view> <view class="flex j-between"> <view class="label">录入人联系方式</view> - <view class="value">{{ orderInfo.reportUserPhone || '' }}</view> + <view class="flex a-center"> + <view class="value">{{ orderInfo.reportUserPhone || '' }}</view> + <image @click.stop="callPhone(orderInfo.reportUserPhone)" src="../../static/tell.png" + class="w-58 h-58 shrink0 " /> + </view> </view> </view> @@ -149,6 +165,14 @@ <!-- 问题描述 --> <view class="problem"> <view class="title">问题描述</view> + <view v-for="(item,index) in 2" :key="index" + class="flex a-center j-between py-17 px-19 br-8 bgcolor1 mb-19"> + <view class="fs-27 lh-38">语音名字</view> + <image v-if="!playFlag" @click.stop="playRecording(item)" src="../../static/24gf-playCircle@2x.png" + class="w-27 h-27 shrink0" /> + <image v-else @click.stop="pausePlaying" src="../../static/pausePlaying.png" + class="w-27 h-27 shrink0" /> + </view> <view class="desc"> <!-- <view class="top">{{ orderInfo.descriptionTitle || "" }}</view> --> <!-- <view class="line1"></view> --> @@ -189,12 +213,16 @@ <view class="topInfo"> <view class="flex a-center j-between mb-15"> <view class="flex a-center"> - <view class="name">办结人员:</view> + <view class="name shrink0">办结人员:</view> <view class="value">{{ orderInfo.completionUsername || '' }}</view> </view> <view class="flex a-center"> - <view class="name">联系电话:</view> - <view class="value">{{ orderInfo.completionUserPhone || '' }}</view> + <view class="name shrink0">联系电话:</view> + <view class="flex a-center"> + <view class="value">{{ orderInfo.completionUserPhone || '' }}</view> + <image @click.stop="callPhone(orderInfo.completionUserPhone)" + src="../../static/tell.png" class="w-58 h-58 shrink0 " /> + </view> </view> </view> <view class="flex a-center"> @@ -368,6 +396,10 @@ delayAudit, revoke } from './service.js' + import { + mapActions, + mapState + } from "vuex"; export default { data() { return { @@ -388,6 +420,9 @@ userInfo: uni.getStorageSync('userInfo'), //个人信息 isParty: false, //true 党员 false 管理员 }; + }, + computed: { + ...mapState(["playFlag"]), }, onPageScroll(e) { this.scoreTopHeight = e.scrollTop @@ -418,6 +453,12 @@ // }) }, methods: { + ...mapActions(["playRecording", "pausePlaying"]), + callPhone(phoneNumber) { + uni.makePhoneCall({ + phoneNumber + }); + }, // 确认撤回 comfirm() { revoke({ @@ -628,6 +669,11 @@ </style> <style lang="scss" scoped> + .bgcolor1 { + background: #FFF1F4; + box-shadow: 0rpx 0rpx 27rpx 0rpx rgba(0, 0, 0, 0.1); + } + .color5 { color: #666160; } diff --git a/H5/static/24gf-playCircle@2x.png b/H5/static/24gf-playCircle@2x.png new file mode 100644 index 0000000..135312f --- /dev/null +++ b/H5/static/24gf-playCircle@2x.png Binary files differ diff --git a/H5/static/home/Group 2@2x.png b/H5/static/Group 2@2x.png similarity index 100% rename from H5/static/home/Group 2@2x.png rename to H5/static/Group 2@2x.png Binary files differ diff --git a/H5/static/home/supervision.png b/H5/static/home/supervision.png new file mode 100644 index 0000000..3740aae --- /dev/null +++ b/H5/static/home/supervision.png Binary files differ diff --git a/H5/static/pausePlaying.png b/H5/static/pausePlaying.png new file mode 100644 index 0000000..2f7b3f4 --- /dev/null +++ b/H5/static/pausePlaying.png Binary files differ diff --git a/H5/static/search.png b/H5/static/search.png new file mode 100644 index 0000000..1c8929e --- /dev/null +++ b/H5/static/search.png Binary files differ diff --git a/H5/static/tell.png b/H5/static/tell.png new file mode 100644 index 0000000..d2ba26d --- /dev/null +++ b/H5/static/tell.png Binary files differ diff --git a/H5/store/index.js b/H5/store/index.js index c111b4a..b3c0662 100644 --- a/H5/store/index.js +++ b/H5/store/index.js @@ -5,13 +5,70 @@ const store = new Vuex.Store({ state: { isList: false, + innerAudioContext: null, + playFlag: false //是否在播放 }, mutations: { SET_ISLIST(state, data) { state.isList = data - } + }, }, - actions: {} + actions: { + // 开始播放 + playRecording({ + state, + dispatch + }, url) { + if (state.innerAudioContext) { + state.innerAudioContext.play() + return + } + state.innerAudioContext = uni.createInnerAudioContext(); + state.innerAudioContext.autoplay = true; + // state.innerAudioContext.src = + // 'https://haitunyingyu.obs.cn-southwest-2.myhuaweicloud.com/admin/6660c5497ff34ee5b2bddaed01dd3880.wav'; + state.innerAudioContext.src = url + state.innerAudioContext.onPlay(() => { + state.playFlag = true; + }); + state.innerAudioContext.onError((res) => { + // console.log('播放错误', res); + dispatch('stopPlaying') + }); + state.innerAudioContext.onEnded((res) => { + // console.log('播放自然结束', res); + dispatch('stopPlaying') + }); + }, + // 暂停播放 + pausePlaying({ + state + }) { + if (state.innerAudioContext) { + try { + state.innerAudioContext.pause(); + state.playFlag = false; + } catch (e) { + //TODO handle the exception + } + } + }, + // 停止播放 + stopPlaying({ + state + }) { + if (state.innerAudioContext) { + try { + state.innerAudioContext.stop(); + state.innerAudioContext.destroy() + state.innerAudioContext = null + state.playFlag = false; + } catch (e) { + //TODO handle the exception + } + } + } + } }) export default store \ No newline at end of file -- Gitblit v1.7.1