13404089107
2025-05-23 473a71335e9744bc66627103102f47e1b67f511b
Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/H5/threeSide
8个文件已修改
254 ■■■■ 已修改文件
H5/pages/index/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/pages/progress/progress.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/pages/statistics/index.vue 120 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/pages/supervision/supervision-progress.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/pages/supervision/supervision.vue 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/pages/appeal-management/statistics/index.jsx 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/pages/logManagement/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/pages/statistics/index.jsx 77 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
H5/pages/index/index.vue
@@ -81,7 +81,7 @@
                    <text class="ml-37 font-bold">党员审核</text>
                </view>
                <view class="pt-38 pb-38 bg1 w-333 br-19 mt-19 flex a-center" @tap.stop="toSupervision"
                    v-if="showData && userInfo.isAdmin == 1">
                    v-if="showData && userInfo.isAdmin == 1 && userInfo.identity == 2">
                    <image class="w-81 h-77 ml-38" src="/static/home/supervision.png" mode=""></image>
                    <text class="ml-37 font-bold">诉求监督</text>
                </view>
H5/pages/progress/progress.vue
@@ -48,7 +48,7 @@
                        </view>
                        <view class="context">{{ item.describe }}</view>
                        <view class="proImg">
                            <view v-if="item.imgUrl">
                            <view v-if="item.imgUrl" class="flex wrap">
                                <view class="imgOrVedio" v-for="(ite, index) in item.imgUrl.split(',')" :key="index">
                                    <image :src="ite" class="img shrink0" mode="aspectFill" />
                                    <view
@@ -58,7 +58,7 @@
                                    </view>
                                </view>
                            </view>
                            <view v-if="item.video">
                            <view v-if="item.video" class="flex wrap">
                                <view class="imgOrVedio" v-for="(ite, index) in item.video.split(',')" :key="index">
                                    <video id="myVideo" class="w-140 h-140 mt-19 shrink0" disabled :controls="false"
                                        :show-center-play-btn="false" :src="ite" />
H5/pages/statistics/index.vue
@@ -50,7 +50,7 @@
          <view class="color6"> 同比上月 </view>
          <view class="txt-aligin-r color4 font-bold mt-4">
            {{ statisticsData.satisfaction.compare > 0 ? "+" : ""
            }}{{ statisticsData.satisfaction.compare }}%
            }}{{ (statisticsData.satisfaction.compare * 1).toFixed(2) }}%
          </view>
        </view>
      </view>
@@ -75,8 +75,7 @@
          <view class="fs-23">
            <view class=""> 同比上月 </view>
            <view class="font-bold color8 txt-aligin-r mt-4">
              {{ statisticsData.demands.compare > 0 ? "+" : ""
              }}{{ statisticsData.demands.compare }}
              {{ (statisticsData.demands.compare * 1).toFixed(2) }}
            </view>
          </view>
        </view>
@@ -99,8 +98,7 @@
          <view class="fs-23">
            <view class=""> 同比上月 </view>
            <view class="font-bold color4 txt-aligin-r mt-4">
              {{ statisticsData.processTime.compare > 0 ? "+" : ""
              }}{{ statisticsData.processTime.compare }}
              {{ (statisticsData.processTime.compare * 1).toFixed(2) }}
            </view>
          </view>
        </view>
@@ -154,8 +152,7 @@
        <view class="fs-23 mt-44">
          <view class="color6"> 同比上月 </view>
          <view class="txt-aligin-r color4 font-bold mt-4">
            {{ statisticsData.overtime.compare > 0 ? "+" : ""
            }}{{ statisticsData.overtime.compare }}
            {{ (statisticsData.overtime.compare * 1).toFixed(2) }}
          </view>
        </view>
      </view>
@@ -311,13 +308,13 @@
        <view class="txt-center pt-38 pb-40 fs-35 lh-48 font-bold"
          >请选择服务社区</view
        >
        <!-- <view
        <view
          class="flex a-center j-between txt-center py-10 fs-27 font-bold bgColor1"
        >
          <view v-if="hasTier(2)" class="flex1">区县</view>
          <view v-if="hasTier(3)" class="flex1">街道</view>
          <view v-if="hasTier(4)" class="flex1">社区</view>
        </view> -->
          <view v-if="showCountyColumn" class="flex1">区县</view>
          <view v-if="showStreetColumn" class="flex1">街道</view>
          <view v-if="showCommunityColumn" class="flex1">社区</view>
        </view>
        <view class="mb-20">
          <picker-view
            :value="value"
@@ -325,7 +322,7 @@
            class="picker-view"
            immediate-change
          >
            <picker-view-column v-if="hasTier(2)">
            <picker-view-column v-if="showCountyColumn">
              <view
                class="item"
                v-for="(item, index) in regionTree"
@@ -334,7 +331,7 @@
                {{ item.name }}
              </view>
            </picker-view-column>
            <picker-view-column v-if="hasTier(3)">
            <picker-view-column v-if="showStreetColumn">
              <view
                class="item"
                v-for="(item, index) in getStreets()"
@@ -343,7 +340,7 @@
                {{ item.name }}
              </view>
            </picker-view-column>
            <picker-view-column v-if="hasTier(4)">
            <picker-view-column v-if="showCommunityColumn">
              <view
                class="item"
                v-for="(item, index) in getCommunities()"
@@ -439,7 +436,29 @@
      satisfactionRate: 0,
      generalSatisfactionRate: 0,
      dissatisfactionRate: 0,
      showCountyColumn: false,
    };
  },
  computed: {
    showStreetColumn() {
      // 判断当前选中的区县/第一级是否有 children 且有街道
      const lastItem = this.regionTree[this.regionTree.length - 1];
      if (!lastItem) return false;
      // 区县为第一级
      if (lastItem.tier === 2) {
        const county = this.regionTree[this.value[0]];
        return county && Array.isArray(county.children) && county.children.some(c => c && c.tier === 3);
      }
      // 街道为第一级
      if (lastItem.tier === 3) {
        return this.regionTree.length > 1;
      }
      return false;
    },
    showCommunityColumn() {
      const communities = this.getCommunities();
      return communities.length > 0;
    },
  },
  onLoad() {
    this.userInfo = uni.getStorageSync("userInfo");
@@ -476,6 +495,9 @@
          this.address = "全部";
          this.currentAreaId = '';
          this.currentTier = -1;
          // showCountyColumn 仍然根据最后一项 tier 判断
          const lastItem = this.regionTree[this.regionTree.length - 1];
          this.showCountyColumn = lastItem && lastItem.tier === 2;
          this.getStatisticsData("", -1);
          this.getChartData(1);
          this.getTypeRankData();
@@ -592,6 +614,8 @@
      this.value = newValue;
    },
    openSelectPopup() {
      console.log(this.regionTree);
      this.value = this.confirmValue;
    },
    handleTabClick(index) {
@@ -716,7 +740,7 @@
        tooltip: {
          trigger: "item",
          confine: true,
          // formatter: '{b}: {c}%',
          formatter: '{b}: {c}%',
          backgroundColor: "rgba(255, 255, 255, 0.9)",
          borderColor: "#FFE0E0",
          borderWidth: 1,
@@ -799,9 +823,13 @@
      }
    },
    hasTier(tier) {
      // tier=2: 区县始终有
      // 检查最后一项的数据类型
      const lastItem = this.regionTree[this.regionTree.length - 1];
      if (!lastItem) return false;
      // 如果最后一项是区县
      if (lastItem.tier === 2) {
      if (tier === 2) return true;
      // tier=3: 当前区县children里有tier=3
      if (tier === 3) {
        const county = this.regionTree[this.value[0]];
        return (
@@ -810,7 +838,6 @@
          county.children.some((c) => c && c.tier === 3)
        );
      }
      // tier=4: 当前区县children里有tier=4,或街道children里有tier=4
      if (tier === 4) {
        const county = this.regionTree[this.value[0]];
        if (!county || !Array.isArray(county.children)) return false;
@@ -824,31 +851,78 @@
          street.children.some((c) => c && c.tier === 4)
        );
      }
      }
      // 如果最后一项是街道
      else if (lastItem.tier === 3) {
        if (tier === 3) return true;
        if (tier === 4) {
          const street = this.regionTree[this.value[0]];
          return (
            street &&
            Array.isArray(street.children) &&
            street.children.some((c) => c && c.tier === 4)
          );
        }
      }
      // 如果最后一项是社区
      else if (lastItem.tier === 4) {
        return tier === 4;
      }
      return false;
    },
    getStreets() {
      const county = this.regionTree[this.value[0]];
      if (!county || !Array.isArray(county.children)) return [];
      // 只返回tier=3的
      // 如果第一层是街道
      if (this.regionTree[this.regionTree.length - 1]?.tier === 3) {
        return this.regionTree.slice(1).map(item => ({
          name: item.name,
          id: item.id,
          tier: item.tier,
          children: item.children || []
        }));
      }
      // 如果当前选中的是区县
      if (county.tier === 2) {
      const streets = county.children.filter((c) => c && c.tier === 3);
      return streets.length
        ? [{ name: "全部", id: "all", tier: 3, children: [] }, ...streets]
        : [];
      }
      return [];
    },
    getCommunities() {
      const county = this.regionTree[this.value[0]];
      if (!county || !Array.isArray(county.children)) return [];
      // 如果第一层是街道
      if (this.regionTree[this.regionTree.length - 1]?.tier === 3) {
        const street = this.regionTree[this.value[0]];
        if (!street || street.id === 'all') return [];
        const communities = street.children?.filter(c => c && c.tier === 4) || [];
        return communities.length ? [{ name: "全部", id: "all", tier: 4 }, ...communities] : [];
      }
      // 如果当前选中的是区县
      if (county.tier === 2) {
      // 区县下直接有社区
      const communities = county.children.filter((c) => c && c.tier === 4);
      if (communities.length)
        return [{ name: "全部", id: "all", tier: 4 }, ...communities];
      // 区县下有街道,街道下有社区
      const street = county.children[this.value[1]];
        const street = county.children[this.value[1] - 1];
      if (street && Array.isArray(street.children)) {
        const comms = street.children.filter((c) => c && c.tier === 4);
        if (comms.length)
          return [{ name: "全部", id: "all", tier: 4 }, ...comms];
      }
      }
      return [];
    },
    async getChartData(timeType = 1) {
@@ -1189,5 +1263,9 @@
.type-rank-list-scroll {
  max-height: 500rpx;
  overflow-y: auto;
  /deep/ .u-line-progress__line {
    min-width: 40rpx;
  }
}
</style>
H5/pages/supervision/supervision-progress.vue
@@ -48,7 +48,7 @@
                        </view>
                        <view class="context">{{ item.describe }}</view>
                        <view class="proImg">
                            <view v-if="item.imgUrl">
                            <view v-if="item.imgUrl" class="flex wrap">
                                <view class="imgOrVedio" v-for="(ite, index) in item.imgUrl.split(',')" :key="index">
                                    <image :src="ite" class="img shrink0" mode="aspectFill" />
                                    <view
@@ -58,7 +58,7 @@
                                    </view>
                                </view>
                            </view>
                            <view v-if="item.video">
                            <view v-if="item.video" class="flex wrap">
                                <view class="imgOrVedio" v-for="(ite, index) in item.video.split(',')" :key="index">
                                    <video id="myVideo" class="w-140 h-140 mt-19 shrink0" disabled :controls="false"
                                        :show-center-play-btn="false" :src="ite" />
@@ -138,12 +138,13 @@
        methods: {
            deleteProgress() {
                delProgress(this.row.id).then(res => {
                    this.$refs.customPopup.show = false
                    uni.showToast({
                        icon: 'none',
                        mask: true,
                        title: '删除成功'
                        title: '删除办理进度成功',
                        duration:2000
                    })
                    this.$refs.customPopup.show = false
                    setTimeout(() => {
                        getComplaintDetail({
                            id: this.id
H5/pages/supervision/supervision.vue
@@ -1,6 +1,7 @@
<template>
    <view class="content">
        <view class="bgColor2 shadow1 pb-19" style="position: sticky;top: 0;z-index: 999;">
        <view v-if="userInfo.superviseFlag == 1" class="bgColor2 shadow1 pb-19"
            style="position: sticky;top: 0;z-index: 999;">
            <view class="h-96 flex a-center fs-27  j-between txt-center  font-w400 color1">
                <view @click="changeType(1)" class="flex1 bgColor2 relative" :class="type == 1 && 'color2 font-bold'">
                    <view class="relative zIndex1000">
@@ -44,7 +45,12 @@
                            </view>
                            已超时{{ item.overTimeDays }}天
                        </view>
                        <view v-if="type == 1">
                        {{ statusObj[item.status] }}
                        </view>
                        <view v-if="type == 2">
                            {{ ['延期被驳回','上报被驳回'][item.auditType - 1] }}
                        </view>
                    </view>
                </view>
                <view v-if="[5,6].includes(item.status)" class="mt-40 fs-23 pl-40 pr-40">
@@ -185,6 +191,7 @@
                    '7': '延期待审核',
                    '8': '已办结'
                },
                userInfo: uni.getStorageSync('userInfo')
            }
        },
        onReachBottom() {
management/src/pages/appeal-management/statistics/index.jsx
@@ -11,7 +11,7 @@
    const columns = [
        {
            title: '述求号',
            title: '诉求号',
            dataIndex: 'serialNumber',
            order: 8,
        },
@@ -33,15 +33,20 @@
        {
            title: '申请时间',
            dataIndex: 'applyTime',
            hideInTable: true,
            valueType: 'dateRange',
            order: 3,
            render: (text, record) => {
                return moment(record.applyTime).format('YYYY-MM-DD HH:mm:ss')
            }
        },
        {
            title: '审批时间',
            dataIndex: 'examineTime',
            valueType: 'dateRange',
            order: 2,
            render: (text, record) => {
                return moment(record.examineTime).format('YYYY-MM-DD HH:mm:ss')
            }
        },
        {
            title: '审批人',
@@ -54,8 +59,26 @@
            hideInSearch: true,
        },
        {
            title: '状态',
            title: '诉求当前状态',
            dataIndex: 'status',
            hideInSearch: true,
            valueEnum: {
                0: '正在办理',
                1: '延期办理',
                2: '超时办理',
                3: '已办结',
                4: '群众撤销',
                5: '上报待审核',
                6: '上级驳回',
                7: '延期待审核',
                8: '已评价',
                9: '延期驳回',
            },
        },
        {
            title: '诉求状态',
            dataIndex: 'status',
            hideInTable: true,
            order: 1,
            valueEnum: {
                0: '正在办理',
management/src/pages/logManagement/index.jsx
@@ -15,9 +15,11 @@
        {
            title: '操作时间',
            dataIndex: 'createTime',
            hideInTable: true,
            valueType: 'dateRange',
            order: 1,
            render: (text, record) => {
                return moment(record.createTime).format('YYYY-MM-DD HH:mm:ss')
            }
        },
        {
            title: '操作用户',
management/src/pages/statistics/index.jsx
@@ -146,35 +146,15 @@
  const typeRankOption = {
    tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
    grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
    dataZoom: [
      {
        type: 'slider',
        show: true,
        startValue: 0,
        endValue: 4,
        bottom: 0,
        showDetail: false,
        showDataShadow: false,
        height: '100%',
        width: 10,
        fillerColor: '#dbdee5',
        borderColor: 'transparent',
        zoomLock: true,
        orient: 'vertical',
        brushSelect: false,
        handleStyle: {
          opacity: 0
    xAxis: {
      type: 'value',
      boundaryGap: [0, 0.01],
      axisLabel: {
        formatter: function(value) {
          return value + '单';
        }
        }
      },
      {
        type: "inside",
        zoomOnMouseWheel: false,
        moveOnMouseMove: true,
        moveOnMouseWheel: true,
        orient: 'vertical'
      },
    ],
    xAxis: { type: 'value', boundaryGap: [0, 0.01] },
    yAxis: { type: 'category', data: allTypeData.map(item => item.name) },
    series: [
      {
@@ -191,17 +171,25 @@
  // 问题评价占比图表配置
  const pieOption = {
    tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
    legend: { orient: 'vertical', left: 'right', data: pieData.map(i => i.name) },
    color: ['#4a90e2', '#6dd400', '#f5a623', '#f44336'],
    legend: { show: false },
    color: ['rgb(80,135,236)', 'rgb(104,187,196)', 'rgb(88,165,92)', 'rgb(242,189,66)'],
    series: [
      {
        name: '评价占比',
        type: 'pie',
        radius: ['50%', '70%'],
        radius: ['40%', '70%'],
        center: ['50%', '50%'],
        avoidLabelOverlap: false,
        label: { show: false, position: 'center' },
        label: {
          show: true,
          formatter: '{b} {d}%'
        },
        labelLine: {
          show: true,
          length: 20,
          length2: 30,
        },
        emphasis: { label: { show: true, fontSize: 18, fontWeight: 'bold' } },
        labelLine: { show: false },
        data: pieData,
      },
    ],
@@ -254,10 +242,10 @@
      })));
      const fourVo = res.data.analyticStatisticsFourVo || {};
      setPieData([
        { value: fourVo.greatSatisfactionRate, name: '非常满意' },
        { value: fourVo.satisfactionRate, name: '满意' },
        { value: fourVo.generalSatisfactionRate, name: '一般' },
        { value: fourVo.dissatisfactionRate, name: '不满意' },
        { value: fourVo.greatSatisfactionNum, name: '非常满意', percent: fourVo.greatSatisfactionRate },
        { value: fourVo.satisfactionRateNum, name: '满意', percent: fourVo.satisfactionRate },
        { value: fourVo.generalSatisfactionNum, name: '一般', percent: fourVo.generalSatisfactionRate },
        { value: fourVo.dissatisfactionNum, name: '不满意', percent: fourVo.dissatisfactionRate },
      ]);
    } catch (e) {
      // 错误处理
@@ -322,7 +310,7 @@
          options={communityOptions} 
          placeholder="请选择社区" 
          fieldNames={{ label: 'name', value: 'communityId' }}
          disabled={!form.getFieldValue('streetId')}
          disabled={adminLevel <= 1 && !form.getFieldValue('districtId')}
        />,
      },
    ];
@@ -337,7 +325,7 @@
          placeholder="请选择街道" 
          fieldNames={{ label: 'name', value: 'streetId' }}
          onChange={handleStreetChange}
          disabled={!form.getFieldValue('districtId')}
          disabled={adminLevel <= 2 && !form.getFieldValue('districtId')}
        />,
      });
    }
@@ -548,7 +536,18 @@
          <div style={{ fontWeight: 600, fontSize: 16, marginBottom: 16, borderLeft: '4px solid #3b7cff', paddingLeft: 8 }}>
            问题评价占比
          </div>
          <ReactECharts option={pieOption} style={{ height: 300 }} />
          <div style={{ width: '100%', display: 'flex', justifyContent: 'center' }}>
            <div style={{ display: 'flex', alignItems: 'center' }}>
              <ReactECharts option={pieOption} style={{ height: 300, width: 520 }} />
              <div style={{ marginLeft: 48 }}>
                {pieData.map((item, idx) => (
                  <div key={item.name} style={{ color: pieOption.color[idx], fontSize: 16, marginBottom: 12 }}>
                    {item.name}:{item.value}({item.percent}%)
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>
      </PageContainer>
    </div>