| | |
| | | <template> |
| | | <view class="content"> |
| | | <view v-if="userInfo.isAdmin == 1" class="flex a-center pl-31 pr-31 fs-31 color1 pt-38"> |
| | | <text class="mr-15">查看范围:</text> |
| | | <view |
| | | class="h-77 flex a-center j-between flex1 pl-31 pr-23 border1 br-15 bgColor1" :class="!address && 'color2'"> |
| | | <view @click.top="selectPopup=true" class="flex1"> |
| | | {{ address || '全部' }} |
| | | </view> |
| | | <u-icon class="shrink0" v-if="address" @click="clearAddress" name="close-circle"></u-icon> |
| | | <image v-else src="/static/down@2x.png" mode="aspectFill" class="w-31 h-31 shrink0"></image> |
| | | </view> |
| | | </view> |
| | | <view class="fs-35 font-bold pt-38 ml-27"> |
| | | 处理满意率 |
| | | </view> |
| | | <view class="ml-29 mr-29 border2 br-15 mt-27 shadow1 flex j-between pl-19 pr-19 pb-35"> |
| | | <view class="mt-19 flex1"> |
| | | <view class="flex a-center"> |
| | | <view class="w-12 h-12 br-6 border3"></view> |
| | | <view class="fs-23 ml-15 color3"> |
| | | 总体满意率 |
| | | </view> |
| | | </view> |
| | | <view class="fs-46 ml-27 mt-12 font-bold"> |
| | | 77% |
| | | </view> |
| | | </view> |
| | | <view class="flex1 flex j-between ml-50"> |
| | | <view class="fs-23 mt-42 txt-center"> |
| | | <view class="color6"> |
| | | 本月 |
| | | </view> |
| | | <view class="fs-27 font-bold color5 mt-2"> |
| | | 88% |
| | | </view> |
| | | </view> |
| | | <view class="fs-23 mt-44"> |
| | | <view class="color6"> |
| | | 同比上月 |
| | | </view> |
| | | <view class="txt-aligin-r color4 font-bold mt-4"> |
| | | +12% |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="fs-35 font-bold mt-38 ml-27"> |
| | | 诉求单统计 |
| | | </view> |
| | | <view class="flex j-between a-center pl-29 pr-29 mt-27"> |
| | | <view class="pl-19 pr-21 shadow1 border2 pt-19 pb-42 flex1 br-15"> |
| | | <view class="flex a-center"> |
| | | <view class="w-12 h-12 br-6 border3"></view> |
| | | <view class="fs-23 ml-15 color3"> |
| | | 诉求单量总计 |
| | | </view> |
| | | </view> |
| | | <view class="fs-46 mt-12 font-bold ml-27"> |
| | | 448451 |
| | | </view> |
| | | <view class="flex j-between mt-21"> |
| | | <view class="fs-23"> |
| | | <view class=""> |
| | | 本月 |
| | | </view> |
| | | <view class="fs-27 font-bold color3 mt-2"> |
| | | 4448 |
| | | </view> |
| | | </view> |
| | | <view class="fs-23"> |
| | | <view class=""> |
| | | 同比上月 |
| | | </view> |
| | | <view class="font-bold color8 txt-aligin-r mt-4"> |
| | | -12% |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="pl-19 pr-21 shadow1 border2 pt-19 pb-42 flex1 ml-31 br-15"> |
| | | <view class="flex a-center"> |
| | | <view class="w-12 h-12 br-6 border3"></view> |
| | | <view class="fs-23 ml-15 color3"> |
| | | 平均处理时间(天) |
| | | </view> |
| | | </view> |
| | | <view class="fs-46 mt-12 font-bold ml-27"> |
| | | 3.2 |
| | | </view> |
| | | <view class="flex j-between mt-21"> |
| | | <view class="fs-23"> |
| | | <view class=""> |
| | | 本月 |
| | | </view> |
| | | <view class="fs-27 font-bold color3 mt-2"> |
| | | 2.2 |
| | | </view> |
| | | </view> |
| | | <view class="fs-23"> |
| | | <view class=""> |
| | | 同比上月 |
| | | </view> |
| | | <view class="font-bold color4 txt-aligin-r mt-4"> |
| | | +12% |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="flex mt-27 gap25 pl-29 pr-29"> |
| | | <view class="flex1 h-154 bgColor2 border4 shadow2 br-19 txt-center"> |
| | | <view class="mt-37 fs-35 color4 font-bold"> |
| | | 4521 |
| | | </view> |
| | | <view class="fs-23 mt-8 color3"> |
| | | 正在办理 |
| | | </view> |
| | | </view> |
| | | <view class="flex1 h-154 bgColor3 border4 shadow2 br-19 txt-center"> |
| | | <view class="mt-37 fs-35 color9 font-bold"> |
| | | 321 |
| | | </view> |
| | | <view class="fs-23 mt-8 color3"> |
| | | 审核中 |
| | | </view> |
| | | </view> |
| | | <view class="flex1 h-154 bgColor4 border4 shadow2 br-19 txt-center"> |
| | | <view class="mt-37 fs-35 color10 font-bold"> |
| | | 6850 |
| | | </view> |
| | | <view class="fs-23 mt-8 color3"> |
| | | 延期办理 |
| | | </view> |
| | | </view> |
| | | <view class="flex1 h-154 bgColor5 border4 shadow2 br-19 txt-center"> |
| | | <view class="mt-37 fs-35 color11 font-bold"> |
| | | 8451 |
| | | </view> |
| | | <view class="fs-23 mt-8 color3"> |
| | | 已办结 |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="pb-35 ml-29 mr-29 border2 br-15 mt-27 shadow1 flex j-between pl-19 pr-19"> |
| | | <view class="mt-19 flex1"> |
| | | <view class="flex a-center"> |
| | | <view class="w-12 h-12 br-6 border3"></view> |
| | | <view class="fs-23 ml-15 color3"> |
| | | 超时办理 |
| | | </view> |
| | | </view> |
| | | <view class="fs-46 ml-27 mt-12 font-bold"> |
| | | 6850 |
| | | </view> |
| | | </view> |
| | | <view class="flex1 flex j-between ml-50"> |
| | | <view class="fs-23 mt-42 txt-center"> |
| | | <view class="color6"> |
| | | 本月 |
| | | </view> |
| | | <view class="fs-27 font-bold color5 mt-2"> |
| | | 4448 |
| | | </view> |
| | | </view> |
| | | <view class="fs-23 mt-44"> |
| | | <view class="color6"> |
| | | 同比上月 |
| | | </view> |
| | | <view class="txt-aligin-r color4 font-bold mt-4"> |
| | | +12% |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="pb-35 ml-29 mr-29 border2 br-15 mt-27 shadow1 flex j-between pl-19 pr-19"> |
| | | <template> |
| | | <view class="content"> |
| | | <view |
| | | v-if="userInfo.isAdmin == 1" |
| | | class="flex a-center pl-31 pr-31 fs-31 color1 pt-38" |
| | | > |
| | | <text class="mr-15">查看范围:</text> |
| | | <view |
| | | class="h-77 flex a-center j-between flex1 pl-31 pr-23 border1 br-15 bgColor1" |
| | | :class="!address && 'color2'" |
| | | > |
| | | <view @click.top="selectPopup = true" class="flex1"> |
| | | {{ address || "全部" }} |
| | | </view> |
| | | <u-icon |
| | | class="shrink0" |
| | | v-if="address" |
| | | @click="clearAddress" |
| | | name="close-circle" |
| | | ></u-icon> |
| | | <image |
| | | v-else |
| | | src="/static/down@2x.png" |
| | | mode="aspectFill" |
| | | class="w-31 h-31 shrink0" |
| | | ></image> |
| | | </view> |
| | | </view> |
| | | <view class="fs-35 font-bold pt-38 ml-27"> 处理满意率 </view> |
| | | <view |
| | | class="ml-29 mr-29 border2 br-15 mt-27 shadow1 flex j-between pl-19 pr-19 pb-35" |
| | | > |
| | | <view class="mt-19 flex1"> |
| | | <view class="flex a-center"> |
| | | <view class="w-12 h-12 br-6 border3"></view> |
| | | <view class="fs-23 ml-15 color3"> 总体满意率 </view> |
| | | </view> |
| | | <view class="fs-46 ml-27 mt-12 font-bold"> |
| | | {{ statisticsData.satisfaction.total }}% |
| | | </view> |
| | | </view> |
| | | <view class="flex1 flex j-between ml-50"> |
| | | <view class="fs-23 mt-42 txt-center"> |
| | | <view class="color6"> 本月 </view> |
| | | <view class="fs-27 font-bold color5 mt-2"> |
| | | {{ statisticsData.satisfaction.month }}% |
| | | </view> |
| | | </view> |
| | | <view class="fs-23 mt-44"> |
| | | <view class="color6"> 同比上月 </view> |
| | | <view class="txt-aligin-r color4 font-bold mt-4"> |
| | | {{ statisticsData.satisfaction.compare > 0 ? "+" : "" |
| | | }}{{ statisticsData.satisfaction.compare }}% |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="fs-35 font-bold mt-38 ml-27"> 诉求单统计 </view> |
| | | <view class="flex j-between a-center pl-29 pr-29 mt-27"> |
| | | <view class="pl-19 pr-21 shadow1 border2 pt-19 pb-42 flex1 br-15"> |
| | | <view class="flex a-center"> |
| | | <view class="w-12 h-12 br-6 border3"></view> |
| | | <view class="fs-23 ml-15 color3"> 诉求单量总计 </view> |
| | | </view> |
| | | <view class="fs-46 mt-12 font-bold ml-27"> |
| | | {{ statisticsData.demands.total }} |
| | | </view> |
| | | <view class="flex j-between mt-21"> |
| | | <view class="fs-23"> |
| | | <view class=""> 本月 </view> |
| | | <view class="fs-27 font-bold color3 mt-2"> |
| | | {{ statisticsData.demands.month }} |
| | | </view> |
| | | </view> |
| | | <view class="fs-23"> |
| | | <view class=""> 同比上月 </view> |
| | | <view class="font-bold color8 txt-aligin-r mt-4"> |
| | | {{ statisticsData.demands.compare > 0 ? "+" : "" |
| | | }}{{ statisticsData.demands.compare }} |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="pl-19 pr-21 shadow1 border2 pt-19 pb-42 flex1 ml-31 br-15"> |
| | | <view class="flex a-center"> |
| | | <view class="w-12 h-12 br-6 border3"></view> |
| | | <view class="fs-23 ml-15 color3"> 平均处理时间(天) </view> |
| | | </view> |
| | | <view class="fs-46 mt-12 font-bold ml-27"> |
| | | {{ statisticsData.processTime.total }} |
| | | </view> |
| | | <view class="flex j-between mt-21"> |
| | | <view class="fs-23"> |
| | | <view class=""> 本月 </view> |
| | | <view class="fs-27 font-bold color3 mt-2"> |
| | | {{ statisticsData.processTime.month }} |
| | | </view> |
| | | </view> |
| | | <view class="fs-23"> |
| | | <view class=""> 同比上月 </view> |
| | | <view class="font-bold color4 txt-aligin-r mt-4"> |
| | | {{ statisticsData.processTime.compare > 0 ? "+" : "" |
| | | }}{{ statisticsData.processTime.compare }} |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="flex mt-27 gap25 pl-29 pr-29"> |
| | | <view class="flex1 h-154 bgColor2 border4 shadow2 br-19 txt-center"> |
| | | <view class="mt-37 fs-35 color4 font-bold"> |
| | | {{ statisticsData.status.processing }} |
| | | </view> |
| | | <view class="fs-23 mt-8 color3"> 正在办理 </view> |
| | | </view> |
| | | <view class="flex1 h-154 bgColor3 border4 shadow2 br-19 txt-center"> |
| | | <view class="mt-37 fs-35 color9 font-bold"> |
| | | {{ statisticsData.status.reviewing }} |
| | | </view> |
| | | <view class="fs-23 mt-8 color3"> 审核中 </view> |
| | | </view> |
| | | <view class="flex1 h-154 bgColor4 border4 shadow2 br-19 txt-center"> |
| | | <view class="mt-37 fs-35 color10 font-bold"> |
| | | {{ statisticsData.status.delayed }} |
| | | </view> |
| | | <view class="fs-23 mt-8 color3"> 延期办理 </view> |
| | | </view> |
| | | <view class="flex1 h-154 bgColor5 border4 shadow2 br-19 txt-center"> |
| | | <view class="mt-37 fs-35 color11 font-bold"> |
| | | {{ statisticsData.status.completed }} |
| | | </view> |
| | | <view class="fs-23 mt-8 color3"> 已办结 </view> |
| | | </view> |
| | | </view> |
| | | <view |
| | | class="pb-35 ml-29 mr-29 border2 br-15 mt-27 shadow1 flex j-between pl-19 pr-19" |
| | | > |
| | | <view class="mt-19 flex1"> |
| | | <view class="flex a-center"> |
| | | <view class="w-12 h-12 br-6 border3"></view> |
| | | <view class="fs-23 ml-15 color3"> 超时办理 </view> |
| | | </view> |
| | | <view class="fs-46 ml-27 mt-12 font-bold"> |
| | | {{ statisticsData.overtime.total }} |
| | | </view> |
| | | </view> |
| | | <view class="flex1 flex j-between ml-50"> |
| | | <view class="fs-23 mt-42 txt-center"> |
| | | <view class="color6"> 本月 </view> |
| | | <view class="fs-27 font-bold color5 mt-2"> |
| | | {{ statisticsData.overtime.month }} |
| | | </view> |
| | | </view> |
| | | <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 }} |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <!-- <view class="pb-35 ml-29 mr-29 border2 br-15 mt-27 shadow1 flex j-between pl-19 pr-19"> |
| | | <view class="mt-19 flex1"> |
| | | <view class="flex a-center"> |
| | | <view class="w-12 h-12 br-6 border3"></view> |
| | |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="mt-27 shadow1 border2 ml-29 mr-29 pt-31 br-15" style="height: 511rpx;"> |
| | | <view class="flex mlr-o tabs mb-40"> |
| | | <view v-for="(item, index) in tabs" :key="index" |
| | | :class="['tab-item', currentTab === index ? 'active' : '']" @click="handleTabClick(index)"> |
| | | {{item}} |
| | | </view> |
| | | </view> |
| | | <view ref="chartRef" id="chart" style="width: 100%; height: 405rpx;"></view> |
| | | </view> |
| | | <view class="fs-35 font-bold mt-38 ml-27"> |
| | | 问题类型排名 |
| | | </view> |
| | | <view class="ml-29 mr-29 mt-27 shadow1 pt-31 border2 pl-38 pr-38 br-15"> |
| | | <uni-data-select v-model="value1" :localdata="range"></uni-data-select> |
| | | <view class="fs-23"> |
| | | <view class="flex a-center mb-38"> |
| | | <view class="w-130 color3"> |
| | | 教育 |
| | | </view> |
| | | <u-line-progress :percentage="95" inactiveColor="#EEEEEE" |
| | | :activeColor="'linear-gradient(270deg, #FF4934 0%, #FF8064 100%)'" height="38rpx"> |
| | | <text class="u-percentage-slot pr-19 fs-23">248</text> |
| | | </u-line-progress> |
| | | </view> |
| | | <view class="flex a-center mb-38"> |
| | | <view class="w-130 color3"> |
| | | 就业 |
| | | </view> |
| | | <u-line-progress :percentage="75" inactiveColor="#EEEEEE" |
| | | :activeColor="'linear-gradient(270deg, #FEA834 0%, #FFD364 100%)'" height="38rpx"> |
| | | <text class="u-percentage-slot pr-19 fs-23">200</text> |
| | | </u-line-progress> |
| | | </view> |
| | | <view class="flex a-center mb-38"> |
| | | <view class="w-130 color3"> |
| | | 医疗 |
| | | </view> |
| | | <u-line-progress :percentage="55" inactiveColor="#EEEEEE" |
| | | :activeColor="'linear-gradient(270deg, #02BAC0 0%, #05DEE1 100%)'" height="38rpx"> |
| | | <text class="u-percentage-slot pr-19 fs-23">174</text> |
| | | </u-line-progress> |
| | | </view> |
| | | <view class="flex a-center mb-38"> |
| | | <view class="w-130 color3"> |
| | | 住房 |
| | | </view> |
| | | <u-line-progress :percentage="35" inactiveColor="#EEEEEE" |
| | | :activeColor="'linear-gradient(270deg, #4791FF 0%, #7DC4FF 100%)'" height="38rpx"> |
| | | <text class="u-percentage-slot pr-19 fs-23">132</text> |
| | | </u-line-progress> |
| | | </view> |
| | | <view class="flex a-center mb-38"> |
| | | <view class="w-130 color3"> |
| | | 养老 |
| | | </view> |
| | | <u-line-progress :percentage="15" inactiveColor="#EEEEEE" |
| | | :activeColor="'linear-gradient(270deg, #4791FF 0%, #7DC4FF 100%)'" height="38rpx"> |
| | | <text class="u-percentage-slot pr-19 fs-23">89</text> |
| | | </u-line-progress> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="fs-35 font-bold mt-38 ml-27"> |
| | | 评价占比 |
| | | </view> |
| | | <view class="ml-29 mr-29 mt-27 shadow1 border2 br-15" style="height: 417rpx;"> |
| | | <view class="flex pl-38 pr-38"> |
| | | <view ref="rateChartRef" id="rateChart" style="width: 288rpx; height: 417rpx;"></view> |
| | | <view style="width: 46rpx;"></view> |
| | | <view class="flex1 pt-54"> |
| | | <view class="mb-27"> |
| | | <view class="flex a-center j-between mb-13"> |
| | | <text class="fs-23">非常满意</text> |
| | | <text class="fs-23 color12">45%</text> |
| | | </view> |
| | | <view class="progress-bar"> |
| | | <view class="progress-inner very-satisfied" style="width: 45%;"></view> |
| | | </view> |
| | | </view> |
| | | <view class="mb-27"> |
| | | <view class="flex a-center j-between mb-13"> |
| | | <text class="fs-23">满意</text> |
| | | <text class="fs-23 color12">20%</text> |
| | | </view> |
| | | <view class="progress-bar"> |
| | | <view class="progress-inner satisfied" style="width: 20%;"></view> |
| | | </view> |
| | | </view> |
| | | <view class="mb-27"> |
| | | <view class="flex a-center j-between mb-13"> |
| | | <text class="fs-23">一般</text> |
| | | <text class="fs-23 color12">30%</text> |
| | | </view> |
| | | <view class="progress-bar"> |
| | | <view class="progress-inner normal" style="width: 30%;"></view> |
| | | </view> |
| | | </view> |
| | | <view class="mb-27"> |
| | | <view class="flex a-center j-between mb-13"> |
| | | <text class="fs-23">不满意</text> |
| | | <text class="fs-23 color12">5%</text> |
| | | </view> |
| | | <view class="progress-bar"> |
| | | <view class="progress-inner unsatisfied" style="width: 5%;"></view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="h-40 safe-b"></view> |
| | | <!-- 选择服务社区 --> |
| | | <u-popup :show="selectPopup" round="16rpx" @close="selectPopup = false" :safe-area-inset-bottom="false" |
| | | @open="openSelectPopup"> |
| | | <view class="relative pb-40"> |
| | | <image @tap.stop="selectPopup = false" src="@/static/closeImg.png" class="w-35 h-35 absolute" |
| | | style="right: 31rpx;top: 46rpx;" /> |
| | | <view class="txt-center pt-38 pb-40 fs-35 lh-48 font-bold">请选择服务社区</view> |
| | | <view class="flex a-center j-between txt-center py-10 fs-27 font-bold bgColor1"> |
| | | <view class="flex1">区县</view> |
| | | <view class="flex1">街道</view> |
| | | <view class="flex1">社区</view> |
| | | </view> |
| | | <view class="mb-20"> |
| | | <picker-view :value="value" @change="bindChange" class="picker-view" immediate-change> |
| | | <picker-view-column> |
| | | <view class="item" v-for="(item, index) in county" :key="index"> |
| | | {{ item.name }} |
| | | </view> |
| | | </picker-view-column> |
| | | <picker-view-column> |
| | | <view class="item" v-for="(item, index) in street" :key="index"> |
| | | {{ item.name }} |
| | | </view> |
| | | </picker-view-column> |
| | | <picker-view-column> |
| | | <view class="item" v-for="(item, index) in community" :key="index"> |
| | | {{ item.name }} |
| | | </view> |
| | | </picker-view-column> |
| | | </picker-view> |
| | | </view> |
| | | <view class="submitBtn" @click="chooseCommunity">确认</view> |
| | | </view> |
| | | </u-popup> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import * as echarts from 'echarts'; |
| | | import { |
| | | getRegionTree |
| | | } from './service.js' |
| | | export default { |
| | | data() { |
| | | return { |
| | | userInfo: {}, |
| | | address: '', |
| | | value: [0, 0, 0], |
| | | confirmValue: [0, 0, 0], |
| | | county: [], //区县 |
| | | street: [], //街道 |
| | | community: [], //社区 |
| | | value1: 0, |
| | | selectPopup: false, |
| | | range: [{ |
| | | value: 0, |
| | | text: "排名前五" |
| | | }, |
| | | { |
| | | value: 1, |
| | | text: "排名前十" |
| | | }, |
| | | { |
| | | value: 2, |
| | | text: "所有排名" |
| | | }, |
| | | ], |
| | | chart: null, |
| | | rateChart: null, |
| | | tabs: ['近7天', '近15天', '近30天'], |
| | | currentTab: 0, |
| | | chartData: { |
| | | dates: [ |
| | | '2025\n04.17', |
| | | '2025\n04.18', |
| | | '2025\n04.19', |
| | | '2025\n04.20', |
| | | '2025\n04.21', |
| | | '2025\n04.22', |
| | | '2025\n04.23' |
| | | ], |
| | | demands: [80, 170, 240, 70, 130, 90, 160], |
| | | completed: [40, 130, 200, 30, 90, 50, 110] |
| | | }, |
| | | rateData: [{ |
| | | value: 45, |
| | | name: '非常满意', |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [{ |
| | | offset: 0, |
| | | color: '#FF8064' |
| | | }, |
| | | { |
| | | offset: 1, |
| | | color: '#FF4934' |
| | | } |
| | | ]) |
| | | } |
| | | }, |
| | | { |
| | | value: 20, |
| | | name: '满意', |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [{ |
| | | offset: 0, |
| | | color: '#05DEE1' |
| | | }, |
| | | { |
| | | offset: 1, |
| | | color: '#02BAC0' |
| | | } |
| | | ]) |
| | | } |
| | | }, |
| | | { |
| | | value: 30, |
| | | name: '一般', |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [{ |
| | | offset: 0, |
| | | color: '#7DC4FF' |
| | | }, |
| | | { |
| | | offset: 1, |
| | | color: '#4791FF' |
| | | } |
| | | ]) |
| | | } |
| | | }, |
| | | { |
| | | value: 5, |
| | | name: '不满意', |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [{ |
| | | offset: 0, |
| | | color: '#FFD364' |
| | | }, |
| | | { |
| | | offset: 1, |
| | | color: '#FEA834' |
| | | } |
| | | ]) |
| | | } |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | onLoad() { |
| | | this.userInfo = uni.getStorageSync('userInfo') |
| | | getRegionTree().then(res => { |
| | | this.county = res.data |
| | | }) |
| | | }, |
| | | mounted() { |
| | | this.$nextTick(() => { |
| | | this.initChart() |
| | | this.initRateChart() |
| | | }) |
| | | }, |
| | | methods: { |
| | | clearAddress() { |
| | | this.address = ''; |
| | | this.value = [0, 0, 0]; |
| | | this.confirmValue = [0, 0, 0]; |
| | | this.street = []; |
| | | this.community = []; |
| | | }, |
| | | //选择服务社区 |
| | | chooseCommunity() { |
| | | let districts = this.county[this.value[0]].name |
| | | let street = this.street[this.value[1]].name |
| | | let community = this.community[this.value[2]].name |
| | | |
| | | this.address = `${districts}-${street}-${community}`; |
| | | |
| | | this.confirmValue = this.value |
| | | this.selectPopup = false |
| | | }, |
| | | // 切换社区 |
| | | bindChange(e, index) { |
| | | if (e.detail.value[0] != this.value[0]) { |
| | | e.detail.value[1] = 0 |
| | | e.detail.value[2] = 0 |
| | | } |
| | | if (e.detail.value[1] != this.value[1]) { |
| | | e.detail.value[2] = 0 |
| | | } |
| | | this.value = e.detail.value |
| | | this.street = this.county[this.value[0]].children |
| | | this.community = this.street[this.value[1]].children |
| | | }, |
| | | openSelectPopup() { |
| | | this.value = this.confirmValue |
| | | this.street = this.county[this.value[0]].children |
| | | this.community = this.street[this.value[1]].children |
| | | }, |
| | | handleTabClick(index) { |
| | | this.currentTab = index |
| | | // 这里可以根据不同的 tab 加载不同时间段的数据 |
| | | // this.loadChartData(index) |
| | | }, |
| | | initChart() { |
| | | // 在 H5 端使用 document.getElementById |
| | | // 在小程序端使用 this.$refs.chartRef |
| | | const chartDom = document.getElementById('chart') || this.$refs.chartRef; |
| | | this.chart = echarts.init(chartDom); |
| | | this.updateChart(); |
| | | }, |
| | | updateChart() { |
| | | const option = { |
| | | color: ['#FF7B7B', '#FFB75B'], |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { |
| | | type: 'shadow' |
| | | } |
| | | }, |
| | | legend: { |
| | | data: ['诉求单量', '诉求办结数'], |
| | | bottom: '0', |
| | | itemGap: uni.upx2px(60), |
| | | selectedMode: true |
| | | }, |
| | | grid: { |
| | | left: '3%', |
| | | right: '4%', |
| | | bottom: '15%', |
| | | top: '3%', |
| | | containLabel: true |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | data: this.chartData.dates, |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: '#E5E5E5' |
| | | } |
| | | }, |
| | | axisTick: { |
| | | show: false |
| | | }, |
| | | axisLabel: { |
| | | color: '#888888', |
| | | fontSize: uni.upx2px(19), |
| | | lineHeight: uni.upx2px(23), |
| | | formatter: function(value) { |
| | | return value.split('\\n').join('\n') |
| | | } |
| | | } |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | | splitLine: { |
| | | lineStyle: { |
| | | type: 'dashed', |
| | | color: '#fff' |
| | | } |
| | | }, |
| | | axisLine: { |
| | | show: false |
| | | }, |
| | | axisTick: { |
| | | show: false |
| | | } |
| | | }, |
| | | series: [{ |
| | | name: '诉求单量', |
| | | type: 'bar', |
| | | barWidth: uni.upx2px(38), |
| | | itemStyle: { |
| | | borderRadius: [20, 20, 20, 20], |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ |
| | | offset: 0, |
| | | color: '#FF807E' |
| | | }, |
| | | { |
| | | offset: 1, |
| | | color: '#FF4948' |
| | | } |
| | | ]) |
| | | }, |
| | | data: this.chartData.demands |
| | | }, |
| | | { |
| | | name: '诉求办结数', |
| | | type: 'line', |
| | | smooth: true, |
| | | symbol: 'circle', |
| | | symbolSize: 8, |
| | | itemStyle: { |
| | | color: '#FFB75B', |
| | | borderWidth: 2, |
| | | borderColor: '#fff', |
| | | shadowColor: '#FB9A0E', |
| | | shadowBlur: 8, |
| | | shadowOffsetY: 4 |
| | | }, |
| | | lineStyle: { |
| | | width: 2, |
| | | curveness: 0.3 |
| | | }, |
| | | data: this.chartData.completed |
| | | } |
| | | ] |
| | | }; |
| | | this.chart && this.chart.setOption(option); |
| | | }, |
| | | initRateChart() { |
| | | const chartDom = document.getElementById('rateChart') || this.$refs.rateChartRef; |
| | | this.rateChart = echarts.init(chartDom); |
| | | this.updateRateChart(); |
| | | }, |
| | | updateRateChart() { |
| | | const option = { |
| | | tooltip: { |
| | | trigger: 'item', |
| | | confine: true, |
| | | // formatter: '{b}: {c}%', |
| | | backgroundColor: 'rgba(255, 255, 255, 0.9)', |
| | | borderColor: '#FFE0E0', |
| | | borderWidth: 1, |
| | | textStyle: { |
| | | color: '#666666', |
| | | fontSize: 12 |
| | | }, |
| | | padding: [8, 12] |
| | | }, |
| | | series: [{ |
| | | name: '评价占比', |
| | | type: 'pie', |
| | | radius: ['55%', '100%'], |
| | | center: ['50%', '50%'], |
| | | avoidLabelOverlap: false, |
| | | label: { |
| | | show: false |
| | | }, |
| | | labelLine: { |
| | | show: false |
| | | }, |
| | | emphasis: { |
| | | scale: false, |
| | | scaleSize: 0 |
| | | }, |
| | | data: this.rateData |
| | | }] |
| | | }; |
| | | this.rateChart && this.rateChart.setOption(option); |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | /deep/.uni-select { |
| | | width: 231rpx; |
| | | height: 65rpx; |
| | | margin: 0 auto; |
| | | margin-bottom: 38rpx; |
| | | font-size: 27rpx; |
| | | color: #797F81; |
| | | border-color: #E5E5E5; |
| | | border-radius: 33rpx; |
| | | padding: 0 31rpx 0 40rpx; |
| | | |
| | | .uni-select__input-text { |
| | | color: #797F81; |
| | | } |
| | | } |
| | | |
| | | .content { |
| | | background: linear-gradient(180deg, #FFDCDB 0%, rgba(255, 255, 255, 0) 100rpx, #fff 100%); |
| | | } |
| | | |
| | | .gap25 { |
| | | gap: 25rpx; |
| | | } |
| | | |
| | | .tabs { |
| | | width: 412rpx; |
| | | background-color: #FFF1F1; |
| | | border-radius: 30rpx; |
| | | height: 65rpx; |
| | | line-height: 65rpx; |
| | | font-size: 27rpx; |
| | | position: relative; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .tab-item { |
| | | color: #797F81; |
| | | flex: 1; |
| | | text-align: center; |
| | | font-weight: 400; |
| | | height: 54rpx; |
| | | line-height: 54rpx; |
| | | border-radius: 27rpx; |
| | | margin: 6rpx; |
| | | position: relative; |
| | | z-index: 1; |
| | | transform: translateZ(0); |
| | | transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); |
| | | |
| | | &.active { |
| | | background-color: #fff; |
| | | color: #FF4948; |
| | | font-weight: 600; |
| | | box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); |
| | | transform: scale(1.02); |
| | | } |
| | | } |
| | | |
| | | .chart-wrapper { |
| | | background: #fff; |
| | | border-radius: 20rpx; |
| | | padding: 20rpx; |
| | | } |
| | | |
| | | .color1 { |
| | | color: #666565; |
| | | } |
| | | |
| | | .color2 { |
| | | color: #C1C1C1; |
| | | } |
| | | |
| | | .color3 { |
| | | color: #666666; |
| | | } |
| | | |
| | | .color4 { |
| | | color: #FF4948; |
| | | } |
| | | |
| | | .color5 { |
| | | color: #696969; |
| | | } |
| | | |
| | | .color6 { |
| | | color: #A4A4A4; |
| | | } |
| | | |
| | | .color7 { |
| | | color: #A7A7A7; |
| | | } |
| | | |
| | | .color8 { |
| | | color: #0FB269; |
| | | } |
| | | |
| | | .color9 { |
| | | color: #FF5600; |
| | | } |
| | | |
| | | .color10 { |
| | | color: #161998; |
| | | } |
| | | |
| | | .color11 { |
| | | color: #08AD60; |
| | | } |
| | | |
| | | .color12 { |
| | | color: #9C9C9E; |
| | | } |
| | | |
| | | .bgColor1 { |
| | | background-color: #fff; |
| | | } |
| | | |
| | | .bgColor2 { |
| | | background-color: #FFF1F4; |
| | | } |
| | | |
| | | .bgColor3 { |
| | | background-color: #FFF8F4; |
| | | } |
| | | |
| | | .bgColor4 { |
| | | background-color: #F4F5FF; |
| | | } |
| | | |
| | | .bgColor5 { |
| | | background-color: #F1FFF8; |
| | | } |
| | | |
| | | .border1 { |
| | | border: 2rpx solid #D9D9D9; |
| | | } |
| | | |
| | | .border2 { |
| | | border: 2rpx solid #FFE0E0; |
| | | } |
| | | |
| | | .border3 { |
| | | border: 4rpx solid #FF4948; |
| | | box-sizing: border-box; |
| | | box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(255, 73, 72, 0.5); |
| | | } |
| | | |
| | | .border4 { |
| | | border: 2rpx solid #FFFFFF; |
| | | } |
| | | |
| | | .shadow1 { |
| | | box-shadow: 0rpx 0rpx 27rpx 0rpx rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .shadow2 { |
| | | box-shadow: 0rpx 0rpx 15rpx 0rpx rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .progress-bar { |
| | | width: 100%; |
| | | height: 8rpx; |
| | | background: #EEEEEE; |
| | | border-radius: 4rpx; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .progress-inner { |
| | | height: 100%; |
| | | border-radius: 4rpx; |
| | | transition: width 0.3s ease-in-out; |
| | | |
| | | &.very-satisfied { |
| | | background: linear-gradient(270deg, #FF8064 0%, #FF4934 100%); |
| | | } |
| | | |
| | | &.satisfied { |
| | | background: linear-gradient(270deg, #05DEE1 0%, #02BAC0 100%); |
| | | } |
| | | |
| | | &.normal { |
| | | background: linear-gradient(270deg, #7DC4FF 0%, #4791FF 100%); |
| | | } |
| | | |
| | | &.unsatisfied { |
| | | background: linear-gradient(270deg, #FFD364 0%, #FEA834 100%); |
| | | } |
| | | } |
| | | |
| | | .picker-view { |
| | | height: 460rpx; |
| | | font-size: 35rpx; |
| | | } |
| | | |
| | | /deep/.picker-view { |
| | | margin: 0 auto; |
| | | |
| | | .item { |
| | | text-align: center; |
| | | font-family: PingFangSC, PingFang SC; |
| | | font-weight: 600; |
| | | font-size: 36rpx; |
| | | color: #333333; |
| | | line-height: 50rpx; |
| | | } |
| | | } |
| | | |
| | | .submitBtn { |
| | | width: calc(100% - 62rpx); |
| | | margin: 0 31rpx; |
| | | line-height: 96rpx; |
| | | text-align: center; |
| | | background: linear-gradient(270deg, #FC8D55 0%, #FF4948 100%); |
| | | border-radius: 48rpx; |
| | | font-weight: 600; |
| | | font-size: 35rpx; |
| | | color: #fff; |
| | | } |
| | | </style> |
| | | </view> --> |
| | | <view |
| | | class="mt-27 shadow1 border2 ml-29 mr-29 pt-31 br-15" |
| | | style="height: 511rpx" |
| | | > |
| | | <view class="flex mlr-o tabs mb-40"> |
| | | <view |
| | | v-for="(item, index) in tabs" |
| | | :key="index" |
| | | :class="['tab-item', currentTab === index ? 'active' : '']" |
| | | @click="handleTabClick(index)" |
| | | > |
| | | {{ item }} |
| | | </view> |
| | | </view> |
| | | <view |
| | | ref="chartRef" |
| | | id="chart" |
| | | style="width: 100%; height: 405rpx" |
| | | ></view> |
| | | </view> |
| | | <view class="fs-35 font-bold mt-38 ml-27"> 问题类型排名 </view> |
| | | <view class="ml-29 mr-29 mt-27 shadow1 pt-31 border2 pl-38 pr-38 br-15"> |
| | | <uni-data-select v-model="value1" :localdata="range"></uni-data-select> |
| | | <view class="fs-23 type-rank-list-scroll"> |
| | | <view class="flex a-center mb-38" v-for="(item, idx) in typeRankList" :key="idx"> |
| | | <view class="w-130 color3">{{ item.typeName }}</view> |
| | | <u-line-progress |
| | | :percentage="item.percent" |
| | | inactiveColor="#EEEEEE" |
| | | :activeColor="item.gradientColor" |
| | | height="38rpx" |
| | | > |
| | | <text class="u-percentage-slot pr-19 fs-23">{{ item.count }}</text> |
| | | </u-line-progress> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="fs-35 font-bold mt-38 ml-27"> 评价占比 </view> |
| | | <view |
| | | class="ml-29 mr-29 mt-27 shadow1 border2 br-15" |
| | | style="height: 417rpx" |
| | | > |
| | | <view class="flex pl-38 pr-38"> |
| | | <view |
| | | ref="rateChartRef" |
| | | id="rateChart" |
| | | style="width: 288rpx; height: 417rpx" |
| | | ></view> |
| | | <view style="width: 46rpx"></view> |
| | | <view class="flex1 pt-54"> |
| | | <view class="mb-27"> |
| | | <view class="flex a-center j-between mb-13"> |
| | | <text class="fs-23">非常满意</text> |
| | | <text class="fs-23 color12">{{ greatSatisfactionRate }}%</text> |
| | | </view> |
| | | <view class="progress-bar"> |
| | | <view |
| | | class="progress-inner very-satisfied" |
| | | :style="{width: greatSatisfactionRate + '%'}" |
| | | ></view> |
| | | </view> |
| | | </view> |
| | | <view class="mb-27"> |
| | | <view class="flex a-center j-between mb-13"> |
| | | <text class="fs-23">满意</text> |
| | | <text class="fs-23 color12">{{ satisfactionRate }}%</text> |
| | | </view> |
| | | <view class="progress-bar"> |
| | | <view |
| | | class="progress-inner satisfied" |
| | | :style="{width: satisfactionRate + '%'}" |
| | | ></view> |
| | | </view> |
| | | </view> |
| | | <view class="mb-27"> |
| | | <view class="flex a-center j-between mb-13"> |
| | | <text class="fs-23">一般</text> |
| | | <text class="fs-23 color12">{{ generalSatisfactionRate }}%</text> |
| | | </view> |
| | | <view class="progress-bar"> |
| | | <view |
| | | class="progress-inner normal" |
| | | :style="{width: generalSatisfactionRate + '%'}" |
| | | ></view> |
| | | </view> |
| | | </view> |
| | | <view class="mb-27"> |
| | | <view class="flex a-center j-between mb-13"> |
| | | <text class="fs-23">不满意</text> |
| | | <text class="fs-23 color12">{{ dissatisfactionRate }}%</text> |
| | | </view> |
| | | <view class="progress-bar"> |
| | | <view |
| | | class="progress-inner unsatisfied" |
| | | :style="{width: dissatisfactionRate + '%'}" |
| | | ></view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="h-40 safe-b"></view> |
| | | <!-- 选择服务社区 --> |
| | | <u-popup |
| | | :show="selectPopup" |
| | | round="16rpx" |
| | | @close="selectPopup = false" |
| | | :safe-area-inset-bottom="false" |
| | | @open="openSelectPopup" |
| | | > |
| | | <view class="relative pb-40"> |
| | | <image |
| | | @tap.stop="selectPopup = false" |
| | | src="@/static/closeImg.png" |
| | | class="w-35 h-35 absolute" |
| | | style="right: 31rpx; top: 46rpx" |
| | | /> |
| | | <view class="txt-center pt-38 pb-40 fs-35 lh-48 font-bold" |
| | | >请选择服务社区</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 class="mb-20"> |
| | | <picker-view |
| | | :value="value" |
| | | @change="bindChange" |
| | | class="picker-view" |
| | | immediate-change |
| | | > |
| | | <picker-view-column v-if="hasTier(2)"> |
| | | <view |
| | | class="item" |
| | | v-for="(item, index) in regionTree" |
| | | :key="index" |
| | | > |
| | | {{ item.name }} |
| | | </view> |
| | | </picker-view-column> |
| | | <picker-view-column v-if="hasTier(3)"> |
| | | <view |
| | | class="item" |
| | | v-for="(item, index) in getStreets()" |
| | | :key="index" |
| | | > |
| | | {{ item.name }} |
| | | </view> |
| | | </picker-view-column> |
| | | <picker-view-column v-if="hasTier(4)"> |
| | | <view |
| | | class="item" |
| | | v-for="(item, index) in getCommunities()" |
| | | :key="index" |
| | | > |
| | | {{ item.name }} |
| | | </view> |
| | | </picker-view-column> |
| | | </picker-view> |
| | | </view> |
| | | <view class="submitBtn" @click="chooseCommunity">确认</view> |
| | | </view> |
| | | </u-popup> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import * as echarts from "echarts"; |
| | | import { |
| | | getRegionTree, |
| | | getStaticsPartOne, |
| | | getStaticsPartTwo, |
| | | getStaticsPartThree, |
| | | getStaticsPartFour |
| | | } from "./service.js"; |
| | | export default { |
| | | data() { |
| | | return { |
| | | userInfo: {}, |
| | | address: "", |
| | | value: [0, 0, 0], |
| | | confirmValue: [0, 0, 0], |
| | | regionTree: [], // 区域树数据 |
| | | value1: 0, |
| | | selectPopup: false, |
| | | range: [ |
| | | { |
| | | value: 0, |
| | | text: "排名前五", |
| | | }, |
| | | { |
| | | value: 1, |
| | | text: "排名前十", |
| | | }, |
| | | { |
| | | value: 2, |
| | | text: "所有排名", |
| | | }, |
| | | ], |
| | | chart: null, |
| | | rateChart: null, |
| | | tabs: ["近7天", "近15天", "近30天"], |
| | | currentTab: 0, |
| | | chartData: null, |
| | | rateData: [], |
| | | statisticsData: { |
| | | satisfaction: { |
| | | total: 0, |
| | | month: 0, |
| | | compare: 0, |
| | | }, |
| | | demands: { |
| | | total: 0, |
| | | month: 0, |
| | | compare: 0, |
| | | }, |
| | | processTime: { |
| | | total: 0, |
| | | month: 0, |
| | | compare: 0, |
| | | }, |
| | | status: { |
| | | processing: 0, |
| | | reviewing: 0, |
| | | delayed: 0, |
| | | completed: 0, |
| | | }, |
| | | overtime: { |
| | | total: 0, |
| | | month: 0, |
| | | compare: 0, |
| | | }, |
| | | completionRate: { |
| | | total: 0, |
| | | month: 0, |
| | | compare: 0, |
| | | }, |
| | | }, |
| | | currentAreaId: '', |
| | | currentTier: -1, |
| | | typeRankList: [], |
| | | greatSatisfactionRate: 0, |
| | | satisfactionRate: 0, |
| | | generalSatisfactionRate: 0, |
| | | dissatisfactionRate: 0, |
| | | }; |
| | | }, |
| | | onLoad() { |
| | | this.userInfo = uni.getStorageSync("userInfo"); |
| | | if (this.userInfo.identity == 1) { |
| | | this.userInfo.isAdmin = 0 |
| | | } |
| | | this.initRegionData(); |
| | | }, |
| | | mounted() { |
| | | this.$nextTick(() => { |
| | | this.initChart(); |
| | | this.initRateChart(); |
| | | }); |
| | | }, |
| | | methods: { |
| | | clearAddress() { |
| | | this.address = ""; |
| | | this.value = [0, 0, 0]; |
| | | this.confirmValue = [0, 0, 0]; |
| | | this.currentAreaId = ''; |
| | | this.currentTier = -1; |
| | | this.getStatisticsData("", -1); |
| | | this.getChartData(1); |
| | | this.getTypeRankData(); |
| | | this.getRateData(); |
| | | }, |
| | | //初始化区域数据 |
| | | initRegionData() { |
| | | getRegionTree().then((res) => { |
| | | if (res.code === 200) { |
| | | this.regionTree = [{name: '全部', id: 'all', tier: 2, children: []}, ...(res.data || [])]; |
| | | this.value = [0, 0, 0]; |
| | | this.confirmValue = [0, 0, 0]; |
| | | this.address = "全部"; |
| | | this.currentAreaId = ''; |
| | | this.currentTier = -1; |
| | | this.getStatisticsData("", -1); |
| | | this.getChartData(1); |
| | | this.getTypeRankData(); |
| | | this.getRateData(); |
| | | } |
| | | }); |
| | | }, |
| | | // 获取当前选中的区域对象 |
| | | getSelectedRegion() { |
| | | // 区县 |
| | | const county = this.regionTree[this.value[0]]; |
| | | if (!county || county.id === "all") return { id: "", tier: -1 }; |
| | | // 有街道 |
| | | const streets = |
| | | county.children && county.children.filter((c) => c && c.tier === 3); |
| | | if (streets && streets.length) { |
| | | const street = streets[this.value[1] - 1]; // -1 因为有"全部"选项 |
| | | if (!street || this.value[1] === 0 || street.id === "all") |
| | | return { id: county.id, tier: county.tier }; |
| | | const communities = |
| | | street.children && street.children.filter((c) => c && c.tier === 4); |
| | | if (communities && communities.length) { |
| | | const community = communities[this.value[2] - 1]; |
| | | if (!community || this.value[2] === 0 || community.id === "all") |
| | | return { id: street.id, tier: street.tier }; |
| | | return { id: community.id, tier: community.tier }; |
| | | } |
| | | return { id: street.id, tier: street.tier }; |
| | | } |
| | | // 区县下直接有社区 |
| | | const communities = |
| | | county.children && county.children.filter((c) => c && c.tier === 4); |
| | | if (communities && communities.length) { |
| | | const community = communities[this.value[1] - 1]; |
| | | if (!community || this.value[1] === 0 || community.id === "all") |
| | | return { id: county.id, tier: county.tier }; |
| | | return { id: community.id, tier: community.tier }; |
| | | } |
| | | // 只选了区县 |
| | | return { id: county.id, tier: county.tier }; |
| | | }, |
| | | // 根据value设置地址显示 |
| | | setAddressByValue() { |
| | | const names = []; |
| | | const county = this.regionTree[this.value[0]]; |
| | | if (!county) { |
| | | this.address = "全部"; |
| | | return; |
| | | } |
| | | |
| | | // 如果选中区县的全部 |
| | | if (county.id === "all") { |
| | | this.address = "全部"; |
| | | return; |
| | | } |
| | | |
| | | names.push(county.name); |
| | | |
| | | // 检查是否有街道 |
| | | const streets = |
| | | county.children && county.children.filter((c) => c && c.tier === 3); |
| | | if (streets && streets.length) { |
| | | const street = streets[this.value[1] - 1]; // -1 因为有"全部"选项 |
| | | if (street && street.id !== "all") { |
| | | names.push(street.name); |
| | | |
| | | // 检查街道下是否有社区 |
| | | const communities = |
| | | street.children && street.children.filter((c) => c && c.tier === 4); |
| | | if (communities && communities.length) { |
| | | const community = communities[this.value[2] - 1]; |
| | | if (community && community.id !== "all") { |
| | | names.push(community.name); |
| | | } |
| | | } |
| | | } |
| | | } else { |
| | | // 区县下直接有社区 |
| | | const communities = |
| | | county.children && county.children.filter((c) => c && c.tier === 4); |
| | | if (communities && communities.length) { |
| | | const community = communities[this.value[1] - 1]; |
| | | if (community && community.id !== "all") { |
| | | names.push(community.name); |
| | | } |
| | | } |
| | | } |
| | | |
| | | this.address = names.join("-"); |
| | | }, |
| | | //选择服务社区 |
| | | chooseCommunity() { |
| | | this.confirmValue = [...this.value]; |
| | | this.setAddressByValue(); |
| | | const { id, tier } = this.getSelectedRegion(); |
| | | this.currentAreaId = id; |
| | | this.currentTier = tier; |
| | | this.selectPopup = false; |
| | | this.getStatisticsData(id, tier); |
| | | this.getChartData(this.currentTab + 1); |
| | | this.getTypeRankData(); |
| | | this.getRateData(); |
| | | }, |
| | | // 切换社区 |
| | | bindChange(e) { |
| | | const newValue = e.detail.value; |
| | | // 级联重置逻辑 |
| | | if (newValue[0] !== this.value[0]) { |
| | | newValue[1] = 0; |
| | | newValue[2] = 0; |
| | | } else if (newValue[1] !== this.value[1]) { |
| | | newValue[2] = 0; |
| | | } |
| | | this.value = newValue; |
| | | }, |
| | | openSelectPopup() { |
| | | this.value = this.confirmValue; |
| | | }, |
| | | handleTabClick(index) { |
| | | this.currentTab = index; |
| | | this.getChartData(index + 1); |
| | | }, |
| | | initChart() { |
| | | const chartDom = document.getElementById("chart") || this.$refs.chartRef; |
| | | this.chart = echarts.init(chartDom); |
| | | if (this.chartData) this.updateChart(); |
| | | }, |
| | | updateChart() { |
| | | if (!this.chartData) return; |
| | | const option = { |
| | | color: ["#FF7B7B", "#FFB75B"], |
| | | tooltip: { |
| | | trigger: "axis", |
| | | axisPointer: { |
| | | type: "shadow", |
| | | }, |
| | | }, |
| | | legend: { |
| | | data: ["诉求单量", "诉求办结数"], |
| | | bottom: "0", |
| | | itemGap: uni.upx2px(60), |
| | | selectedMode: true, |
| | | }, |
| | | grid: { |
| | | left: "3%", |
| | | right: "4%", |
| | | bottom: "15%", |
| | | top: "3%", |
| | | containLabel: true, |
| | | }, |
| | | xAxis: { |
| | | type: "category", |
| | | data: this.chartData.dates, |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: "#E5E5E5", |
| | | }, |
| | | }, |
| | | axisTick: { |
| | | show: false, |
| | | }, |
| | | axisLabel: { |
| | | color: "#888888", |
| | | fontSize: uni.upx2px(19), |
| | | lineHeight: uni.upx2px(23), |
| | | formatter: function (value) { |
| | | return value.split("\n").join("\n"); |
| | | }, |
| | | }, |
| | | }, |
| | | yAxis: { |
| | | type: "value", |
| | | splitLine: { |
| | | lineStyle: { |
| | | type: "dashed", |
| | | color: "#fff", |
| | | }, |
| | | }, |
| | | axisLine: { |
| | | show: false, |
| | | }, |
| | | axisTick: { |
| | | show: false, |
| | | }, |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "诉求单量", |
| | | type: "bar", |
| | | barWidth: uni.upx2px(38), |
| | | itemStyle: { |
| | | borderRadius: [20, 20, 20, 20], |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { |
| | | offset: 0, |
| | | color: "#FF807E", |
| | | }, |
| | | { |
| | | offset: 1, |
| | | color: "#FF4948", |
| | | }, |
| | | ]), |
| | | }, |
| | | data: this.chartData.demands, |
| | | }, |
| | | { |
| | | name: "诉求办结数", |
| | | type: "line", |
| | | smooth: true, |
| | | symbol: "circle", |
| | | symbolSize: 8, |
| | | itemStyle: { |
| | | color: "#FFB75B", |
| | | borderWidth: 2, |
| | | borderColor: "#fff", |
| | | shadowColor: "#FB9A0E", |
| | | shadowBlur: 8, |
| | | shadowOffsetY: 4, |
| | | }, |
| | | lineStyle: { |
| | | width: 2, |
| | | curveness: 0.3, |
| | | }, |
| | | data: this.chartData.completed, |
| | | }, |
| | | ], |
| | | }; |
| | | this.chart && this.chart.setOption(option); |
| | | }, |
| | | initRateChart() { |
| | | const chartDom = |
| | | document.getElementById("rateChart") || this.$refs.rateChartRef; |
| | | this.rateChart = echarts.init(chartDom); |
| | | this.updateRateChart(); |
| | | }, |
| | | updateRateChart() { |
| | | const option = { |
| | | tooltip: { |
| | | trigger: "item", |
| | | confine: true, |
| | | // formatter: '{b}: {c}%', |
| | | backgroundColor: "rgba(255, 255, 255, 0.9)", |
| | | borderColor: "#FFE0E0", |
| | | borderWidth: 1, |
| | | textStyle: { |
| | | color: "#666666", |
| | | fontSize: 12, |
| | | }, |
| | | padding: [8, 12], |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "评价占比", |
| | | type: "pie", |
| | | radius: ["55%", "100%"], |
| | | center: ["50%", "50%"], |
| | | avoidLabelOverlap: false, |
| | | label: { |
| | | show: false, |
| | | }, |
| | | labelLine: { |
| | | show: false, |
| | | }, |
| | | emphasis: { |
| | | scale: false, |
| | | scaleSize: 0, |
| | | }, |
| | | data: this.rateData, |
| | | }, |
| | | ], |
| | | }; |
| | | this.rateChart && this.rateChart.setOption(option); |
| | | }, |
| | | // 添加获取统计数据的方法 |
| | | async getStatisticsData(areaId = "", tier = -1) { |
| | | try { |
| | | const res = await getStaticsPartOne({ |
| | | areaId, |
| | | tier, |
| | | }); |
| | | if (res.code === 200) { |
| | | this.statisticsData = { |
| | | satisfaction: { |
| | | total: res.data.satisfactionRate ?? 0, |
| | | month: res.data.thisMonthSatisfactionRate ?? 0, |
| | | compare: res.data.lastMonthCompareSatisfactionRate ?? 0, |
| | | }, |
| | | demands: { |
| | | total: res.data.allTotal ?? 0, |
| | | month: res.data.thisMonthTotal ?? 0, |
| | | compare: res.data.lastMonthCompareTotal ?? 0, |
| | | }, |
| | | processTime: { |
| | | total: res.data.averageTime ?? 0, |
| | | month: res.data.thisMonthAverageTime ?? 0, |
| | | compare: res.data.lastMonthCompareAverageTime ?? 0, |
| | | }, |
| | | status: { |
| | | processing: res.data.nowTransactTotal ?? 0, |
| | | reviewing: res.data.auditTransactTotal ?? 0, |
| | | delayed: res.data.postponeTransactTotal ?? 0, |
| | | completed: res.data.completeTransactTotal ?? 0, |
| | | }, |
| | | overtime: { |
| | | total: res.data.overtimeTransactTotal ?? 0, |
| | | month: res.data.thisMonthOvertimeTransactTotal ?? 0, |
| | | compare: res.data.lastMonthOvertimeTransactCompareTotal ?? 0, |
| | | }, |
| | | completionRate: { |
| | | total: 0, |
| | | month: 0, |
| | | compare: 0, |
| | | }, |
| | | }; |
| | | // 更新图表数据 |
| | | this.updateChart(); |
| | | this.updateRateChart(); |
| | | } |
| | | } catch (error) { |
| | | console.error("获取统计数据失败:", error); |
| | | } |
| | | }, |
| | | hasTier(tier) { |
| | | // tier=2: 区县始终有 |
| | | if (tier === 2) return true; |
| | | // tier=3: 当前区县children里有tier=3 |
| | | if (tier === 3) { |
| | | const county = this.regionTree[this.value[0]]; |
| | | return ( |
| | | county && |
| | | Array.isArray(county.children) && |
| | | 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; |
| | | // 区县下直接有社区 |
| | | if (county.children.some((c) => c && c.tier === 4)) return true; |
| | | // 区县下有街道,街道下有社区 |
| | | const street = county.children[this.value[1]]; |
| | | return ( |
| | | street && |
| | | Array.isArray(street.children) && |
| | | street.children.some((c) => c && c.tier === 4) |
| | | ); |
| | | } |
| | | return false; |
| | | }, |
| | | getStreets() { |
| | | const county = this.regionTree[this.value[0]]; |
| | | if (!county || !Array.isArray(county.children)) return []; |
| | | // 只返回tier=3的 |
| | | const streets = county.children.filter((c) => c && c.tier === 3); |
| | | return streets.length |
| | | ? [{ name: "全部", id: "all", tier: 3, children: [] }, ...streets] |
| | | : []; |
| | | }, |
| | | getCommunities() { |
| | | const county = this.regionTree[this.value[0]]; |
| | | if (!county || !Array.isArray(county.children)) return []; |
| | | // 区县下直接有社区 |
| | | 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]]; |
| | | 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) { |
| | | try { |
| | | const res = await getStaticsPartTwo({ |
| | | areaId: this.currentAreaId, |
| | | tier: this.currentTier, |
| | | timeType |
| | | }); |
| | | if (res.code === 200 && res.data) { |
| | | // 转换数据格式 |
| | | const dates = res.data.map(item => item.time.replace(/-/g, '\n').replace(/\n(\d{2})$/, '.$1')); |
| | | const demands = res.data.map(item => item.allTotal); |
| | | const completed = res.data.map(item => item.completeTotal); |
| | | this.chartData = { |
| | | dates, |
| | | demands, |
| | | completed |
| | | }; |
| | | this.updateChart(); |
| | | } |
| | | } catch (e) { |
| | | console.error('获取图表数据失败', e); |
| | | } |
| | | }, |
| | | async getTypeRankData() { |
| | | let rank; |
| | | if (this.value1 === 0) rank = 5; |
| | | else if (this.value1 === 1) rank = 10; |
| | | // value1 === 2 时不传rank |
| | | const params = { |
| | | areaId: this.currentAreaId, |
| | | tier: this.currentTier |
| | | }; |
| | | if (rank) params.rank = rank; |
| | | try { |
| | | const res = await getStaticsPartThree(params); |
| | | console.log(JSON.stringify(res.data)); |
| | | |
| | | if (res.code === 200 && Array.isArray(res.data)) { |
| | | // 计算最大值 |
| | | const max = Math.max(...res.data.map(item => item.allTotal), 1); |
| | | const gradients = [ |
| | | 'linear-gradient(270deg, #FF4934 0%, #FF8064 100%)', |
| | | 'linear-gradient(270deg, #FEA834 0%, #FFD364 100%)', |
| | | 'linear-gradient(270deg, #02BAC0 0%, #05DEE1 100%)', |
| | | ]; |
| | | const defaultGradient = 'linear-gradient(270deg, #4791FF 0%, #7DC4FF 100%)'; |
| | | // 处理数据,增加percent字段 |
| | | this.typeRankList = res.data.map((item, idx) => ({ |
| | | typeName: item.name, |
| | | count: item.allTotal, |
| | | percent: Math.round(item.allTotal / max * 100), |
| | | gradientColor: gradients[idx] || defaultGradient |
| | | })); |
| | | } |
| | | } catch (e) { |
| | | console.error('获取问题类型排名失败', e); |
| | | } |
| | | }, |
| | | async getRateData() { |
| | | try { |
| | | const res = await getStaticsPartFour({ |
| | | areaId: this.currentAreaId, |
| | | tier: this.currentTier |
| | | }); |
| | | console.log(JSON.stringify(res.data)); |
| | | if (res.code === 200 && res.data) { |
| | | // 饼图数据 |
| | | const values = [ |
| | | res.data.greatSatisfactionRate ?? 0, |
| | | res.data.satisfactionRate ?? 0, |
| | | res.data.generalSatisfactionRate ?? 0, |
| | | res.data.dissatisfactionRate ?? 0 |
| | | ]; |
| | | const names = ['非常满意', '满意', '一般', '不满意']; |
| | | const gradients = [ |
| | | ['#FF8064', '#FF4934'], |
| | | ['#05DEE1', '#02BAC0'], |
| | | ['#7DC4FF', '#4791FF'], |
| | | ['#FFD364', '#FEA834'] |
| | | ]; |
| | | if (values.every(v => v === 0)) values[0] = 1; // 避免全为0 |
| | | this.rateData = values.map((v, idx) => ({ |
| | | value: v, |
| | | name: names[idx], |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [ |
| | | { offset: 0, color: gradients[idx][0] }, |
| | | { offset: 1, color: gradients[idx][1] } |
| | | ]) |
| | | } |
| | | })); |
| | | // 进度条数据 |
| | | this.greatSatisfactionRate = values[0]; |
| | | this.satisfactionRate = values[1]; |
| | | this.generalSatisfactionRate = values[2]; |
| | | this.dissatisfactionRate = values[3]; |
| | | this.updateRateChart(); |
| | | } |
| | | } catch (e) { |
| | | console.error('获取评价占比失败', e); |
| | | } |
| | | }, |
| | | }, |
| | | watch: { |
| | | value1() { |
| | | this.getTypeRankData(); |
| | | } |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | /deep/.uni-select { |
| | | width: 231rpx; |
| | | height: 65rpx; |
| | | margin: 0 auto; |
| | | margin-bottom: 38rpx; |
| | | font-size: 27rpx; |
| | | color: #797f81; |
| | | border-color: #e5e5e5; |
| | | border-radius: 33rpx; |
| | | padding: 0 31rpx 0 40rpx; |
| | | |
| | | .uni-select__input-text { |
| | | color: #797f81; |
| | | } |
| | | } |
| | | |
| | | .content { |
| | | background: linear-gradient( |
| | | 180deg, |
| | | #ffdcdb 0%, |
| | | rgba(255, 255, 255, 0) 100rpx, |
| | | #fff 100% |
| | | ); |
| | | } |
| | | |
| | | .gap25 { |
| | | gap: 25rpx; |
| | | } |
| | | |
| | | .tabs { |
| | | width: 412rpx; |
| | | background-color: #fff1f1; |
| | | border-radius: 30rpx; |
| | | height: 65rpx; |
| | | line-height: 65rpx; |
| | | font-size: 27rpx; |
| | | position: relative; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .tab-item { |
| | | color: #797f81; |
| | | flex: 1; |
| | | text-align: center; |
| | | font-weight: 400; |
| | | height: 54rpx; |
| | | line-height: 54rpx; |
| | | border-radius: 27rpx; |
| | | margin: 6rpx; |
| | | position: relative; |
| | | z-index: 1; |
| | | transform: translateZ(0); |
| | | transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); |
| | | |
| | | &.active { |
| | | background-color: #fff; |
| | | color: #ff4948; |
| | | font-weight: 600; |
| | | box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); |
| | | transform: scale(1.02); |
| | | } |
| | | } |
| | | |
| | | .chart-wrapper { |
| | | background: #fff; |
| | | border-radius: 20rpx; |
| | | padding: 20rpx; |
| | | } |
| | | |
| | | .color1 { |
| | | color: #666565; |
| | | } |
| | | |
| | | .color2 { |
| | | color: #c1c1c1; |
| | | } |
| | | |
| | | .color3 { |
| | | color: #666666; |
| | | } |
| | | |
| | | .color4 { |
| | | color: #ff4948; |
| | | } |
| | | |
| | | .color5 { |
| | | color: #696969; |
| | | } |
| | | |
| | | .color6 { |
| | | color: #a4a4a4; |
| | | } |
| | | |
| | | .color7 { |
| | | color: #a7a7a7; |
| | | } |
| | | |
| | | .color8 { |
| | | color: #0fb269; |
| | | } |
| | | |
| | | .color9 { |
| | | color: #ff5600; |
| | | } |
| | | |
| | | .color10 { |
| | | color: #161998; |
| | | } |
| | | |
| | | .color11 { |
| | | color: #08ad60; |
| | | } |
| | | |
| | | .color12 { |
| | | color: #9c9c9e; |
| | | } |
| | | |
| | | .bgColor1 { |
| | | background-color: #fff; |
| | | } |
| | | |
| | | .bgColor2 { |
| | | background-color: #fff1f4; |
| | | } |
| | | |
| | | .bgColor3 { |
| | | background-color: #fff8f4; |
| | | } |
| | | |
| | | .bgColor4 { |
| | | background-color: #f4f5ff; |
| | | } |
| | | |
| | | .bgColor5 { |
| | | background-color: #f1fff8; |
| | | } |
| | | |
| | | .border1 { |
| | | border: 2rpx solid #d9d9d9; |
| | | } |
| | | |
| | | .border2 { |
| | | border: 2rpx solid #ffe0e0; |
| | | } |
| | | |
| | | .border3 { |
| | | border: 4rpx solid #ff4948; |
| | | box-sizing: border-box; |
| | | box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(255, 73, 72, 0.5); |
| | | } |
| | | |
| | | .border4 { |
| | | border: 2rpx solid #ffffff; |
| | | } |
| | | |
| | | .shadow1 { |
| | | box-shadow: 0rpx 0rpx 27rpx 0rpx rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .shadow2 { |
| | | box-shadow: 0rpx 0rpx 15rpx 0rpx rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .progress-bar { |
| | | width: 100%; |
| | | height: 8rpx; |
| | | background: #eeeeee; |
| | | border-radius: 4rpx; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .progress-inner { |
| | | height: 100%; |
| | | border-radius: 4rpx; |
| | | transition: width 0.3s ease-in-out; |
| | | |
| | | &.very-satisfied { |
| | | background: linear-gradient(270deg, #ff8064 0%, #ff4934 100%); |
| | | } |
| | | |
| | | &.satisfied { |
| | | background: linear-gradient(270deg, #05dee1 0%, #02bac0 100%); |
| | | } |
| | | |
| | | &.normal { |
| | | background: linear-gradient(270deg, #7dc4ff 0%, #4791ff 100%); |
| | | } |
| | | |
| | | &.unsatisfied { |
| | | background: linear-gradient(270deg, #ffd364 0%, #fea834 100%); |
| | | } |
| | | } |
| | | |
| | | .picker-view { |
| | | height: 460rpx; |
| | | font-size: 35rpx; |
| | | } |
| | | |
| | | /deep/.picker-view { |
| | | margin: 0 auto; |
| | | |
| | | .item { |
| | | text-align: center; |
| | | font-family: PingFangSC, PingFang SC; |
| | | font-weight: 600; |
| | | font-size: 36rpx; |
| | | color: #333333; |
| | | line-height: 50rpx; |
| | | } |
| | | } |
| | | |
| | | .submitBtn { |
| | | width: calc(100% - 62rpx); |
| | | margin: 0 31rpx; |
| | | line-height: 96rpx; |
| | | text-align: center; |
| | | background: linear-gradient(270deg, #fc8d55 0%, #ff4948 100%); |
| | | border-radius: 48rpx; |
| | | font-weight: 600; |
| | | font-size: 35rpx; |
| | | color: #fff; |
| | | } |
| | | |
| | | .type-rank-list-scroll { |
| | | max-height: 500rpx; |
| | | overflow-y: auto; |
| | | } |
| | | </style> |