|
@@ -0,0 +1,546 @@
|
|
|
+<template>
|
|
|
+ <div class="resource">
|
|
|
+ <select-option
|
|
|
+ @query="handleQuery"
|
|
|
+ v-bind:statisticsInfo="statisticsInfo"
|
|
|
+ v-bind:loading="loading"
|
|
|
+ v-bind:normal="normal"
|
|
|
+ v-bind:special="special"
|
|
|
+ v-bind:feedbak="feedbak"
|
|
|
+ />
|
|
|
+ <div class="wrap">
|
|
|
+ <div class="column">
|
|
|
+ <Card title="场所类型划分" width="420" height="245">
|
|
|
+ <Progress :data="placeInfo.data" :maxNum="placeInfo.maxNum" ref="progress" />
|
|
|
+ </Card>
|
|
|
+ <Card title="隐患情况统计" width="420" height="244">
|
|
|
+ <Progress :data="byItemfo.data" :maxNum="byItemfo.maxNum" ref="progress2" />
|
|
|
+ </Card>
|
|
|
+ </div>
|
|
|
+ <Card title="专项检查情况" class="card2">
|
|
|
+ <el-table
|
|
|
+ :data="specialInfoData"
|
|
|
+ style="width: 100%;"
|
|
|
+ height="445"
|
|
|
+ v-loading="loading"
|
|
|
+ ref="table"
|
|
|
+ >
|
|
|
+ <el-table-column
|
|
|
+ prop="enforce_job_item_name"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="专业检查名称"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="enforce_obj_num"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="检查单位数"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column prop="rate" show-overflow-tooltip label="完成率" align="center" />
|
|
|
+ </el-table>
|
|
|
+ </Card>
|
|
|
+ <div class="column">
|
|
|
+ <Card
|
|
|
+ title="模版使用排行"
|
|
|
+ width="420"
|
|
|
+ height="269"
|
|
|
+ v-bind:isMore="true"
|
|
|
+ @more="handleMoreClick('template')"
|
|
|
+ >
|
|
|
+ <el-table
|
|
|
+ :data="templateInfData"
|
|
|
+ style="width: 100%;"
|
|
|
+ height="210"
|
|
|
+ v-loading="loading"
|
|
|
+ ref="table2"
|
|
|
+ >
|
|
|
+ <el-table-column
|
|
|
+ type="index"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="序号"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="template_name"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="模版名称"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="create_org_name"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="创建机构"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="crate_user_name"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="创建人"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="use_num"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="使用次数"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ </el-table>
|
|
|
+ </Card>
|
|
|
+ <Card
|
|
|
+ title="检查规则贡献值"
|
|
|
+ width="420"
|
|
|
+ height="228"
|
|
|
+ v-bind:isMore="true"
|
|
|
+ @more="handleMoreClick('contribute')"
|
|
|
+ >
|
|
|
+ <el-table
|
|
|
+ :data="ontributeInfoData"
|
|
|
+ style="width: 100%;"
|
|
|
+ height="170"
|
|
|
+ v-loading="loading"
|
|
|
+ >
|
|
|
+ <el-table-column
|
|
|
+ type="index"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="序号"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="user_name"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="姓名"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="create_org_name"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="所属机构"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="feedbak_num"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="反馈次数"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column show-overflow-tooltip label="操作" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-link
|
|
|
+ type="primary"
|
|
|
+ @click="handleOntributeDetail(scope.$index, scope.row)"
|
|
|
+ >详情</el-link>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </Card>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-dialog
|
|
|
+ width="65%"
|
|
|
+ top="10vh"
|
|
|
+ v-bind:title="dialogDetailTable.title"
|
|
|
+ :visible.sync="dialogDetailTable.visible"
|
|
|
+ @close="handleDialogClose"
|
|
|
+ >
|
|
|
+ <detail-table
|
|
|
+ v-bind:total="dialogDetailTable.total"
|
|
|
+ v-bind:data="dialogDetailTable.data"
|
|
|
+ v-bind:loading="dialogTableLoading"
|
|
|
+ @nextPage="handleNextPage"
|
|
|
+ ref="table"
|
|
|
+ />
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <el-dialog
|
|
|
+ width="65%"
|
|
|
+ top="10vh"
|
|
|
+ v-bind:title="dialogTemplateTable.title"
|
|
|
+ :visible.sync="dialogTemplateTable.visible"
|
|
|
+ @close="handleDialogClose"
|
|
|
+ >
|
|
|
+ <template-table
|
|
|
+ v-bind:data="dialogTemplateTable.data"
|
|
|
+ v-bind:loading="dialogTableLoading"
|
|
|
+ v-bind:total="dialogTemplateTable.total"
|
|
|
+ @nextPage="handleNextPage"
|
|
|
+ ref="table"
|
|
|
+ />
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <el-dialog
|
|
|
+ width="65%"
|
|
|
+ top="10vh"
|
|
|
+ v-bind:title="dialogContributTable.title"
|
|
|
+ :visible.sync="dialogContributTable.visible"
|
|
|
+ @close="handleDialogClose"
|
|
|
+ >
|
|
|
+ <contribut-table
|
|
|
+ v-bind:data="dialogContributTable.data"
|
|
|
+ v-bind:loading="dialogTableLoading"
|
|
|
+ v-bind:total="dialogContributTable.total"
|
|
|
+ @nextPage="handleNextPage"
|
|
|
+ @lookDetail="handleOntributeDetail"
|
|
|
+ ref="table"
|
|
|
+ />
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import Card from './component/Card.vue'
|
|
|
+import SelectOption from './component/SelectOption.vue'
|
|
|
+import DetailTable from './component/DetailTable.vue'
|
|
|
+import TemplateTable from './component/TemplateTable.vue'
|
|
|
+import ContributTable from './component/ContributTable.vue'
|
|
|
+import Progress from './component/Progress.vue'
|
|
|
+import {
|
|
|
+ getStatisticInfo, getStatisticTotal, getStatisticFeedbak, getStatisticPlaceType, getStatisticByItem,
|
|
|
+ getStatisticSpecialInfo, getStatisticTemplateInfo, getStatisticContributeInfo, getStatisticContributeDetail
|
|
|
+} from '@/api/statistics'
|
|
|
+import { DateTime } from "luxon";
|
|
|
+
|
|
|
+export default {
|
|
|
+ components: {
|
|
|
+ SelectOption,
|
|
|
+ Card,
|
|
|
+ DetailTable,
|
|
|
+ TemplateTable,
|
|
|
+ ContributTable,
|
|
|
+ Progress,
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ queryData: {},
|
|
|
+ loading: false,
|
|
|
+ statisticsInfo: {
|
|
|
+ enforce_obj_num: 0,
|
|
|
+ enforce_person_num: 0,
|
|
|
+ find_item_num: 0,
|
|
|
+ pass_enforce_obj_num: 0,
|
|
|
+ rectify_item_num: 0,
|
|
|
+ un_pass_enforce_obj_num: 0,
|
|
|
+ },
|
|
|
+ normal: {
|
|
|
+ total: 0,
|
|
|
+ done: 0
|
|
|
+ },
|
|
|
+ special: {
|
|
|
+ total: 0,
|
|
|
+ done: 0
|
|
|
+ },
|
|
|
+ feedbak: {
|
|
|
+ tempalte_num: 0,
|
|
|
+ contribute_num: 0
|
|
|
+ },
|
|
|
+ specialInfoData: [],
|
|
|
+ templateInfData: [],
|
|
|
+ ontributeInfoData: [],
|
|
|
+ dialogTableLoading: false,
|
|
|
+ contributDetailId: '',
|
|
|
+ dialogDetailTable: {
|
|
|
+ visible: false,
|
|
|
+ title: '',
|
|
|
+ total: 0,
|
|
|
+ data: []
|
|
|
+ },
|
|
|
+ dialogTemplateTable: {
|
|
|
+ visible: false,
|
|
|
+ title: '',
|
|
|
+ total: 0,
|
|
|
+ data: []
|
|
|
+ },
|
|
|
+ dialogContributTable: {
|
|
|
+ visible: false,
|
|
|
+ title: '',
|
|
|
+ total: 0,
|
|
|
+ data: []
|
|
|
+ },
|
|
|
+ timer: '',
|
|
|
+ timer2: '',
|
|
|
+ placeInfo: {
|
|
|
+ maxNum: 0,
|
|
|
+ data: []
|
|
|
+ },
|
|
|
+ byItemfo: {
|
|
|
+ maxNum: 0,
|
|
|
+ data: []
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ const end = new Date();
|
|
|
+ const start = new Date();
|
|
|
+ start.setMonth(start.getMonth() - 3);
|
|
|
+ this.handleQuery({
|
|
|
+ start_date: DateTime.fromJSDate(start).toFormat("yyyy-LL-dd"),
|
|
|
+ end_date: DateTime.fromJSDate(end).toFormat("yyyy-LL-dd"),
|
|
|
+ enforce_org_id: '',
|
|
|
+ })
|
|
|
+ this.timer = setInterval(this.autoTableScroll, 100)
|
|
|
+
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ autoTableScroll() {
|
|
|
+ const table = this.$refs.table
|
|
|
+ const table2 = this.$refs.table2
|
|
|
+ const divData = table.bodyWrapper
|
|
|
+ const divData2 = table2.bodyWrapper
|
|
|
+ const progress = this.$refs.progress.$el
|
|
|
+ const progress2 = this.$refs.progress2.$el
|
|
|
+ progress.scrollTop += 3
|
|
|
+ if (progress.clientHeight + progress.scrollTop == progress.scrollHeight) {
|
|
|
+ progress.scrollTop = 0
|
|
|
+ }
|
|
|
+ progress2.scrollTop += 3
|
|
|
+ if (progress2.clientHeight + progress2.scrollTop == progress2.scrollHeight) {
|
|
|
+ progress2.scrollTop = 0
|
|
|
+ }
|
|
|
+ divData.scrollTop += 3
|
|
|
+ divData2.scrollTop += 3
|
|
|
+ if (divData.clientHeight + divData.scrollTop == divData.scrollHeight) {
|
|
|
+ divData.scrollTop = 0
|
|
|
+ }
|
|
|
+ if (divData2.clientHeight + divData2.scrollTop == divData2.scrollHeight) {
|
|
|
+ divData2.scrollTop = 0
|
|
|
+ }
|
|
|
+ },
|
|
|
+ resetForm() {
|
|
|
+ this.handleQuery()
|
|
|
+ },
|
|
|
+ handleQuery(data) {
|
|
|
+ console.log('data', data)
|
|
|
+ this.queryData = data
|
|
|
+ this.loading = true
|
|
|
+ Promise.all([getStatisticInfo({ ...data }),
|
|
|
+ getStatisticTotal({ ...data, job_type: 'NORMAL', }),
|
|
|
+ getStatisticTotal({ ...data, job_type: 'SPECIAL', }),
|
|
|
+ getStatisticFeedbak({ ...data }),
|
|
|
+ getStatisticPlaceType({ ...data }),
|
|
|
+ getStatisticByItem({ ...data }),
|
|
|
+ getStatisticSpecialInfo({ ...data }),
|
|
|
+ getStatisticTemplateInfo({
|
|
|
+ ...data,
|
|
|
+ page: 1,
|
|
|
+ size: 50,
|
|
|
+ sort: "create_time desc"
|
|
|
+ }),
|
|
|
+ getStatisticContributeInfo({
|
|
|
+ ...data,
|
|
|
+ page: 1,
|
|
|
+ size: 50,
|
|
|
+ sort: "create_time desc"
|
|
|
+ }),
|
|
|
+ ]).then(res => {
|
|
|
+ if (res[0].data) {
|
|
|
+ this.statisticsInfo = res[0].data
|
|
|
+ }
|
|
|
+ if (res[1].data) {
|
|
|
+ this.normal = res[1].data
|
|
|
+ }
|
|
|
+ if (res[2].data) {
|
|
|
+ this.special = res[2].data
|
|
|
+ }
|
|
|
+ if (res[3].data) {
|
|
|
+ this.feedbak = res[3].data
|
|
|
+ }
|
|
|
+ if (res[4].data) {
|
|
|
+ this.placeInfo = {
|
|
|
+ data: res[4].data,
|
|
|
+ maxNum:
|
|
|
+ Math.max.apply(Math, res[4].data.map(item => { return item.job_num }))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (res[5].data) {
|
|
|
+ const newData = []
|
|
|
+ res[5].data.map(item => {
|
|
|
+ newData.push({
|
|
|
+ job_num: item.enforce_job_item_num,
|
|
|
+ type_name: item.enforce_job_item_name
|
|
|
+ })
|
|
|
+ })
|
|
|
+ this.byItemfo = {
|
|
|
+ data: newData,
|
|
|
+ maxNum:
|
|
|
+ Math.max.apply(Math, newData.map(item => { return item.job_num }))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (res[6].data) {
|
|
|
+ const specialInfoDatas = []
|
|
|
+ res[6].data.map(item => {
|
|
|
+ specialInfoDatas.push({
|
|
|
+ ...item,
|
|
|
+ rate: (Math.round(Number(item.enforce_obj_done) / Number(item.enforce_obj_num) * 10000) / 100.00 + "%")
|
|
|
+ })
|
|
|
+ })
|
|
|
+ this.specialInfoData = specialInfoDatas
|
|
|
+ }
|
|
|
+ if (res[7].data) {
|
|
|
+ this.templateInfData = res[7].data
|
|
|
+ }
|
|
|
+ if (res[8].data) {
|
|
|
+ this.ontributeInfoData = res[8].data
|
|
|
+ }
|
|
|
+ }).finally(() => this.loading = false)
|
|
|
+ },
|
|
|
+ handleOntributeDetail(index, data) {
|
|
|
+ this.contributDetailId = data.id
|
|
|
+ this.dialogDetailTable = {
|
|
|
+ visible: true,
|
|
|
+ data: [],
|
|
|
+ title: data.create_org_name,
|
|
|
+ }
|
|
|
+ this.getOntributeDetail({
|
|
|
+ page: 1,
|
|
|
+ size: 10,
|
|
|
+ sort: "create_time desc",
|
|
|
+ type: 'contribute',
|
|
|
+ id: data.id,
|
|
|
+ title: data.create_org_name
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getOntributeDetail(params) {
|
|
|
+ const { page, size, sort, id, title } = params
|
|
|
+ this.dialogTableLoading = true
|
|
|
+ getStatisticContributeDetail(id, {
|
|
|
+ ...this.queryData,
|
|
|
+ page,
|
|
|
+ size,
|
|
|
+ sort,
|
|
|
+ }).then(res => {
|
|
|
+ if (res.data) {
|
|
|
+ const data = res.data.map(item => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ create_time: DateTime.fromJSDate(new Date(item.create_time)).toFormat("yyyy-LL-dd")
|
|
|
+
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.dialogDetailTable = {
|
|
|
+ ...this.dialogDetailTable,
|
|
|
+ total: res.total,
|
|
|
+ data,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).finally(() =>
|
|
|
+ this.dialogTableLoading = false
|
|
|
+ )
|
|
|
+ },
|
|
|
+ handleNextPage(params) {
|
|
|
+ const { type, page, size, sort } = params
|
|
|
+ if (type === 'contribute') {
|
|
|
+ this.dialogTableLoading = true
|
|
|
+ getStatisticContributeInfo({
|
|
|
+ ...this.queryData,
|
|
|
+ page,
|
|
|
+ size,
|
|
|
+ sort,
|
|
|
+ }).then(res => {
|
|
|
+ if (res.data) {
|
|
|
+ this.dialogContributTable = {
|
|
|
+ visible: true,
|
|
|
+ data: res.data,
|
|
|
+ total: res.total,
|
|
|
+ title: '检查规则贡献值'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).finally(() =>
|
|
|
+ this.dialogTableLoading = false
|
|
|
+ )
|
|
|
+ }
|
|
|
+ if (type === 'contributeDetail') {
|
|
|
+ this.getOntributeDetail({
|
|
|
+ page,
|
|
|
+ size,
|
|
|
+ sort,
|
|
|
+ type: 'contribute',
|
|
|
+ id: this.contributDetailId,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (type === 'template') {
|
|
|
+ this.dialogTableLoading = true
|
|
|
+ getStatisticTemplateInfo({
|
|
|
+ ...this.queryData,
|
|
|
+ page,
|
|
|
+ size,
|
|
|
+ sort,
|
|
|
+ }).then(res => {
|
|
|
+ if (res.data) {
|
|
|
+ this.dialogTemplateTable = {
|
|
|
+ visible: true,
|
|
|
+ data: res.data,
|
|
|
+ total: res.total,
|
|
|
+ title: '模版使用排行'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).finally(() =>
|
|
|
+ this.dialogTableLoading = false
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleMoreClick(type) {
|
|
|
+ if (type === 'contribute') {
|
|
|
+ this.dialogContributTable = {
|
|
|
+ visible: true,
|
|
|
+ data: [],
|
|
|
+ total: 0,
|
|
|
+ title: '检查规则贡献值'
|
|
|
+ }
|
|
|
+ this.handleNextPage({
|
|
|
+ page: 1,
|
|
|
+ size: 10,
|
|
|
+ sort: "create_time desc",
|
|
|
+ type: 'contribute'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (type === 'template') {
|
|
|
+ this.dialogTemplateTable = {
|
|
|
+ visible: true,
|
|
|
+ data: [],
|
|
|
+ total: 0,
|
|
|
+ title: '模版使用排行'
|
|
|
+ }
|
|
|
+ this.handleNextPage({
|
|
|
+ page: 1,
|
|
|
+ size: 10,
|
|
|
+ sort: "create_time desc",
|
|
|
+ type: 'template'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleDialogClose() {
|
|
|
+ this.$refs.table.$emit("close")
|
|
|
+ }
|
|
|
+ },
|
|
|
+ destroyed() {
|
|
|
+ clearInterval(this.timer)
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.wrap {
|
|
|
+ margin-top: 16px;
|
|
|
+ height: 505px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.column {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.card2 {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 300px;
|
|
|
+ margin: 0 10px;
|
|
|
+}
|
|
|
+#place,
|
|
|
+#byItem {
|
|
|
+ margin-top: -60px;
|
|
|
+ margin-left: -10px;
|
|
|
+}
|
|
|
+</style>
|