Commit b88a12e4 by zhongqm

update:删除冗余代码

parent 918e5c15
Showing with 31 additions and 4992 deletions
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="format-detection" content="telephone=no"/> <meta name="format-detection" content="telephone=no"/>
<script src="miniapp://common/js/qing/qing.js"></script> <script src="miniapp://common/js/qing/qing.js"></script>
<!-- <script src="https://staging.jffctest.com/public/js/qing/latest/qing.js"></script>-->
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
......
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": [
"./src/shared/*"
],
"~com/*": [
"./src/shared/components/*"
],
"~lib/*": [
"./src/libraries/*"
],
"~config/*": [
"./src/shared/config/*"
] ,"~proj/*": [
"./src/projectDynamic/*"
]
}
}
}
import axios from 'axios' import axios from 'axios'
var originAdapter = axios.defaults.adapter var originAdapter = axios.defaults.adapter
axios.defaults.adapter = function (config) { // axios.defaults.adapter = function (config) {
if (!/^https?/.test(config.url)) { // if (!/^https?/.test(config.url)) {
return originAdapter(config) // return originAdapter(config)
} // }
return request(config) // return request(config)
} // }
function isObject(value) { function isObject(value) {
return value !== null && typeof value === 'object' return value !== null && typeof value === 'object'
......
const testToken = 'T5043741897901056' // 华南区域:xuhy@cndrealty.com账号 const testToken = 'T5542469125211136' // 华南区域:xuhy@cndrealty.com账号
const testUid = '' // 华南区域:xuhy@cndrealty.com账号 const testUid = '' // 华南区域:xuhy@cndrealty.com账号
export const SetToken = function (val) { export const SetToken = function (val) {
let env = process.env.NODE_ENV let env = process.env.NODE_ENV
...@@ -30,39 +30,10 @@ export const projectMapUrl = 'http://59.57.252.23:8085/app/buildingInfo/index.ht ...@@ -30,39 +30,10 @@ export const projectMapUrl = 'http://59.57.252.23:8085/app/buildingInfo/index.ht
export const code = { // 埋点记录 export const code = { // 埋点记录
// home: 'cdcfdc_xmsj_mobile_module_home', // 首页(运营概览) // home: 'cdcfdc_xmsj_mobile_module_home', // 首页(运营概览)
// subject:'cdcfdc_xmsj_mobile_module_topics', // 首页(各类专题)
// stock: 'cdcfdc_xmsj_mobile_module_stock',
// unpay: 'cdcfdc_xmsj_mobile_module_unreceived',
// difficult: 'cdcfdc_xmsj_mobile_module_diffstock',
// order:'cdcfdc_xmsj_mobile_module_subscribe',
// sign:'cdcfdc_xmsj_mobile_module_sign',
// pay:'cdcfdc_xmsj_mobile_module_recieved',
// top:'cdcfdc_xmsj_mobile_module_rank',
// plan: 'cdcfdc_xmsj_mobile_module_schedule_fullview',
// orderUnSign: 'cdcfdc_xmsj_mobile_module_sign_orderunsign', // 认购未签约
// signUnPay: 'cdcfdc_xmsj_mobile_module_recieved_signunrecieved', // 签约未达款
// pastOrder: 'cdcfdc_xmsj_mobile_module_past_subscribe', // 往期-认购
// pastSign: 'cdcfdc_xmsj_mobile_module_past_sign', // 往期-签约
// pastPay: 'cdcfdc_xmsj_mobile_module_past_recieved', // 往期-回款
// pastCvr: 'cdcfdc_xmsj_mobile_module_past_cvr', // 往期-转化率
// dynamicSystem: 'cdcfdc_xmsj_mobile_module_analysis', // 项目动态系统 (首页、各类专题,均有)
// saleInfo: 'cdcfdc_xmsj_mobile_module_saleInfo', //项目动态系统 - 楼栋/业态销售情况
} }
export const helpCode = { // 指标说明(问号)接口传参代码 export const helpCode = { // 指标说明(问号)接口传参代码
// planHome: 'cdcfdc_xmsj_mobile_module_fullview_home', // planHome: 'cdcfdc_xmsj_mobile_module_fullview_home',
// planProgress: 'cdcfdc_xmsj_mobile_module_fullview_project',
// orderUnSign: 'cdcfdc_xmsj_mobile_module_home_4_1', // 认购未签约
// signUnPay: 'cdcfdc_xmsj_mobile_module_home_5_1', // 签约未达款
// analysisBaseInfo: 'cdcfdc_xmsj_mobile_module_analysis_1', // 项目动态系统 - 项目基本信息
// analysisFirstNodeKPI: 'cdcfdc_xmsj_mobile_module_analysis_2', // 项目动态系统 - 一级节点完成情况
// analysisHeartKPI: 'cdcfdc_xmsj_mobile_module_analysis_3', // 项目动态系统 - 核心指标完成情况
// analysisSaleKPI: 'cdcfdc_xmsj_mobile_module_analysis_4', // 项目动态系统 - 销售指标完成情况
// analysisTargetCost: 'cdcfdc_xmsj_mobile_module_analysis_5', // 项目动态系统 - 目标成本完成情况
// analysisCashFlow: 'cdcfdc_xmsj_mobile_module_analysis_6', // 项目动态系统 - 经营性净现金流动态监控
// analysisMoneyBack: 'cdcfdc_xmsj_mobile_module_analysis_7', // 项目动态系统 - 回款动态监控
// analysisAvgPrice: 'cdcfdc_xmsj_mobile_module_analysis_8', // 项目动态系统 - 均价动态监控
// analysisCostAnalyst: 'cdcfdc_xmsj_mobile_module_analysis_9', // 项目动态系统 - 成本动态监控
// analysisControlledCost: 'cdcfdc_xmsj_mobile_module_analysis_10', // 项目动态系统 - 可控成本动态监控
// analysisPropertySales: 'cdcfdc_xmsj_mobile_module_analysis_11', // 项目动态系统 - 楼栋/业态销售情况
} }
<template>
<div>
<mainTitle :title="title" subTitle="(单位: 亿元)" @clickHeaderIcon="clickDialog" />
<div style="margin-top:0.15rem;">
<div class="tableHeader">
<div class="tableHeadItem" :style="{'width':getItemWidth(index),'text-align':index > 1?'center':''}" :class="[index == 0?'nameItem':'' ]" v-for="(item,index) in titleTextArr" :key="index">
<div class="tableColorAll" v-if="typeof(item) == 'object'">
<div class="tableColor" v-for="(item2,index2) in item" :key="index2">
<div class="colorDiv" :style="{'background-color':colorArray[index2]}"></div>
<span>{{item2}}</span>
</div>
</div>
<span v-if="typeof(item) == 'string'">{{item}}</span>
</div>
</div>
<div class="tableDiv">
<div class="tableAllItem" v-for="(item,index) in dataArray" :key="index">
<div class="tableItem" @click="clickCell(index)">
<div class="tableSubItem" :style="{'width':getItemWidth(index2 - 1),'justify-content':index2 > 2?'center':'flex-start'}" :class="[index2 == 5?'lastRightItem':'',index2 == 1?'nameItem':'' ]" v-for="index2 in 5" :key="index2">
<div v-if="index2 == 1 && item.project && item.project.length" class="downArrow" :class="openStateArray[index]?'upArrow':''"></div>
{{getContext(item,index2)}}
<div class="prograssDiv" :style="{'background-color':colorArray[0],'width':getGrayWidth(item.value[1])}" v-if="index2 == 2">
<div class="redPrograssDiv" :style="{'width':getRedWidth(item.value)}" />
</div>
</div>
</div>
<div v-if="item.project" v-for="(item3,index3) in item.project" :key="index3" class="tableItem tableDetailItem" :class="[openStateArray[index]?'animate':'']">
<div class="tableSubItem" :style="{width:getItemWidth(index2 - 1),'justify-content':index2 > 2?'center':'flex-start'}" :class="[index2 == 5?'lastRightItem':'',index2 == 1?'nameItem':''] " v-for="index2 in 5" :key="index2">
<div v-if="index2 == 1" class="radiusDiv">·</div>
{{getContext(item3,index2)}}
<div class="prograssDiv" :style="{'background-color':colorArray[0],'width':getSubGrayWidth(item3.value[1],index)}" v-if="index2 == 2">
<div class="redPrograssDiv" :style="{'width':getRedWidth(item3.value)}" />
</div>
</div>
<div class="lineDiv"></div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import mainTitle from '~com/commom/mainTitle'
export default {
props: {
dataArray: Array,
title: String
},
components:{
mainTitle
},
data: function() {
return {
titleTextArr: [
'组织 / 项目',
['年度回款目标', '本年累计回款'],
'已回款',
'年度目标',
'完成率'
],
colorArray: ['#414548', '#E54545'],
maxGrayData: 0,
maxSubGrayData: [],
openStateArray: []
}
},
methods: {
clickDialog: function(val) {
this.$emit('clickDialog', val)
},
getItemWidth: function(index) {
switch (index) {
case 0:
return 'calc(27% - 0.05rem)'
break
case 1:
return '32%'
break
case 3:
return '16%'
break
default:
// return '20%'
return 'calc((100% - 27% - 32% - 16%) / 2.0)'
break
}
},
getContext: function(item, val) {
switch (val) {
case 1:
return item.name
break
case 3:
return item.value[0]
break
case 4:
return item.value[1]
break
case 5:
return Number((item.percent * 100).toFixed(2)) + '%'
break
default:
break
}
},
getGrayWidth: function(val) {
if (val == 0) return '0%'
return (Number(val) / this.maxGrayData) * 100 + '%'
},
getRedWidth: function(item) {
if (item[0] > item[1]) {
return '100%'
}
if (item[1] == 0) {
return '0%'
}
let percent = (item[0] / item[1]) * 100
if (percent < 100) {
return percent + '%'
} else {
return '100%'
}
},
getSubGrayWidth: function(itemValue, index) {
let maxGray = this.maxSubGrayData[index]
if (maxGray != 0 && itemValue != 0) {
return (Number(itemValue) / maxGray) * 100 + '%'
}
return '0%'
},
clickCell: function(index) {
let state = !this.openStateArray[index]
this.openStateArray.splice(index, 1, state)
// console.log(this.openStateArray)
}
},
watch: {
dataArray: {
handler: function(val, oldVal) {
for (let item of val) {
if (item.value[1] > this.maxGrayData) {
this.maxGrayData = item.value[1]
}
if (item.project) {
let tmpMax = 0
for (let item2 of item.project) {
if (item2.value[1] > tmpMax) {
tmpMax = item2.value[1]
}
}
this.maxSubGrayData.push(tmpMax)
}
}
// console.log(this.maxSubGrayData)
// if (oldVal != null && val.length != oldVal.length) {
this.openStateArray.splice(0, this.openStateArray.length)
for (let i = 0; i < val.length; i++) {
this.openStateArray.push(false)
// }
}
},
immediate: true
}
}
}
</script>
<style lang="less" scoped>
.tableHeader {
width: calc(~'100% - 0.2rem');
padding: 0.1rem;
color: @new-main-text-color;
font-size: 0.12rem;
display: flex;
flex-direction: row;
align-items: center;
background: linear-gradient(
to left,
rgba(71, 79, 90, 1),
rgba(11, 20, 29, 0)
);
.tableHeadItem {
.tableColorAll {
display: flex;
flex-direction: column;
.tableColor {
display: flex;
flex-direction: row;
align-items: center;
.colorDiv {
width: 0.1rem;
height: 0.1rem;
border-radius: 20%;
margin-right: 0.1rem;
}
}
}
}
}
// .tableDiv {
// padding: 0rem 0.1rem
// }
.tableItem {
width: calc(~'100% - 0.2rem');
padding: 0.08rem 0.1rem 0rem;
color: @new-table-text-color;
font-size: 0.13rem;
display: flex;
flex-direction: row;
position: relative;
flex-wrap: wrap;
overflow: hidden;
.tableSubItem {
display: flex;
flex-direction: row;
align-items: center;
position: relative;
}
.lastRightItem {
position: relative;
// left: -0.1rem;
// margin-right: 0.1rem;
}
}
.prograssDiv {
height: 0.1rem;
width: 100%;
position: relative;
.redPrograssDiv {
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
background: linear-gradient(to right, rgba(229, 69, 69, 0.2), #e54545);
}
}
.downArrow {
content: ' ';
height: 5px;
width: 5px;
margin-right: 0.05rem;
border-width: 0 1px 1px 0;
border-color: @arrow-color;
border-style: solid;
-webkit-transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0);
transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0);
transition: all 0.25s;
}
.upArrow {
transform: rotate(-135deg);
}
.tableDetailItem {
background-color: #26303a;
color: @data-value-text-color;
padding: 0rem;
.radiusDiv {
margin-right: 0.05rem;
font-size: 0.16rem;
}
max-height: 0;
// 避免动画开始闪烁
backface-visibility: hidden;
opacity: 0;
transition: opacity 0.5s;
perspective: 1000;
}
.lineDiv {
width: 100%;
height: 1px;
margin-top: 0.04rem;
}
.lineDiv:after {
content: '';
border: 1px @section-division-line-color solid;
border-width: 1px 1px 1px 0px;
-webkit-transform: scale(0.5, 0.5);
transform: scale(0.5, 0.5);
position: absolute;
left: -50%;
right: -50%;
}
.animate {
max-height: 9999px;
padding: 0.04rem 0.1rem 0rem;
// 避免动画开始闪烁
backface-visibility: hidden;
opacity: 1;
transition: opacity 0.5s;
perspective: 1000;
}
.nameItem {
padding-right: 0.05rem;
}
</style>
<template>
<div>
<mainTitle :title="title" subTitle="(单位: 亿元)" @clickHeaderIcon="clickDialog" />
<div class="tableHeader" style="margin-top:0.15rem" >
<div class="tableHeaderItem" v-for="(item,index) in titleArray" :key="index" :style="{'text-align':index > 0?'center':'','width':getWidth(index)}">{{item}}</div>
</div>
<div class="tableContent">
<div class="tableItem" v-for="(item,index) in dataArray" :key="index">
<div class="tableSubItem" :style="{'text-align':index2 > 0?'center':'','width':getWidth(index2)}" v-for="(item2,index2) in 3" :key="index2">{{getText(index2,item,index)}}</div>
</div>
</div>
</div>
</template>
<script>
import mainTitle from '~com/commom/mainTitle'
export default {
components: {
mainTitle
},
props: {
dataArray: Array,
title: String
},
data: function() {
return {
titleArray: ['组织', '奖励', '惩罚']
}
},
methods: {
clickDialog: function(val) {
this.$emit('clickDialog', val)
},
getText: function(index, item, num) {
switch (index) {
case 0:
return num + 1 + ' ' + item.name
break
case 1:
return item.rewards
break
case 2:
return item.punishment
break
default:
break
}
},
getWidth: function(val) {
switch (val) {
case 0:
return '40%'
break
case 1:
case 2:
return '30%'
break
default:
break
}
}
}
}
</script>
<style lang="less" scoped>
.title {
width: 100%;
text-align: center;
font-size: 0.14rem;
padding: 0.1rem 0rem;
}
.tableHeader {
width: calc(~'100% - 0.6rem');
color: @new-main-text-color;
padding: 0.05rem 0.3rem;
font-size: 0.14rem;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
background: linear-gradient(
to left,
rgba(71, 79, 90, 1),
rgba(11, 20, 29, 0)
);
.tableHeaderItem {
// width: calc(~'(100% - 0.6rem) / 3');
// text-align: center;
position: relative;
}
}
.tableContent {
color: @data-value-text-color;
font-size: 0.14rem;
margin-top: 0.05rem;
.tableItem {
width: calc(~'100% - 0.6rem');
display: flex;
flex-direction: row;
align-items: center;
padding: 0.05rem 0.3rem;
justify-content: space-between;
.tableSubItem {
// width: calc(~'(100% - 0.6rem) / 3');
text-align: left;
}
}
}
</style>
<template>
<div>
<mainTitle :title="title" subTitle="(单位: 亿元)" @clickHeaderIcon="clickDialog" />
<compareBar :dataArray="saleData" />
</div>
</template>
<script>
import mainTitle from '~com/commom/mainTitle'
import compareBar from '~com/commom/compareBarChart'
export default {
components: {
mainTitle,
compareBar
},
props: {
title: String,
saleData: Array
},
methods: {
clickDialog: function(val) {
this.$emit('clickDialog', val)
}
}
}
</script>
<style>
</style>
<template>
<div>
<mainTitle :title="title" subTitle="" @clickHeaderIcon="clickDialog" />
<flex-group :divisionLine='false' :dataArray="rewardsPunishmentsData" />
</div>
</template>
<script>
import mainTitle from '~com/commom/mainTitle'
import flexGroup from '~com/commom/flexGroup'
export default {
components: {
mainTitle,
flexGroup
},
props: {
title:String,
rewardsPunishmentsData:Array
},
methods: {
clickDialog: function(val) {
this.$emit('clickDialog', val)
}
}
}
</script>
<style>
</style>
<template>
<div class="companyFilterDiv">
<group class="table" gutter=0>
<filterGroup isLink :dataArray="titleData" v-model="selectData" @clickCell="goNext" />
</group>
</div>
</template>
<script>
import { Group } from 'vux'
import filterGroup from './filterGroup'
import Api from '@/api'
export default {
components: {
Group,
filterGroup
},
data: function() {
return {
titleData: [
// {
// id: 'x9oAAAV7u1vM567U',
// code: 'XMQY',
// level: 1,
// name: '厦门区域',
// parentId: null,
// isLeaf: 0,
// describe: null
// },
// {
// id: '5682E0A5095FA0B3ABE363086D76D622',
// code: '755FC',
// level: 1,
// name: '深圳事业部',
// parentId: null,
// isLeaf: 1,
// describe: null
// }
],
selectData: null
}
},
name: 'allCompany',
methods: {
goNext: function(val) {
let arr = []
arr.push(val)
this.$store.commit('setCompanyTreeArray', arr)
this.$emit('doNext', {
from: 0,
to: 1
})
},
showAlert: function(msg, callback) {
this.$vux.alert.show({
title: '提示',
content: msg,
onHide() {
if (callback) {
callback()
}
}
})
}
},
mounted: function() {
this.selectData = null
let param = {
parentId: '',
parentLevel: -1,
isSchedule: 20
}
if (this.$route.name == 'plan') { // 进度模块传 10 ,其余模块传 20
param.isSchedule = 10
}
this.$mas
.proxy(Api.companyURL, param)
.then(result => {
this.titleData = result.data.initList
})
.catch(error => {
if (error.hasOwnProperty('data')) {
if (error.data.hasOwnProperty('code')) {
if (error.data.code === 40002) {
this.showAlert('您的登录已超时,请退出重新登录。')
return
} else if (error.data.code === 40001 || error.data.code === 40003) {
this.showAlert('您的认证失效,请尝试退出后重新登录')
return
}
this.showAlert(
'网络有误:' +
error.data.msg +
'<br />错误代码:' +
error.data.code
)
} else {
this.showAlert('网络有误:' + error.data.msg)
}
return
}
this.showAlert('网络有误')
})
},
activated: function() {
this.selectData = null
},
watch: {
selectData: function(val) {
this.$emit('input', val)
}
}
}
</script>
<style scoped lang="less">
</style>
<template>
<div class="companyFilterDiv">
<group
class="table"
gutter=0
>
<filterGroup
isLink
:dataArray="titleData"
v-model="selectData"
@clickCell="goNext"
/>
</group>
</div>
</template>
<script>
import { Group } from 'vux'
import filterGroup from './filterGroup'
import Api from '@/api'
export default {
components: {
Group,
filterGroup
},
data: function () {
return {
titleData: [],
selectData: null
}
},
name: 'allArea',
methods: {
goNext: function (val) {
if (val.isLeaf) return
var [...arr2] = this.$store.state.shareStore.companyTreeArray
arr2.push(val)
this.$store.commit('setCompanyTreeArray', arr2)
this.$emit('doNext', {
from: 1,
to: 2
})
},
showAlert: function (msg, callback) {
this.$vux.alert.show({
title: '提示',
content: msg,
onHide() {
if (callback) {
callback()
}
}
})
}
},
mounted: function () {
let treeArray = this.$store.state.shareStore.companyTreeArray
this.lastObj = treeArray[0]
// console.log('compnay2请求')
setTimeout(() => {
let param = {
parentId: this.lastObj.id.length ? this.lastObj.id : '',
parentLevel: 0,
isSchedule: 20
}
if (this.$route.name == 'plan') {
param.isSchedule = 10
}
this.$mas
.proxy(Api.companyURL, param)
.then(result => {
this.titleData = result.data.initList
// console.log(this.titleData)
})
.catch(error => {
if (error.hasOwnProperty('data')) {
if (error.data.hasOwnProperty('code')) {
if (error.data.code === 40002) {
this.showAlert('您的登录已超时,请退出重新登录。')
return
} else if (error.data.code === 40001 || error.data.code === 40003) {
this.showAlert('您的认证失效,请尝试退出后重新登录')
return
}
this.showAlert(
'网络有误:' +
error.data.msg +
'<br />错误代码:' +
error.data.code
)
} else {
this.showAlert('网络有误:' + error.data.msg)
}
return
}
this.showAlert('网络有误')
})
}, 300)
},
activated: function () {
this.selectData = null
},
watch: {
selectData: function (val) {
this.$emit('input', val)
}
}
}
</script>
<style scoped>
</style>
<template>
<div class="companyFilterDiv">
<group class="table" gutter=0>
<filterGroup
isLink
:dataArray="titleData"
v-model="selectData"
@clickCell="goNext" />
</group>
</div>
</template>
<script>
import { Group } from 'vux'
import filterGroup from './filterGroup'
import Api from '@/api'
export default {
components: {
Group,
filterGroup
},
data: function() {
return {
titleData: [],
selectData: null
}
},
name: 'allCity',
methods: {
goNext: function (val) {
console.log(val)
if(val.isLeaf) {
} else {
var [...arr2] = this.$store.state.shareStore.companyTreeArray
arr2.push(val)
this.$store.commit('setCompanyTreeArray', arr2)
this.$emit('doNext', {
from: 3,
to: 4
})
}
},
showAlert: function(msg, callback) {
this.$vux.alert.show({
title: '提示',
content: msg,
onHide() {
if (callback) {
callback()
}
}
})
}
},
mounted: function() {
let treeArray = this.$store.state.shareStore.companyTreeArray
this.lastObj = treeArray[1]
let param = {
parentId: this.lastObj.id.length ? this.lastObj.id : '',
parentLevel: this.lastObj.id.length ? 1 : -1,
isSchedule: 20
}
if (this.$route.name == 'plan') {
param.isSchedule = 10
}
this.$mas
.proxy(Api.companyURL, param)
.then(result => {
this.titleData = result.data.initList
})
.catch(error => {
if (error.hasOwnProperty('data')) {
if (error.data.hasOwnProperty('code')) {
if (error.data.code === 40002) {
this.showAlert('您的登录已超时,请退出重新登录。')
return
} else if (error.data.code === 40001 || error.data.code === 40003) {
this.showAlert('您的认证失效,请尝试退出后重新登录')
return
}
this.showAlert(
'网络有误:' +
error.data.msg +
'<br />错误代码:' +
error.data.code
)
} else {
this.showAlert('网络有误:' + error.data.msg)
}
return
}
this.showAlert('网络有误')
})
},
activated: function() {
this.selectData = null
},
watch: {
selectData: function(val) {
this.$emit('input', val)
}
}
}
</script>
<style>
</style>
<template>
<div class="companyFilterDiv">
<group class="table" gutter=0>
<filterGroup :dataArray="titleData" v-model="selectData" />
</group>
</div>
</template>
<script>
import { Group } from 'vux'
import filterGroup from './filterGroup'
import Api from '@/api'
export default {
components: {
Group,
filterGroup
},
data: function() {
return {
titleData: [],
selectData: null
}
},
name: 'allSubCity',
methods: {
showAlert: function(msg, callback) {
this.$vux.alert.show({
title: '提示',
content: msg,
onHide() {
if (callback) {
callback()
}
}
})
}
},
mounted: function() {
let treeArray = this.$store.state.shareStore.companyTreeArray
this.lastObj = treeArray[2] || {}
let param = {
parentId: this.lastObj.id.length ? this.lastObj.id : '',
parentLevel: this.lastObj.id.length ? 2 : -1,
isSchedule: 20
}
if (this.$route.name == 'plan') {
param.isSchedule = 10
}
this.$mas
.proxy(Api.companyURL, param)
.then(result => {
this.titleData = result.data.initList
})
.catch(error => {
if (error.hasOwnProperty('data')) {
if (error.data.hasOwnProperty('code')) {
if (error.data.code === 40002) {
this.showAlert('您的登录已超时,请退出重新登录。')
return
} else if (error.data.code === 40001 || error.data.code === 40003) {
this.showAlert('您的认证失效,请尝试退出后重新登录')
return
}
this.showAlert(
'网络有误:' +
error.data.msg +
'<br />错误代码:' +
error.data.code
)
} else {
this.showAlert('网络有误:' + error.data.msg)
}
return
}
this.showAlert('网络有误')
})
},
activated: function() {
this.selectData = null
},
watch: {
selectData: function(val) {
this.$emit('input', val)
}
}
}
</script>
<style>
</style>
<template>
<div class="filterBg companyFilterAllDiv">
<div class="companyTitle companyTitle2">
<div v-for="(item,index) in historyTree" :key="index" @click="clickTitle(index)">{{item.name}} /</div>
</div>
<transition :name="transitionName">
<keep-alive :include="cacheStringList">
<component class="child-view" :is="componentName" @doNext="clickNextLeaf" v-model="selectData" />
</keep-alive>
</transition>
</div>
</template>
<script>
import company1 from './company1'
import company2 from './company2'
import company3 from './company3'
import company4 from './company4'
var PermissionType = {
UNKNOWN: 0,
ALL: 1,
REGION: 2,
CITY: 3,
SUB_CITY: 4
}
export default {
components: {
company1,
company2,
company3,
company4
},
props: {},
data: function() {
return {
titleData: [],
selectData: null,
componentName: '',
transitionName: '',
cacheArray: []
}
},
methods: {
clickNextLeaf: function(val) {
this.transitionName = 'slide-left'
let toIndex = val.to
this.selectData = null
switch (toIndex) {
case 1:
this.componentName = 'company2'
this.cacheArray.push('allArea')
break
case 2:
this.componentName = 'company3'
break
case 4:
//二级子公司
this.componentName = 'company4'
break
default:
break
}
},
clickTitle: function(val) {
if (this.$store.state.shareStore.companyTreeArray.length == 0) {
return
}
// 判断标题点击的有效
let permission = this.$store.state.shareStore.permission
console.log('clickTitle', val, permission, this.$store.state.shareStore)
if (permission != PermissionType.ALL) {
if(permission == PermissionType.SUB_CITY) {
return
} else if (permission == PermissionType.CITY) {
if(val < 2){
return
}
} else {
// 当仅有区域权限的,进入第二级,点击【全集团】无效
// 进入第三极,点击【全集团】也是进入第二级
if (val == 0) {
if (this.$store.state.shareStore.companyTreeArray.length == 1) {
return
} else {
val = 1
}
}
}
}
this.selectData = null
this.transitionName = 'slide-right'
switch (val) {
case 0:
this.componentName = 'company1'
this.$store.commit('setCompanyTreeArray', [])
this.cacheArray.pop()
break
case 1:
let [...arr] = this.$store.state.shareStore.companyTreeArray
switch(arr.length){
case 2:
arr.pop()
break
case 3:
arr.pop()
arr.pop()
break
case 4:
arr.pop()
arr.pop()
arr.pop()
break
}
this.$store.commit('setCompanyTreeArray', arr)
this.componentName = 'company2'
break
case 2:
let arr2 = [...this.$store.state.shareStore.companyTreeArray]
arr2.pop()
this.$store.commit('setCompanyTreeArray', arr2)
this.componentName = 'company3'
default:
break
}
}
},
mounted: function() {
// // 状态重置
this.selectData = null
const companyTreeArray = this.$store.state.shareStore.confirmCompanyTreeArray
let permission = this.$store.state.shareStore.permission
let isCompanyLeaf = this.$store.state.shareStore.isCompanyLeaf
console.log('mounted', permission, isCompanyLeaf, companyTreeArray, this.$store.state)
switch (permission) {
case PermissionType.ALL:
case PermissionType.UNKNOWN:
//全集团权限,切换城市公司时,已选择过公司,则只更新组件,不更新数据
this.cacheArray.push('allCompany')
switch (companyTreeArray.length) {
case 1:
this.componentName = 'company2'
break
case 2:
this.componentName = 'company3'
break
case 3:
this.componentName = 'company4'
break
default:
this.componentName = 'company1'
this.$store.commit('setCompanyTreeArray', [])
this.$store.commit('saveConfirmCompanyTreeArray', [])
}
break
case PermissionType.REGION:
this.cacheArray.push('allArea')
//区域权限,切换城市公司时,已选择过公司,则只更新组件,不更新数据
switch (companyTreeArray.length) {
case 2:
this.componentName = 'company3'
break
default:
this.componentName = 'company2'
this.$store.commit('setCompanyTreeArray', [{ name: '全集团', id: '' }])
this.$store.commit('saveConfirmCompanyTreeArray', [{ name: '全集团', id: '' }])
}
break
case PermissionType.CITY:
if(companyTreeArray.length == 3 && !companyTreeArray[companyTreeArray.length-1].isLeaf) {
this.componentName = 'company4'
} else {
this.componentName = 'company3'
}
break
case PermissionType.SUB_CITY:
this.componentName = 'company4'
break
default:
break
}
},
activated() {
const companyTreeArray = this.$store.state.shareStore.confirmCompanyTreeArray
let permission = this.$store.state.shareStore.permission
let isCompanyLeaf = this.$store.state.shareStore.isCompanyLeaf
console.log('activated', permission, isCompanyLeaf, companyTreeArray, this.$store.state)
// this.cacheArray.splice(0, this.cacheArray.length)
switch (permission) {
case PermissionType.ALL:
case PermissionType.UNKNOWN:
//全集团权限,切换城市公司时,已选择过公司,则只更新组件,不更新数据
// this.cacheArray.push('allCompany')
switch (companyTreeArray.length) {
case 1:
this.componentName = 'company2'
break
case 2:
this.componentName = 'company3'
break
case 3:
this.componentName = 'company4'
break
default:
this.componentName = 'company1'
this.$store.commit('setCompanyTreeArray', [])
this.$store.commit('saveConfirmCompanyTreeArray', [])
}
break
case PermissionType.REGION:
// this.cacheArray.push('allArea')
//区域权限,切换城市公司时,已选择过公司,则只更新组件,不更新数据
switch (companyTreeArray.length) {
case 2:
this.componentName = 'company3'
break
default:
this.componentName = 'company2'
this.$store.commit('setCompanyTreeArray', [{ name: '全集团', id: '' }])
this.$store.commit('saveConfirmCompanyTreeArray', [{ name: '全集团', id: '' }])
}
break
case PermissionType.CITY:
if(companyTreeArray.length == 3 && !companyTreeArray[companyTreeArray.length-1].isLeaf) {
this.componentName = 'company4'
} else {
this.componentName = 'company3'
}
break
case PermissionType.SUB_CITY:
this.componentName = 'company4'
break
default:
break
}
},
computed: {
cacheStringList: function() {
return this.cacheArray.join(',')
},
historyTree: function() {
if (this.$store.state.shareStore.companyTreeArray.length == 0) {
return [{ name: '全集团', id: '' }]
}
return this.$store.state.shareStore.companyTreeArray
}
},
watch: {
selectData: function(val) {
this.$emit('input', val)
}
}
}
</script>
<style lang="less" scoped>
.companyTitle2 {
margin-top: 0px;
padding-top: 0.1rem;
}
.companyFilterAllDiv {
height: 3.5rem;
}
.child-view {
// max-height: 300px;
overflow: scroll;
position: absolute;
width: 100%;
transition: all 0.3s cubic-bezier(0.55, 0, 0.1, 1);
}
.slide-left-enter,
.slide-right-leave-active {
opacity: 0;
-webkit-transform: translate(50px, 0);
transform: translate(50px, 0);
}
.slide-left-leave-active,
.slide-right-enter {
opacity: 0;
-webkit-transform: translate(-50px, 0);
transform: translate(-50px, 0);
}
</style>
<template>
<div>
<cell-box :isLink="isLink && isLeaf(index)" :border-intent="false" v-for="(item,index) in titleArray" :key="index">
<div @click="clickRadio(item,isLeaf(index))" class="radioDiv">
<img class="iconDiv" :src="item.key == selectData? require('@/assets/images/selectIcon.png'):require('@/assets/images/unSelectIcon.png')" />
</div>
<div class="cellTitle" @click="clickCell(index)">{{item.value}}</div>
</cell-box>
</div>
</template>
<script>
import { CellBox, Icon } from 'vux'
export default {
props: {
dataArray: Array,
isLink: {
type: Boolean,
default: false
},
value: Object
},
components: {
CellBox,
Icon
},
data: function() {
return {
selectData: null,
// selectData: 1, // 首页-运营概况,版本切换,默认选中“年度预算版”
titleArray: []
}
},
methods: {
checkType: function(val) {
if (val.key == this.selectData) {
return 'success'
}
return 'circle'
},
clickRadio: function(val,linkVal) {
let isLink = this.isLeaf && linkVal
console.log(isLink,'clickRadio', val, linkVal)
val.isLeaf = !isLink
this.selectData = val.key
this.$emit('input', val)
},
clickCell: function(val) {
console.log('clickCell', val, this.dataArray, this.titleArray)
if (this.isLink && this.isLeaf(val)) {
this.$emit('clickCell', this.dataArray[val])
} else {
this.clickRadio(this.titleArray[val])
}
},
isSelect: function(val) {
if (val.key == this.selectData) {
return 'selectIcon'
}
return 'unSelectIcon'
},
isLeaf: function(val) {
let obj = this.dataArray[val]
return !obj.isLeaf
},
arrData: function(val) {
this.titleArray.splice(0, this.titleArray.length)
if(this.$store.state.shareStore.currentCompany) {
const { key } = this.$store.state.shareStore.currentCompany
this.selectData = key
}
for (let obj of this.dataArray) {
this.titleArray.push({
key: obj.id,
value: obj.name
})
if(obj.isLeaf) {
if(obj.id == this.selectData) {
this.$emit('input', this.$store.state.shareStore.currentCompany)
} else if(this.dataArray.length == 1) {
this.selectData = obj.id
this.$emit('input', {key: obj.id, value: obj.name, isLeaf: true})
// 保存选中公司信息
this.$store.commit('saveCurrentCompany', {key: obj.id, value: obj.name, isLeaf: true})
}
}
}
}
},
watch: {
dataArray: {
handler: function(val, oldVal) {
// 清空选项
// this.selectData = null
if (val.length > 0) {
this.arrData(val)
}
},
immediate: true
},
value: function(val) {
if (!val) {
this.selectData = null
}
if (val && val.key === 1) {
this.selectData = 1
}
if (val && val.key === 2) {
this.selectData = 2
}
}
}
}
</script>
<style scoped>
.selectIcon {
background-color: white;
}
unSelectIcon {
background-color: transparent;
}
.weui-icon-success:before {
margin: 0px;
}
.weui-icon-circle:before {
margin: 0px;
}
.radioDiv {
/* padding-right: 0.35em; */
display: flex;
justify-content: flex-start;
align-items: center;
/* border: 1px red solid; */
height: 98%;
width: 0.4rem;
position: absolute;
padding-left: 0.15rem;
top: 0rem;
}
.iconDiv {
height: 0.23rem;
width: 0.23rem;
}
.cellTitle {
font-weight: 200;
font-size: 0.14rem;
padding: 0.08rem;
width: 90%;
margin-left: 0.5rem;
}
</style>
<style lang="less">
.table {
.weui-cell_access.vux-cell-box {
padding: 0.1rem 0.15rem 0.1rem 0rem;
}
.weui-cell {
padding: 0.1rem 0.15rem 0.1rem 0rem;
}
.weui-cells:before {
border-width: 0px;
}
.weui-cells {
background-color: transparent !important;
}
.weui-cell:before {
border-color: @table-division-line-color;
transform: scaleY(0.5);
transform-origin: 0 0;
}
.weui-cells:after {
border-color: @table-division-line-color;
transform-origin: 0 0;
}
.vux-label {
color: @data-value-text-color;
font-size: 0.14rem;
margin: 0.08rem 0px;
}
.cellValueDiv {
color: white;
font-weight: 300;
font-size: 0.14rem;
padding: 0.08rem;
}
}
.weui-btn {
font-size: 0.18rem;
}
</style>
\ No newline at end of file
<template>
<div>
<div class="filterAllDiv">
<div
class="filterItem"
v-for="(item,index) in titleArray"
:key="index"
@click="clickItem(index)"
>
<span>{{item}}</span>
<img v-show="versionData.key === 2 && index !== 1 ? false : true" :src="require('@/assets/images/downWhiteArrow.png')" />
</div>
</div>
<div v-transfer-dom>
<div
class="filterTable"
:class="selectIndex > -1?'animate':''"
>
<div class="filterCom">
<component
:is="componentName"
:type="pageType"
v-model="selectData"
/>
</div>
<x-button
class="comfirmBtn"
:disabled="!bgEnable"
@click.native="clickDone"
>确定</x-button>
</div>
</div>
<div v-transfer-dom>
<div
v-if="checkMask"
class="weui-mask maskDiv"
@click="clickmask"
>
</div>
</div>
<div v-transfer-dom>
<div
class="guidenDiv"
v-if="componentName == 'companyFilterHome' && !showGuidence"
@click="clickGuidence"
>
<img :src="require('@/assets/images/guidenBg.png')" />
</div>
</div>
</div>
</template>
<script>
import { TransferDomDirective as TransferDom, XButton } from 'vux'
import SingleFilter from '../filter/singleFilter'
import companyFilterHome from '../filter/companyFilterHome'
import { setCookie, getCookie } from '~lib/utils/common'
export default {
directives: {
TransferDom
},
props: {
titleArray: Array,
isVersionSwitchShow: {
typy: Boolean,
default: false
}
},
components: {
XButton,
SingleFilter,
companyFilterHome
},
data: function () {
return {
selectIndex: -1,
componentName: '',
pageType: '',
bgEnable: false,
selectData: null,
showGuidence: false
}
},
methods: {
clickItem: function (val) {
if (this.versionData.key === 2 && val !== 1) {
return
}
if (this.selectIndex == val) return
// 清空选项
this.selectData = null
this.selectIndex = val
switch (val) {
case 0:
this.componentName = 'SingleFilter'
this.pageType = 'project'
break
case 1:
this.componentName = 'companyFilterHome'
break
case 2:
this.componentName = 'SingleFilter'
this.pageType = 'bore'
break
default:
break
}
this.$emit('showFilterTable', true)
},
clickmask: function (val) {
this.$emit('showFilterTable', false)
// 清除缓存公司层级,恢复为已确定保存的公司层级
this.$store.commit('setCompanyTreeArray', this.$store.state.shareStore.confirmCompanyTreeArray)
this.selectIndex = -1
setTimeout(() => {
this.componentName = ''
}, 100)
},
clickGuidence: function (val) {
this.showGuidence = true
setCookie('showGuidence', true, 999)
},
clickDone: function () {
let [...filterArray] = this.$store.state.shareStore.filterArray
console.log(this.selectData, this.$store.state.shareStore)
// 缓存对象的叶子数值,以免破坏其他结构
let tmpLeaf = this.selectData.isLeaf
delete this.selectData.isLeaf;
if (this.componentName == 'SingleFilter') {
if (this.pageType == 'bore') {
// 选择口径
filterArray.splice(0, 1, this.selectData)
} else {
// 选择项目
filterArray.splice(2, 1, this.selectData)
}
} else {
filterArray.splice(1, 1, this.selectData)
this.$store.commit('setCompanyLeafType', tmpLeaf)
// 保存公司层级
this.$store.commit('saveConfirmCompanyTreeArray', this.$store.state.shareStore.companyTreeArray)
// 保存选中公司信息
this.$store.commit('saveCurrentCompany', {...this.selectData, isLeaf: tmpLeaf})
// 保持
this.$store.commit('setFilterComType', this.$store.state.shareStore.companyTreeArray.length + 1)
}
// 通知vux
this.$store.commit('setFilterData', filterArray)
// 如果是在往期数据模块切换时,在点击“确认”按钮时,需触发另外的逻辑
this.$emit('clickDoneBtn', filterArray)
this.clickmask()
}
},
computed: {
versionData() {
return this.$store.state.shareStore.version
},
checkMask: function () {
if (this.selectIndex > -1) {
if (this.showGuidence) {
return true
} else {
if (this.selectIndex != 1) {
return true
}
}
}
return false
}
},
mounted: function () {
/*
if (getCookie('showGuidence')) {
this.showGuidence = Boolean(getCookie('showGuidence'))
}
*/
getCookie('showGuidence')
.then(val => {
if (val) {
this.showGuidence = Boolean(val)
}
})
},
watch: {
selectData: function (val) {
val ? (this.bgEnable = true) : (this.bgEnable = false)
},
isVersionSwitchShow (n, o) {
if (n) {
this.clickmask()
}
},
versionData (newValue, oldValue) {
let [...filterArray] = this.$store.state.shareStore.filterArray
if (newValue.key === 2) {
filterArray[0] = {key: '', value: "全口径"} // 动态预算版时,自动切换回选中“全口径”状态
filterArray[2] = {key: '10', value: "操盘"} // 动态预算版时,自动切换回选中“操盘”状态
this.$store.commit('setFilterData', filterArray)
}
}
}
}
</script>
<style lang="less" scoped>
.filterAllDiv {
padding: 0rem 0.1rem;
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
background-color: @header-background-color;
z-index: 599;
}
.filterItem {
position: relative;
height: 0.3rem;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
width: 31%;
margin-top: 0.1rem;
margin-bottom: 0.1rem;
font-size: 0.16rem;
font-weight: 100;
span {
max-width: 80%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
img {
margin-left: 0.05rem;
width: 0.14rem;
height: auto;
}
}
.filterTable {
position: absolute;
top: calc(~"48px + 0.5rem");
max-height: 0px;
width: 100%;
transition: max-height 0.5s cubic-bezier(0, 1, 0, 1) -0.1s;
position: absolute;
overflow: hidden;
}
.animate {
max-height: 9999px;
transition-timing-function: cubic-bezier(0.5, 0, 1, 0);
transition-delay: 0s;
z-index: 4999;
}
.maskDiv {
position: absolute;
top: calc(~"48px + 0.5rem");
}
.comfirmBtn {
height: 0.45rem;
width: 100%;
}
.guidenDiv {
width: 100%;
z-index: 4999;
position: fixed;
top: 0px;
bottom: 0px;
left: 0px;
background-color: rgba(0, 0, 0, 0.8);
img {
width: 100%;
position: absolute;
top: calc(~"48px + 0.5rem");
}
}
</style>
<template>
<div class="filterBg">
<group class="table" gutter=0 style="max-height: 300px;overflow: scroll;">
<filterGroup :dataArray="titleData" v-model="selectData" />
</group>
</div>
</template>
<script>
import { Group } from 'vux'
import filterGroup from './filterGroup'
import Api from '@/api'
export default {
name: 'singleFilter',
props: {
type: String,
value: Object
},
components: {
Group,
filterGroup
},
data: function() {
return {
titleData: [],
selectData: null
}
},
methods: {
arrBoreData: function(val) {
this.titleData.splice(0, this.titleData.length)
this.titleData.push({
name: '全口径',
id: ''
})
for (let obj of val) {
this.titleData.push(obj)
}
},
arrProjectData: function(val) {
this.titleData.splice(0, this.titleData.length)
this.titleData.push({
name: '全项目',
id: ''
})
for (let obj of val) {
this.titleData.push(obj)
}
},
getBoreData: function() {
this.$mas
.proxy(Api.belongURL, null)
.then(result => {
this.arrBoreData(result.data.initList)
})
.catch(error => {
if (error.hasOwnProperty('data')) {
if (error.data.hasOwnProperty('code')) {
if (error.data.code === 40002) {
this.showAlert('您的登录已超时,请退出重新登录。')
return
} else if (error.data.code === 40001 || error.data.code === 40003) {
this.showAlert('您的认证失效,请尝试退出后重新登录')
return
}
this.showAlert(
'网络有误:' +
error.data.msg +
'<br />错误代码:' +
error.data.code
)
} else {
this.showAlert('网络有误:' + error.data.msg)
}
return
}
this.showAlert('网络有误')
})
},
showAlert: function(msg, callback) {
this.$vux.alert.show({
title: '提示',
content: msg,
onHide() {
if (callback) {
callback()
}
}
})
},
getProjectData: function() {
this.$mas
.proxy(Api.projectURL, null)
.then(result => {
this.arrProjectData(result.data.initList)
})
.catch(error => {
if (error.hasOwnProperty('data')) {
if (error.data.hasOwnProperty('code')) {
if (error.data.code === 40002) {
this.showAlert('您的登录已超时,请退出重新登录。')
return
} else if (error.data.code === 40001 || error.data.code === 40003) {
this.showAlert('您的认证失效,请尝试退出后重新登录')
return
}
this.showAlert(
'网络有误:' +
error.data.msg +
'<br />错误代码:' +
error.data.code
)
} else {
this.showAlert('网络有误:' + error.data.msg)
}
return
}
this.showAlert('网络有误')
})
}
},
mounted: function() {},
watch: {
value: function(val) {
this.selectData = val
},
isClickBtn: function(val) {
// if (val && this.selectData) {
// if (this.type == 'bore') {
// this.value.splice(0, 1, this.selectData)
// } else if (this.type == 'project') {
// this.value.splice(2, 1, this.selectData)
// }
// }
// this.$emit('disposeCompelete')
},
selectData: function(val) {
this.$emit('input', val)
},
type: {
handler: function(val) {
if (val == 'bore') {
this.getBoreData()
} else {
this.getProjectData()
}
},
immediate: true
}
}
}
</script>
<style>
</style>
<template>
<div>
<popup
v-model="showVersionSwitch"
position="top"
:is-transparent="true"
:show-mask="true"
@on-hide="clickmask"
>
<div class="position-vertical-demo" v-show="showVersionSwitch"> <!-- v-show="showVersionSwitch 是为了关闭动画效果-->
<div class="filterBg">
<group class="table" gutter=0 style="max-height: 300px;overflow: scroll;">
<filterGroup :dataArray="titleData" v-model="selectData" />
</group>
</div>
<x-button
v-show="showVersionSwitch"
class="comfirmBtn"
:disabled="!bgEnable"
@click.native="clickDone"
>确定</x-button>
</div>
</popup>
</div>
</template>
<script>
import { TransferDomDirective as TransferDom } from 'vux'
import { Group, Popup, XButton } from 'vux'
import filterGroup from './filterGroup'
export default {
directives: {
TransferDom
},
components: {
XButton,
Group,
filterGroup,
Popup
},
props: {
versionSwitch: {
type: Boolean,
default: false
},
},
data: function () {
return {
titleData: [{
id: 1, //id字段必须要有(因为filterGroup子组件需要使用)
name:'年度预算版',
},{
id: 2,
name:'动态预算版'
}],
bgEnable: false,
selectData: null,
showVersionSwitch: false
}
},
methods: {
clickmask: function (val) {
this.showVersionSwitch = false
this.$emit('hideFilterTable', false) // 重置右侧标题栏的显示状态:即隐藏状态
this.selectData = null // 清空“已选择项”
},
clickDone: function () {
let versionSelected = this.selectData
// 通知vux
this.$store.commit('setVersion', versionSelected)
this.clickmask()
}
},
computed: {
versionData() {
return this.$store.state.shareStore.version
}
},
watch: {
selectData: function (val) {
(val && val.key) !== this.versionData.key ? (this.bgEnable = true) : (this.bgEnable = false)
},
versionSwitch (newval, oldvalue) {
this.showVersionSwitch = newval
switch(this.versionData.key) {
case 1:
this.selectData = {
key: 1,
value: '年度预算版'
}
break
case 2:
this.selectData = {
key: 2,
value: '动态预算版'
}
break
default:
this.selectData = {
key: 1,
value: '年度预算版'
}
}
}
}
}
</script>
<style lang="less" scoped>
.animate {
max-height: 9999px;
transition-timing-function: cubic-bezier(0.5, 0, 1, 0);
transition-delay: 0s;
z-index: 4999;
}
.comfirmBtn {
height: 0.45rem;
width: 100%;
}
</style>
<template>
<div>
<mainTitle title="难点库存" @clickHeaderIcon="clickDialog" />
<double-value style="margin-top:0.2rem" :dataArray="dataArray" showMore @clickMore="clickMore"/>
<div style="margin-top:0.16rem" class="divisionLine" />
<doubleHalfCircle :dataArray="circleArray" ref="circleDiv4" :showAnimation="percentShow" />
</div>
</template>
<script>
import mainTitle from '~com/commom/mainTitle'
import doubleValue from '~com/commom/doubleValue2'
import doubleHalfCircle from '~com/commom/doubleHalfCircle'
export default {
components: {
mainTitle,
doubleValue,
doubleHalfCircle
},
props: {
dataArray: Array,
circleArray: Array,
scrollDistance: Number,
clientHeight: Number
},
data: function() {
return {
circleOffsetTop: -1,
percentShow: false
}
},
methods: {
clickDialog: function(val) {
this.$emit('clickDialog', val)
},
getCircleOffsetTop: function() {
let circleHalfHeight = this.$refs.circleDiv4.$el.clientHeight / 3.0
return (
this.$refs.circleDiv4.$el.offsetTop -
this.clientHeight +
circleHalfHeight
)
},
checkAnimationStatus: function() {
if ((this.circleOffsetTop = -1)) {
this.circleOffsetTop = this.getCircleOffsetTop()
}
if (this.scrollDistance > this.circleOffsetTop) {
this.percentShow = true
}
},
clickMore:function(){
this.$emit('clickMore',null)
}
},
watch: {
circleArray: function(val) {
this.percentShow = false
this.$nextTick(() => {
this.checkAnimationStatus()
})
},
scrollDistance: function(val) {
this.checkAnimationStatus()
}
}
}
</script>
<style>
</style>
<template>
<div>
<mainTitle
title="认购"
subTitle="(单位: 亿元)"
@clickHeaderIcon="clickDialog"
/>
<hori-double-value
title="本年达售去化率"
:dataArray="orderThisYearArray"
isPercent
/>
<div
style="margin-top:0.1rem"
class="divisionLine"
/>
<tri-half-circle
style="margin-top:0.35rem"
:dataArray="circleArray"
ref="circleDiv1"
:showAnimation="percentShow"
@clickMore="clickMore"
/>
<div
style="margin-top:0.16rem"
class="divisionLine"
/>
<bar-chart
style="margin-top:0.32rem"
:dataArray="rankArray"
title="各组织认购完成情况"
showMore
@clickMore="clickMore"
/>
</div>
</template>
<script>
import mainTitle from '~com/commom/mainTitle'
import horiDoubleValue from '~com/commom/horiDoubleValue'
import triHalfCircle from '~com/commom/triHalfCircle'
import barChart from '~com/commom/bluePercentBar'
export default {
components: {
mainTitle,
horiDoubleValue,
triHalfCircle,
barChart
},
props: {
orderThisYearArray: Array,
circleArray: Array,
rankArray: Array,
scrollDistance: Number,
clientHeight: Number
},
data: function () {
return {
circleOffsetTop: -1,
percentShow: false,
}
},
methods: {
clickDialog: function (val) {
this.$emit('clickDialog', val)
},
clickMore: function (val) {
this.$emit('clickLink', 'order')
},
getCircleOffsetTop: function () {
let circleHalfHeight = this.$refs.circleDiv1.$el.clientHeight / 3.0
return (
this.$refs.circleDiv1.$el.offsetTop -
this.clientHeight +
circleHalfHeight
)
},
checkAnimationStatus: function () {
if ((this.circleOffsetTop = -1)) {
this.circleOffsetTop = this.getCircleOffsetTop()
}
if (this.scrollDistance > this.circleOffsetTop) {
this.percentShow = true
}
}
},
watch: {
circleArray: function (val) {
this.percentShow = false
this.$nextTick(() => {
this.checkAnimationStatus()
})
},
scrollDistance: function (val) {
this.checkAnimationStatus()
}
}
}
</script>
<style lang="less" scoped>
.allTitleDiv {
margin-top: 0.1rem;
}
</style>
<template>
<div>
<single-value title="回款" subTitle="(单位: 亿元)" dataTitle="签约未达款金额" :dataValue="aveOrderNoPayCount" @clickHeaderIcon="clickDialog" newStyle showMore @clickMore="clickMorePay"/>
<div style="margin-top:0.16rem" class="divisionLine" />
<tri-half-circle style="margin-top:0.35rem" :dataArray="circleArray" ref="circleDiv3" :showAnimation="percentShow" @clickMore="clickMore"/>
<div style="margin-top:0.16rem" class="divisionLine" />
<bar-chart style="margin-top:0.32rem" :dataArray="rankArray" title="各组织回款完成情况" showMore @clickMore="clickMore"/>
</div>
</template>
<script>
import singleValue from '~com/commom/singleValue'
import triHalfCircle from '~com/commom/triHalfCircle'
import barChart from '~com/commom/bluePercentBar'
export default {
components: {
singleValue,
triHalfCircle,
barChart
},
props: {
aveOrderNoPayCount: [Number, String],
circleArray: Array,
rankArray: Array,
scrollDistance: Number,
clientHeight: Number
},
data: function() {
return {
circleOffsetTop: -1,
percentShow: false
}
},
methods: {
clickDialog: function(val) {
this.$emit('clickDialog', val)
},
clickMore: function(val) {
this.$emit('clickLink', 'pay')
},
clickMorePay: function(val) {
this.$emit('clickPayLink', 'singUnPay')
},
getCircleOffsetTop: function() {
let circleHalfHeight = this.$refs.circleDiv3.$el.clientHeight / 3.0
return (
this.$refs.circleDiv3.$el.offsetTop -
this.clientHeight +
circleHalfHeight
)
},
checkAnimationStatus: function() {
if ((this.circleOffsetTop = -1)) {
this.circleOffsetTop = this.getCircleOffsetTop()
}
if (this.scrollDistance > this.circleOffsetTop) {
this.percentShow = true
}
}
},
watch: {
circleArray: function(val) {
this.percentShow = false
this.$nextTick(() => {
this.checkAnimationStatus()
})
},
scrollDistance: function(val) {
this.checkAnimationStatus()
}
}
}
</script>
<style>
</style>
<template>
<div>
<single-value title="签约" subTitle="(单位: 亿元)" dataTitle="认购未签约金额" :dataValue="aveOrderNoSignCount" @clickHeaderIcon="clickDialog" newStyle showMore @clickMore="clickMoreSign"/>
<div style="margin-top:0.1rem" class="divisionLine" />
<tri-half-circle style="margin-top:0.35rem" :dataArray="circleArray" ref="circleDiv2" :showAnimation="percentShow" @clickMore="clickMore"/>
<div style="margin-top:0.16rem" class="divisionLine" />
<bar-chart style="margin-top:0.32rem" :dataArray="rankArray" title="各组织签约完成情况" showMore @clickMore="clickMore"/>
</div>
</template>
<script>
import singleValue from '~com/commom/singleValue'
import triHalfCircle from '~com/commom/triHalfCircle'
import barChart from '~com/commom/bluePercentBar'
export default {
components: {
singleValue,
triHalfCircle,
barChart
},
props: {
aveOrderNoSignCount: [Number, String],
circleArray: Array,
rankArray: Array,
scrollDistance: Number,
clientHeight: Number
},
data: function() {
return {
circleOffsetTop: -1,
percentShow: false
}
},
methods: {
clickDialog: function(val) {
this.$emit('clickDialog', val)
},
clickMore: function(val) {
this.$emit('clickLink', 'sign')
},
clickMoreSign (val) {
this.$emit('clickSignLink', 'orderUnSign')
},
getCircleOffsetTop: function() {
let circleHalfHeight = this.$refs.circleDiv2.$el.clientHeight / 3.0
return (
this.$refs.circleDiv2.$el.offsetTop -
this.clientHeight +
circleHalfHeight
)
},
checkAnimationStatus: function() {
if ((this.circleOffsetTop = -1)) {
this.circleOffsetTop = this.getCircleOffsetTop()
}
if (this.scrollDistance > this.circleOffsetTop) {
this.percentShow = true
}
}
},
watch: {
circleArray: function(val) {
this.percentShow = false
this.$nextTick(() => {
this.checkAnimationStatus()
})
},
scrollDistance: function(val) {
this.checkAnimationStatus()
}
}
}
</script>
<style>
</style>
<template>
<div class="statusDiv">
<mainTitle
title="总体情况"
subTitle="(单位: 亿元)"
@clickHeaderIcon="clickDialog"
/>
<hori-flex-group
:dataArray="dataArray"
@clickItem="clickItem"
ref="horiGroup"
/>
<div v-transfer-dom>
<transition name="fade">
<div
class="guidenDiv"
@click="clickGuidence"
v-if="!showGuidence && isUpdateData"
>
<img
:src="require('@/assets/images/statusGuidence.png')"
:style="{'top':guidenceTop + 'px'}"
/>
</div>
</transition>
</div>
</div>
</template>
<script>
import { TransferDomDirective as TransferDom } from 'vux'
import mainTitle from '~com/commom/mainTitle'
import flexGroup from '~com/commom/flexGroup'
import HoriFlexGroup from '~com/commom/horiFlexGroup'
import { getRealPx } from '~config/config'
import { setCookie, getCookie } from '~lib/utils/common'
export default {
directives: {
TransferDom
},
components: {
mainTitle,
flexGroup,
HoriFlexGroup
},
props: {
dataArray: Array
},
data: function () {
return {
showGuidence: false,
guidenceTop: 0,
isUpdateData: false,
}
},
methods: {
clickDialog: function (title) {
this.$emit('clickDialog', title)
},
clickItem: function (val) {
this.$emit('clickItem', val)
},
clickGuidence: function (val) {
this.showGuidence = true
setCookie('xzsb1', true, 999)
},
calDataDivTop: function (val) {
this.$nextTick(() => {
this.guidenceTop = this.$refs.horiGroup.$el.offsetTop + 48 + getRealPx(0.5) - getRealPx(0.1)
})
},
},
mounted: function () {
this.calDataDivTop()
/*
if (getCookie('xzsb1')) {
this.showGuidence = Boolean(getCookie('xzsb1'))
}
*/
getCookie('xzsb1')
.then(val => {
if (val) {
this.showGuidence = Boolean(val)
}
})
},
watch: {
dataArray: function (val) {
this.$nextTick(() => {
this.isUpdateData = true
})
}
}
}
</script>
<style lang="less" scoped>
.statusDiv {
.allTitleDiv {
margin-top: 0.13rem;
}
}
.guidenDiv {
width: 100%;
z-index: 4999;
position: fixed;
top: 0px;
bottom: 0px;
left: 0px;
background-color: rgba(0, 0, 0, 0.8);
img {
width: 100%;
position: absolute;
}
}
</style>
<template>
<div>
<single-value
title="库存"
subTitle="(单位: 亿元)"
dataTitle="未认购库存"
:dataValue="stockAmount"
@clickHeaderIcon="clickDialog"
newStyle
showMore
@clickMore="clickMore"
/>
<div
style="margin-top:0.16rem"
class="divisionLine"
/>
<barChart
style="margin-top:0.36rem"
title="已达售及计划达售情况"
:dataArray=dataArray
/>
</div>
</template>
<script>
import mainTitle from '~com/commom/mainTitle'
import singleValue from '~com/commom/singleValue'
import barChart from '~com/commom/barChart2'
export default {
components: {
mainTitle,
singleValue,
barChart
},
props: {
stockAmount: [String, Number],
dataArray: Array
},
methods: {
clickDialog: function (val) {
this.$emit('clickDialog', val)
},
clickMore: function (val) {
this.$emit('clickMore', null)
}
}
}
</script>
<style>
</style>
<template>
<div>
<mainTitle title="操盘与不操盘的对标" @clickHeaderIcon="clickDialog" />
</div>
</template>
<script>
import mainTitle from '~com/commom/mainTitle'
export default {
methods: {
clickDialog: function(val) {
this.$emit('clickDialog', val)
}
}
}
</script>
<style>
</style>
<template>
<div>
<single-value title="未达款" subTitle="(单位: 亿元)" dataTitle="累计未达款" :dataValue="dataString" @clickHeaderIcon="clickDialog" showMore @clickMore="clickMore" newStyle/>
<div style="margin-top:0.1rem" class="divisionLine" />
<circle-chart :dataArray="dataArray" />
</div>
</template>
<script>
import singleValue from '~com/commom/singleValue'
import circleChart from '../unPay/circleChart'
export default {
components: {
singleValue,
circleChart
},
props: {
dataString: {
type:[Number,String]
},
dataArray: Array
},
methods: {
clickDialog: function(title) {
this.$emit('clickDialog', title)
},
clickMore: function() {
this.$emit('clickMore')
}
}
}
</script>
<style>
</style>
<template>
<div class="view-content has-header bgImg">
<!-- <h1>测试界面</h1> -->
</div>
</template>
<script>
import Api from '@/api'
export default {
name: 'intro',
data: function () {
return {
defaultProjectName: '操盘'
}
},
methods: {
enterAllPage: function () {
// 设置cache,方便之前的逻辑对接
this.$router.cacheNameArray.push('homepage')
this.$router.cacheNameArray.push('subject')
// 提交权限
this.$store.commit('setTabbarPermission', true)
this.$router.replace('/homepage')
},
enterHome: function () {
this.$router.cacheNameArray.push('homepage')
this.$store.commit('setTabbarPermission', false)
this.$router.replace('/homepage')
},
enterSubject: function () {
this.$router.cacheNameArray.push('subject')
this.$store.commit('setTabbarPermission', false)
this.$router.replace('/subject')
},
noPermission: function () {
this.showAlert('您没有权限进入', '确认', () => {
this.$nativeApi.navigator.exit()
})
},
checkTokenStatus: function (fun) {
let that = this
if (!this.$mas.token) {
this.$nativeApi.account.getUser().then(data => {
that.$mas.token = data.ssoToken
fun()
})
} else {
fun()
}
},
storeCompanyPermission: function (val) {
console.log(val, this.$store.state.shareStore)
this.$store.commit('setPermission', val.level + 1) // 根据定义的数值
this.$store.commit('setFilterComType', val.level + 1)
if ((val.level + 1) >= 2) {
// 保存公司是否叶子节点状态
this.$store.commit('setCompanyLeafType', val.initList[0].isLeaf ? true : false)
}
if (val.level != 0) {
let [...tempFilterArray] = this.$store.state.shareStore.filterArray
tempFilterArray.splice(1, 1, {
value: val.initList[0].name,
key: val.initList[0].id
})
// 保存默认选中公司信息
this.$store.commit('saveCurrentCompany', {key: val.initList[0].id, value: val.initList[0].name, isLeaf: val.initList[0].isLeaf ? true : false})
// 通知vux
this.$store.commit('setFilterData', tempFilterArray)
if (val.level >= 2) {
this.$store.commit('setCompanyTreeArray', [...val.tabList])
this.$store.commit('saveConfirmCompanyTreeArray', [...val.tabList])
}
}
},
storeDefaultProject: function (val) {
if (this.defaultProjectName == '全项目') {
return;
}
let tmpObj = null;
for (let item of val.initList) {
if (item.name == this.defaultProjectName) {
tmpObj = item
}
}
let [...tempFilterArray] = this.$store.state.shareStore.filterArray
tempFilterArray.splice(2, 1, {
value: tmpObj.name,
key: tmpObj.id
})
// 通知vux
this.$store.commit('setFilterData', tempFilterArray)
},
arrPermissionData: function (val) {
//缓存权限信息
this.$store.commit('setPrmissionArray', val)
// 没有权限
if (val.length == 0) {
this.noPermission()
return
}
// 2种大情况,1.有所有权限,2有单独权限
let singlePage = false
let homePermission = false
if (val.length == 1) {
singlePage = true
for (let item of val) {
if (item.permissionInfo.name == '首页') {
homePermission = true
// 保留首页权限
this.$store.commit('setHomepagePermission', item.lowerList)
break
} else {
// 查询专题的子类,获取权限
for (let subItem of item.lowerList) {
if (subItem.permissionInfo.name == '库存') {
this.$store.commit('setStockPermission', subItem.lowerList)
} else if (subItem.permissionInfo.name == '未达款') {
this.$store.commit('setUnpayPermission', subItem.lowerList)
} else if (subItem.permissionInfo.name == '难点库存') {
this.$store.commit('setDifficultyStockPermission', subItem.lowerList)
} else if (subItem.permissionInfo.name == '全景计划') {
this.$store.commit('setPlanPermission', subItem.lowerList)
}
}
}
}
} else {
for (let item of val) {
if (item.permissionInfo.name == '首页') {
homePermission = true
// 保留首页权限
this.$store.commit('setHomepagePermission', item.lowerList)
} else {
// 查询专题的子类,获取权限
for (let subItem of item.lowerList) {
if (subItem.permissionInfo.name == '库存') {
this.$store.commit('setStockPermission', subItem.lowerList)
} else if (subItem.permissionInfo.name == '未达款') {
this.$store.commit('setUnpayPermission', subItem.lowerList)
} else if (subItem.permissionInfo.name == '难点库存') {
this.$store.commit('setDifficultyStockPermission', subItem.lowerList)
} else if (subItem.permissionInfo.name == '全景计划') {
this.$store.commit('setPlanPermission', subItem.lowerList)
}
}
}
}
if (!homePermission) {
singlePage = true
}
}
// 根据标志位,进入对应的界面
if (!singlePage) {
this.enterAllPage()
} else {
if (homePermission) {
this.enterHome()
} else {
this.enterSubject()
}
}
},
showAlert: function (msg, btnText, callback) {
this.$vux.alert.show({
title: '提示',
content: msg,
buttonText: btnText ? btnText : '确定',
onHide() {
if (callback) {
callback()
}
}
})
},
fetchData: function () {
Promise.all([
this.$mas.proxy(Api.subject_permission, null),
this.$mas.proxy(Api.companyURL, {
parentId: '',
parentLevel: -1,
isSchedule: 20
}),
this.$mas.proxy(Api.projectURL, null)
])
.then(resArray => {
this.arrPermissionData(resArray[0].data)
this.storeCompanyPermission(resArray[1].data)
this.storeDefaultProject(resArray[2].data)
})
.catch(error => {
if (error.hasOwnProperty('data')) {
if (error.data.hasOwnProperty('code')) {
if (error.data.code === 40002) {
this.showAlert('您的登录已超时,请退出重新登录。')
return
} else if (error.data.code === 40001 || error.data.code === 40003) {
this.showAlert('您的认证失效,请尝试退出后重新登录')
return
}
this.showAlert(
'网络有误:' +
error.data.msg +
'<br />错误代码:' +
error.data.code
)
} else {
if (error.data.msg.indexOf('权限')) {
this.noPermission()
return
}
this.showAlert('网络有误:' + error.data.msg)
}
return
}
this.showAlert('网络有误', '重试', () => {
this.fetchData()
})
})
}
},
mounted: function () {
let that = this
setTimeout(() => {
that.checkTokenStatus(() => {
that.fetchData()
})
}, 500)
},
activated: function () {
this.$store.commit('setNavbarShow', false)
}
}
</script>
<style lang="less" scoped>
.bgImg {
top: 0 !important;
}
</style>
<template>
<div class="opening-page">
<div class="title-bar">
<x-header @on-click-title="handleClickTitle" :left-options="{backText:''}">
海西首座E30地块楼盘
<span class="downArrow" :class="{'upArrow': showPopup}"></span>
<div slot="overwrite-left" @click="clickGoback">
<img :src="require('@/assets/images/goBackIcon.png')" class="goBackImg" />
</div>
</x-header>
</div>
<div class="page-content">
<div class="unit">
单位:万元
</div>
<div class="table-header">
<div class="col1 cell flex flex-center">楼栋</div>
<div class="col2 cell flex flex-center">总套数</div>
<div class="col3 cell flex flex-center">已认购套数</div>
<div class="col4-5 flex-v">
<div class="cell flex-1">定金已缴</div>
<div class="flex f-main-center">
<div class="col4 cell flex-1">套数</div>
<div class="col5 cell flex-1">金额</div>
</div>
</div>
<div class="col6-7 flex-v">
<div class="cell flex-1">首付已缴</div>
<div class="flex f-main-center">
<div class="col6 cell flex-1">套数</div>
<div class="col7 cell flex-1">金额</div>
</div>
</div>
</div>
<div class="table-content flex-1">
<scroller ref="scroller" :on-infinite="loadMore" noDataText="已经到底了">
<div class="row">
<div class="total-cell col1">合计</div>
<div class="col2">200</div>
<div class="col3">200</div>
<div class="col4">10</div>
<div class="col5">12</div>
<div class="col6">10</div>
<div class="col7">8</div>
</div>
<div class="row" v-for="i in [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23]" :key="i">
<div class="col1">3#</div>
<div class="col2">200</div>
<div class="col3">200</div>
<div class="col4">10</div>
<div class="col5">12</div>
<div class="col6">10</div>
<div class="col7">8</div>
</div>
</scroller>
</div>
</div>
<div v-transfer-dom>
<popup position="top" v-model="showPopup" style="background: transparent;">
<group gutter="0" style="margin-top:46px">
<radio class="radio" :options="radioOpts" @on-change="handleBuildingChange"></radio>
</group>
</popup>
</div>
</div>
</template>
<script>
import { XHeader, Popup, TransferDom, Radio, Group } from 'vux'
export default {
name: 'opening',
directives: {
TransferDom
},
components: {
XHeader,
Popup,
Radio,
Group,
},
data () {
return {
showPopup: false,
radioOpts: [
{
key: '01',
value: 'radio1'
},
{
key: '02',
value: 'radio2'
},
{
key: '03',
value: 'radio3'
}
],
maxHeight: '100%',
scroll: {
scroller: null
},
xList: [
[
{
field_name: "building",
name: "楼栋",
rowspan: 2
},
]
],
xField: ['building'],
yList: [
{
building: '3#'
}
]
}
},
methods: {
clickGoback () {
this.$router.goBack()
},
handleClickTitle () {
this.showPopup = !this.showPopup
},
loadMore () {
},
handleBuildingChange (value, label) {
console.log('handleBuildingChange', value, label)
this.showPopup = !this.showPopup
}
},
}
</script>
<style lang="less" scoped>
.opening-page {
position: absolute;
top: 0;
width: 100%;
height: 100%;
.title-bar {
width: 100%;
height: 48px;
position: fixed;
z-index: 501;
.goBackImg{
width: 60%;
}
.icon-down {
font-size: 8px;
}
.downArrow {
content: ' ';
position: relative;
top: -5px;
height: 6px;
width: 6px;
border-width: 0 2px 2px 0;
border-color: @arrow-color;
border-style: solid;
-webkit-transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0);
transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0);
transition: all 0.25s;
}
.upArrow {
transform: rotate(-135deg);
}
}
.page-content {
position: absolute;
top: 48px;
display: flex;
flex-direction: column;
width: 100%;
bottom: 0;
}
}
.unit {
background-color: rgba(107,111,123,0.2);
padding: 0.05rem 0.1rem;
color: #AFBCC5;
font-size: 12px;
font-weight: 400;
margin-bottom: 0.1rem;
}
.table-header {
display: flex;
width: 100%;
align-items: center;
background-color: #212C38;
border-top: 1px solid #2A3949;
border-bottom: 1px solid #2A3949;
color: #D1E0EA;
font-size: 12px;
font-weight: 400;
.cell {
border-right: 1px solid #2A3949;
}
.col4, .col5, .col6, .col7 {
border-top: 1px solid #2A3949;
}
}
.table-content {
position: relative;
overflow: hidden;
}
.cell {
text-align: center;
}
.col1 {
width: 13%;
height: 100%;
}
.col2 {
width: 15%;
height: 100%;
}
.col3 {
width: 20%;
height: 100%;
}
.col4-5, .col6-7 {
width: 26%;
text-align: center;
}
.row {
border-bottom: 1px solid #2A3949;
width: 100%;
height: 34px;
display: flex;
font-size: 14px;
font-weight: bold;
color: #D1E0EA;
.total-cell {
font-size: 12px;
font-weight: 400;
}
div {
display: flex;
justify-content: center;
align-items: center;
}
.col4, .col5, .col6, .col7 {
width: 13%;
}
.col4, .col6 {
color: #E54545;
}
.col5, .col7 {
color: #36B37E;
}
}
.radio {
background-color: #0E1822;
}
</style>
\ No newline at end of file
<template>
<main-com />
</template>
<script>
import mainCom from "../index";
export default {
name: "pastData",
components: {
mainCom
},
};
</script>
<style lang="less" scoped>
</style>
<template>
<main-com />
</template>
<script>
import mainCom from "../index";
export default {
name: "pastData2",
components: {
mainCom
},
};
</script>
<style lang="less" scoped>
</style>
<template>
<main-com />
</template>
<script>
import mainCom from "../index";
export default {
name: "pastData3",
components: {
mainCom
},
};
</script>
<style lang="less" scoped>
</style>
<template>
<div class="stacked-line-chart">
<div class="titleDiv">
{{title}}
</div>
<div class="line-chart-wrapper">
<div :id="chartId" class="barDiv" />
</div>
</div>
</template>
<script>
import echarts from 'echarts'
import { getRealPx } from '~config/config'
var PageType = {
Order: 1,
Sign: 2,
Pay: 3,
Conversion: 4
}
var DataType = {
CountMonth: 0,
CurrentMonth: 1
}
export default {
name: 'stackedLineChart',
props: {
pageType: Number,
dataType: Number,
monthList: Array,
stackedLineData: Array,
refreshFlag: Boolean
},
activated: function() {
this.initEchart()
},
data: function() {
return {
barColor: '#E54545',
colorArray: ['#ff0000', '#04C6E5', '#ffb200', '#20F856', '#6C00F9', '#FF84BA', '#0057e5','#1b4c38','#B50079','#CCFF00', '#91c7ae', '#D9C1D7', '#546570', ],
title: '',
chartId: this.rndNum(10),
seriesData: [],
echart: null,
selectIndex: -1
}
},
computed: {
xAxisLabelArray () { // x轴标题
return this.handleMonthList() || []
},
legendData () {
return this.stackedLineData && this.stackedLineData.map(item => item.itemInfo.name)
}
},
watch: {
dataType: function(val, oldVal) {
this.drawStackedLineEchart()
},
stackedLineData () {
this.drawStackedLineEchart()
},
refreshFlag () {
this.drawStackedLineEchart()
}
},
methods: {
rndNum: function(n) {
var rnd = ''
for (var i = 0; i < n; i++) rnd += Math.floor(Math.random() * 10)
return rnd
},
initEchart: function() {
if (!this.echart) {
this.echart = echarts.init(document.getElementById(this.chartId))
} else {
this.echart.clear()
}
},
sortarr(arr){ // 月份排序处理
for(let i=0;i<arr.length-1;i++){
for(let j=0;j<arr.length-1-i;j++){
if(arr[j].id > arr[j+1].id){
var temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
return arr;
},
handleMonthList () {
let arrSortTemp = this.sortarr(this.monthList) || []
let arr = []
arrSortTemp.map((item, i) => {
// arr[i] = item.month + '月'
arr[i] = item.id
})
return arr
},
handleCurrentRata () {
if (this.pageType !== PageType.Conversion) {
let type = this.dataType === DataType.CountMonth ? 'rateTotalInfo' : 'rateInfo'
let rate = 'realityRate'
let seriesTemp = []
if (this.stackedLineData) {
this.stackedLineData.map(item => {
let dataTemp = []
this.xAxisLabelArray.map((item1, index1) => {
let targetObj = item.monthRateInfo.find((item2, index2) => item2.monthInfo.id == item1)
if (!targetObj[type][rate]) { // 怕有null,先处理下
dataTemp[index1] = 0
} else {
dataTemp[index1] = (Number(targetObj[type][rate])*100).toFixed(1)
}
})
seriesTemp.push({
name: item.itemInfo.name,
type: 'line',
data: dataTemp
})
})
}
// console.log('seriesData-非转化率',seriesTemp)
return seriesTemp
} else { // 转化率页面处理
let type = this.dataType === DataType.CountMonth ? 'subscribeNoSignInfo' : 'signNoReceivedInfo'
let rate = this.dataType === DataType.CountMonth ? 'subscribeNoSignRate' : 'signNoReceivedRate'
let seriesTemp = []
if (this.stackedLineData) {
this.stackedLineData.map(item => {
let dataTemp = []
this.xAxisLabelArray.map((item1, index1) => {
let targetObj = item.monthCVRInfo.find((item2, index2) => item2.monthInfo.id == item1)
if (!targetObj[type][rate]) { // 怕有null,先处理下
dataTemp[index1] = 0
} else {
dataTemp[index1] = (Number(targetObj[type][rate])*100).toFixed(1)
}
})
seriesTemp.push({
name: item.itemInfo.name,
type: 'line',
data: dataTemp
})
})
}
// console.log('seriesData-转化率',seriesTemp)
return seriesTemp
}
},
setOptions: function() {
let that = this
let labelOption = {
normal: {
show: true,
position: 'top',
color: '#D1E0EA',
fontWeight: 'bold',
fontSize: getRealPx(0.18),
fontFamily: 'valueFonts1'
}
}
let options = {
color: this.colorArray,
legend: {
// bottom: 80,
// type: 'scroll',
type: 'plain',
textStyle: {
color: '#fff'
},
inactiveColor: '#6F6973', // 图例关闭时的颜色
// itemWidth: '25',
data:this.legendData
},
grid: {
top: getRealPx(0.5),
left: getRealPx(0.4),
right: getRealPx(0.01),
bottom: getRealPx(0.3)
},
xAxis: {
type: 'category',
data: this.xAxisLabelArray,
axisLabel: {
interval: 0, // 0 - 强制显示每一列;1 - 隔一个标签显示一个标签
// rotate: 45,
// fontSize: getRealPx(0.12),
// color: '#708CA6',
textStyle: {
color: function (value, index,) {
let date = new Date();
let newYear = date.getFullYear()
// console.log('x轴',value, index, newYear)
return newYear > Number(value.substr(0, 4)) ? '#708CA6' : '#e6edf3'
}
},
formatter: function (value, index) {
return (value.slice(4)+'月').replace(/(0\d+)/g, value.slice(5))
}
},
axisTick: {
},
axisPointer: {
show: true,
lineStyle: {
// color: '#ccc'
},
snap: true // 吸附
}
},
yAxis: {
show: true,
type: 'value',
splitNumber: 4,
axisLine: { // 坐标轴轴线
// show: false
},
axisLabel: {
textStyle: {
color: '#708CA6',
lineHeight: 20,
fontSize: 12
},
formatter: `{value}%`,
margin: 1
},
splitLine: {
show: true,
lineStyle: {
type: 'dashed',
color: '#304050'
}
},
},
series: this.seriesData,
tooltip: {
trigger: 'axis',
textStyle: {
fontSize: '12',
fontWeight: 300
},
confine: true,
formatter:function(params) {
let relVal = params[0].name;
for (var i = 0, l = params.length; i < l; i++) {
let valueTemp = params[i].value > 0 ? params[i].value+"%" : params[i].value
relVal += '<br/>' + params[i].marker + params[i].seriesName + ' : ' + valueTemp;
}
return relVal;
}
},
dataZoom: {
show: true,
type: 'inside',
filterMode: 'filter',
minValueSpan: 6,
maxValueSpan: 12,
realtime: true
}
}
this.echart.setOption(options)
},
drawStackedLineEchart: function() {
this.echart.clear()
this.seriesData = this.handleCurrentRata()
this.setLineChartTitle()
this.setOptions()
},
setLineChartTitle () {
switch (this.pageType) {
case PageType.Order:
if (this.dataType === DataType.CountMonth) {
this.title = '累计认购指标完成率'
} else {
this.title = '月度认购指标完成率'
}
break
case PageType.Sign:
if (this.dataType === DataType.CountMonth) {
this.title = '累计签约指标完成率'
} else {
this.title = '月度签约指标完成率'
}
break
case PageType.Pay:
if (this.dataType === DataType.CountMonth) {
this.title = '累计回款指标完成率'
} else {
this.title = '月度回款指标完成率'
}
break
case PageType.Conversion:
if (this.dataType === DataType.CountMonth) {
this.title = '认购签约率趋势图'
} else {
this.title = '签约回款率趋势图'
}
break
default:
this.title = '累计认购指标完成率'
}
}
}
}
</script>
<style lang="less" scoped>
.stacked-line-chart {
margin-top: 0.1rem;
.titleDiv {
width: 100%;
text-align: center;
color: @data-value-text-color;
font-weight: normal;
font-size: 0.16rem;
}
.line-chart-wrapper {
width: 100%;
overflow-x: scroll;
overflow: hidden;
.barDiv {
width: 100%;
position: relative;
height: 2.8rem;
margin-top: 0.11rem;
}
}
}
</style>
<template>
<div class="allDiv">
<div class="itemDiv" v-for="(item,index) in titleArray" :key="index" @click="clickBtn(index)">
<img :src="selectIndex == index ? imgActiveArray[index] :imgunActiveArray[index]" />
<div :class="{'highlightText':selectIndex == index}">{{titleArray[index]}}</div>
</div>
</div>
</template>
<script>
export default {
activated () {
switch (this.$store.state.shareStore.pastNavType.currentPageType) {
case 1: // 认购
this.selectIndex = 0
break
case 2: // 签约
this.selectIndex = 1
break
case 3: // 回款
this.selectIndex = 2
break
case 4: // 转化率
this.selectIndex = 3
break
default:
this.selectIndex = 0
break
}
},
data: function() {
return {
selectIndex: 0,
titleArray: ['认购', '签约', '回款', '转化率'],
imgActiveArray: [
require('@/assets/images/orderActiveIcon.png'),
require('@/assets/images/signActiveIcon.png'),
require('@/assets/images/payActiveIcon.png'),
require('@/assets/images/conversionRateActiveIcon.png')
],
imgunActiveArray: [
require('@/assets/images/orderUnActiveIcon.png'),
require('@/assets/images/signUnActiveIcon.png'),
require('@/assets/images/payUnActiveIcon.png'),
require('@/assets/images/conversionRateUnActiveIcon.png')
]
}
},
methods: {
clickBtn: function(val) {
this.selectIndex = val
this.$emit('changeType', val)
}
},
// mounted: function() {
// switch (this.$route.params.type) {
// case 'pastOrder': // 认购
// this.selectIndex = 0
// break
// case 'pastSign': // 签约
// this.selectIndex = 1
// break
// case 'pastPay': // 回款
// this.selectIndex = 2
// break
// case 'pastConversion': // 转化率
// this.selectIndex = 3
// break
// default:
// this.selectIndex = 0
// break
// }
// }
}
</script>
<style lang="less" scoped>
.allDiv {
width: 100%;
display: flex;
flex-direction: row;
height: 100%;
}
.itemDiv {
width: calc(~'100% / 3');
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
img {
width: 0.24rem;
height: 0.24rem;
}
div {
margin-left: 0.1rem;
font-size: 0.14rem;
color: #708ca6;
}
}
.highlightText {
color: white !important;
}
</style>
<template>
<div class="monthPopup">
<div v-transfer-dom>
<popup
v-model="showMonthSelect"
position="top"
:is-transparent="true"
:show-mask="true"
@on-hide="clickmask"
>
<popup-header
:left-text="'取消'"
:right-text="'全选'"
:title="'选择月份'"
:show-bottom-border="true"
@on-click-left="clickCancel"
@on-click-right="selectAll"
/>
<div class="position-vertical-demo">
<div class="filterBg">
<group class="monthList" gutter=0 style="max-height: 300px;overflow: scroll;">
<checklist class="cellItem" required :options="commonList" v-model="selectData"></checklist>
</group>
</div>
<x-button
v-show="showMonthSelect"
class="comfirmBtn"
:disabled="!bgEnable"
@click.native="clickDone"
>确定</x-button>
</div>
</popup>
</div>
</div>
</template>
<script>
import { TransferDomDirective as TransferDom } from 'vux'
import { Group, Popup, PopupHeader, XButton, Checklist } from 'vux'
export default {
directives: {
TransferDom
},
components: {
XButton,
Group,
Popup,
PopupHeader,
Checklist
},
props: {
isShowPopup: {
type: Boolean,
default: false
},
monthList: {
type: Array
},
refreshFlag: Boolean
},
activated: function () {
this.currentSelectedMonthList.length > 0 ?
this.selectData = this.currentSelectedMonthList :
this.selectData = this.defaultSelectedMonthList
this.$emit('selectedMonthList', this.sortarr2(this.selectData))
},
mounted: function() {
// this.$emit('selectedMonthList', this.sortarr2(this.currentSelectedMonthList))
},
data: function () {
return {
showMonthSelect: false,
bgEnable: false,
// commonList: this.getMonthList(), // 本地计算月份列表,已不用
commonList: [],
defaultSelectedMonthList: [], // 默认选中当前月及之前的两个月,共三个月
selectData: []
}
},
computed: {
currentSelectedMonthList () {
return this.$store.state.shareStore.monthListInfo.monthFilter
}
},
watch: {
isShowPopup (newval, oldvalue) {
this.showMonthSelect = newval
if (newval) {
this.currentSelectedMonthList.length > 0 ?
this.selectData = this.currentSelectedMonthList :
this.selectData = this.defaultSelectedMonthList
}
},
selectData: function (val) {
// console.log('se',val.length, this.selectDataTemp.length)
(val && val.length) >0 ? (this.bgEnable = true) : (this.bgEnable = false)
},
monthList () {
this.handleMonthList()
},
refreshFlag () {
this.handleMonthList()
}
},
methods: {
getMonthList () {
let d = new Date();
let result = [];
let nowMonth = (d.getMonth() + 1) < 10 ? '0' + (d.getMonth() + 1) : (d.getMonth() + 1)
result.push(d.getFullYear() + "-" + nowMonth)
for(let i = 0; i < 12; i++) {
d.setMonth(d.getMonth() - 1)
let m = d.getMonth() + 1
m = m < 10 ? "0" + m : m
result.push(d.getFullYear() + "-" + m)
}
let rev = result.reverse()
return rev
},
sortarr(arr){ // 月份排序处理
for(let i=0;i<arr.length-1;i++){
for(let j=0;j<arr.length-1-i;j++){
if(arr[j].id > arr[j+1].id){
var temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
return arr;
},
sortarr2(arr){ // 已选月份排序处理
let arrTemp = arr.map(item => item.replace(/-/g,''))
for(let i=0;i<arrTemp.length-1;i++){
for(let j=0;j<arrTemp.length-1-i;j++){
if(arrTemp[j] > arrTemp[j+1]){
var temp=arrTemp[j];
arrTemp[j]=arrTemp[j+1];
arrTemp[j+1]=temp;
}
}
}
// return arrTemp.map(item => (item.slice(4)+'月').replace(/(0\d+)/g, item.slice(5)))
return arrTemp
},
handleMonthList () {
let arrSortTemp = this.sortarr(this.monthList) || []
let arr = []
arrSortTemp.map((item, i) => {
let m = item.month
m = m < 10 ? "0" + m : m
arr[i] = item.year + '-' + m
})
this.commonList = arr
this.defaultSelectedMonthList = arr.slice(-3) // 存储默认选择的月份
if (!this.currentSelectedMonthList.length) {
this.$emit('selectedMonthList', this.sortarr2(this.defaultSelectedMonthList))
}
},
clickmask: function (val) {
this.showMonthSelect = false
this.$emit('hidePopup', false) // 重置右侧标题栏的显示状态:即隐藏状态
this.currentSelectedMonthList.length > 0
? this.selectData = this.currentSelectedMonthList
: this.selectData = this.defaultSelectedMonthList
},
selectAll () {
this.selectData = this.commonList
},
clickCancel () {
this.clickmask()
},
clickDone: function () {
this.handleMonthList()
this.$store.commit('updateMonthFilter', {monthFilter: this.selectData})
// 将选中月份格式化后传递给父组件
this.$emit('selectedMonthList', this.sortarr2(this.selectData))
this.clickmask()
}
}
}
</script>
<style lang="less" scoped>
.vux-popup-header {
background-color: #0b141d;
}
</style>
<style lang="less">
.vux-popup-header {
.vux-popup-header-left {
color: #fff;
font-size: 18px;
}
.vux-popup-header-title {
color: #fff;
font-size: 18px;
}
.vux-popup-header-right {
color: #fff;
font-size: 18px;
}
}
.monthList {
.cellItem {
.weui-cells__title + .weui-cells {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.weui-cells_checkbox .weui-check:checked + .vux-checklist-icon-checked:before {
color: #e54545!important;
}
}
.weui-cell_access.vux-cell-box {
padding: 0.1rem 0.15rem 0.1rem 0rem;
}
.weui-cell {
padding: 0.1rem 0.02rem;
margin-right: 0.08rem;
min-width: 25%;
max-width: 100%/3;
font-size: 14px;
}
.weui-cells:before {
border-width: 0px;
}
.weui-cells {
background-color: transparent !important;
}
.weui-cell:before {
border-color: @table-division-line-color;
transform: scaleY(0.5);
transform-origin: 0 0;
border: none!important;
}
.weui-cells:after {
border-color: @table-division-line-color;
transform-origin: 0 0;
}
.vux-label {
color: @data-value-text-color;
font-size: 0.14rem;
margin: 0.08rem 0px;
}
.cellValueDiv {
color: white;
font-weight: 300;
font-size: 0.14rem;
padding: 0.08rem;
}
}
</style>
<template>
<div class="table-wrapper">
<area-table class="tableDiv"
:currentPageType="currentPageType"
:currentDataType="currentDataType"
:currentTableSelect="currentTableSelect"
:isRealThree="isRealThree"
:paramHeaderArray="headerArray"
:paramDataArray="dataArray"
:totalData="totalData"
@clickSubRow="clickItem"
/>
<bottom-tip />
</div>
</template>
<script>
import Api from '@/api'
import AreaTable from './areaTable'
import bottomTip from '~com/commom/bottomTip'
export default {
name: 'areaDetail',
components: {
AreaTable,
bottomTip
},
props: {
currentPageType: Number,
currentDataType: Number,
currentTableSelect: Number,
isRealThree: Boolean,
tableObj: {
type: Object,
default: function () {
return {}
}
},
monthListFilter: Array
},
data() {
return {
headerArray: ['区域'],
dataArray: [],
totalData: []
}
},
computed: {
filterResultArray() {
return JSON.parse(this.$route.params.filterArray)
},
filterCompanyType() {
return Number(this.$route.params.filterComType)
},
filterCompanyLeafType() {
return Boolean(JSON.parse(this.$route.params.filterComLeafType).leafType)
}
},
watch: {
tableObj (val) {
this.arrData(val)
},
monthListFilter () {
this.arrHeaderData() // 更新表格标题
}
},
methods: {
arrHeaderData: function() {
this.headerArray.splice(1, this.headerArray.length)
let firstTitle = ''
switch (this.filterCompanyType) {
case 1:
firstTitle = '区域'
break
case 2:
firstTitle = '城市'
break
case 3:
if (this.isRealThree) {
firstTitle = '项目'
} else {
firstTitle = '城市公司'
}
break
case 4:
firstTitle = '项目'
break
default:
firstTitle = '区域'
}
this.headerArray[0] = firstTitle
this.headerArray = [...this.headerArray, ...this.monthListFilter]
this.headerArray.splice(this.headerArray.length)
},
arrData: function(val) {
this.totalData = val.sumTotal
this.dataArray.splice(0, this.dataArray.length)
this.dataArray = val.dataList
// this.dataArray.splice(this.dataArray.length)
},
clickItem: function(item) {
// console.log('clickItem',item)
this.$emit('clickItem', item)
}
}
}
</script>
<style lang="less" scoped>
.tableDiv {
margin-top: 0.13rem;
}
</style>
<template>
<div class="view-content has-header content noBGImg">
<minenodelist-table
@on-item-click="handleItemClick"
:showBackTop="showBackTop"
:hasMore="hasMore"
:showStarIcon="showStarIcon"
:dataSource="nodeList"
class="nodelist-table"
@load-more="loadMore"
ref="nodeListScroller">
</minenodelist-table>
</div>
</template>
<script>
import Api from '@/api'
import { scrollBackTo } from '~lib/mixins/overallPlanMixin'
import MinenodelistTable from './node/mineNodeListTable'
export default {
name: "cityNodeList",
mixins: [scrollBackTo],
components: {
MinenodelistTable
},
created () {
const { cityName, stateName, cityId, state } = this.$route.query
this.cityId = cityId
this.cityName = cityName
this.stateName = stateName
this.state = state
this.fetchNodeList({}, true)
},
activated () {
this.$store.commit('setNavTitle', `${this.cityName}-${this.stateName}`)
},
data () {
return {
cityId: '',
cityName: '',
stateName: '',
state: '',
nodeList: [],
firstLoad: true,
currentPageInfo: {
pageNum: 1
}
}
},
computed: {
showStarIcon () {
return false
},
hasMore () {
return this.currentPageInfo.hasNextPage
},
showBackTop () {
return this.currentPageInfo.pageNum > 2
},
filterResultArray() {
return this.$store.state.shareStore.filterArray
}
},
methods: {
handleItemClick (item) {
this.$router.push({ name: 'nodeInfo', query: item })
},
fetchNodeList (options, firstPage, cb) {
let companyId = this.filterResultArray[1].key
let params = {
companyIds: companyId,
rootCompanyId: this.cityId,
level: 0,
state: this.state,
...options
}
if (firstPage) {
this.firstLoad = true
params.pageNum = 1
}
let apiPath = Api.schedule_overall_detail
this.$mas
.proxy(apiPath, params)
.then(result => {
if (result.msgType === 'success') {
if (result.data && result.data.nodeList) {
this.currentPageInfo = result.data.nodeList.currentPageInfo || {}
// 重新赋值
if (this.currentPageInfo.pageNum === 1) {
this.nodeList = result.data.nodeList.nodeList || []
} else {
// 拼接下页数据
this.nodeList = this.nodeList.concat((result.data.nodeList.nodeList))
cb()
}
this.firstLoad = false
} else {
this.showAlert(`获取数据失败!`)
}
} else {
this.showAlert(`${result.msg}`)
}
})
.catch(error => {
if (error.hasOwnProperty('data')) {
if (error.data.hasOwnProperty('code')) {
if (error.data.code === 40002) {
this.showAlert('您的登录已超时,请退出重新登录。')
return
} else if (error.data.code === 40001 || error.data.code === 40003) {
this.showAlert('您的认证失效,请尝试退出后重新登录')
return
}
this.showAlert(
'网络有误:' +
error.data.msg +
'<br />错误代码:' +
error.data.code
)
} else {
this.showAlert('网络有误:' + error.data.msg)
}
return
}
this.showAlert('网络有误')
})
},
loadMore (callback) {
if (this.hasMore) {
this.fetchNodeList({
pageNum: this.currentPageInfo.pageNum + 1
}, false, callback)
} else {
callback(true) // 没有更多数据
}
},
showAlert: function (msg, callback) {
this.$vux.alert.show({
title: '提示',
content: msg,
onHide() {
if (callback) {
callback()
}
}
})
}
}
}
</script>
<style lang="less" scoped>
</style>
\ No newline at end of file
<template>
<div class="first-node">
<mainTitle title="当年一级节点" :hiddenIcon="false" @clickHeaderIcon="clickDialog" />
<flexbox>
<flexbox-item>
<div class="flexbox-item">
<label>当年考核数</label>
<span>{{defaultValue(nodeInfo.checkValue)}}</span>
</div>
</flexbox-item>
<flexbox-item>
<div class="flexbox-item">
<label>目前应完成数</label>
<span>{{defaultValue(nodeInfo.targetValue)}}</span>
</div>
</flexbox-item>
</flexbox>
<flexbox>
<flexbox-item>
<div class="flexbox-item">
<label>目前按期完成数</label>
<span>{{defaultValue(nodeInfo.realityValue)}}</span>
</div>
</flexbox-item>
<flexbox-item>
<div class="flexbox-item">
<label>完成率</label>
<span>{{completePercent(nodeInfo.realityRate)}}%</span>
</div>
</flexbox-item>
</flexbox>
<div class="divider"></div>
<div style="padding:0 15px;">
<h2>一级节点状态占比图</h2>
<div id="chart"></div>
<x-table :content-bordered="false" :cell-bordered="false">
<thead>
<tr>
<th>节点状态</th>
<th>个数</th>
<th>占比</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in nodeStateList" :key="index" @click="clickNodeStateItem(item)">
<td :style="tdStyle(item)" ><i :class="stateIconClass(item)"></i>{{item.name}}</td>
<td :style="tdStyle(item)">{{defaultValue(item.value)}}</td>
<td :style="tdStyle(item)">{{completePercent(item.rate)}}%</td>
</tr>
</tbody>
</x-table>
</div>
</div>
</template>
<script>
import { Flexbox, FlexboxItem, XTable } from 'vux'
import echarts from 'echarts'
import mainTitle from '~com/commom/mainTitle'
import { formatNumber } from '@/utils/textUtil'
export default {
name: 'first-node',
components: {
Flexbox,
FlexboxItem,
XTable,
mainTitle,
},
props: {
dataSource: {
type: Object,
required: true
}
},
mounted () {
this.initEchart()
},
data () {
return {
maxIndex: 0
}
},
computed: {
filterResultArray() {
return this.$store.state.shareStore.filterArray
},
filterCompanyLeafType() {
return Boolean(this.$store.state.shareStore.isCompanyLeaf)
},
nodeInfo () {
return (this.dataSource && this.dataSource.nodeInfo) || {}
},
nodeStateList () {
return (this.dataSource && this.dataSource.nodeStateList) || []
}
},
watch: {
nodeStateList (newVal, oldVal) {
this.$echart.setOption({
series: [
{
type: 'pie',
data: newVal.map((item) => Object.assign({}, item, { value: this.completePercent(item.rate) }))
}
]
})
if (newVal.length > 0) {
this.downplay(this.maxIndex)
let maxValue = newVal[0].rate
this.maxIndex = 0
for (let index = 1; index < newVal.length; index++) {
const element = newVal[index]
if (element.rate > maxValue) {
maxValue = element.rate
this.maxIndex = index
}
}
this.highlightMax(this.maxIndex)
}
}
},
methods: {
initEchart () {
this.$echart = echarts.init(document.getElementById('chart'))
let data = this.nodeStateList.map((item) => Object.assign({}, item, { value: this.completePercent(item.rate) }))
this.$echart.setOption({
color: ['#36B37E', '#E78218', '#FFAB00', '#C81D13', '#E54545', '#AFBCC5'],
series: [
{
name: '一级节点状态占比图',
type: 'pie',
radius: ['60%', '80%'],
avoidLabelOverlap: false,
label: {
normal: {
show: false,
position: 'center'
},
emphasis: {
show: true,
formatter: '{b}\n{d}%',
textStyle: {
fontSize: '14',
fontWeight: 'bold'
}
}
},
labelLine: {
normal: {
show: false
}
},
data: data
}
]
})
this.$echart.on('mouseover', (e) => {
if (e.dataIndex !== this.maxIndex) {
this.$echart.dispatchAction({
type: 'downplay',
seriesIndex: 0,
dataIndex: this.maxIndex
})
}
})
window.addEventListener('resize', function () { this.$echart.resize() });
},
// 取消高亮
downplay (index) {
this.$echart.dispatchAction({
type: 'downplay',
seriesIndex: 0,
dataIndex: index
})
},
// 显示高亮
highlightMax (maxIndex) {
this.$echart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: maxIndex
})
},
defaultValue (val) {
return val || 0
},
completePercent (rate) {
// 完成率百分值
return formatNumber(rate)
},
stateIconClass (item) {
switch (item.name) {
case '按期完成':
return 'iconfont iconicon_red_small icon_small green'
case '逾期10天以内完成':
return 'iconfont iconicon_red_small icon_small yellow'
case '逾期10天以内':
return 'circle_small_yellow'
case '逾期10天以上完成':
return 'iconfont iconicon_red_small icon_small red'
case '逾期10天以上':
return 'circle_small_red'
case '未到期':
return 'circle_small_gray'
default:
return ''
}
},
tdStyle (item) {
switch (item.name) {
case '按期完成':
return { color: '#36B37E' }
default:
return {}
}
},
clickDialog (val) {
this.$emit('clickDialog', val)
},
clickNodeStateItem (item) {
const { value, key } = this.filterResultArray[1]
// 当前公司是否是叶子节点,是则跳转到城市节点信息页面,不是则跳转到节点状态区域城市表
if (this.filterCompanyLeafType) {
this.$router.push({ name: 'cityNodeList', query: {cityName: value, stateName: item.name, cityId: key, state: item.state } })
} else {
this.$router.push({ name: 'nodeStateTable', params: {name: item.name, state: item.state} })
}
}
}
}
</script>
<style lang="less" scoped>
.first-node {
color: white;
.flexbox-item {
display: flex;
flex-direction: column;
padding-top: 5px;
color: white;
align-items: center;
label {
font-size: 14px;
font-weight: 400;
opacity: 0.9;
}
span {
font-size: 20px;
font-family: DIN;
font-weight: bold;
}
}
.divider {
height: 1px;
background-color: #405669;
margin-top: 5px;
margin-bottom: 5px;
margin-left: 15px;
margin-right:15px;
}
h2 {
font-size: 18px;
font-weight: 400;
line-height: 24px;
color: white;
text-align: center;
}
#chart {
height: 200px;
}
thead, tbody {
color: white;
font-size: 14px;
font-weight: 400;
}
.vux-table {
line-height: 32px;
}
.vux-table:after,
.vux-table.vux-table-no-content-bordered tr:last-child td:before {
border: none;
}
.vux-table th,
.vux-table td {
text-align: start;
}
.icon_small {
font-size: 11px;
margin-right: 5px;
}
.green {
color: #36B37E;
}
.yellow {
color: #E78218;
}
.red {
color: #E54545;
}
.circle_small_red {
display: inline-block;
height: 12px;
width: 12px;
border-radius: 50%;
background-color: #E54545;
margin-right: 5px;
}
.circle_small_yellow {
display: inline-block;
height: 12px;
width: 12px;
border-radius: 50%;
background-color: #FFAB00;
margin-right: 5px;
}
.circle_small_gray {
display: inline-block;
height: 12px;
width: 12px;
border-radius: 50%;
background-color: #999999;
margin-right: 5px;
}
}
</style>
<template>
<div class="hierarchy-popup">
<c-popover placement="bottom" :fullWidth="true" v-model="show" @on-hide="handleCancelPopup">
<div id="popupContent" slot="content" class="popup-content">
<companyFilterHome v-model="selectData" v-if="show"></companyFilterHome>
<div>
<x-button
class="comfirmBtn"
:disabled="!selectData"
@click.native="handleConfirm">确定</x-button>
</div>
</div>
<slot></slot>
</c-popover>
</div>
</template>
<script>
import { TransferDom, Popup, Popover, XButton, Group, Cell, CellBox } from 'vux'
import CPopover from '~com/commom/c-popover'
import companyFilterHome from '../filter/companyFilterHome'
export default {
name: 'hierarchy-popup',
directives: {
TransferDom
},
components: {
Popup,
CPopover,
Popover,
XButton,
Group,
Cell,
CellBox,
companyFilterHome
},
props: {
currentCompany: {
type: Object
}
},
mounted () {
let content = document.getElementById('popupContent')
content.addEventListener("touchmove", (e) => {
e.stopPropagation()
if (e.target.className !== 'cellTitle') {
e.preventDefault()
}
})
},
activated () {
this.selectData = this.$store.state.shareStore.currentCompany
},
data() {
return {
selectData: null,
show: false
}
},
methods: {
handleConfirm () {
let [...filterArray] = this.$store.state.shareStore.filterArray
filterArray.splice(1, 1, this.selectData)
this.$store.commit('setCompanyLeafType', this.selectData && this.selectData.isLeaf)
// 保存公司层级
this.$store.commit('saveConfirmCompanyTreeArray', this.$store.state.shareStore.companyTreeArray)
// 保存选中公司信息
this.$store.commit('saveCurrentCompany', {...this.selectData})
// 保持
this.$store.commit('setFilterComType', this.$store.state.shareStore.companyTreeArray.length + 1)
// 同步更新运营概览页面(首页)的公司
this.$store.commit('setFilterData', filterArray)
this.show = false
this.$emit('on-selected', this.selectData)
},
handleCancelPopup () {
// 保存公司层级
this.$store.commit('setCompanyTreeArray', this.$store.state.shareStore.confirmCompanyTreeArray)
}
}
}
</script>
<style lang="less">
.c-popover {
.companyFilterDiv {
border-top: 1px solid #353B45;
}
.radioDiv {
width: auto;
padding-left: 15px;
position: relative;
}
.cellTitle {
margin-left: 15px;
padding-left: 0;
}
}
</style>
<style scoped>
.popup-content {
overflow: scroll;
width: 100%;
}
</style>
<template>
<div class="home-tab">
<hierarchy-popup style="width:100%" :currentCompany="currentCompany" @on-selected="handleChange">
<div class="sub-title-wrapper">
<span class="sub-title">{{currentCompany.value}}<i class="iconfont iconicon_down icon-down"></i></span>
</div>
</hierarchy-popup>
<div class="divider"></div>
<first-node v-if="showFirstNode" :dataSource="overallInfo" @clickDialog="clickDialog"></first-node>
<situation-block v-if="showSituation" :dataSource="situationList" @clickDialog="clickDialog"></situation-block>
<div v-transfer-dom>
<x-dialog v-model="showDialog">
<div
class="dialogDiv"
v-if="dialogItemData"
>
<div class="dialogHeader">
<span class="title">
{{dialogItemData.algDescMainTitle}}
</span>
<div
class="closeDiv"
@click="()=>{showDialog = false;dialogItemData = null}"
>
<img :src="require('@/assets/images/closeDialogIcon.png')" />
</div>
</div>
<div class="dialogContent">
<div class="title">
{{dialogItemData.algDescSubTitle ? dialogItemData.algDescSubTitle : dialogItemData.name}}
</div>
<div
class="content"
id="dialogContent"
>
<div
class="item"
v-for="(item,index) in dialogItemData.algDescEntryList"
:key="index"
>
<div class="circle"></div>
<div class="text">
<span v-html="handleBreak(item.desc)"></span>
</div>
</div>
</div>
</div>
</div>
</x-dialog>
</div>
</div>
</template>
<script>
import Api, { helpCode } from '@/api'
import firstNode from './firstNode'
import situationBlock from './situationBlock'
import hierarchyPopup from './hierarchyPopup'
import { TransferDom, XDialog } from 'vux'
export default {
name: 'home-tab',
directives: {
TransferDom
},
components: {
hierarchyPopup,
firstNode,
XDialog,
situationBlock
},
created () {
this.checkCardShowStatus()
},
activated () {
this.checkCardShowStatus()
if (this.$store.state.shareStore.currentCompany) {
this.currentCompany = Object.assign({}, this.$store.state.shareStore.currentCompany)
} else if (this.$store.state.shareStore.filterArray && this.$store.state.shareStore.filterArray.length > 1) {
this.currentCompany = Object.assign({}, this.$store.state.shareStore.filterArray[1])
}
},
data () {
return {
currentCompany: {},
overallInfo: {},
nodeInfo: {},
showDialog: false,
dialogArray: [], // 帮助提示对话框内容
dialogItemData: null,
isFirstLoading: false,
showFirstNode: false,
showSituation: false
}
},
computed: {
situationList () {
let tmpArr = []
if (this.nodeInfo.allNodeInfo) {
tmpArr.push({ name: '总体节点完成率', ...this.nodeInfo.allNodeInfo })
}
if (this.nodeInfo.twoNodeInfo) {
tmpArr.push({ name: '二级节点完成率', ...this.nodeInfo.twoNodeInfo })
}
if (this.nodeInfo.threeNodeInfo) {
tmpArr.push({ name: '三级节点完成率', ...this.nodeInfo.threeNodeInfo })
}
return tmpArr
}
},
watch: {
currentCompany(newValue, oldValue) {
if (newValue.key !== oldValue.key) {
this.fetchData()
// if (this.isFirstLoading) {
// this.fetchData()
// }
}
}
},
methods: {
checkCardShowStatus () {
let planHomePermission = this.$store.state.shareStore.planHomePermission.lowerList
for (let item of planHomePermission) {
if (item.name == '当年一级节点') {
this.showFirstNode = true
} else if (item.name == '当年进度概况') {
this.showSituation = true
}
}
},
noPermission: function () {
this.showAlert('您没有权限进入', '确认', () => {
this.$nativeApi.navigator.exit()
// this.$router.push({ name: 'subject' })
})
},
showAlert: function (msg, callback) {
this.$vux.alert.show({
title: '提示',
content: msg,
onHide() {
if (callback) {
callback()
}
}
})
},
handleChange (value) {
this.currentCompany = Object.assign({}, value)
},
clickDialog (titleVal) {
// console.log(titleVal)
for (let obj of this.dialogArray) {
let objName = obj.name
if (objName == titleVal) {
this.dialogItemData = obj
}
}
if (this.dialogItemData) {
this.showDialog = true
}
},
handleBreak: function (val) {
var reg = new RegExp('\n', 'g')
let str = val.replace(reg, '</br>')
return str
},
getRequestArray () {
let tmpArray = [
this.$mas.proxy(Api.dialogURL, {
code: helpCode.planHome
})
]
let params = {
companyIds: this.currentCompany.key,
level: 0
}
// 总体情况
tmpArray.push(this.$mas.proxy(Api.schedule_overall_info, params))
// 进度概括
tmpArray.push(this.$mas.proxy(Api.schedule_rate_info, params))
return tmpArray
},
fetchData () {
Promise.all(this.getRequestArray())
.then(resArray => {
if (resArray[0].msgType === 'success') {
this.dialogArray.splice(0, this.dialogArray.length)
this.dialogArray = resArray[0].data[0].algDescList
}
if (resArray[1].msgType === 'success') {
this.overallInfo = resArray[1].data
} else {
this.showAlert(`${resArray[1].msg}`)
}
if (resArray[2].msgType === 'success') {
this.nodeInfo = resArray[2].data
} else {
this.showAlert(`${resArray[2].msg}`)
}
})
.catch(error => {
if (error.hasOwnProperty('data')) {
if (error.data.hasOwnProperty('code')) {
if (error.data.code === 40002) {
this.showAlert('您的登录已超时,请退出重新登录。')
return
} else if (error.data.code === 40001 || error.data.code === 40003) {
this.showAlert('您的认证失效,请尝试退出后重新登录')
return
}
this.showAlert(
'网络有误:' +
error.data.msg +
'<br />错误代码:' +
error.data.code
)
} else {
this.showAlert('网络有误:' + error.data.msg)
}
return
}
this.showAlert('网络有误')
})
}
}
}
</script>
<style lang="less" scoped>
.home-tab {
.sub-title-wrapper {
width: 100%;
height: 48px;
background-color: #0B151E;
display: flex;
align-items: center;
justify-content: center;
}
.sub-title {
font-size: 18px;
font-weight: 400;
color: white;
}
.icon-down {
font-size: 8px;
color: white;
margin-left: 12px;
vertical-align: middle;
}
.divider {
height: 1px;
background-color: #353B45;
}
}
</style>
<template>
<div class="plan">
<div class="content-wrapper">
<keep-alive exclude="hierarchyPopup">
<component :is="currentTabComponent"></component>
</keep-alive>
</div>
<tabbar v-model="selectedTabIndex" class="tabbar" @on-index-change="onTabChange">
<tabbar-item class="tab-item">
<i class="iconfont iconicon_home_page_gray" slot="icon"></i>
<span slot="label">首页</span>
</tabbar-item>
<tabbar-item class="tab-item">
<i class="iconfont iconicon_ranking_gray" slot="icon"></i>
<span slot="label">排行</span>
</tabbar-item>
<tabbar-item class="tab-item">
<i class="iconfont iconicon_schedule_gray" slot="icon"></i>
<span slot="label">项目进度</span>
</tabbar-item>
<tabbar-item class="tab-item">
<i class="iconfont iconic_me_gray" slot="icon"></i>
<span slot="label">我的</span>
</tabbar-item>
</tabbar>
</div>
</template>
<script>
import { Tabbar, TabbarItem } from 'vux'
import homeTab from './home'
import rankTab from './rank'
import progressTab from './progress'
import mineTab from './mine'
export default {
name: 'plan',
components: {
Tabbar,
TabbarItem
},
created () {
this.initPlanPermission()
},
activated: function () {
this.$store.commit('setNavbarShow', true)
this.$store.commit('setNavTitle', this.currentTitle)
},
data () {
return {
currentTitle: '全景计划概况',
currentTabComponent: homeTab,
selectedTabIndex : 0
}
},
methods: {
initPlanPermission () {
let planPermission = this.$store.state.shareStore.planPermission
for (let item of planPermission) {
if (item.permissionInfo.name == '首页') {
this.$store.commit('setPlanHomePermission', item)
} else if (item.permissionInfo.name == '排行') {
this.$store.commit('setPlanRankPermission', item)
} else if (item.permissionInfo.name == '项目进度') {
this.$store.commit('setPlanProgressPermission', item)
}
}
this.initTabIndex()
},
initTabIndex() {
let planHomePermission = this.$store.state.shareStore.planHomePermission.lowerList
let planRankPermission = this.$store.state.shareStore.planRankPermission.lowerList
let planProgressPermission = this.$store.state.shareStore.planProgressPermission.lowerList
if (planRankPermission.length) {
this.selectedTabIndex = 0
} else if (planProgressPermission.length) {
this.selectedTabIndex = 1
} else if (planProgressPermission.length) {
this.selectedTabIndex = 2
} else {
this.selectedTabIndex = 0
}
},
onTabChange (index) {
this.selectedTabIndex = index
let planHomePermission = this.$store.state.shareStore.planHomePermission
let planRankPermission = this.$store.state.shareStore.planRankPermission
// let planRankPermission = this.$store.state.shareStore.planRankPermission
switch (index) {
case 0:
this.currentTitle = '全景计划概况'
this.currentTabComponent = homeTab
if (!(planHomePermission.permissionInfo && planHomePermission.permissionInfo.hasOwnProperty('name'))) {
this.noPermission()
}
break
case 1:
this.currentTitle = '完成率排行'
this.currentTabComponent = rankTab
if (!(planRankPermission.permissionInfo && planRankPermission.permissionInfo.hasOwnProperty('name'))) {
this.noPermission()
}
break
case 2:
this.currentTitle = '项目进度'
this.currentTabComponent = progressTab
break
case 3:
this.currentTitle = '我的'
this.currentTabComponent = mineTab
break
default:
this.currentTitle = '全景计划概况'
this.currentTabComponent = homeTab
}
this.$store.commit('setNavTitle', this.currentTitle)
// if (!(planRankPermission.permissionInfo && planRankPermission.permissionInfo.hasOwnProperty('name'))) {
// this.noPermission()
// }
},
noPermission: function () {
this.showAlert('您没有权限进入', '确认', () => {
this.$nativeApi.navigator.exit()
})
},
showAlert: function (msg, callback) {
this.$vux.alert.show({
title: '提示',
content: msg,
onHide() {
if (callback) {
callback()
}
}
})
}
}
}
</script>
<style lang="less" scoped>
.plan {
top: 48px;
bottom: 0px;
display: flex;
flex-direction: column;
.content-wrapper {
display: flex;
flex-direction: column;
flex: 1;
overflow-y: auto;
overflow-x: hidden;
width: 100%;
padding-bottom: 70px;
}
.tabbar {
position: fixed;
width: 100%;
height: 70px;
background-color: #0B141D;
}
.tab-item {
margin: auto;
color: #6C7277;
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment