diff --git a/.env.dev b/.env.dev index 1dab39b1..c8f7babc 100644 --- a/.env.dev +++ b/.env.dev @@ -6,8 +6,8 @@ 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.33.83: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/package.json b/package.json index b49478d6..96caca06 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "benz-amr-recorder": "^1.1.5", "bpmn-js-token-simulation": "0.10.0", "clipboard": "2.0.8", + "code-brick-zj": "^1.1.1", "core-js": "^3.26.0", "crypto-js": "^4.0.0", "echarts": "5.4.0", diff --git a/src/api/cockpit.js b/src/api/cockpit.js index a65b0995..44a1ddb8 100644 --- a/src/api/cockpit.js +++ b/src/api/cockpit.js @@ -76,3 +76,121 @@ export function getOrderDetail(data) { }); } +export function getDataBackUp(data) { + return request({ + url: "/lb/data-backup/page", + method: "post", + data: data, + }); +} + +export function recoverDataBackUp(data) { + return request({ + url: "/lb/data-backup/recover", + method: "post", + data: data, + }); +} + +// 导出Banner Excel +export function exportDataBackUp(data) { + return request({ + url: "/lb/data-backup/export-excel", + method: "post", + data: data, + responseType: "blob", + }); +} +export function getDataBackUpDetail(data) { + return request({ + url: "/lb/data-backup/get", + method: "post", + data: data, + }); +} + +export function updateDataBackUpDetail(data) { + return request({ + url: "/lb/data-backup/update", + method: "post", + data: data, + }); +} + + +export function getSalesRevenueGroupData(data) { + return request({ + url: "/lb/sales-revenue/getGroupData", + method: "post", + data: data, + }); +} + +export function getGrossMarginGroupData(data) { + return request({ + url: "/lb/gross-margin/getGroupData", + method: "post", + data: data, + }); +} + +export function getExpenseAnalysisGroupData(data) { + return request({ + url: "/lb/expense-analysis/getGroupData", + method: "post", + data: data, + }); +} + +export function getSheetYieldGroupData(data) { + return request({ + url: "/lb/sheet-yield/getGroupData", + method: "post", + data: data, + }); +} + +export function getInputOutputRateGroupData(data) { + return request({ + url: "/lb/input-output-rate/getGroupData", + method: "post", + data: data, + }); +} +export function getSalesRevenueFactoryData(data) { + return request({ + url: "/lb/sales-revenue/getFactoryData", + method: "post", + data: data, + }); +} +export function getExpenseAnalysisFactoryData(data) { + return request({ + url: "/lb/expense-analysis/getFactoryData", + method: "post", + data: data, + }); +} +export function getGrossMarginFactoryData(data) { + return request({ + url: "/lb/gross-margin/getFactoryData", + method: "post", + data: data, + }); +} + +export function getSheetYieldFactoryData(data) { + return request({ + url: "/lb/sheet-yield/getFactoryData", + method: "post", + data: data, + }); +} + +export function getInputOutputRateFactoryData(data) { + return request({ + url: "/lb/input-output-rate/getFactoryData", + method: "post", + data: data, + }); +} diff --git a/src/assets/images/base/合肥.png b/src/assets/images/base/合肥.png new file mode 100644 index 00000000..051c3827 Binary files /dev/null and b/src/assets/images/base/合肥.png differ diff --git a/src/assets/images/base/宜兴.png b/src/assets/images/base/宜兴.png new file mode 100644 index 00000000..57300dd1 Binary files /dev/null and b/src/assets/images/base/宜兴.png differ diff --git a/src/assets/images/base/宿迁.png b/src/assets/images/base/宿迁.png new file mode 100644 index 00000000..4cf4316d Binary files /dev/null and b/src/assets/images/base/宿迁.png differ diff --git a/src/assets/images/base/桐城.png b/src/assets/images/base/桐城.png new file mode 100644 index 00000000..83eaf9a2 Binary files /dev/null and b/src/assets/images/base/桐城.png differ diff --git a/src/assets/images/base/洛阳.png b/src/assets/images/base/洛阳.png new file mode 100644 index 00000000..f0ff18ec Binary files /dev/null and b/src/assets/images/base/洛阳.png differ diff --git a/src/assets/images/base/漳州.png b/src/assets/images/base/漳州.png new file mode 100644 index 00000000..9fcd021e Binary files /dev/null and b/src/assets/images/base/漳州.png differ diff --git a/src/assets/images/base/秦皇岛.png b/src/assets/images/base/秦皇岛.png new file mode 100644 index 00000000..7d1724ee Binary files /dev/null and b/src/assets/images/base/秦皇岛.png differ diff --git a/src/assets/images/base/自贡.png b/src/assets/images/base/自贡.png new file mode 100644 index 00000000..23c65ae4 Binary files /dev/null and b/src/assets/images/base/自贡.png differ diff --git a/src/assets/images/bgBase/合肥.png b/src/assets/images/bgBase/合肥.png new file mode 100644 index 00000000..29291ee6 Binary files /dev/null and b/src/assets/images/bgBase/合肥.png differ diff --git a/src/assets/images/bgBase/宜兴.png b/src/assets/images/bgBase/宜兴.png new file mode 100644 index 00000000..51a26348 Binary files /dev/null and b/src/assets/images/bgBase/宜兴.png differ diff --git a/src/assets/images/bgBase/宿迁.png b/src/assets/images/bgBase/宿迁.png new file mode 100644 index 00000000..0fc88fbd Binary files /dev/null and b/src/assets/images/bgBase/宿迁.png differ diff --git a/src/assets/images/bgBase/桐城.png b/src/assets/images/bgBase/桐城.png new file mode 100644 index 00000000..ae32e57c Binary files /dev/null and b/src/assets/images/bgBase/桐城.png differ diff --git a/src/assets/images/bgBase/洛阳.png b/src/assets/images/bgBase/洛阳.png new file mode 100644 index 00000000..ae9d85af Binary files /dev/null and b/src/assets/images/bgBase/洛阳.png differ diff --git a/src/assets/images/bgBase/漳州.png b/src/assets/images/bgBase/漳州.png new file mode 100644 index 00000000..e2c98c99 Binary files /dev/null and b/src/assets/images/bgBase/漳州.png differ diff --git a/src/assets/images/bgBase/秦皇岛.png b/src/assets/images/bgBase/秦皇岛.png new file mode 100644 index 00000000..ef309444 Binary files /dev/null and b/src/assets/images/bgBase/秦皇岛.png differ diff --git a/src/assets/images/bgBase/自贡.png b/src/assets/images/bgBase/自贡.png new file mode 100644 index 00000000..a54ca822 Binary files /dev/null and b/src/assets/images/bgBase/自贡.png differ diff --git a/src/assets/img/downArrow.png b/src/assets/img/downArrow.png new file mode 100644 index 00000000..5b8425b0 Binary files /dev/null and b/src/assets/img/downArrow.png differ diff --git a/src/assets/img/labelBg.png b/src/assets/img/labelBg.png new file mode 100644 index 00000000..b751b4a5 Binary files /dev/null and b/src/assets/img/labelBg.png differ diff --git a/src/assets/img/opLargeBg.png b/src/assets/img/opLargeBg.png new file mode 100644 index 00000000..bc824b5e Binary files /dev/null and b/src/assets/img/opLargeBg.png differ diff --git a/src/assets/img/operatingRevenueBg.png b/src/assets/img/operatingRevenueBg.png new file mode 100644 index 00000000..5d1e9c63 Binary files /dev/null and b/src/assets/img/operatingRevenueBg.png differ diff --git a/src/assets/img/topArrow.png b/src/assets/img/topArrow.png new file mode 100644 index 00000000..3622b95a Binary files /dev/null and b/src/assets/img/topArrow.png differ diff --git a/src/main.js b/src/main.js index 2e5e2101..b7fcea9a 100644 --- a/src/main.js +++ b/src/main.js @@ -17,6 +17,8 @@ import './tongji' // 百度统计 import { getDicts } from "@/api/system/dict/data"; import { getConfigKey } from "@/api/infra/config"; import { parseTime, resetForm, handleTree, addBeginAndEndTime, divide } from "@/utils/ruoyi"; +import CodeBrickZj from "code-brick-zj"; +Vue.use(CodeBrickZj); import { isEmpty } from "@/utils"; import Pagination from "@/components/Pagination"; // 自定义表格工具扩展 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 23d45b55..f51fb238 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -76,6 +76,20 @@ function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) { } } const needBlankLayout = [ + "/operatingRevenue", + "/totalProfit", + "/operatingProfit", + "/expenseAnalysis", + "/grossMargin", + "/inputOutputRatio", + "/rawSheetYield", + "/productionCostAnalysis", + "/unitPriceAnalysis", + "/netPriceAnalysis", + "/salesVolumeAnalysis", + '/procurementGainAnalysis', + '/fullCostAnalysis', + // '/expenseAnalysis', "/cost", // cost 根路由 "/cost/profitImpactAnalysis", // cost 子菜单(完整路径) ]; diff --git a/src/views/home/components/Header.vue b/src/views/home/components/Header.vue index 9523dc8c..82c397d1 100644 --- a/src/views/home/components/Header.vue +++ b/src/views/home/components/Header.vue @@ -2,7 +2,7 @@
- benmaLogo + benmaLogo
{{ topTitle }}
@@ -24,16 +24,16 @@
-
{{ item.text }} -
+
-->
- 日期选择 + 月份选择
- +
@@ -52,32 +52,32 @@ export default { currentTime: '', timeTimer: null, date: undefined, - activeIndex: -1, + // activeIndex: -1, activeTime: 1, // 0=日,1=月,2=年(默认选中“日”) pageRoutes: [ - { text: '营业收入', path: '/operatingRevenue' }, + { text: '营业收入', path: '/operatingRevenue/operatingRevenueIndex' }, { text: '利润分析', path: '/profitAnalysis' }, { text: '产销率库存分析', path: '/PSIAnal' }, { text: '成本分析', path: '/cost/cost' }, { text: '驾驶舱报表', path: '/cockpit' } ], // 定义时间类型配置:text=按钮文字,pickerType=选择器类型,placeholder=占位符 - timeTypes: [ - { text: '日', pickerType: 'date', placeholder: '选择日期' }, - { text: '月', pickerType: 'month', placeholder: '选择月份' }, - { text: '年', pickerType: 'year', placeholder: '选择年份' } - ] + // timeTypes: [ + // { text: '日', pickerType: 'date', placeholder: '选择日期' }, + // { text: '月', pickerType: 'month', placeholder: '选择月份' }, + // { text: '年', pickerType: 'year', placeholder: '选择年份' } + // ] } }, computed: { - // 动态获取日期选择器类型 - getPickerType() { - return this.timeTypes[this.activeTime].pickerType; - }, - // 动态获取日期选择器占位符 - getPickerPlaceholder() { - return this.timeTypes[this.activeTime].placeholder; - } + // // 动态获取日期选择器类型 + // getPickerType() { + // return this.timeTypes[this.activeTime].pickerType; + // }, + // // 动态获取日期选择器占位符 + // getPickerPlaceholder() { + // return this.timeTypes[this.activeTime].placeholder; + // } }, methods: { goToPage(path, index) { @@ -93,48 +93,57 @@ export default { * @returns {Object} 包含 start(开始时间)、end(结束时间)、dimension(维度)的区间对象 */ calculateTimeRange() { + // 固定为月维度 + const mode = 2; + // 初始化时间戳为0(兜底值) let startTime = 0; let endTime = 0; - const mode = this.activeTime + 1; // 1=日,2=月,3=年 - const defaultMoment = moment(); // 默认当前时间 + // 存储目标月份(仅数字,如10、12) + let targetMonth = ''; + // 默认当前月份 + const defaultMoment = moment(); - const targetMoment = this.date - ? moment(this.date, this.getPickerType === 'date' ? 'YYYY-MM-DD' : (this.getPickerType === 'month' ? 'YYYY-MM' : 'YYYY')) - : defaultMoment; + try { + // 仅处理月份维度:固定使用YYYY-MM格式解析日期 + let targetMoment = this.date + ? moment(this.date, 'YYYY-MM') // 解析传入的月份(如"2025-10") + : defaultMoment; - if (!targetMoment.isValid()) { - console.error('无效日期:', this.date); - return { startTime, endTime, mode }; - } + // 验证日期是否有效,无效则使用当前月份兜底 + if (!targetMoment.isValid()) { + console.warn('无效的月份格式(请使用YYYY-MM),已使用当前月份:', this.date); + targetMoment = defaultMoment; + } - // 1. 日维度:00:00:00 → 23:59:59(无毫秒) - if (this.activeTime === 0) { - startTime = targetMoment.startOf('day').millisecond(0).valueOf(); - endTime = targetMoment.endOf('day').millisecond(0).valueOf(); - } + // 仅获取月份(数字格式,如10、12;若要两位格式如01、10,使用'MM') + targetMonth = targetMoment.format('M'); // 'M'是1-12,'MM'是01-12,可按需选择 - // 2. 月维度:当月1日00:00:00 → 当月最后一天23:59:59(无毫秒) - else if (this.activeTime === 1) { + // 打印仅含月份的结果 + console.log('targetMonth', targetMonth); + + // 计算当月第一天00:00:00(去掉毫秒)的毫秒级时间戳 startTime = targetMoment.startOf('month').millisecond(0).valueOf(); + // 计算当月最后一天23:59:59(去掉毫秒)的毫秒级时间戳 endTime = targetMoment.endOf('month').millisecond(0).valueOf(); + + // 【可选】调试输出:查看时间范围详情 + // console.log('月份时间范围:', { + // startTime: moment(startTime).format('YYYY-MM-DD HH:mm:ss'), + // endTime: moment(endTime).format('YYYY-MM-DD HH:mm:ss'), + // startTimeStamp: startTime, + // endTimeStamp: endTime + // }); + } catch (error) { + console.error('计算月份时间范围时出错:', error); } - // 3. 年维度:当年1月1日00:00:00 → 当年最后一天23:59:59(无毫秒) - else if (this.activeTime === 2) { - startTime = targetMoment.startOf('year').millisecond(0).valueOf(); - endTime = targetMoment.endOf('year').millisecond(0).valueOf(); - } - - // 调试输出:验证是否去掉毫秒 - console.log('时间范围计算结果:', { + // 返回月份相关的所有信息:时间戳、维度、仅月份值 + return { + startTime, + endTime, mode, - startTime: moment(startTime * 1000).format('YYYY-MM-DD HH:mm:ss'), // 格式:2025-11-30 00:00:00 - endTime: moment(endTime * 1000).format('YYYY-MM-DD HH:mm:ss'), // 格式:2025-11-30 23:59:59(无毫秒) - startTimeStamp: startTime, // 秒级时间戳(如:1764422400) - endTimeStamp: endTime // 秒级时间戳(如:1764508799) - }); - - return { startTime, endTime, mode }; + targetMonth // 现在仅为月份数字,如"10" + }; }, /** * 核心方法2:传递时间区间给父组件(首次进入时触发,传递“当月第一天0点→次月第一天0点”) @@ -305,7 +314,7 @@ export default { } .dateP .label { - width: 70px; + width: 165px; height: 28px; background: rgba(236, 244, 254, 1); transform: skew(-25deg); @@ -356,7 +365,7 @@ export default { ::v-deep .custom-date-picker { position: absolute; right: 8px; - width: 132px !important; + width: 165px !important; height: 28px !important; position: relative; margin: 0 !important; @@ -364,7 +373,7 @@ export default { /* 1. 调整输入框文字:确保行高与输入框高度一致,垂直居中 */ .el-input__inner { height: 28px !important; - width: 132px !important; + width: 165px !important; text-align: center; padding-left: 15px !important; padding-right: 32px !important; diff --git a/src/views/home/components/changeBase.vue b/src/views/home/components/changeBase.vue new file mode 100644 index 00000000..0f5a9c8c --- /dev/null +++ b/src/views/home/components/changeBase.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/src/views/home/components/container.vue b/src/views/home/components/container.vue index f3875d5a..f0b55d03 100644 --- a/src/views/home/components/container.vue +++ b/src/views/home/components/container.vue @@ -8,6 +8,16 @@ {{ name }} +
+ +
+ 月度 +
+ +
+ 累计 +
+
@@ -22,12 +32,22 @@ export default { name: 'Container', components: {}, // eslint-disable-next-line vue/require-prop-types - props: ['name', 'size', 'icon', 'topSize'], + props: ['name', 'size', 'icon', 'topSize','isShowTab'], data() { - return {}; + return { + activeTab: 'month' // 初始化激活的Tab(支持父组件传默认值) + }; }, computed: {}, - methods: {}, + methods: { + handleTabClick(tabType) { + this.activeTab = tabType; + // 向父组件派发Tab切换事件,传递当前选中的Tab类型 + this.$emit('tabChange', tabType); + // 可选:同时传递更详细的信息(如标签名) + // this.$emit('tabChange', { type: tabType, name: tabType === 'month' ? '月度' : '累计' }); + }, + }, }; @@ -43,35 +63,37 @@ export default { .content-top { height: 60px; -.title-wrapper { - display: flex; - align-items: center; - margin-left: 10px; - /* 垂直居中关键属性 */ - height: 100%; - /* 继承父容器高度,确保垂直居中范围 */ - } - .title-icon { - font-size: 30px; - margin-right: 12px; - margin-top: 4px; - /* 图标和文字之间的间距 */ - flex-shrink: 0; - /* 防止图标被压缩 */ - } + .title-wrapper { + display: flex; + align-items: center; + margin-left: 10px; + /* 垂直居中关键属性 */ + height: 100%; + /* 继承父容器高度,确保垂直居中范围 */ + } + + .title-icon { + font-size: 30px; + margin-right: 12px; + margin-top: 4px; + /* 图标和文字之间的间距 */ + flex-shrink: 0; + /* 防止图标被压缩 */ + } + + .title-text { + font-family: PingFangSC, PingFang SC; + font-weight: 400; + font-size: 24px; + color: #000000; + letter-spacing: 3px; + text-align: left; + font-style: normal; + // 移除固定行高,避免影响垂直对齐 + // line-height: 60px; + } - .title-text { - font-family: PingFangSC, PingFang SC; - font-weight: 400; - font-size: 24px; - color: #000000; - letter-spacing: 3px; - text-align: left; - font-style: normal; - // 移除固定行高,避免影响垂直对齐 - // line-height: 60px; - } // width: 547px; // background: url(../../../assets/img/contentTopBasic.png) no-repeat; // background-size: 100% 100%; @@ -106,11 +128,12 @@ export default { background-size: 100% 100%; background-position: 0 0; } - &__rawTopTitleLarge { - background: url(../../../assets/img/rawTopTitleLarge.png) no-repeat; - background-size: 100% 100%; - background-position: 0 0; - } + + &__rawTopTitleLarge { + background: url(../../../assets/img/rawTopTitleLarge.png) no-repeat; + background-size: 100% 100%; + background-position: 0 0; + } } @@ -167,11 +190,19 @@ export default { background-size: 100% 100%; background-position: 0 0; } - &__rawTopBg { - background: url(../../../assets/img/rawTopBg.png) no-repeat; - background-size: 100% 100%; - background-position: 0 0; - } + + &__rawTopBg { + background: url(../../../assets/img/rawTopBg.png) no-repeat; + background-size: 100% 100%; + background-position: 0 0; + } + + &__opLargeBg { + background: url(../../../assets/img/opLargeBg.png) no-repeat; + background-size: 100% 100%; + background-position: 0 0; + } + // &__left { // background: url(../../../../../../../assets/img/left.png) no-repeat; // background-size: 100% 100%; @@ -262,4 +293,41 @@ export default { .container-body { flex: 1; } +.tab-group { + display: inline-flex; + position: absolute; + right: 5%; + top: 10%; + z-index: 9999; + align-items: center; + border-radius: 24px; + overflow: hidden; + gap: 8px; // Tab之间的间距 +} + +// Tab基础样式(统一) +.tab-item { + padding: 0 24px; + width: 79px; + height: 24px; + line-height: 24px; + font-size: 12px; + cursor: pointer; + text-align: center; + border-radius: 12px; + transition: all 0.2s ease; // 样式切换动画 +} + +// 未激活的Tab样式(原first-child样式) +.tab-item:not(.active) { + background: #ECF4FE; + color: #0B58FF; +} + +// 激活的Tab样式(原last-child样式) +.tab-item.active { + background: #3071FF; + color: #F9FCFF; + font-weight: bold; +} diff --git a/src/views/home/components/core-bottom-leftItem.vue b/src/views/home/components/core-bottom-leftItem.vue index 2b1c3764..609251df 100644 --- a/src/views/home/components/core-bottom-leftItem.vue +++ b/src/views/home/components/core-bottom-leftItem.vue @@ -1,6 +1,6 @@