diff --git a/.env.dev b/.env.dev index c8f7babc..a5e7dc35 100644 --- a/.env.dev +++ b/.env.dev @@ -5,8 +5,8 @@ ENV = 'development' VUE_APP_TITLE = 洛玻集团驾驶舱 # 芋道管理系统/开发环境 -# VUE_APP_BASE_API = 'http://172.16.32.18:7070' -VUE_APP_BASE_API = 'http://172.16.32.95:7070' +VUE_APP_BASE_API = 'http://172.16.32.18:7070' +# VUE_APP_BASE_API = 'http://172.16.32.95:7070' # VUE_APP_BASE_API = 'http://172.16.33.83:7070' # VUE_APP_BASE_API = 'http://192.168.0.35:7070' diff --git a/src/api/cockpit.js b/src/api/cockpit.js index 44a1ddb8..92ca4558 100644 --- a/src/api/cockpit.js +++ b/src/api/cockpit.js @@ -194,3 +194,55 @@ export function getInputOutputRateFactoryData(data) { data: data, }); } +export function getUnitPriceAnalysisGroupData(data) { + return request({ + url: "/lb/unit-price-analysis/getGroupData", + method: "post", + data: data, + }); +} +export function getUnitPriceAnalysisBaseData(data) { + return request({ + url: "/lb/unit-price-analysis/getBaseData", + method: "post", + data: data, + }); +} + +export function getProfitAnalysisManageList(data) { + return request({ + url: "/lb/profit-analysis/manageList", + method: "post", + data: data, + }); +} + +export function getProfitAnalysisTotalList(data) { + return request({ + url: "/lb/profit-analysis/profitTotalList", + method: "post", + data: data, + }); +} +export function getCostAnalysisData(data) { + return request({ + url: "/lb/cost-analysis/XXCostList2", + method: "post", + data: data, + }); +} + +export function getSingleMaterialAnalysis(data) { + return request({ + url: "/lb/cost-analysis/singleMaterialAnalysis", + method: "post", + data: data, + }); +} +export function getSingleMaterialCostAnalysis(data) { + return request({ + url: "/lb/cost-analysis/singleMaterialCostAnalysis", + method: "post", + data: data, + }); +} diff --git a/src/views/home/components/Header.vue b/src/views/home/components/Header.vue index 82c397d1..0c5848fb 100644 --- a/src/views/home/components/Header.vue +++ b/src/views/home/components/Header.vue @@ -8,9 +8,9 @@
-
+
@@ -188,7 +188,7 @@ export default { height: 117px; width: 100%; display: flex; - justify-content: space-around; + justify-content: space-between; background: url('../../../assets/img/topTitle.png') no-repeat; background-size: cover; background-position: 0 0; @@ -339,7 +339,7 @@ export default { display: flex; flex-direction: column; margin-top: 12px; - margin-right: 4px; + margin-right: 16px; gap: 20px; } diff --git a/src/views/home/components/changeBase.vue b/src/views/home/components/changeBase.vue index 0f5a9c8c..8defd54f 100644 --- a/src/views/home/components/changeBase.vue +++ b/src/views/home/components/changeBase.vue @@ -26,52 +26,52 @@ import bgBaseTongcheng from '@/assets/images/bgBase/桐城.png'; import bgBaseLuoyang from '@/assets/images/bgBase/洛阳.png'; import bgBaseHefei from '@/assets/images/bgBase/合肥.png'; import bgBaseSuqian from '@/assets/images/bgBase/宿迁.png'; -import bgBaseQinhuangdao from '@/assets/images/bgBase/秦皇岛.png'; +import bgBaseQinhuangdao from '@/assets/images/bgBase/秦皇岛.png';// 补充:江苏 export default { name: "BaseSelector", props: { factory: { - type: Number, - default: 1, // 默认选中宜兴(序号1) - validator: (val) => val >= 1 && val <= 8 // 校验序号范围 + type: [String, Number], + default: 5, // 新映射中“宜兴”对应序号7 + validator: (val) => [5, 2, 7, 3, 8, 9, 10].includes(val) // 校验序号范围(匹配新的baseNameToIndexMap) } }, data() { return { - activeButton: 0, // 初始化默认选中索引0(宜兴) - buttonList: ['宜兴', '漳州', '自贡', '桐城', '洛阳', '合肥', '宿迁', '秦皇岛'], + activeButton: 5, // 初始化默认选中索引2(对应buttonList中的“宜兴”) + buttonList: ['合肥', '桐城', '宜兴', '自贡', '漳州', '洛阳', '秦皇岛', '宿迁'], // 匹配截图顺序 imgMap: { base: { - 宜兴: baseYixing, - 漳州: baseZhangzhou, - 自贡: baseZigong, - 桐城: baseTongcheng, - 洛阳: baseLuoyang, 合肥: baseHefei, - 宿迁: baseSuqian, - 秦皇岛: baseQinhuangdao + 桐城: baseTongcheng, + 宜兴: baseYixing, + 自贡: baseZigong, + 漳州: baseZhangzhou, + 洛阳: baseLuoyang, + 秦皇岛: baseQinhuangdao, + 宿迁: baseSuqian }, bgBase: { - 宜兴: bgBaseYixing, - 漳州: bgBaseZhangzhou, - 自贡: bgBaseZigong, - 桐城: bgBaseTongcheng, - 洛阳: bgBaseLuoyang, 合肥: bgBaseHefei, - 宿迁: bgBaseSuqian, - 秦皇岛: bgBaseQinhuangdao + 桐城: bgBaseTongcheng, + 宜兴: bgBaseYixing, + 自贡: bgBaseZigong, + 漳州: bgBaseZhangzhou, + 洛阳: bgBaseLuoyang, + 秦皇岛: bgBaseQinhuangdao, + 宿迁: bgBaseSuqian } }, - baseNameToIndex: { - 宜兴: 1, - 漳州: 2, + baseNameToIndexMap: { // 新的名称→序号映射 + 宜兴: 7, + 漳州: 8, 自贡: 3, - 桐城: 4, - 洛阳: 5, - 合肥: 6, - 宿迁: 7, - 秦皇岛: 8 + 桐城: 2, + 洛阳: 9, + 合肥: 5, + 秦皇岛: 10, // 补充 + 宿迁: 6 // 补充 } }; }, @@ -79,20 +79,20 @@ export default { // 监听父组件传递的factory变化,同步本地选中索引 factory: { handler(newVal) { - // 强制转换为数字,避免非数字值导致错误 - const val = Number(newVal); - if (val >= 1 && val <= 8) { - this.activeButton = val - 1; // 序号1→索引0(宜兴) - } else { - this.activeButton = 0; // 非法值默认选中宜兴 - } + // 根据新的baseNameToIndexMap,找到对应的基地名称 + const targetName = Object.keys(this.baseNameToIndexMap).find(name => this.baseNameToIndexMap[name] === newVal); + // 根据名称找到buttonList中的索引 + const targetIndex = this.buttonList.indexOf(targetName); + // 合法索引则更新,否则默认选中宜兴 + this.activeButton = targetIndex > -1 ? targetIndex : 2; console.log('当前选中基地:', this.buttonList[this.activeButton], '序号:', newVal); }, immediate: true // 初始化立即执行 }, // 监听本地选中索引变化,向父组件发送事件 activeButton(newVal) { - const selectedIndex = newVal + 1; // 索引0→序号1 + const selectedName = this.buttonList[newVal]; + const selectedIndex = this.baseNameToIndexMap[selectedName] || 5; // 默认返回宜兴的序号7 this.$emit('baseChange', selectedIndex); } }, @@ -101,12 +101,12 @@ export default { this.activeButton = index; }, getIndexByName(name) { - return this.baseNameToIndex[name] || 1; + return this.baseNameToIndexMap[name] || 5; } }, mounted() { - // 修复:初始化时触发事件,传递默认选中的宜兴序号(1) - this.$emit('baseChange', 1); + // 初始化时触发事件,传递默认选中的宜兴序号(7) + this.$emit('baseChange', 5); } }; @@ -126,7 +126,7 @@ export default { text-align: center; cursor: pointer; white-space: nowrap; - margin-right: -35px; + margin-right: -35px; // 重叠效果,可根据需求调整 transition: all 0.2s ease; &:hover, diff --git a/src/views/home/components/coresBar.vue b/src/views/home/components/coresBar.vue index 289ce516..a1682b6c 100644 --- a/src/views/home/components/coresBar.vue +++ b/src/views/home/components/coresBar.vue @@ -118,11 +118,11 @@ export default { } ], yAxis: { - type: 'value', + // type: 'value', nameTextStyle: { color: 'rgba(0, 0, 0, 0.45)', fontSize: 14, align: 'left' }, // min: () => 0, // max: (value) => Math.ceil(value.max), - // scale: true, + scale: true, axisTick: { show: false }, axisLabel: { color: 'rgba(0, 0, 0, 0.45)', fontSize: 12 }, splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, diff --git a/src/views/home/components/purchase-Item.vue b/src/views/home/components/purchase-Item.vue index 2629b9b2..8707aeb1 100644 --- a/src/views/home/components/purchase-Item.vue +++ b/src/views/home/components/purchase-Item.vue @@ -54,50 +54,37 @@ export default { name: "Container", components: {}, - props: ["finance",'dateData'], + props: { + finance: { + type: Object, + default: () => ({}) // 明确props默认值为空对象 + }, + dateData: { + type: Object, + default: () => ({}) + } + }, data() { return { - // itemList: [ - // { - // name: "营业收入·万元", - // targetValue: 16, - // currentValue: 17.2, // 大于目标值(绿色) - // progress: 107.5, - // route: 'operatingRevenue' - // }, - // { - // name: "经营性利润·万元", - // targetValue: 16, - // currentValue: 16, // 等于目标值(绿色) - // progress: 100, - // route: 'profitAnalysis' - // }, - // { - // name: "利润总额·万元", - // targetValue: 16, - // currentValue: 14.8, // 小于目标值(黄色) - // progress: 92.5, - // route: 'profitAnalysis' - // }, - // { - // name: "毛利率·%", - // targetValue: 16, - // currentValue: 15.5, // 小于目标值(黄色) - // progress: 96.875, - // route: 'profitAnalysis' - // } - // ] + // 关键修复1:初始化itemList为空数组(必选,否则初始状态下v-for报错且数据无法响应式更新) + itemList: [] }; }, watch: { finance: { handler(newVal) { - if (newVal) { + // 关键修复2:增强数据判断,避免空值/无效值触发错误 + if (newVal && Object.keys(newVal).length > 0) { + // 转换数据并赋值给itemList(响应式更新) this.itemList = this.transformData(newVal); + console.log('finance更新,itemList已同步', this.itemList); + } else { + // 当finance为空时,重置itemList为空数组 + this.itemList = []; } }, - immediate: true, - deep: true + immediate: true, // 组件挂载时立即执行,初始化数据 + deep: true // 深度监听finance对象内部属性变化 } }, methods: { @@ -112,13 +99,18 @@ export default { // 遍历映射关系,转换数据 return Mapping.map(mappingItem => { + // 关键修复3:兜底更严谨,避免rawData[mappingItem.key]不存在导致报错 const data = rawData[mappingItem.key] || { rate: 0, real: 0, target: 0 }; + // 额外兜底:避免data中的属性为undefined + const target = data.target || 0; + const real = data.real || 0; + const rate = data.rate || 0; return { name: mappingItem.name, - targetValue: data.target, - currentValue: data.real, - progress: Math.round(data.rate), // 将小数率转换为百分比并四舍五入 + targetValue: target, + currentValue: real, + progress: Math.round(rate), // 将小数率转换为百分比并四舍五入 route: mappingItem.route }; }); @@ -128,9 +120,10 @@ export default { this.$router.push({ path: route, query: { - dateData: this.dateData + // 关键修复4:dateData是对象,需序列化后传递(否则路由query无法正常接收对象) + dateData: JSON.stringify(this.dateData) } - }); + }); } } } @@ -254,7 +247,7 @@ export default { /* 进度条 - 实际值≥目标值(绿色) */ .bar-exceed { - background:rgba(98, 213, 180, 1) !important; + background: rgba(98, 213, 180, 1) !important; opacity: 1 !important; } diff --git a/src/views/home/expenseAnalysis/expenseAnalysisBase.vue b/src/views/home/expenseAnalysis/expenseAnalysisBase.vue index a87caf10..9294ca02 100644 --- a/src/views/home/expenseAnalysis/expenseAnalysisBase.vue +++ b/src/views/home/expenseAnalysis/expenseAnalysisBase.vue @@ -185,7 +185,7 @@ export default { this.beilv = _this.clientWidth / 1920; })(); }; - this.factory = this.$route.query.factory ? this.$route.query.factory : this.factory + this.factory = this.$route.query.factory ? Number(this.$route.query.factory) : this.factory }, methods: { handleChange(value) { diff --git a/src/views/home/expenseAnalysisComponents/dataTrend.vue b/src/views/home/expenseAnalysisComponents/dataTrend.vue index 2782a541..920febea 100644 --- a/src/views/home/expenseAnalysisComponents/dataTrend.vue +++ b/src/views/home/expenseAnalysisComponents/dataTrend.vue @@ -129,10 +129,8 @@ export default { */ getRateFlag(rate) { if (isNaN(rate) || rate === null || rate === undefined) return 0; - // 原始rate若为小数(如0.8 → 80%,1.1 → 110%),则*100后判断 - const ratePercent = rate; - return ratePercent >= 100 ? 1 : 0; - } + return +(rate >= 100 || rate === 0); // + 号将布尔值转为数字(true→1,false→0) + }, }, }; diff --git a/src/views/home/expenseAnalysisComponents/monthlyRelatedMetrics.vue b/src/views/home/expenseAnalysisComponents/monthlyRelatedMetrics.vue index 6d973838..3eb08e75 100644 --- a/src/views/home/expenseAnalysisComponents/monthlyRelatedMetrics.vue +++ b/src/views/home/expenseAnalysisComponents/monthlyRelatedMetrics.vue @@ -86,7 +86,7 @@ export default { // 达标标识判断(≥100返回1,<100返回0) getRateFlag(rate) { if (isNaN(rate) || rate === null || rate === undefined) return 0; - return rate >= 100 ? 1 : 0; + return +(rate >= 100 || rate === 0); // + 号将布尔值转为数字(true→1,false→0) }, // 处理费用数据 diff --git a/src/views/home/expenseAnalysisComponents/operatingLineBarSale.vue b/src/views/home/expenseAnalysisComponents/operatingLineBarSale.vue index b3f3d2cf..e7ec0eb7 100644 --- a/src/views/home/expenseAnalysisComponents/operatingLineBarSale.vue +++ b/src/views/home/expenseAnalysisComponents/operatingLineBarSale.vue @@ -13,14 +13,14 @@ export default { resizeHandler: null, // 存储resize事件处理函数 // 核心:基地名称与序号的映射表(固定顺序) baseNameToIndexMap: { - '宜兴': 1, - '漳州': 2, + '宜兴': 7, + '漳州': 8, '自贡': 3, - '桐城': 4, - '洛阳': 5, - '合肥': 6, - '宿迁': 7, - '秦皇岛': 8 + '桐城': 2, + '洛阳': 9, + '合肥': 5, + '宿迁': 6, + '秦皇岛': 10 } }; }, diff --git a/src/views/home/expenseAnalysisComponents/operatingLineChart.vue b/src/views/home/expenseAnalysisComponents/operatingLineChart.vue index 3c30d9ca..efde8896 100644 --- a/src/views/home/expenseAnalysisComponents/operatingLineChart.vue +++ b/src/views/home/expenseAnalysisComponents/operatingLineChart.vue @@ -85,13 +85,10 @@ export default { * @param {number} rate 处理后的rate值(已*100) * @returns {0|1} flag值 */ -getRateFlag(rate) { - // 处理非数字/空值,默认返回 0 - if (isNaN(rate) || rate === null || rate === undefined) return 0; - // 核心逻辑:≥100 → 1;<100 → 0 - return rate >= 100 ? 1 : 0; -}, - + getRateFlag(rate) { + if (isNaN(rate) || rate === null || rate === undefined) return 0; + return +(rate >= 100 || rate === 0); // + 号将布尔值转为数字(true→1,false→0) + }, /** * 核心处理函数:在所有数据都准备好后,才组装 chartData */ diff --git a/src/views/home/expenseAnalysisComponents/operatingLineChartCumulative.vue b/src/views/home/expenseAnalysisComponents/operatingLineChartCumulative.vue index c3e41d2e..29b35069 100644 --- a/src/views/home/expenseAnalysisComponents/operatingLineChartCumulative.vue +++ b/src/views/home/expenseAnalysisComponents/operatingLineChartCumulative.vue @@ -79,13 +79,10 @@ export default { * @param {number} rate 处理后的rate值(已*100) * @returns {0|1} flag值 */ -getRateFlag(rate) { - // 处理非数字/空值,默认返回 0 - if (isNaN(rate) || rate === null || rate === undefined) return 0; - // 核心逻辑:≥100 → 1;<100 → 0 - return rate >= 100 ? 1 : 0; -}, - + getRateFlag(rate) { + if (isNaN(rate) || rate === null || rate === undefined) return 0; + return +(rate >= 100 || rate === 0); // + 号将布尔值转为数字(true→1,false→0) + }, /** * 核心处理函数:在所有数据都准备好后,才组装 chartData */ diff --git a/src/views/home/expenseAnalysisComponents/verticalBarChart.vue b/src/views/home/expenseAnalysisComponents/verticalBarChart.vue index fb6aef94..b3b0bdd9 100644 --- a/src/views/home/expenseAnalysisComponents/verticalBarChart.vue +++ b/src/views/home/expenseAnalysisComponents/verticalBarChart.vue @@ -43,6 +43,10 @@ export default { } }, methods: { + getRateFlag(rate) { + if (isNaN(rate) || rate === null || rate === undefined) return 0; + return +(rate >= 100 || rate === 0); // + 号将布尔值转为数字(true→1,false→0) + }, updateChart() { const chartDom = this.$refs[this.refName]; if (!chartDom) { @@ -57,6 +61,8 @@ export default { this.myChart = echarts.init(chartDom); const diff = this.detailData.diff || 0 const rate = this.detailData.rate || 0 + const flagValue = this.getRateFlag(this.detailData.rate) || 0 + const option = { tooltip: { trigger: 'axis', @@ -198,18 +204,25 @@ export default { } }, itemStyle: { - // 实际的渐变颜色(绿系渐变,与预算区分) - color: { - type: 'linear', - x: 0, y: 0, x2: 0, y2: 1, - colorStops: [ - { offset: 0, color: '#AEEFE0' }, // 浅绿 - { offset: 1, color: '#76DABE' } // 深绿 - ] - }, - borderRadius: [4, 4, 0, 0], - borderWidth: 0, - }, + color: flagValue === 1 + ? { + type: 'linear', + x: 0, y: 0, x2: 0, y2: 1, + colorStops: [ + { offset: 0, color: 'rgba(174, 239, 224, 1)' }, + { offset: 1, color: 'rgba(118, 218, 190, 1)' } + ] + } + : { + type: 'linear', + x: 0, y: 0, x2: 0, y2: 1, + colorStops: [ + { offset: 0, color: 'rgba(253, 209, 129, 1)' }, + { offset: 1, color: 'rgba(249, 164, 74, 1)' } + ] + }, + borderRadius: [4, 4, 0, 0] + } }, { value: this.detailData.target, label: { diff --git a/src/views/home/expenseAnalysisComponents/yearRelatedMetrics.vue b/src/views/home/expenseAnalysisComponents/yearRelatedMetrics.vue index ccc6c992..ad0f68c4 100644 --- a/src/views/home/expenseAnalysisComponents/yearRelatedMetrics.vue +++ b/src/views/home/expenseAnalysisComponents/yearRelatedMetrics.vue @@ -86,7 +86,7 @@ export default { // 达标标识判断(≥100返回1,<100返回0) getRateFlag(rate) { if (isNaN(rate) || rate === null || rate === undefined) return 0; - return rate >= 100 ? 1 : 0; + return +(rate >= 100 || rate === 0); // + 号将布尔值转为数字(true→1,false→0) }, // 处理费用数据 diff --git a/src/views/home/fullCostAnalysis/fullCostAnalysis.vue b/src/views/home/fullCostAnalysis/fullCostAnalysis.vue index 4f6fd097..8d7045e5 100644 --- a/src/views/home/fullCostAnalysis/fullCostAnalysis.vue +++ b/src/views/home/fullCostAnalysis/fullCostAnalysis.vue @@ -16,7 +16,7 @@ gap: 12px; grid-template-columns:1624px; "> - +
@@ -25,7 +25,7 @@ gap: 12px; grid-template-columns: 1624px; "> - +
@@ -50,7 +50,7 @@ import { mapState } from "vuex"; import operatingLineChart from "../fullCostAnalysisComponents/operatingLineChart"; import operatingLineChartCumulative from "../fullCostAnalysisComponents/operatingLineChartCumulative.vue"; -import { getSalesRevenueData } from '@/api/cockpit' +import { getUnitPriceAnalysisGroupData } from '@/api/cockpit' import moment from "moment"; export default { name: "DayReport", @@ -68,11 +68,9 @@ export default { timer: null, beilv: 1, value: 100, - saleData: {}, - premiumProduct: {}, - salesTrendMap: {}, - grossMarginTrendMap: {}, - salesProportion:{}, + selectDate: {}, + thisMonData: {}, + totalData: {}, }; }, @@ -141,22 +139,27 @@ export default { }, methods: { getData(obj) { - getSalesRevenueData({ - startTime: obj.startTime, - endTime: obj.endTime, - timeDim: obj.mode + getUnitPriceAnalysisGroupData({ + startTime: this.selectDate.startTime, + endTime: this.selectDate.endTime, + paramName: '全成本' + // timeDim: this.selectDate.mode }).then((res) => { console.log(res); - this.saleData = res.data.SaleData - this.premiumProduct = res.data.premiumProduct - this.salesTrendMap = res.data.salesTrendMap - this.grossMarginTrendMap = res.data.grossMarginTrendMap - this.salesProportion = res.data.salesProportion ? res.data.salesProportion : {} + this.thisMonData = res.data.thisMonData + this.totalData = res.data.totalData + + // this.saleData = res.data.SaleData + // this.premiumProduct = res.data.premiumProduct + // this.salesTrendMap = res.data.salesTrendMap + // this.grossMarginTrendMap = res.data.grossMarginTrendMap + // this.salesProportion = res.data.salesProportion ? res.data.salesProportion : {} }) }, handleTimeChange(obj) { - console.log(obj, 'obj'); - this.getData(obj) + // console.log(obj, 'obj'); + this.selectDate = obj + this.getData() }, handleClickOutside() { this.$store.dispatch("app/closeSideBar", { withoutAnimation: false }); @@ -228,12 +231,14 @@ export default { - - + diff --git a/src/views/home/fullCostAnalysisComponents/dataTrendBar.vue b/src/views/home/fullCostAnalysisComponents/dataTrendBar.vue index 8066853d..83ff8013 100644 --- a/src/views/home/fullCostAnalysisComponents/dataTrendBar.vue +++ b/src/views/home/fullCostAnalysisComponents/dataTrendBar.vue @@ -28,7 +28,7 @@
- 展示顺序 + 类目选择