|
|
@@ -7,104 +7,99 @@
|
|
|
<dv-decoration-5 :class="$style.center" :dur="5" />
|
|
|
<dv-decoration-8 :class="$style.right" :reverse="true" />
|
|
|
<div :class="$style.title">{{ title }}</div>
|
|
|
- <dv-border-box-8 :class="$style.year">
|
|
|
+ <div :class="$style.year" @click.prevent="tabChange()">
|
|
|
+ <dv-border-box-8>{{tab == 'mubiao' ? '质量目标' : '质量指标'}}</dv-border-box-8>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ :class="$style.datewrap"
|
|
|
+ v-if="tab == 'zhibiao'"
|
|
|
+ >
|
|
|
+ <div>月份:</div>
|
|
|
<el-date-picker
|
|
|
- v-model="year"
|
|
|
- type="year"
|
|
|
- value-format="yyyy"
|
|
|
- format="yyyy"
|
|
|
- placeholder="统计年度"
|
|
|
- style="width: 80px"
|
|
|
- :readonly="false"
|
|
|
- :editable="true"
|
|
|
- :clearable="false"
|
|
|
- @change="updateAll"
|
|
|
- />
|
|
|
- </dv-border-box-8>
|
|
|
- <dv-decoration-7 :class="$style.cycle">
|
|
|
- <el-dropdown @command="changeCycle">
|
|
|
- <span class="el-dropdown-link" :style="`font-size: ${fontSize}px;`">{{ selectedCycle }}</span>
|
|
|
- <el-dropdown-menu slot="dropdown" class="dept-dropdown">
|
|
|
- <el-dropdown-item
|
|
|
- v-for="(item, index) in cycleList"
|
|
|
- :key="index"
|
|
|
- :command="index"
|
|
|
- >{{ item }}</el-dropdown-item>
|
|
|
- </el-dropdown-menu>
|
|
|
- </el-dropdown>
|
|
|
- </dv-decoration-7>
|
|
|
+ v-model="endDate"
|
|
|
+ type="monthrange"
|
|
|
+ align="right"
|
|
|
+ unlink-panels
|
|
|
+ style="background-color: transparent;color: #fff"
|
|
|
+ format="yyyy 年 MM 月"
|
|
|
+ value-format="yyyy-MM"
|
|
|
+ @change="checkYear(endDate, 'end')"
|
|
|
+ range-separator="至"
|
|
|
+ start-placeholder="开始日期"
|
|
|
+ end-placeholder="结束日期"
|
|
|
+ >
|
|
|
+ </el-date-picker>
|
|
|
+ </div>
|
|
|
+
|
|
|
<div :class="$style.back" @click.prevent="goBack()">
|
|
|
- <dv-border-box-8>返回</dv-border-box-8>
|
|
|
+ <dv-border-box-8>退出</dv-border-box-8>
|
|
|
</div>
|
|
|
<div :class="$style.parse" @click="toggleAutoPlay">
|
|
|
<img v-if="autoPlay" src="~@/assets/images/icons/parse.png">
|
|
|
<img v-else src="~@/assets/images/icons/play.png">
|
|
|
</div>
|
|
|
+ <div :class="$style.pnButton">
|
|
|
+ <el-button
|
|
|
+ icon="el-icon-arrow-left"
|
|
|
+ :class="$style.preNextButton"
|
|
|
+ circle
|
|
|
+ @click.native="skipTo('pre')"
|
|
|
+ ></el-button>
|
|
|
+ <div :class="$style.textContent">{{ chartIndex + 1 }}</div>
|
|
|
+ <el-button
|
|
|
+ icon="el-icon-arrow-right"
|
|
|
+ :class="$style.preNextButton"
|
|
|
+ circle
|
|
|
+ @click.native="skipTo('next')"
|
|
|
+ ></el-button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
<!-- 图表区域 -->
|
|
|
<dv-border-box-1>
|
|
|
- <month-chart v-if="renderData.length && selectedCycle === '每月'" :info="renderData" :font-size="fontSize" :choose-year="year" />
|
|
|
- <quarter-chart v-if="renderData.length && selectedCycle === '每季度'" :info="renderData" :font-size="fontSize" :choose-year="year" />
|
|
|
- <year-chart v-if="renderData.length && selectedCycle === '每年'" :info="renderData" :font-size="fontSize" :choose-year="year" />
|
|
|
+ <mu-biao-chart v-if="renderData.length" :info="renderData" :font-size="fontSize" :choose-year="year" @child-event="handleChildEvent" />
|
|
|
</dv-border-box-1>
|
|
|
</dv-full-screen-container>
|
|
|
+ <zhibiao-dialog v-if="showDialog" loading="true" :targetName="zhibiao" :dateRange="dateRange" @closeDialog="showDialog = false"></zhibiao-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
<script>
|
|
|
import screenfull from 'screenfull'
|
|
|
+import { getQualityIndicator } from '@/api/platform/chart/chart'
|
|
|
export default {
|
|
|
components: {
|
|
|
- MonthChart: () => import('./components/monthChart.vue'),
|
|
|
- QuarterChart: () => import('./components/quarterChart.vue'),
|
|
|
- YearChart: () => import('./components/yearChart.vue')
|
|
|
+ MuBiaoChart: () => import('./components/muBiaoChart.vue'),
|
|
|
+ ZhibiaoDialog: () => import('./components/zhibiaoDialog.vue')
|
|
|
},
|
|
|
data () {
|
|
|
const d = new Date()
|
|
|
return {
|
|
|
+ tab: 'mubiao',
|
|
|
level: '',
|
|
|
- title: '质量指标统计',
|
|
|
+ title: '质量指标看板',
|
|
|
year: d.toJSON().slice(0, 4),
|
|
|
cycleList: [],
|
|
|
- sizeMap: {
|
|
|
- '每月': 4,
|
|
|
- '每季度': 4,
|
|
|
- '每年': 4
|
|
|
- },
|
|
|
- // year: '2023',
|
|
|
initData: {},
|
|
|
renderData: [],
|
|
|
fontSize: 18,
|
|
|
- itemIndex: 0,
|
|
|
chartIndex: 0,
|
|
|
dataFetchTimer: null,
|
|
|
autoPlayTimer: null,
|
|
|
- autoPlay: true
|
|
|
- }
|
|
|
- },
|
|
|
- computed: {
|
|
|
- selectedCycle () {
|
|
|
- return this.cycleList[this.itemIndex] || '每月'
|
|
|
- },
|
|
|
- size () {
|
|
|
- return this.sizeMap[this.selectedCycle]
|
|
|
+ autoPlay: true,
|
|
|
+ size: 4,
|
|
|
+ pageAll: 0,
|
|
|
+ BeginDate: "",
|
|
|
+ endDate: "2026-02",
|
|
|
+ dataScope: [],
|
|
|
+ dateRange: '',
|
|
|
+ showDialog: false,
|
|
|
+ zhibiao: ''
|
|
|
}
|
|
|
},
|
|
|
watch: {
|
|
|
chartIndex (v) {
|
|
|
- this.renderData = this.initData[this.selectedCycle] ? this.initData[this.selectedCycle].slice(v * this.size, (v + 1) * this.size) : []
|
|
|
- },
|
|
|
- itemIndex (v) {
|
|
|
- this.renderData = this.initData[this.selectedCycle] ? this.initData[this.selectedCycle].slice(this.chartIndex * this.size, (this.chartIndex + 1) * this.size) : []
|
|
|
+ this.renderData = this.initData && this.initData.length > 0 ? this.initData.slice(v * this.size, (v + 1) * this.size) : []
|
|
|
}
|
|
|
},
|
|
|
- // beforeRouteEnter (to, from, next) {
|
|
|
- // Promise.all([]).done(([res]) => {
|
|
|
- // console.log(res)
|
|
|
- // }).then(err => {
|
|
|
- // window.observer.trigger('error', err)
|
|
|
- // next()
|
|
|
- // })
|
|
|
- // },
|
|
|
created () {
|
|
|
// 默认全屏展示
|
|
|
if (screenfull.isEnabled && !screenfull.isFullscreen) {
|
|
|
@@ -112,6 +107,13 @@ export default {
|
|
|
}
|
|
|
|
|
|
this.updateAll()
|
|
|
+
|
|
|
+ if (!this.BeginDate && !this.endDate) {
|
|
|
+ this.BeginDate = this.getDate(1) + "";
|
|
|
+ this.endDate = this.getDate(0);
|
|
|
+ this.dataScope.push(this.BeginDate);
|
|
|
+ this.dataScope.push(this.endDate);
|
|
|
+ }
|
|
|
},
|
|
|
beforeDestroy () {
|
|
|
if (screenfull.isFullscreen) {
|
|
|
@@ -120,14 +122,57 @@ export default {
|
|
|
this.clenUp()
|
|
|
},
|
|
|
methods: {
|
|
|
+ handleChildEvent(e) {
|
|
|
+ console.log('子组件传参',e)
|
|
|
+ this.zhibiao = e.title
|
|
|
+ this.dateRange = `${e.xName.split('年度')[0]}01-${e.xName.split('年度')[0]}12`
|
|
|
+ this.stopAutoPlay()
|
|
|
+ this.showDialog = true
|
|
|
+ },
|
|
|
+ checkYear(date, date2) {
|
|
|
+ this.dateRange = date.map(item => item.replace('-', '')).join('-')
|
|
|
+ this.updateAll()
|
|
|
+ },
|
|
|
+ /* 获取当前年份*/
|
|
|
+ getDate(year, isString) {
|
|
|
+ year = year || 0;
|
|
|
+ let nowDate = new Date();
|
|
|
+ let date = new Date(new Date().setDate(1) + 31 * 24 * 60 * 60 * 1000);
|
|
|
+ let month = date.getMonth() + 1;
|
|
|
+ let m1 = nowDate.getMonth() + 1;
|
|
|
+ let month1 = m1 < 10 ? "0" + m1 : nowDate.getMonth() + 1;
|
|
|
+ month = month < 10 ? "0" + month : "" + month;
|
|
|
+ if(isString){
|
|
|
+ return `${nowDate.getFullYear() - year}01-${nowDate.getFullYear()-year}${month1}`
|
|
|
+ }else{
|
|
|
+ return [
|
|
|
+ nowDate.getFullYear() - year + "-01",
|
|
|
+ nowDate.getFullYear() - year + "-" + month1,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ tabChange () {
|
|
|
+ console.log(this.getDate(), 111)
|
|
|
+ if(this.tab == 'mubiao') {
|
|
|
+ this.tab = 'zhibiao'
|
|
|
+ this.dateRange = this.getDate(0, true)
|
|
|
+ this.endDate = this.getDate(0, false)
|
|
|
+ } else {
|
|
|
+ this.tab = 'mubiao'
|
|
|
+ this.dateRange = ''
|
|
|
+ }
|
|
|
+ this.targetName = ''
|
|
|
+ this.chartIndex = 0
|
|
|
+ this.updateAll()
|
|
|
+ },
|
|
|
initializeData () {
|
|
|
const w = window.innerWidth
|
|
|
const { first = '', second = '' } = this.$store.getters.level || {}
|
|
|
|
|
|
this.initData = {}
|
|
|
- this.itemIndex = 0
|
|
|
this.chartIndex = 0
|
|
|
- this.level = second || first
|
|
|
+ this.level = second || first
|
|
|
this.fontSize = w >= 1600 ? 20 : w > 1366 && w < 1600 ? 18 : 16
|
|
|
},
|
|
|
updateAll () {
|
|
|
@@ -135,49 +180,26 @@ export default {
|
|
|
this.fetchData().then(() => {
|
|
|
this.startAutoPlay()
|
|
|
this.setupTimer()
|
|
|
- this.renderData = this.initData[this.selectedCycle] ? this.initData[this.selectedCycle].slice(this.chartIndex * this.size, (this.chartIndex + 1) * this.size) : []
|
|
|
+ this.renderData = this.initData ? this.initData.slice(this.chartIndex * this.size, (this.chartIndex + 1) * this.size) : []
|
|
|
+ console.log('renderData',this.renderData)
|
|
|
})
|
|
|
},
|
|
|
async fetchData () {
|
|
|
- // 月度指标统计本年度,季度指标统计今年和去年,年度指标统计所有
|
|
|
- // const sql = `select a.id_ as aid, a.di_dian_ as place, a.bian_zhi_bu_men_ as dept, a.tong_ji_pin_lv_ as cycle, a.tong_ji_yue_fen_ as statisticalTime, a.create_time_ as createTime, b.id_ as bid, b.zhi_liang_mu_biao as goal, b.zhi_liang_zhi_bia as target, b.zhi_biao_xian_zhi as limitValue, b.shi_ji_shu_zhi_ as result, b.yuan_shi_shu_ju_ as originalData from t_zlzbpjb a inner join (select tong_ji_yue_fen_, max(create_time_) as max from t_zlzbpjb where di_dian_ = '${this.level}' group by tong_ji_yue_fen_) a_latest on a.tong_ji_yue_fen_ = a_latest.tong_ji_yue_fen_ and a.create_time_ = a_latest.max left join t_zlzbpjzb b on a.id_ = b.parent_id_ where a.shi_fou_guo_shen_ = '已完成' and a.di_dian_ = '${this.level}' and ((a.tong_ji_pin_lv_ = '每月' and a.tong_ji_yue_fen_ like concat(${this.year}, '%') or (a.tong_ji_pin_lv_ = '每季度' and (a.tong_ji_yue_fen_ like concat(${this.year}, '%') or a.tong_ji_yue_fen_ like concat(${this.year - 1}, '%'))) or a.tong_ji_pin_lv_ = '每年')`
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- this.$common.request('query', {
|
|
|
- key: 'getQualityTargetData',
|
|
|
- params: [this.level, this.year, this.year - 1]
|
|
|
- }).then(res => {
|
|
|
- const { data = [] } = res.variables || {}
|
|
|
- const dataMap = {
|
|
|
- '每月': new Array(12).fill({}),
|
|
|
- '每季度': this.generateQuarter(),
|
|
|
- '每年': this.generateYear()
|
|
|
- }
|
|
|
- // 组装数据
|
|
|
- const result = {}
|
|
|
- data.forEach((item, index) => {
|
|
|
- const { cycle, statisticalTime, target, result: targetValue, limitValue } = item
|
|
|
- if (!result[cycle]) {
|
|
|
- result[cycle] = []
|
|
|
- }
|
|
|
- let targetIndex = result[cycle].findIndex(i => i.title === target)
|
|
|
- if (targetIndex === -1) {
|
|
|
- result[cycle].push({
|
|
|
- title: target,
|
|
|
- data: dataMap[cycle].map(d => ({ ...d }))
|
|
|
- })
|
|
|
- targetIndex = result[cycle].length - 1
|
|
|
- }
|
|
|
- const dataIndex = cycle === '每月' ? parseInt(statisticalTime.split('年')[1].split('月')[0]) - 1 : result[cycle][targetIndex].data.findIndex(i => i.statisticalTime === statisticalTime)
|
|
|
- result[cycle][targetIndex].data[dataIndex] = { ...item, result: parseFloat(targetValue), limitValue: parseFloat(limitValue) }
|
|
|
- })
|
|
|
- this.initData = result
|
|
|
- this.cycleList = Object.keys(this.initData)
|
|
|
- console.log(this.initData)
|
|
|
- resolve()
|
|
|
- }).catch(error => {
|
|
|
- reject(error)
|
|
|
- })
|
|
|
- })
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ const params = {
|
|
|
+ requestType: this.tab == 'mubiao' ? 'mubiao' : 'zhibiao',
|
|
|
+ targetName: this.targetName,
|
|
|
+ dateRange: this.dateRange //202601-202612
|
|
|
+ }
|
|
|
+ getQualityIndicator(params).then(res => {
|
|
|
+ this.initData = res.data
|
|
|
+ this.pageAll = Math.ceil(this.initData.length / this.size)
|
|
|
+ console.log(this.pageAll, 'this.initData',this.initData)
|
|
|
+ resolve()
|
|
|
+ }).catch(error => {
|
|
|
+ reject(error)
|
|
|
+ })
|
|
|
+ })
|
|
|
},
|
|
|
generateQuarter () {
|
|
|
const result = []
|
|
|
@@ -213,21 +235,17 @@ export default {
|
|
|
clearInterval(this.autoPlayTimer)
|
|
|
},
|
|
|
showNextData () {
|
|
|
- // console.log(this.chartIndex)
|
|
|
+ console.log(this.chartIndex, '111111111')
|
|
|
if (!this.autoPlay) {
|
|
|
return
|
|
|
}
|
|
|
- if (!this.initData[this.selectedCycle]) {
|
|
|
+ if (!this.initData) {
|
|
|
this.clenUp()
|
|
|
return
|
|
|
}
|
|
|
- if ((this.chartIndex + 1) * this.size < this.initData[this.selectedCycle].length) {
|
|
|
+ if ((this.chartIndex + 1) * this.size < this.initData.length) {
|
|
|
this.chartIndex++
|
|
|
- } else if (this.itemIndex < this.cycleList.length - 1) {
|
|
|
- this.itemIndex++
|
|
|
- this.chartIndex = 0
|
|
|
- } else {
|
|
|
- this.itemIndex = 0
|
|
|
+ } else {
|
|
|
this.chartIndex = 0
|
|
|
}
|
|
|
},
|
|
|
@@ -248,7 +266,6 @@ export default {
|
|
|
// 手动切换
|
|
|
this.stopAutoPlay()
|
|
|
// 更新当前指标
|
|
|
- this.itemIndex = e
|
|
|
this.chartIndex = 0
|
|
|
this.startAutoPlay()
|
|
|
},
|
|
|
@@ -257,6 +274,22 @@ export default {
|
|
|
},
|
|
|
goBack () {
|
|
|
this.$router.back(-1)
|
|
|
+ },
|
|
|
+ skipTo(type) {
|
|
|
+ this.stopAutoPlay()
|
|
|
+ if (type === "pre") {
|
|
|
+ if(this.chartIndex == 0){
|
|
|
+ this.chartIndex = this.pageAll - 1;
|
|
|
+ }else{
|
|
|
+ this.chartIndex = this.chartIndex - 1;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ if(this.chartIndex == this.pageAll - 1){
|
|
|
+ this.chartIndex = 0;
|
|
|
+ }else{
|
|
|
+ this.chartIndex = this.chartIndex + 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -332,7 +365,7 @@ export default {
|
|
|
top: 15px;
|
|
|
transform: translateX(-50%);
|
|
|
}
|
|
|
- .year, .cycle, .back, .parse {
|
|
|
+ .year, .back, .parse {
|
|
|
width: 8%;
|
|
|
max-width: 180px;
|
|
|
cursor: pointer;
|
|
|
@@ -350,87 +383,74 @@ export default {
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
align-items: center;
|
|
|
- :global {
|
|
|
- .el-input--small .el-input__inner {
|
|
|
- width: 100% !important;
|
|
|
- background: rgba(255, 255, 255, 0);
|
|
|
- border: none;
|
|
|
- color: #fff;
|
|
|
- font-size: 16px;
|
|
|
- cursor: pointer;
|
|
|
- // padding-left: 0;
|
|
|
- padding-right: 0;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- .cycle {
|
|
|
- display: flex;
|
|
|
- min-width: 150px;
|
|
|
- justify-content: flex-end;
|
|
|
- // width: 125px;
|
|
|
- right: 75%;
|
|
|
- padding-left: 10px;
|
|
|
- color: #fff;
|
|
|
- font-size: 22px;
|
|
|
- font-weight: 400;
|
|
|
- :global {
|
|
|
- .el-dropdown {
|
|
|
- width: calc(100% - 52px);
|
|
|
- text-overflow: ellipsis;
|
|
|
- overflow: hidden;
|
|
|
- white-space: nowrap;
|
|
|
- .el-dropdown-link {
|
|
|
- text-align: center;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
.back {
|
|
|
width: 5%;
|
|
|
- left: calc(75% + 80px);
|
|
|
+ left: calc(80% + 80px);
|
|
|
}
|
|
|
.parse {
|
|
|
width: 2%;
|
|
|
- left: 75%;
|
|
|
+ left: 80%;
|
|
|
align-items: center;
|
|
|
padding: 5px;
|
|
|
> img {
|
|
|
height: calc(100% - 10px);
|
|
|
}
|
|
|
}
|
|
|
- @media only screen and (max-width: 1680px) {
|
|
|
- .year, .cycle, .back, .parse {
|
|
|
- height: 2.5rem;
|
|
|
- line-height: 2.5rem;
|
|
|
- margin-top: 2.5%;
|
|
|
- }
|
|
|
- .year {
|
|
|
- right: 82%;
|
|
|
- }
|
|
|
- .cycle {
|
|
|
- width: 5%;
|
|
|
- min-width: 120px;
|
|
|
- font-size: 18px;
|
|
|
- font-weight: normal;
|
|
|
- }
|
|
|
- .back {
|
|
|
- left: calc(75% + 60px);
|
|
|
- }
|
|
|
- }
|
|
|
- @media only screen and (max-width: 1366px) {
|
|
|
- .year {
|
|
|
- right: 80%;
|
|
|
- }
|
|
|
- .cycle {
|
|
|
- right: 70%;
|
|
|
- min-width: 140px;
|
|
|
- font-size: 16px;
|
|
|
- font-weight: normal;
|
|
|
- }
|
|
|
- .back {
|
|
|
- left: calc(75% + 50px);
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ .pnButton {
|
|
|
+ width: 7%;
|
|
|
+ font-size: 100%;
|
|
|
+ text-align: left;
|
|
|
+ position: absolute;
|
|
|
+ left: calc(78% - 90px);
|
|
|
+ margin-top: 2%;
|
|
|
+ padding: 5px;
|
|
|
+ .textContent {
|
|
|
+ display: inline-block;
|
|
|
+ width: 25%;
|
|
|
+ font-size: 115%;
|
|
|
+ text-align: center;
|
|
|
+ color: rgb(63, 150, 165);
|
|
|
+ }
|
|
|
+ .preNextButton {
|
|
|
+ background: transparent;
|
|
|
+ border: 2px solid rgb(63, 150, 165);
|
|
|
+ padding: 6px;
|
|
|
+ :global {
|
|
|
+ .el-icon-arrow-left {
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 900;
|
|
|
+ color: rgb(63, 150, 165);
|
|
|
+ }
|
|
|
+ .el-icon-arrow-right {
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 900;
|
|
|
+ color: rgb(63, 150, 165);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .datewrap{
|
|
|
+ width: 50%;
|
|
|
+ height: 45%;
|
|
|
+ line-height: 45%;
|
|
|
+ text-align: center;
|
|
|
+ margin: 2.3% 0 0 6.7%;
|
|
|
+ font-size: 100%;
|
|
|
+ color: #fff !important;
|
|
|
+ align-items: center;
|
|
|
+ display: flex;
|
|
|
+ position: absolute;
|
|
|
+ right: 32%;
|
|
|
+ :global{
|
|
|
+ .el-range-input{
|
|
|
+ color: #fff;
|
|
|
+ background: transparent;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
</style>
|