移动端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

492 lines
13 KiB

<template>
<cs-page :selected="0" isTab title="智慧环保">
<view class="view-container">
<view class="drop-box">
<van-dropdown-menu active-color="#17C653">
<van-dropdown-item
:value="queryParams.deptId"
:options="dropOption.dept"
title="按部门"
@change="
v => {
querySelect(v, 'deptId')
}
"
></van-dropdown-item>
<van-dropdown-item
:value="queryParams.selectWeek"
:options="dropOption.select_week"
title="按周期"
@change="
v => {
querySelect(v, 'selectWeek')
}
"
/>
</van-dropdown-menu>
</view>
<scroll-view
:scroll-y="true"
:style="{ maxHeight: `${viewHeigth}px` }"
:refresher-enabled="true"
class="view"
@refresherrefresh="refresherrefresh"
:refresher-triggered="refresherTriggered"
@refresherpulling="refresherpulling"
>
<view class="box row-1">
<view
class="wd-flex"
style="justify-content: space-around; padding: 24rpx"
>
<view
class="wd-flex wd-flex-col wd-flex-center"
style="gap: 8rpx"
>
<u-count-to
:start-val="0"
:end-val="detail.taskCount"
font-size="24"
blod="500"
color="#071437"
class="number"
></u-count-to>
<view style="color: #4b5675">任务数量</view>
</view>
<view
class="wd-flex wd-flex-col wd-flex-center"
style="gap: 8rpx"
>
<u-count-to
:start-val="0"
:end-val="detail.inspectionsCount"
font-size="24"
blod="500"
color="#071437"
></u-count-to>
<view style="color: #4b5675">执法记录</view>
</view>
<view
class="wd-flex wd-flex-col wd-flex-center"
style="gap: 8rpx"
>
<u-count-to
:start-val="0"
:end-val="detail.enterpriseCount"
font-size="24"
blod="500"
color="#071437"
></u-count-to>
<view style="color: #4b5675">企业数量</view>
</view>
</view>
<qiun-data-charts
type="ring"
:opts="opts"
:chartData="chartData"
:canvas2d="true"
style="height: 288rpx"
></qiun-data-charts>
<view class="wd-flex" style="gap: 24rpx; flex-wrap: wrap">
<view
class="wd-flex wd-flex-col wd-flex-center"
v-for="item in detail.legendData"
:key="item"
style="
border: 2rpx solid #f9f9f9;
width: calc(100% / 3 - 16rpx);
padding: 24rpx;
gap: 8rpx;
border-radius: 8rpx;
"
>
<view class="wd-flex wd-flex-col" style="gap: 8rpx">
<view
class="wd-flex"
style="align-items: center; gap: 8rpx"
>
<view
:style="{
width: '16rpx',
height: '8rpx',
borderRadius: '8rpx',
backgroundColor: item.color
}"
></view>
<view class="people-name">{{ item.name }}</view>
</view>
<view class="wd-flex wd-flex-center">
<u-count-to
:start-val="0"
:end-val="Number(item.value)"
font-size="16"
color="#071437"
></u-count-to>
<text class="number">%</text>
</view>
</view>
</view>
</view>
</view>
<view class="box row-1">
<view
class="wd-flex"
style="margin-top: 24rpx; justify-content: center"
>
<view
style="
background-color: #f9f9f9;
display: inline-flex;
padding: 8rpx;
"
>
<view
class="tab"
v-for="(item, index) in tabs"
:key="index"
:style="{
'--index': tabs.findIndex(
i => i.type == queryParams.type
)
}"
@tap="changeTab(item.type)"
>
<view
class="name"
:style="{
color:
queryParams.type == item.type
? '#071437'
: '#78829d',
fontWeight:
queryParams.type == item.type ? 'bold' : '400'
}"
>
{{ item.name }}
</view>
</view>
</view>
</view>
<view style="min-height: 440rpx">
<view
v-for="(item, index) in list"
:key="index"
class="wd-flex"
style="justify-content: space-between; padding: 24rpx"
>
<view class="wd-font-500">{{ item.name }}</view>
<view class="wd-font-500" style="color: #17c653">
<view>
<u-count-to
:start-val="0"
:end-val="Number(item.count) || 0"
bold
font-size="14"
color="#17C653"
></u-count-to>
<text>{{ queryParams.type == 1 ? '天' : '次' }}</text>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</cs-page>
</template>
<script>
import { getDictBatchByType, getDeptTree } from '@/api/system/dict.js'
import { HomeApi } from '@/api/common/home.js'
export default {
data() {
return {
dictMap: {},
queryParams: {
selectWeek: '3',
deptId: '',
type: 1
},
detail: {},
opts: {},
chartData: {},
viewHeigth: 0,
tabs: [
{
name: '资质临期',
type: 1
},
{
name: '整改次数',
type: 2
}
],
refresherTriggered: false,
list: [],
dropOption: {},
color: []
}
},
onLoad: async function () {
await uni.hideTabBar()
uni.hideTabBar({
animation: false
})
await this.getDict()
if (!this.$roles.checkRole(['director'])) {
this.queryParams.deptId = this.$store.getters.deptId
}
await this.init()
},
onReady() {
this.$nextTick(() => {
this.getPageHeight()
})
},
onShow() {
this.init()
},
methods: {
getPageHeight() {
const query = uni.createSelectorQuery().in(this)
query
.select('.view-container')
.boundingClientRect()
.select('.drop-box')
.boundingClientRect()
.select('.cs-tabber-container')
.boundingClientRect()
.exec(res => {
this.viewHeigth = res[0].height - res[1].height
})
},
async getDict() {
const dict = await getDictBatchByType({
type: ['select_week'].join(',')
})
const dept = await getDeptTree()
if (!this.$roles.checkRole(['director'])) {
this.dropOption.dept = [
...dept.data
.filter(i => {
return i.id == this.$store.getters.deptId
})
.map(i => {
return {
value: i.id,
text: i.name
}
})
]
} else {
this.dropOption.dept = [
...dept.data.map(i => {
return {
value: i.id,
text: i.name
}
}),
{
value: '',
text: '全部'
}
]
}
this.dropOption.select_week = [
...dict.data.select_week.map(i => {
return {
value: i.value,
text: i.label
}
})
]
},
async init() {
// if (!this.$roles.checkRole(['director'])) {
// this.queryParams.deptId = this.$store.getters.deptId
// }
const res = await HomeApi.getPieData(this.queryParams)
this.detail = res.data
let curIndex = 0
const colorMap = []
const data = this.detail.completionRate.map((item, index) => {
const color = this.getGradientColor(
index,
this.detail.completionRate.length
)
const res = {
...item,
color
}
colorMap.push(color)
return res
})
colorMap.push('#F9F9F9')
this.color = colorMap
this.detail.legendData = data
this.setPieData(data, this.detail.taskCompletionRate)
this.getList()
},
async getList() {
const res = await HomeApi.getListData(this.queryParams)
this.list = res.data
},
setPieData(data, max) {
const pieData = data.map(i => {
return {
name: i.name,
value: Number(i.pieValue)
}
})
if (Number(max) < 100) {
pieData.splice(pieData.length, 0, {
name: '',
value: 100 - Number(max)
})
}
this.opts = {
legend: {
show: false
},
color: this.color,
rotate: false,
rotateLock: false,
padding: [0, 0, 0, 0],
dataLabel: false,
enableScroll: false,
title: {
name: `${max}%`,
fontSize: 24,
color: '#071437'
},
subtitle: {
name: '完成率',
fontSize: 14,
color: '#78829D'
},
extra: {
ring: {
ringWidth: 15,
activeOpacity: 0.5,
offsetAngle: 90,
labelWidth: 15,
border: false,
borderColor: '#F9F9F9',
borderWidth: 0.5,
linearType: 'none'
}
}
}
this.chartData = {
series: [
{
data: [...pieData]
}
]
}
},
sectionChange(index) {
this.queryParams.enterprise = index
},
querySelect(v, key) {
this.queryParams[key] = v.detail
this.init()
},
changeTab(type) {
this.queryParams.type = type
this.getList()
},
refresherpulling() {
const that = this
if (!this.refresherTriggered) {
this.refresherTriggered = true
setTimeout(() => {
that.refresherTriggered = false
}, 1000)
}
},
refresherrefresh() {
this.init()
},
numFilter(value) {
// 先保留三位小数
let tempVal = parseFloat(value).toFixed(3)
// 然后截取前两位小数
let realVal = tempVal.substring(0, tempVal.length - 1)
return realVal
},
getGradientColor(index, total) {
const opacity = 1 - index / total + 0.1
return `rgba(4, 180, 64, ${opacity})`
}
}
}
</script>
<style lang="scss" scoped>
.view-container {
height: 100%;
}
.view {
padding: 0 24rpx 48rpx;
.box {
padding: 24rpx;
background-color: #fff;
border: 2rpx solid #f9f9f9;
border-radius: 24rpx;
}
.row-1 {
display: flex;
flex-flow: column nowrap;
gap: 24rpx;
margin-top: 24rpx;
&:last-child {
margin-bottom: 84rpx;
}
}
.people-name {
max-width: 4rem;
max-height: 1rem;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
color: #4b5675;
}
.tab {
position: relative;
padding: 8rpx 32rpx;
.name {
z-index: 2;
position: inherit;
}
&:first-child::before {
content: '';
position: absolute;
inset: 0;
background-color: #fff;
border-radius: 4rpx;
transform: translateX(calc(var(--index) * 100%));
transition: 0.2s all;
z-index: 1;
}
}
}
.drop-box {
padding: 24rpx;
border-bottom: 2rpx solid #f1f1f4;
background-color: #fff;
::v-deep .van-dropdown-menu {
box-shadow: none;
height: fit-content !important;
font-size: 26rpx;
padding: 8rpx 24rpx;
}
::v-deep .van-dropdown-item {
margin-bottom: 64rpx;
}
}
</style>