pyt
2025-02-25 195c9fa42adb18ae1a9cbbfa13ee8ad3ad6cade7
Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/H5/threeSide
17个文件已修改
5个文件已添加
2193 ■■■■■ 已修改文件
H5/pages/add-progress/index.vue 510 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/pages/dispatchWorkOrder/dispatchWorkOrder.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/pages/index/index.vue 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/pages/list/list.vue 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/pages/problemReporting/problemReporting.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/pages/result-entry/index.vue 678 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/pages/work-detail/postpone-apply.vue 307 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/pages/work-detail/service.js 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/pages/work-detail/work-detail.vue 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/static/packUp.png 补丁 | 查看 | 原始文档 | blame | 历史
H5/static/unfold.png 补丁 | 查看 | 原始文档 | blame | 历史
H5/utils/request.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/config/routes.ts 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/app.tsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/components/RightContent/AvatarDropdown.tsx 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/components/RightContent/service.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/global.less 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/pages/setting/role/components/addAndEdit.jsx 192 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/pages/setting/role/index.jsx 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/pages/setting/role/service.js 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/requestErrorConfig.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/utils/antdUtils.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/pages/add-progress/index.vue
@@ -6,7 +6,7 @@
                <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.detailedAddress }}</view>
                <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">
@@ -79,104 +79,153 @@
</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: {
        submit() {
            if (!this.describe) {
                this.rulsFlag = true
                return uni.showToast({
                    icon: 'none',
                    title: '请输入办理进度描述'
                })
    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,
            }
            if (this.imgUrls.length == 0) {
                return uni.showToast({
                    icon: 'none',
                    title: '请上传图片'
                })
            }
            if (this.video.length == 0) {
                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,
        },
        onLoad(params) {
            this.complaintId = params.id
            getComplaintDetail({
                id: params.id
            }).then(res => {
                this.info = res.data
            })
        },
        methods: {
            submit() {
                if (!this.describe) {
                    this.rulsFlag = true
                    return uni.showToast({
                        icon: 'none',
                        mask: true
                        title: '请输入办理进度描述'
                    })
                }
            })
        },
        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) {
                if (this.imgUrls.length == 0) {
                    return uni.showToast({
                        icon: 'none',
                        title: '请上传图片'
                    })
                }
                if (this.video.length == 0) {
                    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: config.uploadToken
                                    },
                                    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
                                        })
                                    }
                                })
                            }
                        },
                    })
                } else {
                    uni.chooseVideo({
                        camera: 'back',
                        success: (res) => {
                            this.video.push('loading')
                            this.againCklicFlag = true
                            const tempFilePath = res.tempFilePath;
                            uni.uploadFile({
                                url: config.imageUrl,
                                filePath: imgPathList[0],
                                filePath: tempFilePath,
                                timeout: 1000 * 45,
                                name: 'file',
                                header: {
@@ -184,16 +233,14 @@
                                },
                                success: (res) => {
                                    if (JSON.parse(res.data).code == 200) {
                                        this.imgUrls = this.imgUrls.filter(item => item !=
                                        this.video = this.video.filter(item => item !=
                                            'loading')
                                        this.$nextTick(() => {
                                            this.imgUrls.push(JSON.parse(res.data)
                                                .data)
                                            this.localImageUrls.push(imgPathList[0])
                                            this.video.push(JSON.parse(res.data).data)
                                        })
                                    } else {
                                        this.againCklicFlag = true
                                        this.imgUrls = this.imgUrls.filter(
                                        this.video = this.video.filter(
                                            item => item != 'loading')
                                        uni.showToast({
                                            title: '上传失败,请重新上传',
@@ -204,7 +251,7 @@
                                },
                                fail: (err) => {
                                    this.againCklicFlag = true
                                    this.imgUrls = this.imgUrls.filter(
                                    this.video = this.video.filter(
                                        item => item != 'loading')
                                    uni.showToast({
                                        title: '上传失败,请重新上传',
@@ -214,175 +261,128 @@
                                }
                            })
                        }
                    },
                    })
                }
            },
            // 去大屏播放视频
            openVideo(url) {
                uni.navigateTo({
                    url: `/pages/work-detail/maxVideo?url=${url}`
                })
            } else {
                uni.chooseVideo({
                    camera: 'back',
                    success: (res) => {
                        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: config.uploadToken
                            },
                            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
                                })
                            }
                        })
                    }
                })
            }
        },
        // 去大屏播放视频
        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;
    .bs-1 {
        box-shadow: 0rpx 0rpx 27rpx 0rpx rgba(0, 0, 0, 0.1);
    }
    .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;
    .color1 {
        color: #FF4948;
    }
        .video {
            z-index: 999;
    .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;
}
    .videoImg {
        width: 140.38rpx;
        height: 140.38rpx;
        border-radius: 7.69rpx;
        position: relative;
    }
#myVideo {
    z-index: 1;
}
    #myVideo {
        z-index: 1;
    }
.zIndex999 {
    z-index: 999;
}
    .zIndex999 {
        z-index: 999;
    }
</style>
H5/pages/dispatchWorkOrder/dispatchWorkOrder.vue
@@ -7,7 +7,7 @@
            </view>
            <view class="address">
                <view class="adr">{{detail.detailedAddress || ''}}</view>
                <view class="adr">{{detail.location || ''}}</view>
                <image src="/static/position@2x.png" class="w-31 h-31" mode="aspectFill"></image>
            </view>
@@ -76,7 +76,7 @@
            };
        },
        onLoad(option) {
            option.id = 1
            // option.id = 1
            if (option.id) {
                this.id = option.id
                getDetail({
H5/pages/index/index.vue
@@ -27,7 +27,7 @@
                    <image class="w-81 h-77 ml-38" src="/static/home/img4.png" mode=""></image>
                    <text class="ml-37">诉求录入</text>
                </view>
                <view class="pt-38  pb-38 bg1 w-333 mt-19 br-19 flex a-center">
                <view class="pt-38  pb-38 bg1 w-333 mt-19 br-19 flex a-center" @click="goToList()">
                    <image class="w-81 h-77 ml-38" src="/static/home/img2.png" mode=""></image>
                    <text class="ml-37">诉求列表</text>
                </view>
@@ -117,11 +117,14 @@
                bannerlist: [],
                msgList: [],
                msgListTotal: [],
                member:1,
                userInfo:{},
                member: 1,
                userInfo: {},
            }
        },
        onLoad() {
        onLoad(e) {
            if (e.token && e.token != 'null') {
                uni.setStorageSync('token', e.token)
            }
            this.getBanner()
            this.getMessagelist()
            this.getappletcinfo()
@@ -133,13 +136,13 @@
                    this.bannerlist = resp.data
                })
            },
            getappletcinfo(){
                getappletcinfo().then(resp=>{
                    console.log(resp,'-----判断角色');
                    this.userInfo =resp.data
                    this.member =resp.data?2:1
                    uni.setStorageSync('userInfo',resp.data)
                    uni.setStorageSync('member',this.member)
            getappletcinfo() {
                getappletcinfo().then(resp => {
                    console.log(resp, '-----判断角色');
                    this.userInfo = resp.data
                    this.member = resp.data ? 2 : 1
                    uni.setStorageSync('userInfo', resp.data)
                    uni.setStorageSync('member', this.member)
                })
            },
            getMessagelist() {
@@ -153,22 +156,23 @@
                        const timeDifference = new Date().getTime() - new Date(item.createTime).getTime()
                        // 使用 dayjs 的 duration 来处理时间差
                          // 计算总秒数
                            const totalSeconds = Math.floor(timeDifference / 1000);
                            // 计算天数
                            const days = Math.floor(totalSeconds / (3600 * 24));
                            // 计算剩余的秒数
                            const remainingSecondsAfterDays = totalSeconds % (3600 * 24);
                            // 计算小时数
                            const hours = Math.floor(remainingSecondsAfterDays / 3600);
                            // 计算剩余的秒数
                            const remainingSecondsAfterHours = remainingSecondsAfterDays % 3600;
                            // 计算分钟数
                            const minutes = Math.floor(remainingSecondsAfterHours / 60);
                        item.time = days&&hours?`${days} 天 ${hours}小时 ${minutes} `:!days&&hours?`${hours}小时 ${minutes}`:`${minutes}`
                        // 计算总秒数
                        const totalSeconds = Math.floor(timeDifference / 1000);
                        // 计算天数
                        const days = Math.floor(totalSeconds / (3600 * 24));
                        // 计算剩余的秒数
                        const remainingSecondsAfterDays = totalSeconds % (3600 * 24);
                        // 计算小时数
                        const hours = Math.floor(remainingSecondsAfterDays / 3600);
                        // 计算剩余的秒数
                        const remainingSecondsAfterHours = remainingSecondsAfterDays % 3600;
                        // 计算分钟数
                        const minutes = Math.floor(remainingSecondsAfterHours / 60);
                        item.time = days && hours ? `${days} 天 ${hours}小时 ${minutes} ` : !days && hours ?
                            `${hours}小时 ${minutes}` : `${minutes}`
                        return item
                    })
                    this.msgList = JSON.parse(JSON.stringify(this.msgListTotal)).filter(item => item.promptType ==
@@ -208,6 +212,11 @@
                    }
                });
            },
            goToList() {
                uni.navigateTo({
                    url: '/pages/list/list'
                })
            }
        }
    }
H5/pages/list/list.vue
@@ -8,19 +8,22 @@
                </view>
                <view v-if="searchParams.type == ''" class="bgColor1"></view>
            </view>
            <view @click="changeType('0')" class="flex1 relative" :class="searchParams.type == '0' && 'color2 font-bold'">
            <view @click="changeType('0')" class="flex1 relative"
                :class="searchParams.type == '0' && 'color2 font-bold'">
                <view class="relative zIndex1000">
                    上报待审核
                </view>
                <view v-if="searchParams.type == '0'" class="bgColor1"></view>
            </view>
            <view @click="changeType('1')" class="flex1 relative" :class="searchParams.type == '1' && 'color2 font-bold'">
            <view @click="changeType('1')" class="flex1 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 relative" :class="searchParams.type == '2' && 'color2 font-bold'">
            <view @click="changeType('2')" class="flex1 relative"
                :class="searchParams.type == '2' && 'color2 font-bold'">
                <view class="relative zIndex1000">
                    办结
                </view>
@@ -34,13 +37,15 @@
            </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">
            <view class="mt-31 br-19 bgColor3 shadow2 oh pb-31" v-for="(item,index) in list" :key="item.id"
                @click="toDetail(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 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>
@@ -107,8 +112,9 @@
                        描述图片
                    </view>
                    <view class="mt-19 flex wrap a-center">
                        <image v-for="(item1,index) in item.images" :key="index" :src="item1" @click="previewImage(item.images,index)"
                            class="br-19 w-142 h-154 mr-13 mb-10 shrink0" mode="aspectFill"></image>
                        <image v-for="(item1,index) in item.images" :key="index" :src="item1"
                            @click="previewImage(item.images,index)" class="br-19 w-142 h-154 mr-13 mb-10 shrink0"
                            mode="aspectFill"></image>
                    </view>
                </view>
                <view class="mt-31 border1">
@@ -128,7 +134,7 @@
                </view>
            </view>
        </view>
        <view class="safe-b pt-20"></view>
    </view>
</template>
@@ -145,9 +151,9 @@
                searchParams: {
                    pageNum: 1,
                    pageSize: 10,
                    type: '',//全部:不传,上报待审核:0,正在办理:1, 办结:2
                    type: '', //全部:不传,上报待审核:0,正在办理:1, 办结:2
                },
                list:[],
                list: [],
                status: 'loadMore',
                statusObj: {
                    // 0-正在办理 1-延期办理 2-超时办理 3-已办结 4-群众撤销 5-上报待审核 6-上级驳回
@@ -164,8 +170,8 @@
        onReachBottom() {
            if (this.status == 'loadMore') {
                this.searchParams.pageNum += 1
                this.fetchList(this.searchParams,(e)=>{
                    this.list = [...this.list,...e.records]
                this.fetchList(this.searchParams, (e) => {
                    this.list = [...this.list, ...e.records]
                    if (this.list.length == e.total) {
                        this.status = 'noMore'
                    } else {
@@ -182,7 +188,7 @@
        },
        onShow() {
            this.searchParams.pageNum = 1
            this.fetchList(this.searchParams,(e)=>{
            this.fetchList(this.searchParams, (e) => {
                this.list = e.records || []
                if (this.list.length == e.total) {
                    this.status = 'noMore'
@@ -192,12 +198,12 @@
            })
        },
        methods: {
            fetchList(params,callback) {
            fetchList(params, callback) {
                if (this.status == 'loading') return
                this.status = 'loading'
                getList(params).then(res=>{
                getList(params).then(res => {
                    if (res.code == 200) {
                        res.data.records.map(item=>{
                        res.data.records.map(item => {
                            if (item.images) {
                                item.images = item.images.split(',')
                            }
@@ -209,23 +215,23 @@
            // 添加办理进度
            addProgress(id) {
                uni.navigateTo({
                    url:`/pages/progress/progress?id=${id}`
                    url: `/pages/progress/progress?id=${id}`
                })
            },
            // 办理结果录入
            addResult(id) {
                uni.navigateTo({
                    url:`/pages/result-entry/index?id=${id}`
                    url: `/pages/result-entry/index?id=${id}`
                })
            },
            // 切换状态筛选
            changeType(type) {
                this.searchParams = {
                    pageNum: 1,
                    pageSize: 10,
                    type,//全部:不传,上报待审核:0,正在办理:1, 办结:2
                this.searchParams = {
                    pageNum: 1,
                    pageSize: 10,
                    type, //全部:不传,上报待审核:0,正在办理:1, 办结:2
                }
                this.fetchList(this.searchParams,(e)=>{
                this.fetchList(this.searchParams, (e) => {
                    this.list = e.records || []
                    if (this.list.length == e.total) {
                        this.status = 'noMore'
@@ -235,12 +241,17 @@
                })
            },
            // 预览图片
            previewImage(list,index) {
            previewImage(list, index) {
                uni.previewImage({
                    urls: list,
                    current: index,
                });
            },
            toDetail(item) {
                uni.navigateTo({
                    url: `/pages/work-detail/work-detail?id=${item.id}`
                })
            }
        }
    }
</script>
@@ -303,7 +314,7 @@
    .color8 {
        color: #fff;
    }
    .color9 {
        color: #999999;
    }
@@ -339,7 +350,7 @@
    .bgColor6 {
        background: linear-gradient(270deg, #FC8D55 0%, #FF4948 100%);
    }
    .bgColor7 {
        background: #FF4948;
    }
H5/pages/problemReporting/problemReporting.vue
@@ -7,7 +7,7 @@
            </view>
            <view class="address">
                <view class="adr">{{detail.detailedAddress || ''}}</view>
                <view class="adr">{{detail.location || ''}}</view>
                <image src="/static/position@2x.png" class="w-31 h-31" mode="aspectFill"></image>
            </view>
@@ -63,7 +63,7 @@
            };
        },
        onLoad(option) {
            option.id = 1
            // option.id = 1
            if (option.id) {
                this.id = option.id
                getDetail({
H5/pages/result-entry/index.vue
@@ -9,7 +9,7 @@
                    </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.detailedAddress }}</view>
                    <view class="fs-27 lh-38 color2">{{ info.location }}</view>
                    <image src="@/static/detailImg/dwei.png" class="w-31 h-31 shrink0" />
                </view>
                <view v-if="!unfoldFlag" class="flex a-center j-between mt-31 mx-13">
@@ -77,14 +77,15 @@
                    </view>
                </view>
            </view>
            <view @tap="unfold" class="bgcolor3 absolute w-100 txt-center"
                style="bottom:-58rpx;left: 50%;transform: translate(-50%,-50%);">
                <image src="/static/location/back.png" class="h-23 w-15" style="transform: rotate(-90deg);" />
            <view @tap="unfold" class="absolute" style="bottom:-90rpx;left: 50%;transform: translate(-50%,-50%);">
                <image v-if="!unfoldFlag" src="@/static/unfold.png" class="h-54 w-156" />
                <image v-if="unfoldFlag" src="@/static/packUp.png" class="h-54 w-156" />
            </view>
        </view>
        <view class="br-19 mt-76 bs-1 pt-35 pb-33">
            <view class="fs-27 lh-38 font-bold ml-31">处理状态</view>
            <view @tap="showList = true" class="br-15 py-15 pl-31 mx-31 pr-27 mt-27 flex j-between a-center border2" :class="(rulsFlag && !status) && 'bgcolor-border'">
            <view @tap="showList = true" class="br-15 py-15 pl-31 mx-31 pr-27 mt-27 flex j-between a-center border2"
                :class="(rulsFlag && !status) && 'bgcolor-border'">
                <view :class="!status && 'color6'">{{ status ? status : '请选择当前处理状态' }}</view>
                <image src="/static/location/back.png" class="h-23 w-15" style="transform: rotate(-90deg);" />
            </view>
@@ -174,126 +175,186 @@
</template>
<script>
import { saveResult, getComplaintDetail } from './service'
import config from '@/config/index.js'
export default {
    data() {
        return {
            showList: false,
            columns: [['已办结', '群众撤销']],
            unfoldFlag: false, //是否展开
            id: '',//诉求id
            info: {},//工单详情
            completionDescription: '',//办结结果描述
            localImageUrls: [], //本地回显的图片
            completionImages: [],//办结结果图片
            completionOtherDescription: '',//其他说明
            completionVideos: [],//办结结果视频
            status: '',//处理状态
            againCklicFlag: true,
            rulsFlag: false,
        }
    },
    onLoad(params) {
        this.id = params.id
        getComplaintDetail({ id: params.id }).then(res => {
            this.info = res.data
        })
    },
    methods: {
        submit() {
            if (!this.status) {
                this.rulsFlag = true
                return uni.showToast({
                    title: '请选择当前处理状态',
                    icon: 'none',
                    mask: true
                })
    import {
        saveResult,
        getComplaintDetail
    } from './service'
    import config from '@/config/index.js'
    export default {
        data() {
            return {
                showList: false,
                columns: [
                    ['已办结', '群众撤销']
                ],
                unfoldFlag: false, //是否展开
                id: '', //诉求id
                info: {}, //工单详情
                completionDescription: '', //办结结果描述
                localImageUrls: [], //本地回显的图片
                completionImages: [], //办结结果图片
                completionOtherDescription: '', //其他说明
                completionVideos: [], //办结结果视频
                status: '', //处理状态
                againCklicFlag: true,
                rulsFlag: false,
            }
            if (!this.completionDescription) {
                this.rulsFlag = true
                return uni.showToast({
                    title: '请填写办结结果描述',
                    icon: 'none',
                    mask: true
                })
            }
            if (this.completionImages.length == 0) {
                return uni.showToast({
                    title: '请上传办结结果图片',
                    icon: 'none',
                    mask: true
                })
            }
            if (this.completionVideos.length == 0) {
                return uni.showToast({
                    title: '请上传办结结果视频',
                    icon: 'none',
                    mask: true
                })
            }
            saveResult({
                id: this.id,
                status: this.status == '已办结' ? 3 : 4,
                completionDescription: this.completionDescription,
                completionImages: this.completionImages.join(','),
                completionOtherDescription: this.completionOtherDescription,
                completionVideos: this.completionVideos.join(',')
        },
        onLoad(params) {
            this.id = params.id
            getComplaintDetail({
                id: params.id
            }).then(res => {
                if (res.code == 200) {
                    uni.showToast({
                        title: '提交成功',
                        icon: 'success',
                        mask: true
                    })
                    setTimeout(() => {
                        uni.navigateBack()
                    }, 1500)
                } else {
                    uni.showToast({
                        title: res.msg,
                this.info = res.data
            })
        },
        methods: {
            submit() {
                if (!this.status) {
                    this.rulsFlag = true
                    return uni.showToast({
                        title: '请选择当前处理状态',
                        icon: 'none',
                        mask: true
                    })
                }
            })
        },
        confirm({ value }) {
            this.status = value[0]
            this.showList = false
        },
        cancel() {
            this.showList = false
        },
        unfold() {
            this.unfoldFlag = !this.unfoldFlag
        },
        delImg(item) {
            this.localImageUrls = this.localImageUrls.filter(i => i != item)
            this.completionImages = this.completionImages.filter(i => i != item)
        },
        delVideo(item) {
            this.completionVideos = this.completionVideos.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.completionImages.push('loading')
                        this.againCklicFlag = true
                        let imgPathList = chooseImageRes.tempFilePaths;
                        if (imgPathList.length > 0) {
                if (!this.completionDescription) {
                    this.rulsFlag = true
                    return uni.showToast({
                        title: '请填写办结结果描述',
                        icon: 'none',
                        mask: true
                    })
                }
                if (this.completionImages.length == 0) {
                    return uni.showToast({
                        title: '请上传办结结果图片',
                        icon: 'none',
                        mask: true
                    })
                }
                if (this.completionVideos.length == 0) {
                    return uni.showToast({
                        title: '请上传办结结果视频',
                        icon: 'none',
                        mask: true
                    })
                }
                saveResult({
                    id: this.id,
                    status: this.status == '已办结' ? 3 : 4,
                    completionDescription: this.completionDescription,
                    completionImages: this.completionImages.join(','),
                    completionOtherDescription: this.completionOtherDescription,
                    completionVideos: this.completionVideos.join(',')
                }).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
                        })
                    }
                })
            },
            confirm({
                value
            }) {
                this.status = value[0]
                this.showList = false
            },
            cancel() {
                this.showList = false
            },
            unfold() {
                this.unfoldFlag = !this.unfoldFlag
            },
            delImg(item) {
                this.localImageUrls = this.localImageUrls.filter(i => i != item)
                this.completionImages = this.completionImages.filter(i => i != item)
            },
            delVideo(item) {
                this.completionVideos = this.completionVideos.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.completionImages.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: config.uploadToken
                                    },
                                    success: (res) => {
                                        if (JSON.parse(res.data).code == 200) {
                                            this.completionImages = this.completionImages.filter(
                                                item => item !=
                                                'loading')
                                            this.$nextTick(() => {
                                                this.completionImages.push(JSON.parse(res
                                                        .data)
                                                    .data)
                                                this.localImageUrls.push(imgPathList[0])
                                            })
                                        } else {
                                            this.againCklicFlag = true
                                            this.completionImages = this.completionImages.filter(
                                                item => item != 'loading')
                                            uni.showToast({
                                                title: '上传失败,请重新上传',
                                                icon: 'none',
                                                mask: true
                                            })
                                        }
                                    },
                                    fail: (err) => {
                                        this.againCklicFlag = true
                                        this.completionImages = this.completionImages.filter(
                                            item => item != 'loading')
                                        uni.showToast({
                                            title: '上传失败,请重新上传',
                                            icon: 'none',
                                            mask: true
                                        })
                                    }
                                })
                            }
                        },
                    })
                } else {
                    uni.chooseVideo({
                        camera: 'back',
                        success: (res) => {
                            this.completionVideos.push('loading')
                            this.againCklicFlag = true
                            const tempFilePath = res.tempFilePath;
                            uni.uploadFile({
                                url: config.imageUrl,
                                filePath: imgPathList[0],
                                filePath: tempFilePath,
                                timeout: 1000 * 45,
                                name: 'file',
                                header: {
@@ -301,16 +362,16 @@
                                },
                                success: (res) => {
                                    if (JSON.parse(res.data).code == 200) {
                                        this.completionImages = this.completionImages.filter(item => item !=
                                        this.completionVideos = this.completionVideos.filter(
                                            item => item !=
                                            'loading')
                                        this.$nextTick(() => {
                                            this.completionImages.push(JSON.parse(res.data)
                                            this.completionVideos.push(JSON.parse(res.data)
                                                .data)
                                            this.localImageUrls.push(imgPathList[0])
                                        })
                                    } else {
                                        this.againCklicFlag = true
                                        this.completionImages = this.completionImages.filter(
                                        this.completionVideos = this.completionVideos.filter(
                                            item => item != 'loading')
                                        uni.showToast({
                                            title: '上传失败,请重新上传',
@@ -321,7 +382,7 @@
                                },
                                fail: (err) => {
                                    this.againCklicFlag = true
                                    this.completionImages = this.completionImages.filter(
                                    this.completionVideos = this.completionVideos.filter(
                                        item => item != 'loading')
                                    uni.showToast({
                                        title: '上传失败,请重新上传',
@@ -331,195 +392,117 @@
                                }
                            })
                        }
                    },
                    })
                }
            },
            // 去大屏播放视频
            openVideo(url) {
                uni.navigateTo({
                    url: `/pages/work-detail/maxVideo?url=${url}`
                })
            } else {
                uni.chooseVideo({
                    camera: 'back',
                    success: (res) => {
                        this.completionVideos.push('loading')
                        this.againCklicFlag = true
                        const tempFilePath = res.tempFilePath;
                        uni.uploadFile({
                            url: config.imageUrl,
                            filePath: tempFilePath,
                            timeout: 1000 * 45,
                            name: 'file',
                            header: {
                                Authorization: config.uploadToken
                            },
                            success: (res) => {
                                if (JSON.parse(res.data).code == 200) {
                                    this.completionVideos = this.completionVideos.filter(item => item !=
                                        'loading')
                                    this.$nextTick(() => {
                                        this.completionVideos.push(JSON.parse(res.data).data)
                                    })
                                } else {
                                    this.againCklicFlag = true
                                    this.completionVideos = this.completionVideos.filter(
                                        item => item != 'loading')
                                    uni.showToast({
                                        title: '上传失败,请重新上传',
                                        icon: 'none',
                                        mask: true
                                    })
                                }
                            },
                            fail: (err) => {
                                this.againCklicFlag = true
                                this.completionVideos = this.completionVideos.filter(
                                    item => item != 'loading')
                                uni.showToast({
                                    title: '上传失败,请重新上传',
                                    icon: 'none',
                                    mask: 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;
}
.color5 {
    color: #FC8D55;
}
.color6 {
    color: rgba(0, 0, 0, 0.24);
}
.color99 {
    color: #FB9A0E;
}
.bgcolor-border {
    background: rgba(255, 253, 241, 1) !important;
    border: 2rpx solid #FFE58F !important;
}
.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) 91rpx);
}
.bgcolor3 {
    background: #FFFBE6;
}
.bgcolor4 {
    background: #F8F8F8;
}
.bgcolor5 {
    background: rgba(0, 0, 0, .23);
}
.bgcolor6 {
    background: linear-gradient(270deg, #FC8D55 0%, #FF4948 100%);
}
.bgcolor7 {
    background-color: rgba(252, 141, 85, 1);
}
.bgcolor8 {
    background: #FFFBE6;
}
.border1 {
    border: 2rpx solid #FFF1B8;
}
.border2 {
    border: 2rpx solid rgba(0, 0, 0, 0.15);
}
.safe-box {
    height: env(safe-area-inset-bottom);
}
.line-box {
    box-shadow: 0rpx 0rpx 27rpx 0rpx rgba(0, 0, 0, 0.1);
    height: 2rpx;
    background: rgba(0, 10, 26, 0.07);
}
.transition-h {
    transition: max-height 0.5s ease-out;
}
.max-300 {
    max-height: 300rpx;
}
.max-9999 {
    max-height: 9999rpx;
}
.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;
    .bs-1 {
        box-shadow: 0rpx 0rpx 27rpx 0rpx rgba(0, 0, 0, 0.1);
    }
}
.imgOrVedio {
    margin-right: 17rpx;
    position: relative;
    .color1 {
        color: #FF4948;
    }
    .img {
        width: 140rpx;
        height: 140rpx;
        border-radius: 8rpx;
        margin-top: 19rpx;
    .color2 {
        color: rgba(0, 0, 0, .8);
    }
    .color3 {
        color: #FAAD14;
    }
    .color4 {
        color: #FFFFFF;
    }
    .color5 {
        color: #FC8D55;
    }
    .color6 {
        color: rgba(0, 0, 0, 0.24);
    }
    .color99 {
        color: #FB9A0E;
    }
    .bgcolor-border {
        background: rgba(255, 253, 241, 1) !important;
        border: 2rpx solid #FFE58F !important;
    }
    .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) 91rpx);
    }
    .bgcolor3 {
        background: #FFFBE6;
    }
    .bgcolor4 {
        background: #F8F8F8;
    }
    .bgcolor5 {
        background: rgba(0, 0, 0, .23);
    }
    .bgcolor6 {
        background: linear-gradient(270deg, #FC8D55 0%, #FF4948 100%);
    }
    .bgcolor7 {
        background-color: rgba(252, 141, 85, 1);
    }
    .bgcolor8 {
        background: #FFFBE6;
    }
    .border1 {
        border: 2rpx solid #FFF1B8;
    }
    .border2 {
        border: 2rpx solid rgba(0, 0, 0, 0.15);
    }
    .safe-box {
        height: env(safe-area-inset-bottom);
    }
    .line-box {
        box-shadow: 0rpx 0rpx 27rpx 0rpx rgba(0, 0, 0, 0.1);
        height: 2rpx;
        background: rgba(0, 10, 26, 0.07);
    }
    .transition-h {
        transition: max-height 0.8s cubic-bezier(0.25, 0.8, 0.25, 1);
    }
    .max-300 {
        max-height: 300rpx;
    }
    .max-9999 {
        max-height: 9999rpx;
    }
    .videoOpen {
@@ -533,6 +516,7 @@
        display: flex;
        align-items: center;
        justify-content: center;
        margin-top: 19rpx;
        .video {
            z-index: 999;
@@ -540,40 +524,70 @@
            height: 140rpx;
        }
    }
}
.videoImg {
    width: 140.38rpx;
    height: 140.38rpx;
    border-radius: 7.69rpx;
    position: relative;
}
    .imgOrVedio {
        margin-right: 17rpx;
        position: relative;
#myVideo {
    z-index: 1;
}
        .img {
            width: 140rpx;
            height: 140rpx;
            border-radius: 8rpx;
            margin-top: 19rpx;
        }
.zIndex999 {
    z-index: 999;
}
        .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;
/deep/.u-popup__content {
    border-radius: 16rpx 16rpx 0rpx 0rpx;
}
            .video {
                z-index: 999;
                width: 140rpx;
                height: 140rpx;
            }
        }
    }
/deep/ .u-toolbar {
    border-bottom: 2rpx solid RGBA(243, 243, 243, 1);
}
    .videoImg {
        width: 140.38rpx;
        height: 140.38rpx;
        border-radius: 7.69rpx;
        position: relative;
    }
/deep/ .u-toolbar__wrapper__cancel {
    font-weight: 400;
    font-size: 30rpx;
    color: #FF4948 !important;
}
    #myVideo {
        z-index: 1;
    }
/deep/ .u-toolbar__wrapper__confirm {
    font-weight: 400;
    font-size: 30rpx;
    color: #FF4948 !important;
}
    .zIndex999 {
        z-index: 999;
    }
    /deep/.u-popup__content {
        border-radius: 16rpx 16rpx 0rpx 0rpx;
    }
    /deep/ .u-toolbar {
        border-bottom: 2rpx solid RGBA(243, 243, 243, 1);
    }
    /deep/ .u-toolbar__wrapper__cancel {
        font-weight: 400;
        font-size: 30rpx;
        color: #FF4948 !important;
    }
    /deep/ .u-toolbar__wrapper__confirm {
        font-weight: 400;
        font-size: 30rpx;
        color: #FF4948 !important;
    }
</style>
H5/pages/work-detail/postpone-apply.vue
@@ -1,64 +1,81 @@
<template>
    <view class="px-31 pt-38">
        <view class="br-19 bs-1 pt-21 pb-35 px-27 bgcolor2">
        <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>诉求号:7843523454</view>
                <view class="color1">正在办理</view>
                <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">江苏省常州市溧阳市牛顿大道172号</view>
                <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">教育</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">沙振</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">14225874426</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 class="pt-25 pl-31 mt-27 fs-27 br-8 bgcolor4" style="height: 365rpx;" placeholder="请输入办理进度描述" />
            <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 in 4" :key="item">
                    <image src="/static/logo.png" class="w-140 h-140 shrink0 br-8" />
                    <view class="absolute w-140 h-140 bgcolor5 top0 left0 br-8">
                        <view class="absolute" style="top: 50%;left: 50%;transform: translate(-50%,-50%);">
                            <image @tap="viewImage(item)" src="@/static/Appeal/amplify.png" class="w-19 h-19 mr-35"
                                mode="" />
                            <image src="@/static/Appeal/trash.png" class="w-19 h-19" />
                <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>
                <image src="/static/Appeal/add.png" class="w-140 h-140 shrink0" />
                <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="relative mr-15" v-for="item in 4" :key="item">
                    <image src="@/static/logo.png" class="w-140 h-140 shrink0 br-8" />
                    <view class="absolute w-140 h-140 bgcolor5 top0 left0 br-8">
                        <view class="absolute" style="top: 50%;left: 50%;transform: translate(-50%,-50%);">
                            <image @tap="viewImage(item)" src="@/static/Appeal/amplify.png" class="w-19 h-19 mr-35"
                                mode="" />
                            <image src="@/static/Appeal/trash.png" class="w-19 h-19" />
                <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>
                <image src="@/static/Appeal/add.png" class="w-140 h-140 shrink0" />
                <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 class="mt-38 fs-35 lh-96 br-48 txt-center font-bold bgcolor6 color4">提交延期申请</view>
        <view @click.stop="submit" class="mt-38 fs-35 lh-96 br-48 txt-center font-bold bgcolor6 color4">提交延期申请
        </view>
        <view class="safe-box"></view>
        <u-popup round="19rpx" :show="showPop" mode="center" @close="close" @open="open">
            <view class="popup-content">
                <view class="title-pop">确认操作</view>
@@ -67,7 +84,7 @@
                </view>
                <view class="botton-btn">
                    <view class="cancle" @click.stop="showPop=false">取消</view>
                    <view class="sure" @click.stop="submitReject">确认</view>
                    <view class="sure" @click.stop="sureSubmit()">确认</view>
                </view>
            </view>
        </u-popup>
@@ -75,24 +92,202 @@
</template>
<script>
    import {
        saveProcess,
        getComplaintDetail
    } from './service'
    import config from '@/config/index.js'
    export default {
        data() {
            return {
                showPop: true,
                complaintId: '', //诉求id
                info: {}, //工单详情
                describe: '', //办理进度描述
                localImageUrls: [], //本地回显的图片
                imgUrls: [], //传给后端的url
                video: [],
                againCklicFlag: true,
                rulsFlag: false,
                showPop: false,
            }
        },
        onLoad(params) {
            this.complaintId = params.id
            getComplaintDetail({
                id: params.id
            }).then(res => {
                this.info = res.data
            })
        },
        methods: {
            close() {
            submit() {
                if (!this.describe) {
                    this.rulsFlag = true
                    return uni.showToast({
                        icon: 'none',
                        title: '请输入办理进度描述'
                    })
                }
                if (this.imgUrls.length == 0) {
                    return uni.showToast({
                        icon: 'none',
                        title: '请上传图片'
                    })
                }
                if (this.video.length == 0) {
                    return uni.showToast({
                        icon: 'none',
                        title: '请上传视频'
                    })
                }
                this.showPop = true
            },
            open() {
            sureSubmit() {
                let obj = {
                    complaintId: this.complaintId,
                    comment: this.describe,
                    images: this.imgUrls.join(','),
                    videos: 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: [require('@/static/logo.png')]
                    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: config.uploadToken
                                    },
                                    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
                                        })
                                    }
                                })
                            }
                        },
                    })
                } else {
                    uni.chooseVideo({
                        camera: 'back',
                        success: (res) => {
                            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: config.uploadToken
                                },
                                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
                                    })
                                }
                            })
                        }
                    })
                }
            },
            // 去大屏播放视频
            openVideo(url) {
                uni.navigateTo({
                    url: `/pages/work-detail/maxVideo?url=${url}`
                })
            },
        }
    }
</script>
@@ -150,6 +345,52 @@
        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;
    }
    .popup-content {
        background: url('/static/pop@2x.png') no-repeat center center;
        width: 576.92rpx;
H5/pages/work-detail/service.js
@@ -16,9 +16,17 @@
export const reportAudit = (params) => {
    return request.post(`/api/huacheng-sangeshenbian/applet/complaint/reportAudit`, params, 'JSON')
}
// 上级端
// 上级端-秒杀商品列表
export const getHomeGoodsSeckillVOList = (params) => {
    return request.post(`/goods/forepart/goods-seckill/getHomeGoodsSeckillVOList`, params)
// 延期申请
export const saveProcess = (params) => {
    return request.post(`/api/huacheng-sangeshenbian/applet/complaint/saveDelay`, params, )
}
// 延期申请
export const delayAudit = (params) => {
    return request.post(`/api/huacheng-sangeshenbian/applet/complaint/delayAudit`, params, )
}
// 工单详情
export const getComplaintDetail = (params) => {
    return request.get('/api/huacheng-sangeshenbian/applet/complaint/detail', params)
}
H5/pages/work-detail/work-detail.vue
@@ -1,6 +1,6 @@
<template>
    <view class="content">
        <u-navbar title="诉求详情" :bgColor="scoreTopHeight>300?'#ffffff':'transparent'" autoBack>
        <u-navbar title="诉求详情" :bgColor="scoreTopHeight>100?'#ffffff':'transparent'" autoBack>
        </u-navbar>
        <view class="topColor">
        </view>
@@ -87,7 +87,7 @@
                        </view>
                        <view class="flex j-between">
                            <view class="label">上报时间</view>
                            <view class="value">{{orderInfo.reportTime||''}}</view>
                            <view class="value">{{orderInfo.reportTime|formatTime}}</view>
                        </view>
                        <view class="flex j-between">
                            <view class="label">上报说明</view>
@@ -107,12 +107,12 @@
                    </view>
                </view>
                <view class="addressCard">
                    <view class="address">{{orderInfo.detailedAddress||""}}</view>
                    <view class="address">{{orderInfo.location||""}}</view>
                    <image src="../../static/detailImg/dwei.png" class="addressIcon shrink0" mode="aspectFill"></image>
                </view>
                <view class="flex j-between">
                    <view class="label">创建时间</view>
                    <view class="value">{{orderInfo.createTime||''}}</view>
                    <view class="value">{{orderInfo.createTime|formatTime}}</view>
                </view>
                <view class="flex j-between">
                    <view class="label">问题类型</view>
@@ -128,17 +128,20 @@
                </view>
                <view class="flex j-between">
                    <view class="label">详细地址</view>
                    <view class="value">{{orderInfo.detailedAddress||''}}</view>
                    <view class="value">{{orderInfo.location||''}}</view>
                </view>
                <!-- 上级端需要的字段 -->
                <view class="flex j-between">
                    <view class="label">录入人</view>
                    <view class="value">{{orderInfo.createBy||''}}</view>
                <view v-if="!isParty">
                    <view class="flex j-between">
                        <view class="label">录入人</view>
                        <view class="value">{{orderInfo.nickname||''}}</view>
                    </view>
                    <view class="flex j-between">
                        <view class="label">录入人联系方式</view>
                        <view class="value">{{orderInfo.contactNumber||''}}</view>
                    </view>
                </view>
                <view class="flex j-between">
                    <view class="label">录入人联系方式</view>
                    <view class="value">{{orderInfo.contactNumber||''}}</view>
                </view>
                <!--  上级端需要的字段-->
            </view>
@@ -153,7 +156,7 @@
                </view>
                <view class="title">描述图片</view>
                <view class="descPic" v-if="problemImg.length>0">
                    <view class="picItem" v-for="(item,index) in problemImg">
                    <view class="picItem" v-for="(item,index) in problemImg" @click.stop="viewImage(item)">
                        <image :src="item" class="img shrink0" mode="aspectFill">
                        </image>
                    </view>
@@ -203,7 +206,7 @@
                </view>
                <view class="title">描述图片</view>
                <view class="descPic" v-if="resultImg.length>0">
                    <view class="picItem" v-for="(item,index) in resultImg">
                    <view class="picItem" v-for="(item,index) in resultImg" @click.stop="viewImage(item)">
                        <image :src="item" class="img shrink0" mode="aspectFill">
                        </image>
                    </view>
@@ -242,7 +245,7 @@
                            </view>
                            <view class="context">{{item.describe||''}}</view>
                            <view class="proImg">
                                <view class="imgOrVedio" v-for="(ite,ind) in item.imgList">
                                <view class="imgOrVedio" v-for="(ite,ind) in item.imgList" @click.stop="viewImage(ite)">
                                    <image :src="ite" class="img shrink0" mode="aspectFill">
                                    </image>
                                </view>
@@ -302,7 +305,7 @@
            <view class="btnAdd" @click="addProgress">添加办理进度</view>
            <view class="btnAdd" @click="resultEntery">办理结果录入</view>
        </view>
        <view class="btnButtom" v-if="orderInfo.status==5 && !isParty">
        <view class="btnButtom" v-if="[1,5].includes(orderInfo.status) && !isParty">
            <view class="cancel" @click.stop="showPop=true">驳回</view>
            <view class="sure" @click.stop="submitReSolve">审核通过</view>
        </view>
@@ -335,11 +338,13 @@
</template>
<script>
    import dayjs from '@/uni_modules/uview-ui/libs/util/dayjs.js'
    import {
        workOrderDetail,
        list,
        getUserInfo,
        reportAudit
        reportAudit,
        delayAudit
    } from './service.js'
    export default {
        data() {
@@ -366,6 +371,12 @@
            this.scoreTopHeight = e.scrollTop
        },
        filters: {
            formatTime(val) {
                if (!val) return ''
                return dayjs(val).format('YYYY-MM-DD HH:mm:ss')
            }
        },
        onShow() {
            list({
                pageNum: 1,
@@ -375,7 +386,11 @@
            })
            this.getDetailInfo()
        },
        onLoad() {
        onLoad(params) {
            if (params.id) {
                this.id = params.id
            }
            getUserInfo().then(res => {
                if (res.data == null) {
                    this.isParty = true
@@ -389,6 +404,11 @@
        methods: {
            open() {},
            close() {},
            viewImage(item) {
                uni.previewImage({
                    urls: [item]
                })
            },
            // 去大屏播放视频
            openVideo(url) {
                uni.navigateTo({
@@ -443,28 +463,49 @@
                        icon: 'none'
                    })
                }
                reportAudit({
                    id: this.id,
                    auditResult: 2,
                    rejectReason: this.rejectText
                }).then(res => {
                    this.showPop = false
                    this.getDetailInfo()
                })
                if (this.orderInfo.status == 5) { //上报
                    reportAudit({
                        id: this.id,
                        auditResult: 2,
                        rejectReason: this.rejectText
                    }).then(res => {
                        this.showPop = false
                        this.getDetailInfo()
                    })
                } else { //延期
                    delayAudit({
                        complaintId: this.id,
                        auditResult: 2,
                        rejectReason: this.rejectText
                    }).then(res => {
                        this.showPop = false
                        this.getDetailInfo()
                    })
                }
            },
            // 确认通过审批
            submitReSolve() {
                reportAudit({
                    id: this.id,
                    auditResult: 1,
                }).then(res => {
                    this.getDetailInfo()
                })
                if (this.orderInfo.status == 5) { //上报
                    reportAudit({
                        id: this.id,
                        auditResult: 1,
                    }).then(res => {
                        this.getDetailInfo()
                    })
                } else { //延期
                    delayAudit({
                        complaintId: this.id,
                        auditResult: 1,
                    }).then(res => {
                        this.getDetailInfo()
                    })
                }
            },
            //延期申请
            applyOverTime() {
                uni.navigateTo({
                    url: `/pages/work-detail/postpone-apply`
                    url: `/pages/work-detail/postpone-apply?id=${this.id}`
                })
            },
            // 问题上报
H5/static/packUp.png
H5/static/unfold.png
H5/utils/request.js
@@ -19,7 +19,7 @@
    return new Promise(function(resolve, reject) {
        let token = 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOjE4OTI0ODk0OTc5Nzk5NDA4NjUsInR5cGUiOjEsImV4cCI6MTc0MDQ2NjQ3MCwiY3JlYXRlZCI6MTc0MDM4MDA3MDQzN30.oOlB8GBE50WmV4Kw-Uuy33rQpQ-homoJQ61QXs34rkQIr-jFlAn9dUOgebitI9bz5PUaFImSldhY6vokRjmYlg'
        let token = uni.getStorageSync('token')
        let header = {
            'content-type': type ? 'application/x-www-form-urlencoded;charset=UTF-8' : 'application/json',
            'Authorization': 'Bearer ' + token,
management/config/routes.ts
@@ -36,19 +36,24 @@
  {
    path: '/setting',
    // layout: false,
    name:'系统设置',
    name: '系统设置',
    routes: [
      {
        name: '职位管理',
        path: '/setting/career',
        component: './setting/career/index',
      },
      {
        name: '角色管理',
        path: '/setting/role',
        component: './setting/role',
      },
    ],
  },
  {
    path: '/work-order',
    // layout: false,
    name:'工单事项管理',
    name: '工单事项管理',
    routes: [
      {
        name: '工单事项配置',
@@ -70,7 +75,7 @@
  {
    path: '/message-notification',
    // layout: false,
    name:'消息通知',
    name: '消息通知',
    routes: [
      {
        name: '消息通知',
management/src/app.tsx
@@ -7,6 +7,7 @@
import { errorConfig } from './requestErrorConfig';
const loginPath = '/login';
import '../public/font.css'
import { useEffect, useState } from 'react';
/**
@@ -39,8 +40,21 @@
// ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
  const [title, setTitle] = useState('');
  useEffect(() => {
    const updateTitle = () => {
      const now = new Date();
      const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
      const formattedDate = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()} ${now.getHours()}:${now.getMinutes()} ${days[now.getDay()]}`;
      setTitle(formattedDate);
    };
    updateTitle();
    const interval = setInterval(updateTitle, 1000); // 每分钟更新一次
    return () => clearInterval(interval); // 清除定时器
  }, []);
  return {
    title,
    logo: false,
    avatarProps: {
      title: <AvatarName />,
management/src/components/RightContent/AvatarDropdown.tsx
@@ -1,7 +1,8 @@
import { outLogin } from './service';
import { outLogin, getUnreadCount } from './service';
import { LogoutOutlined } from '@ant-design/icons';
import { useModel } from '@umijs/max';
import React from 'react';
import React, { useEffect, useState } from 'react';
import { Access, history, useAccess } from 'umi';
import { flushSync } from 'react-dom';
import './style.less';
@@ -22,6 +23,17 @@
  const { initialState, setInitialState } = useModel('@@initialState');
  const [unreadCount, setUnreadCount] = useState(0);
  useEffect(() => {
    const timer = setInterval(() => {
      getUnreadCount().then((res: any) => {
        setUnreadCount(res.data || 0);
      });
    }, 1000 * 5)
    return () => clearInterval(timer);
  }, []);
  const onMenuClick = async () => {
    await outLogin();
@@ -33,10 +45,13 @@
  }
  return <div style={{ display: 'flex', alignItems: 'center', color: '#000' }}>
    <div className='unread' >
      <div>未读提醒</div>
      <div style={{ border: '1px solid red', borderRadius: '50%', width: '18px', lineHeight: '18px', marginLeft: '5px', textAlign: 'center', color: 'red' }}>1</div>
    </div>
    {
      unreadCount > 0 &&
      <div className='unread' onClick={() => { history.push('/message-notification/list') }}>
        <div>未读提醒</div>
        <div style={{ border: '1px solid red', borderRadius: '50%', width: '18px', lineHeight: '16px', marginLeft: '5px', textAlign: 'center', color: 'red', flexShrink: 0 }}>{unreadCount}</div>
      </div>
    }
    <div className="logoOut" onClick={onMenuClick}>退出登录<LogoutOutlined style={{ marginLeft: '5px' }} /></div>
  </div>
};
management/src/components/RightContent/service.js
@@ -1,8 +1,17 @@
import { request } from '@umijs/max';
// 退出登录
export async function outLogin(data) {
  return request('/api/huacheng-sangeshenbian/systemUser/logout', {
    method: 'POST',
    data,
  });
}
// 获取未读数量
export async function getUnreadCount(data) {
  return request('/api/huacheng-sangeshenbian/messageNotification/unreadCount', {
    method: 'GET',
    data,
  });
}
management/src/global.less
@@ -55,6 +55,12 @@
    }
  }
}
.ant-pro-global-header-header-actions-avatar>div:hover {
  background: #fff;
}
:where(.css-dev-only-do-not-override-17md30i).ant-menu-light .ant-menu-submenu-selected>.ant-menu-submenu-title,
:where(.css-dev-only-do-not-override-17md30i).ant-menu-light>.ant-menu .ant-menu-submenu-selected>.ant-menu-submenu-title{
  color: rgba(0, 0, 0, 0.95);
}
management/src/pages/setting/role/components/addAndEdit.jsx
New file
@@ -0,0 +1,192 @@
import { Form, Input, Modal, Tree, Button, Spin } from 'antd';
import { forwardRef, useImperativeHandle, useState } from 'react';
import { useEffect } from 'react';
import { getTree, getAddTree } from '../service';
const formItemLayout = {
    labelCol: { span: 6 },
    wrapperCol: { span: 18 },
};
const AddAndEdit = ({ visible, onSave, onUpdate, onCancel }, ref) => {
    const [form] = Form.useForm();
    const [data, setData] = useState({})
    const [treeData, setTreeData] = useState([]);//权限树
    const [treeSeletKeys, setTreeSeletKeys] = useState([]); //勾选权限
    const [detailType, setDetailType] = useState(false);//是否详情
    const [spinning, setSpinning] = useState(false);
    useEffect(() => {
        // 获取权限树
        getAddTree().then(res => {
            setTreeData(res.data)
        })
    }, [])
    useImperativeHandle(ref, () => {
        return {
            refreshData: (data, type) => {
                setDetailType(type || false)
                if (data.id) {
                    // 获取角色的权限树
                    getTree(data.id).then(res => {
                        setTreeSeletKeys(res.data.systemMenuIds || []);
                    })
                }
                setData(data)
                form.setFieldsValue(data);
            },
            clean: () => {
                setSpinning(false)
            },
        };
    });
    // 保存
    const okHandle = () => {
        form.validateFields().then((values) => {
            setSpinning(true)
            values.menuIds = treeSeletKeys
            delete values.tree
            if (data.id) {
                values.id = data.id
                onUpdate(values)
            } else {
                onSave(values);
            }
        });
    };
    // 选中树
    const onCheck = (e, row) => {
        let seletKeys = e.checked;
        treeData.find(item => {
            if (item.children) {
                let arr1 = item.children.find((item1) => {//循环子路由
                    if (item1.children) {
                        let arr2 = item1.children.find((item2) => {//循环子路由下按钮
                            return item2.id == row.node.id;
                        });
                        if (row.checked) {
                            if (arr2 && !seletKeys.includes(item1.id)) {
                                seletKeys.push(item1.id);
                            }
                            if (arr2 && !seletKeys.includes(item.id)) {
                                seletKeys.push(item.id);
                            }
                        } else {
                            let isCheck = item1.children.find((item2) => seletKeys.includes(item2.id));
                            if (!isCheck) {
                                let arr = seletKeys.filter((it) => it != item1.id);
                                seletKeys = arr;
                            }
                        }
                    }
                    return item1.id == row.node.id;
                });
                if (row.checked) {
                    if (arr1 && !seletKeys.includes(item.id)) {
                        seletKeys.push(item.id);
                    }
                } else {
                    let isCheck = item.children.find((item1) => seletKeys.includes(item1.id));
                    if (!isCheck) {
                        let arr = seletKeys.filter((it) => it != item.id);
                        seletKeys = arr;
                    }
                }
            }
            return item.id == row.node.id;
        });
        if (row.node.children.length != 0) {
            row.node.children.map((item) => {
                if (row.checked) {
                    if (!seletKeys.includes(item.id)) {
                        seletKeys.push(item.id);
                    }
                } else {
                    seletKeys = seletKeys.filter((item1) => item1 != item.id);
                }
                if (item.children.length != 0) {
                    item.children.map((item1) => {
                        if (row.checked) {
                            if (!seletKeys.includes(item1.id)) {
                                seletKeys.push(item1.id);
                            }
                        } else {
                            seletKeys = seletKeys.filter((item2) => item2 != item1.id);
                        }
                    });
                }
            });
        }
        setTreeSeletKeys(seletKeys);
    };
    return (
        <Modal
            getContainer={false}
            width="20%"
            destroyOnClose
            title={detailType ? '角色详情' : data.id ? '编辑角色' : '添加角色'}
            open={visible}
            onCancel={() => onCancel(false)}
            afterClose={() => {
                form.resetFields()
                setTreeSeletKeys([])
            }}
            footer={
                !detailType ?
                    [
                        <Button key="back" onClick={() => onCancel(false)}>取消</Button>,
                        <Button key="submit" type="primary" onClick={okHandle}>
                            确定
                        </Button>
                    ]
                    :
                    <Button key="back" onClick={() => onCancel(false)}>关闭</Button>
            }
        >
            <Form layout="horizontal" {...formItemLayout} form={form} scrollToFirstError>
                <Form.Item
                    name="name"
                    label="角色名称"
                    rules={[{ required: true, message: '请输入角色名称' }]}
                >
                    <Input disabled={detailType} placeholder='请输入角色名称' />
                </Form.Item>
                <Form.Item
                    name="tree"
                    label="角色权限"
                    rules={[{
                        required: true,
                        validator: (rule, value) => {
                            return new Promise((resolve, reject) => {
                                if (value) {
                                    resolve('');
                                } else {
                                    if (treeSeletKeys.length === 0) {
                                        reject(new Error('请选择角色权限'));
                                    }
                                    resolve('');
                                }
                            })
                        }
                    }]}>
                    <Tree
                        checkable
                        checkStrictly
                        checkedKeys={treeSeletKeys}
                        treeData={treeData}
                        disabled={detailType}
                        fieldNames={{ title: 'name', key: 'id' }}
                        onCheck={onCheck}
                    />
                </Form.Item>
            </Form>
            <Spin spinning={spinning} fullscreen />
        </Modal >
    );
};
export default forwardRef(AddAndEdit);
management/src/pages/setting/role/index.jsx
New file
@@ -0,0 +1,127 @@
import { PageContainer, ProTable } from '@ant-design/pro-components';
import { buildProTableDataSource, sendRequest, showDelConfirm } from '@/utils/antdUtils';
import { Button, Space } from 'antd';
import { useRef, useState } from 'react';
import { Access, history, useAccess } from 'umi';
import { getList, del, edit, add } from './service'
import AddAndEdit from './components/addAndEdit'
const Role = () => {
    const actionRef = useRef();
    const addViewRef = useRef();
    const [modalVisible, handleModalVisibles] = useState(false);
    const access = useAccess();
    const columns = [
        {
            title: '角色名称',
            dataIndex: 'name',
        },
        {
            title: '操作',
            hideInSearch: true,
            render: (text, record) => {
                return (
                    <Space>
                        {
                            record.roleId != 1 &&
                            // <Access accessible={access.settings_role_edit}>
                            <Button
                                type="link"
                                onClick={() => {
                                    addViewRef.current.refreshData(record);
                                    handleModalVisibles(true)
                                }}
                            >
                                编辑
                            </Button>
                            //  </Access>
                        }
                        {
                            record.roleId != 1 &&
                            // <Access accessible={access.settings_role_detele}>
                            <Button
                                type="link"
                                onClick={() => {
                                    showDelConfirm(async () => {
                                        let status = await sendRequest(del, record.id)
                                        if (status) {
                                            actionRef.current.reload();
                                        }
                                    }, '确认删除所选信息吗?');
                                }}
                            >
                                删除
                            </Button>
                            //  </Access>
                        }
                        {/* <Access accessible={access.settings_role_detail}> */}
                        <Button
                            type="link"
                            onClick={() => {
                                addViewRef.current.refreshData(record, true);
                                handleModalVisibles(true)
                            }}
                        >
                            查看详情
                        </Button>
                        {/* </Access> */}
                    </Space >
                );
            },
        },
    ]
    return <PageContainer title='角色管理'>
        <ProTable
            rowKey='id'
            actionRef={actionRef}
            columns={columns}
            pagination={{
                showSizeChanger: true,
                showQuickJumper: true,
                defaultPageSize: 10,
            }}
            request={(params) => buildProTableDataSource(getList, params)}
            toolBarRender={(action, selectRows) => [
                // <Access accessible={access.settings_role_add}>
                <Space>
                    <Button
                        type="primary"
                        onClick={() => {
                            addViewRef.current.refreshData({});
                            handleModalVisibles(true)
                        }}
                    >
                        添加
                    </Button>
                </Space>
                //  </Access>
            ]}
        />
        <AddAndEdit
            ref={addViewRef}
            visible={modalVisible}
            onSave={async (fileds) => {
                let success = await sendRequest(add, fileds);
                if (success) {
                    handleModalVisibles(false);
                    actionRef.current.reload();
                }
                addViewRef.current.clean();
            }}
            onUpdate={async (fileds) => {
                let success = await sendRequest(edit, fileds);
                if (success) {
                    handleModalVisibles(false);
                    actionRef.current.reload();
                }
                addViewRef.current.clean();
            }}
            onCancel={() => handleModalVisibles(false)}
        />
    </PageContainer>
};
export default Role;
management/src/pages/setting/role/service.js
New file
@@ -0,0 +1,47 @@
import { request } from '@umijs/max';
// 列表
export const getList = async (params) => {
    return request(`/api/huacheng-sangeshenbian/systemRole/list`, {
        method: 'GET',
        params
    });
}
// 编辑获取角色权限树
export const getTree = async (id) => {
    return request(`/api/huacheng-sangeshenbian/systemRole/getSystemRoleInfo/${id}`, {
        method: 'GET',
    });
}
// 新增获取权限树
export const getAddTree = async (id) => {
    return request(`/api/huacheng-sangeshenbian/systemMenu/getSystemMenuList`, {
        method: 'GET',
    });
}
// 新增
export const add = async (data) => {
    return request('/api/huacheng-sangeshenbian/systemRole/add', {
        method: 'POST',
        data,
    });
}
// 编辑
export const edit = async (data) => {
    return request('/api/huacheng-sangeshenbian/systemRole/edit', {
        method: 'POST',
        data,
    });
}
// 删除
export const del = async (id) => {
    return request(`/api/huacheng-sangeshenbian/systemRole/delete/${id}`, {
        method: 'DELETE',
    });
}
management/src/requestErrorConfig.ts
@@ -36,7 +36,7 @@
      o.headers = {
        ...config.headers,
        Authorization,
        Authorization:'Bearer ' + Authorization,
      }
      // }
      // 拦截请求配置,进行个性化处理。
management/src/utils/antdUtils.js
@@ -103,11 +103,11 @@
}
export async function buildProTableDataSource(fun, params) {
  params.pageCurr = params.current;
  params.pageNum = params.current;
  delete params.current
  const response = await fun(params);
  const data = Promise.resolve({
    data: response.data.list || [],
    data: response.data.records || [],
    total: response.data.total || 0,
    success: true,
    pageSize: response.data.size || 10,