Compare commits

...

21 Commits

Author SHA1 Message Date
f208c3c744 路由跳转逻辑bug修复 2026-03-30 09:27:47 +08:00
b05d42cfc8 3.27修改入参及数据获取字段变更 2026-03-30 08:49:16 +08:00
9b0a768216 指标和预算填报删除指标类型 2026-03-27 08:36:02 +08:00
ee4fdbd45b 修改icon提示 2026-03-20 10:25:15 +08:00
5465a43bcc 去掉默认的账密 2026-03-19 09:13:27 +08:00
2465f89d26 集团页面默认值 2026-03-16 15:16:16 +08:00
09c7fd1f63 修复切换展示顺序,完成率不一起切换的问题 2026-03-13 15:42:39 +08:00
195979b3e0 需改样式,图表右侧缩进 2026-03-13 14:47:54 +08:00
0e6caec8d8 样坏修改 2026-03-13 14:03:58 +08:00
acc327212e 修改 2026-03-13 10:11:42 +08:00
dd1f639c77 集团页面左侧图样式修改 2026-03-13 10:02:23 +08:00
b36acbf1e6 制造成本分析下所有单项页面修改 2026-03-13 09:44:43 +08:00
660bc4b58b 修改bug 2026-03-12 15:07:18 +08:00
2a316f89c6 修改禅道bug 2026-03-11 15:59:57 +08:00
4d3b2b13b8 驾驶舱报表&指标填报&接口添加loading 2026-03-11 09:54:39 +08:00
1d5af53e1a 权限跳转修改+预算填报修改 2026-03-10 08:53:03 +08:00
d379d7bb5b 预算填报页面添加字段 2026-03-09 15:35:58 +08:00
418c29095b 页面权限 2026-03-09 15:02:09 +08:00
ef230b3836 登录后跳转到打标页面 2026-03-06 09:28:06 +08:00
9f2f7036fd 增加退出登录 2026-03-05 16:09:07 +08:00
2f3586e2f2 预算&指标填报 2026-03-05 11:12:34 +08:00
252 changed files with 3067 additions and 2085 deletions

View File

@@ -9,7 +9,12 @@ VUE_APP_TITLE = 洛玻集团驾驶舱
# 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'
# 杨姗姗
# VUE_APP_BASE_API = 'http://172.16.20.218:7070'
# 小田
VUE_APP_BASE_API = 'http://172.16.19.232:7070'
# 测试
# VUE_APP_BASE_API = 'http://192.168.0.35:8080'
# 路由懒加载

1
.gitignore vendored
View File

@@ -20,3 +20,4 @@ selenium-debug.log
*.local
package-lock.json
sync_luobo.bat

View File

@@ -117,6 +117,22 @@ export function updateDataBackUpDetail(data) {
});
}
export function copyLastMonthData(data) {
return request({
url: "/lb/index-target-month/copyLastMonth",
method: "post",
data: data,
});
}
export function copyLastYearData(data) {
return request({
url: "/lb/index-target-year/copyLastYear",
method: "post",
data: data,
});
}
export function getSalesRevenueGroupData(data) {
return request({
@@ -254,6 +270,13 @@ export function getCalendar(data) {
data: data,
});
}
export function getCalendarYear(data) {
return request({
url: "lb/index-target-year/getCalendarYear",
method: "post",
data: data,
});
}
export function getLevelStruc(data) {
return request({
url: "/lb/index-target-month/getLevelStruc",

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>切片</title>
<title>全屏</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="01-运营驾驶舱" transform="translate(-1864.000000, -12.000000)" fill="#0B58FF">
<g id="icon/可视化/全屏" transform="translate(1864.000000, 12.000000)">

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g id="组_1" data-name="组 1" transform="translate(-970 -281.875)">
<g id="编辑备份" transform="translate(970 281.5)">
<rect id="矩形" width="16" height="16" transform="translate(0 0.375)" opacity="0"/>
<path id="形状" d="M12.281,5.406a.512.512,0,0,0,1.023,0V2.559A2.559,2.559,0,0,0,10.746,0H2.559A2.559,2.559,0,0,0,0,2.559v8.188A2.559,2.559,0,0,0,2.559,13.3H5.415a.512.512,0,1,0,0-1.023H2.559a1.535,1.535,0,0,1-1.535-1.535V2.559A1.535,1.535,0,0,1,2.559,1.023h8.188a1.535,1.535,0,0,1,1.535,1.535Z" transform="translate(1.535 1.535)" fill="#3d7aff"/>
</g>
<g id="移出" transform="translate(978 290.608)">
<path id="形状结合" d="M0,2.821a.746.746,0,0,0,.529.73l.118.011,3.68-.011L3.459,4.4a.656.656,0,0,0,.816,1.02l.1-.083L6.146,3.6a1.107,1.107,0,0,0,.321-.634l.012-.2,0-.026a.61.61,0,0,0-.015-.125,1.106,1.106,0,0,0-.189-.455l-.107-.129L4.39.2a.656.656,0,0,0-1.022.814L4.23,2.108.654,2.1l-.125.011A.88.88,0,0,0,0,2.821Z" transform="translate(0 0)" fill="#3d7aff"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>展开备份</title>
<title>展开菜单</title>
<g id="12-月修改-2-版" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="01-运营驾驶舱展开" transform="translate(-1818.000000, -12.000000)" fill="#0B58FF">
<g id="展开备份" transform="translate(1818.000000, 12.000000)">
<g id="展开菜单" transform="translate(1818.000000, 12.000000)">
<rect id="矩形" stroke="#0B58FF" opacity="0" x="0.5" y="0.5" width="31" height="31"></rect>
<path d="M26.9054416,1.26315789 L27.1627614,1.2715785 C27.589262,1.29963047 28.0033877,1.39768715 28.3969525,1.56449606 C28.853625,1.75530116 29.2618455,2.03033772 29.6157539,2.38424612 C29.967102,2.73559426 30.2434779,3.1465945 30.4352441,3.6024321 C30.6356746,4.07532525 30.7368421,4.57721075 30.7368421,5.09455843 L30.7368421,26.9054416 L30.7284215,27.1627614 C30.7003695,27.589262 30.6023129,28.0033877 30.4355039,28.3969525 C30.2446988,28.853625 29.9696623,29.2618455 29.6157539,29.6157539 C29.2644057,29.967102 28.8534055,30.2434779 28.3975679,30.4352441 C27.9246748,30.6356746 27.4227892,30.7368421 26.9054416,30.7368421 L5.09455843,30.7368421 L4.83723859,30.7284215 C4.41073802,30.7003695 3.99661229,30.6023129 3.60304751,30.4355039 C3.14637497,30.2446988 2.73815452,29.9696623 2.38424612,29.6157539 C2.03289798,29.2644057 1.75652209,28.8534055 1.56475593,28.3975679 C1.36432537,27.9246748 1.26315789,27.4227892 1.26315789,26.9054416 L1.26315789,5.09455843 L1.2715785,4.83723859 C1.29963047,4.41073802 1.39768715,3.99661229 1.56449606,3.60304751 C1.75530116,3.14637497 2.03033772,2.73815452 2.38424612,2.38424612 C2.73559426,2.03289798 3.1465945,1.75652209 3.6024321,1.56475593 C4.07532525,1.36432537 4.57721075,1.26315789 5.09455843,1.26315789 L26.9054416,1.26315789 Z M26.9054416,3.17216771 L5.09455843,3.17216771 L4.94438644,3.17795455 C3.95326514,3.25463661 3.17216771,4.08386243 3.17216771,5.09455843 L3.17216771,26.9054416 L3.17795455,27.0556136 C3.25463661,28.0467349 4.08386243,28.8278323 5.09455843,28.8278323 L26.9054416,28.8278323 L27.0556136,28.8220454 C28.0467349,28.7453634 28.8278323,27.9161376 28.8278323,26.9054416 L28.8278323,5.09455843 L28.8220454,4.94438644 C28.7453634,3.95326514 27.9161376,3.17216771 26.9054416,3.17216771 Z M29.2015182,9.76714413 L29.2015182,11.8615014 L2.12281432,11.8615014 L2.12281432,9.76714413 L29.2015182,9.76714413 Z" id="形状结合" fill-rule="nonzero" opacity="0.79078311"></path>
</g>

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -1,6 +1,6 @@
<!--?xml version="1.0" encoding="UTF-8"?-->
<svg width="100%" height="100%" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet">
<title>icon/可视化/退出全屏</title>
<title>退出全屏</title>
<g id="00首页" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-1802.000000, -40.000000)" fill="#0B58FF" id="icon/可视化/退出全屏">
<g transform="translate(1802.000000, 40.000000)">

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -143,7 +143,7 @@ h6 {
.pagination-container .el-pagination {
right: 0;
position: absolute;
position: absolute !important;
}
@media (max-width: 768px) {

View File

@@ -9,7 +9,7 @@
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
<div class="avatar-wrapper">
<img :src="avatar" class="user-avatar">
<img :src="require(`../../assets/images/choicepart/avatar.png`)" class="user-avatar">
<span v-if="nickname" class="user-nickname">{{ nickname }}</span>
<i class="el-icon-caret-bottom" />
</div>
@@ -188,7 +188,7 @@ export default {
cursor: pointer;
position: absolute;
right: -20px;
top: 25px;
top: 18px;
font-size: 12px;
}
}

View File

@@ -1,14 +1,14 @@
<template>
<div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
<transition name="sidebarLogoFade">
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
<div v-if="collapse" key="collapse" class="sidebar-logo-link">
<img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
</div>
<div v-else key="expand" class="sidebar-logo-link">
<img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
</router-link>
</div>
</transition>
</div>
</template>

View File

@@ -8,6 +8,46 @@ import { isRelogin } from '@/utils/request'
NProgress.configure({ showSpinner: false })
// 从菜单树中查找第一个可见叶子菜单路径(按接口返回顺序)
function findFirstLeafPathFromMenus(menus) {
if (!Array.isArray(menus) || menus.length === 0) return null
function dfs(list, parentPath = '') {
for (const item of list) {
if (item.visible === false) continue
const rawPath = item.path || ''
const currentPath = rawPath.startsWith('/')
? rawPath
: `${parentPath}/${rawPath}`.replace(/\/+/g, '/')
if (item.children && item.children.length > 0) {
const found = dfs(item.children, currentPath)
if (found != null) return found
} else {
return currentPath
}
}
return null
}
return dfs(menus)
}
function findFirstLeafPathFromRoutes(routes) {
if (!Array.isArray(routes) || routes.length === 0) return null
const stack = [...routes]
while (stack.length) {
const route = stack.shift()
if (!route || route.hidden === true) continue
if (Array.isArray(route.children) && route.children.length > 0) {
stack.unshift(...route.children)
continue
}
const p = route.path || ''
if (typeof p === 'string' && p.startsWith('/') && p !== '/404') {
return p
}
}
return null
}
// 增加三方登陆 update by 芋艿
const whiteList = ['/login', '/social-login', '/auth-redirect', '/bind', '/register', '/oauthLogin/gitee']
@@ -17,21 +57,35 @@ router.beforeEach((to, from, next) => {
to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
/* has token*/
if (to.path === '/login') {
next({ path: '/' })
next({ path: store.getters.defaultPath || '/' })
NProgress.done()
} else {
if (store.getters.roles.length === 0) {
isRelogin.show = true
// 获取字典数据 add by 芋艿
store.dispatch('dict/loadDictDatas')
// 获取部门权限
store.dispatch('GetLevel')
// 判断当前用户是否已拉取完 user_info 信息
store.dispatch('GetInfo').then(userInfo => {
isRelogin.show = false
// 触发 GenerateRoutes 事件时,将 menus 菜单树传递进去
store.dispatch('GenerateRoutes', userInfo.menus).then(accessRoutes => {
store.dispatch('GenerateRoutes', userInfo.menus).then(accessRoutes => {
// 根据 roles 权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
const menuDefaultPath = findFirstLeafPathFromMenus(userInfo.menus)
const routeFallbackPath = findFirstLeafPathFromRoutes(accessRoutes)
const defaultPath = menuDefaultPath || routeFallbackPath || '/'
store.dispatch('SetDefaultPath', defaultPath)
// 仅当目标为根路径 '/' 时跳默认页;否则保持当前路径(含刷新场景),避免刷新被误判为“未匹配”而跳到默认页
if (to.path === '/') {
const matched = router.match(defaultPath)
const hasMatch = matched && Array.isArray(matched.matched) && matched.matched.length > 0
const safePath = hasMatch ? defaultPath : (routeFallbackPath || '/')
next({ path: safePath, replace: true })
} else {
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成当前页刷新时保留 to 的路径
}
})
}).catch(err => {
store.dispatch('LogOut').then(() => {
@@ -40,7 +94,12 @@ router.beforeEach((to, from, next) => {
})
})
} else {
next()
if (to.path === '/') {
const defaultPath = store.getters.defaultPath || '/'
next({ path: defaultPath, replace: true })
} else {
next()
}
}
}
} else {

View File

@@ -64,13 +64,13 @@ export const constantRoutes = [
component: (resolve) => require(["@/views/error/401"], resolve),
hidden: true,
},
{
path: "/",
// component: () => import('@/views/choicePart'),
component: () => import("@/views/home"),
hidden: true,
meta: { requireToken: true },
},
// {
// path: "/",
// // component: () => import('@/views/choicePart'),
// component: () => import("@/views/home"),
// hidden: true,
// meta: { requireToken: true },
// },
// {
// path: "/operatingRevenue",
// // component: () => import('@/views/choicePart'),

View File

@@ -17,7 +17,10 @@ const getters = {
topbarRouters:state => state.permission.topbarRouters,
defaultRoutes:state => state.permission.defaultRoutes,
sidebarRouters:state => state.permission.sidebarRouters,
defaultPath: state => state.permission.defaultPath,
// 数据字典
dict_datas: state => state.dict.dictDatas
dict_datas: state => state.dict.dictDatas,
// 部门层级
levelList: state => state.user.levelList
}
export default getters

View File

@@ -11,8 +11,12 @@ const permission = {
addRoutes: [],
sidebarRouters: [], // 左侧边菜单的路由,被 Sidebar/index.vue 使用
topbarRouters: [], // 顶部菜单的路由,被 TopNav/index.vue 使用
defaultPath: '/', // 登录后默认跳转路径(由菜单 jumpFlag===1 决定)
},
mutations: {
SET_DEFAULT_PATH: (state, path) => {
state.defaultPath = path || '/'
},
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
@@ -48,6 +52,9 @@ const permission = {
commit('SET_TOPBAR_ROUTES', sidebarRoutes)
resolve(rewriteRoutes)
})
},
SetDefaultPath({commit}, path) {
commit('SET_DEFAULT_PATH', path)
}
}
}

View File

@@ -1,5 +1,6 @@
import {login, logout, getInfo, socialLogin, smsLogin} from '@/api/login'
import {setToken, removeToken} from '@/utils/auth'
import {getLevelStruc} from '@/api/cockpit'
const user = {
state: {
@@ -7,7 +8,8 @@ const user = {
name: '',
avatar: '',
roles: [],
permissions: []
permissions: [],
levelList:[]
},
mutations: {
@@ -28,6 +30,9 @@ const user = {
},
SET_PERMISSIONS: (state, permissions) => {
state.permissions = permissions
},
SET_LEVEL_LIST: (state, levelList) => {
state.levelList = levelList
}
},
@@ -122,7 +127,21 @@ const user = {
})
})
},
// 获取层级
GetLevel({ commit, state }) {
return new Promise((resolve, reject) => {
getLevelStruc().then(res => {
// 如果未加载到数据,则直接返回
if (!res || !res.data) {
return;
}
commit('SET_LEVEL_LIST', res.data)
resolve()
})
}).catch(error => {
reject(error)
})
},
// 退出系统
LogOut({ commit, state }) {
return new Promise((resolve, reject) => {

View File

@@ -81,6 +81,9 @@ export const DICT_TYPE = {
PROMOTION_COUPON_TAKE_TYPE: 'promotion_coupon_take_type', // 优惠劵的领取方式
PROMOTION_ACTIVITY_STATUS: 'promotion_activity_status', // 优惠活动的状态
PROMOTION_CONDITION_TYPE: 'promotion_condition_type', // 营销的条件类型枚举
// ========== 模块 ==========
LB_DW: 'lb_dw'
}
/**
@@ -139,3 +142,15 @@ export function getDictDataLabel(dictType, value) {
const dict = getDictData(dictType, value);
return dict ? dict.label : '';
}
// table中用来过滤字典
export function publicFormatter(dictTable) {
const dictDatas = getDictDatas(dictTable)
return function (val) {
const arr = {}
dictDatas.map((item) => {
arr[item.value] = item.label
})
return arr?.[val]
}
}

View File

@@ -1,5 +1,5 @@
import axios from 'axios'
import {Message, MessageBox, Notification} from 'element-ui'
import {Message, MessageBox, Notification, Loading} from 'element-ui'
import store from '@/store'
import {getAccessToken, getRefreshToken, getTenantId, setToken, getVisitTenantId} from '@/utils/auth'
import errorCode from '@/utils/errorCode'
@@ -31,8 +31,36 @@ const service = axios.create({
// 禁用 Cookie 等信息
withCredentials: false,
})
let loadingInstance = null
function startLoading() {
loadingInstance = Loading.service({
fullscreen: false,
text: '拼命加载中...',
background: 'rgba(0, 0, 0, 0.1)'
})
}
function endLoading() {
loadingInstance.close()
}
let needLoadingRequestCount = 0
function showFullScreenLoading() {
if (needLoadingRequestCount === 0) {
startLoading()
}
needLoadingRequestCount++
}
function tryHideFullScreenLoading() {
if (needLoadingRequestCount <= 0) return
needLoadingRequestCount--
if (needLoadingRequestCount === 0) {
endLoading()
}
}
// request拦截器
service.interceptors.request.use(config => {
showFullScreenLoading()
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
if (getAccessToken() && !isToken) {
@@ -88,12 +116,14 @@ service.interceptors.request.use(config => {
}
return config
}, error => {
tryHideFullScreenLoading()
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(async res => {
tryHideFullScreenLoading()
let { data } = res
// 未设置状态码则默认成功状态
// 二进制数据则直接返回,例如说 Excel 导出
@@ -202,6 +232,7 @@ service.interceptors.response.use(async res => {
}
}, error => {
console.log('err' + error)
tryHideFullScreenLoading()
let {message} = error;
if (message === "Network Error") {
message = "后端接口连接异常";

View File

@@ -16,8 +16,8 @@
gap: 12px;
grid-template-columns:416px 1192px;
">
<indicatorCalendar :calendarList="calendarList" />
<indicatorDetails :timeType="timeType" />
<indicatorCalendar :timeType="timeType" :calendarObj='calendarObj'/>
<indicatorDetails :timeType="timeType" @updateLeft='getData' @updateLevel='getLevel'/>
</div>
</div>
<!-- <div class="top" style="margin-top: -20px; display: flex; gap: 16px">
@@ -53,8 +53,9 @@ import { mapState } from "vuex";
// import operatingLineChart from "../operatingComponents/operatingLineChart";
// import operatingLineChartCumulative from "../operatingComponents/operatingLineChartCumulative.vue";
import { getSalesRevenueGroupData, getCalendar } from '@/api/cockpit'
import { getSalesRevenueGroupData } from '@/api/cockpit'
import moment from "moment";
import {getCalendar, getCalendarYear} from '@/api/cockpit';
export default {
name: "DayReport",
components: {
@@ -78,7 +79,8 @@ export default {
selectDate:{},
monthData: {},
ytdData: {},
calendarList:{},
calendarObj:{},
levelId: null
};
},
@@ -144,37 +146,29 @@ export default {
this.beilv = _this.clientWidth / 1920;
})();
};
this.getData()
// this.getData()
},
methods: {
// sortChange(value) {
// this.sort = value
// this.getData()
// },
getData() {
getCalendar().then((res) => {
console.log(res, 'res');
this.calendarList = res.data
// this.monthData = res.data.month
// this.ytdData = res.data.ytd
})
// getSalesRevenueGroupData({
// startTime: this.dateData.startTime,
// endTime: this.dateData.endTime,
// sort: this.sort,
// index: undefined,
// factory: undefined
// // timeDim: obj.mode
// }).then((res) => {
// console.log(res);
// this.monthData= res.data.month
// this.ytdData = res.data.ytd
// })
if(this.timeType == 'month'){
getCalendar({levelId: this.levelId}).then((res) => {
this.calendarObj = res.data
})
}else{
getCalendarYear({levelId: this.levelId}).then((res) => {
this.calendarObj = res.data
})
}
},
// 层级变动
getLevel(id) {
this.levelId = id
this.getData()
},
handleTimeChange(obj) {
console.log(obj, 'obj');
this.timeType = obj
// this.getData()
this.getData()
},
handleClickOutside() {
this.$store.dispatch("app/closeSideBar", { withoutAnimation: false });

View File

@@ -8,6 +8,15 @@
<!-- 右侧区域全屏按钮 -->
<div class="right-content">
<el-dropdown trigger="click">
<el-button type="text" class="logout-btn" :title="'退出'">
<svg-icon style="color: #0B58FF;" icon-class="logout" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native='logout'>退出登录</el-dropdown-item>
<el-dropdown-item @click.native='handleToggle'>切换账号</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-button type="text" class="screen-btn" @click="changeHomeSider">
<svg-icon style="color: #0B58FF;" v-if="openSider" icon-class="closeSider" />
<svg-icon style="color: #0B58FF;" v-else icon-class="openSider" />
@@ -36,6 +45,7 @@
<script>
import moment from 'moment'
import {getPath} from "@/utils/ruoyi";
export default {
name: 'Header',
props: {
@@ -139,6 +149,19 @@ export default {
const timeRange = this.calculateTimeRange();
this.$emit('timeRangeChange', timeRange);
console.log('触发时间范围变化:', timeRange);
},
async logout() {
this.$modal.confirm('确定注销并退出系统吗?', '提示').then(() => {
this.$store.dispatch('LogOut').then(() => {
location.href = getPath('/index');
})
}).catch(() => {});
},
handleToggle() {
this.$store.dispatch('LogOut').then(() => {
location.href = getPath('/index');
})
}
},
watch: {
@@ -325,10 +348,11 @@ export default {
.right-content {
display: flex;
margin-bottom: 60px;
margin-top: 12px;
margin-right: 16px;
justify-content: flex-end;
gap: 10px;
gap: 21px;
height: 35px;
}
.current-time {
@@ -345,6 +369,15 @@ export default {
color: #00fff0;
font-size: 26px;
padding: 0;
margin: 0;
}
.logout-btn {
width: 30px;
height: 30px;
font-size: 30px;
padding: 0;
margin-top: 2px;
}
}

View File

@@ -11,10 +11,10 @@
style="display: flex; gap: 16px; flex-wrap: wrap; align-content: flex-start; row-gap: 8px;">
<!-- 循环生成12个月通过判断当前月份索引添加current类 -->
<div class="monthItem" :class="{
'has-data': month.haveData,
'current': index === currentMonthIndex // 本月匹配current样式
}" v-for="(month, index) in monthList" :key="index">
{{ month.name }}
'has-data': calendar.haveData,
'current': calendar.isActive // 本月匹配current样式
}" v-for="(calendar, index) in calendarList" :key="index">
{{ calendar.name }}
</div>
</div>
</div>
@@ -25,49 +25,35 @@
<script>
import Container from './container.vue'
// import * as echarts from 'echarts'
// import topItem from './operating-item.vue'
export default {
name: 'ProductionStatus',
components: { Container },
// mixins: [resize],
props: {
calendarList: { // 接收父组件传递的年月状态对象
timeType: {
type: String,
default: 'month', // 默认月份维度
},
calendarObj: { // 接收父组件传递的年月状态对象
type: Object, // 注意父组件传递的是对象不是数组修正props类型
default: () => ({}) // 默认空对象,避免报错
},
},
data() {
return {
chart: null,
// 初始化12个月的列表可根据实际需求修改haveData默认值
monthList: [
{ name: '1月', haveData: false, isActive: false },
{ name: '2月', haveData: false, isActive: false },
{ name: '3月', haveData: false, isActive: false },
{ name: '4月', haveData: false, isActive: false },
{ name: '5月', haveData: false, isActive: false },
{ name: '6月', haveData: false, isActive: false },
{ name: '7月', haveData: false, isActive: false },
{ name: '8月', haveData: false, isActive: false },
{ name: '9月', haveData: false, isActive: false },
{ name: '10月', haveData: false, isActive: false },
{ name: '11月', haveData: false, isActive: false },
{ name: '12月', haveData: false, isActive: false }
],
}
},
computed: {
// 计算属性获取当前月份对应的索引0-11对应1月-12月
currentMonthIndex() {
// new Date().getMonth() 返回 0(1月) - 11(12月)正好匹配monthList索引
return new Date().getMonth();
calendarList:[],// 日历列表
}
},
watch: {
// 监听calendarList变化实时更新monthList的haveData状态
calendarList: {
// timeType: {
// immediate: true, // 组件挂载时立即执行一次
// deep: true, // 深度监听对象内部属性变化
// handler() {
// this.updateMonthHaveData();
// }
// },
calendarObj:{
immediate: true, // 组件挂载时立即执行一次
deep: true, // 深度监听对象内部属性变化
handler(newVal) {
@@ -75,28 +61,24 @@ export default {
}
}
},
mounted() {
// 初始化图表(若需展示图表,需在模板中添加对应 DOM
// this.$nextTick(() => this.updateChart())
},
mounted() {},
methods: {
// 根据calendarList更新monthList的haveData状态
// 根据月或者年维度,获取不同的接口,拿到数据,更新左侧日历框
updateMonthHaveData(calendarObj) {
if (!calendarObj || typeof calendarObj !== 'object') return;
// 遍历12个月匹配对应年月
this.monthList.forEach((month, index) => {
// 获取月份数字(索引+1补两位如1→0110→10
const monthNum = (index + 1).toString().padStart(2, '0');
// 拼接成calendarList中的键格式如2025-01
const yearMonthKey = `2025-${monthNum}`; // 若年份不固定可改为props传递年份
// 判断calendarObj中该键对应的值1→true0→false无该键则保持默认false
if (calendarObj.hasOwnProperty(yearMonthKey)) {
month.haveData = calendarObj[yearMonthKey] === 1;
if(this.timeType == 'month'){
const keys = Object.keys(calendarObj);
this.calendarList = []
for(let i = 0; i < keys.length; i++) {
this.calendarList.push({name:i+1+'月',haveData:calendarObj[keys[i]],isActive:i==new Date().getMonth()})
}
});
},
}else{
const keys = Object.keys(calendarObj);
this.calendarList = []
for(let i = 0; i < keys.length; i++) {
this.calendarList.push({name:keys[i]+'年',haveData:calendarObj[keys[i]],isActive:keys[i]==new Date().getFullYear()})
}
}
}
}
}
</script>
@@ -119,7 +101,6 @@ export default {
line-height: 42px;
text-align: center;
font-style: normal;
cursor: pointer; // 鼠标悬浮手型
transition: all 0.2s ease; // 过渡效果,样式切换更平滑
border: 2px solid transparent; // 透明边框,避免选中时布局偏移
margin: 0; // 清除默认外边距,进一步缩小缝隙
@@ -140,5 +121,3 @@ export default {
border: 2px solid #0B58FF !important;
}
</style>
<style></style>

View File

@@ -8,7 +8,7 @@
<div style="width: 4px;height: 16px;background: #0B58FF;border-radius: 1px;margin-top: 10px;"></div>
<el-form :inline="true" :model="form" class="demo-form-inline">
<el-form-item label="所属层级">
<el-select v-model="form.levelId" placeholder="请选择">
<el-select v-model="form.levelId" placeholder="请选择" @change='handleLevelChange'>
<el-option v-for="item in levelLList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
@@ -22,7 +22,7 @@
</el-form-item>
<el-form-item>
<el-button style="background-color: #0B58FF;" type="primary" @click="onSubmit">查询</el-button>
<!-- <el-button type="primary" plain size="medium">导入</el-button> -->
<el-button type="primary" plain size="medium" @click='importExcel'>导入</el-button>
</el-form-item>
</el-form>
</div>
@@ -35,14 +35,14 @@
<div v-if="!isDetail" style="display: flex;gap: 8px;align-items: center;height: 32px;">
<div style="width: 4px;height: 16px;background: #0B58FF;border-radius: 1px;"></div>
<div style="width: 58px;
height: 16px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 14px;
color: rgba(0,0,0,0.85);
line-height: 16px;
text-align: right;
font-style: normal;">指标详情</div>
height: 16px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 14px;
color: rgba(0,0,0,0.85);
line-height: 16px;
text-align: right;
font-style: normal;">指标详情</div>
<el-button style="background-color: #0B58FF;height: 32px;line-height: 10px;" type="primary"
@click="handleEdit">编辑</el-button>
</div>
@@ -53,12 +53,12 @@ font-style: normal;">指标详情</div>
<div
style="width: 58px;height: 16px;font-family: PingFangSC, PingFang SC;font-weight: 400;font-size: 14px;color: rgba(0,0,0,0.85);line-height: 16px;text-align: right;font-style: normal;">
快捷操作</div>
<!-- <el-button style="height: 32px;line-height: 10px;" type="primary" plain size="medium"
@click="onSubmit">复制上月</el-button>
<el-button style="height: 32px;line-height: 10px;" type="primary" plain size="medium"
@click="onSubmit">全部上调5%</el-button>
@click="copyLastMonth">复制上月/</el-button>
<el-button style="height: 32px;line-height: 10px;" type="primary" plain size="medium"
@click="onSubmit">全部调5%</el-button> -->
@click="allUp">全部调5%</el-button>
<el-button style="height: 32px;line-height: 10px;" type="primary" plain size="medium"
@click="allDown">全部下调5%</el-button>
<el-button style="height: 32px;line-height: 10px;" type="primary" plain size="medium"
@click="handleClear">清空配置</el-button>
<el-button style="background-color: #0B58FF;height: 32px;line-height: 10px;" type="primary"
@@ -69,28 +69,28 @@ font-style: normal;">指标详情</div>
<!-- 表格组件添加key属性强制刷新绑定所有必要属性 -->
<base-table style="height: 700px;" :maxHeight=" '700' " @emitFun="inputChange" class="right-aside"
:table-props="tableProps" :page="form.pageNo" :limit="form.pageSize" :table-data="tableData" ref="baseTable"
:key="`base-table-${isDetail}-${timeType}`"></base-table>
:table-props="tableProps" :page="form.pageNo" :limit="form.pageSize" :table-data="tableData" ref="baseTable" id='calendarTable'
:key="tableKey"></base-table>
</div>
</div>
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading"
:on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" action="#" :disabled="upload.isUploading"
:on-change="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
<div class="el-upload__tip" slot="tip">
<el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据
</div>
<span>仅允许导入xlsxlsx格式文件</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;"
@click="importTemplate">下载模板</el-link>
</div>
<div class="el-upload__tip" slot="tip">
<el-radio-group v-model="upload.timeDim">
<el-radio :label="2">月预算</el-radio>
<el-radio :label="3">年预算</el-radio>
</el-radio-group>
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="upload.open = false"> </el-button>
<el-button @click="cancelBtn"> </el-button>
</div>
</el-dialog>
</Container>
@@ -99,9 +99,11 @@ font-style: normal;">指标详情</div>
<script>
import Container from './container.vue'
import { getLevelStruc, getTargetMonthPage, updateTargetMonthData, getTargetYearPage, updateTargetYearData, getDictListData } from '@/api/cockpit'
import { getLevelStruc, getTargetMonthPage, updateTargetMonthData, getTargetYearPage, updateTargetYearData,copyLastMonthData, copyLastYearData} from '@/api/cockpit'
import inputArea from './inputArea.vue' // 导入输入组件
import { getBaseHeader } from "@/utils/request";
import { publicFormatter } from '@/utils/dict';
import {getAccessToken, getTenantId} from '@/utils/auth'
import axios from 'axios';
export default {
name: 'ProductionStatus',
components: {
@@ -118,34 +120,33 @@ export default {
data() {
return {
form: {
levelId: 1,
levelId: undefined,
pageNo: 1,
pageSize: 100,
date: undefined, // 统一存储日期(月份/年份)
startTime: undefined, // 起始时间戳
endTime: undefined // 结束时间戳
},
dictData: [],
upload: {
// 是否显示弹出层(用户导入)
// 是否显示弹出层
open: false,
// 弹出层标题(用户导入)
title: "",
// 弹出层标题
title: "预算填报导入",
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的用户数据
updateSupport: 0,
// 设置上传的请求头部
headers: getBaseHeader(),
// 上传的地址
url: process.env.VUE_APP_BASE_API + '/admin-api/system/user/import'
fileList:[],
currentFile:null,
timeDim: 2
},
getDataList: null, // 动态切换的查询接口
updateData: null, // 动态切换的更新接口
isDetail: false, // 编辑状态标识false=只读true=编辑
tableData: [], // 表格数据
levelLList: [], // 所属层级下拉数据
tableProps: [] // 表格列配置
tableProps: [], // 表格列配置
tableKey:0,// 强制表格更新
allUpBtn: false, // 全部上调按钮状态
allDownBtn: false // 全部下调按钮状态
}
},
watch: {
@@ -182,7 +183,6 @@ export default {
this.initDefaultDate();
// 2. 计算对应时间戳
this.calculateTimeStamp();
this.getDictData()
// 3. 先初始化表格配置(优先于数据请求,避免表格空配置渲染)
this.initTableProps(this.isDetail);
// 4. 等待配置就绪后,再请求数据,避免异步冲突
@@ -191,14 +191,178 @@ export default {
});
},
methods: {
getDictData() {
getDictListData({ pageNo: 1, pageSize: 100, dictType: 'lb_dw' }).then((res) => {
this.dictData = res.data.list
// 清空配置
handleClear() {
// 清空target
this.tableData.forEach(item => {
item.target = null;
})
this.tableKey++;
this.allDownBtn = false;
this.allUpBtn = false;
},
//复制上月/上年数据(调用接口不同)
copyLastMonth() {
if(this.timeType === 'month') {
this.$modal.confirm('是否确认复制上月数据?').then(() => {
this.copyLastMonthDataPage()
}).then(() => {
this.$modal.msgSuccess("复制成功");
}).catch(() => { });
}else{
this.$modal.confirm('是否确认复制上年数据?').then(() => {
this.copyLastYearDataPage()
}).then(() => {
this.$modal.msgSuccess("复制成功");
}).catch(() => { });
}
},
copyLastMonthDataPage() {
copyLastMonthData({
levelId: this.form.levelId,
startTime: this.form.startTime,
endTime: this.form.endTime,
pageSize: this.form.pageSize,
pageNo: this.form.pageNo
}).then((res) => {
this.tableData = res.data.map(item => {
// 新增unitLabel字段存储匹配后的显示名称
return {
...item
};
});
this.tableKey++;
this.allDownBtn = false;
this.allUpBtn = false;
}).catch(err => {
console.error('获取表格数据失败:', err);
this.tableData = [];
});
},
copyLastYearDataPage() {
copyLastYearData({
levelId: this.form.levelId,
startTime: this.form.startTime,
endTime: this.form.endTime,
pageSize: this.form.pageSize,
pageNo: this.form.pageNo
}).then((res) => {
this.tableData = res.data.map(item => {
// 新增unitLabel字段存储匹配后的显示名称
return {
...item
};
});
this.tableKey++;
this.allDownBtn = false;
this.allUpBtn = false;
}).catch(err => {
console.error('获取表格数据失败:', err);
this.tableData = [];
});
},
//全部上调5%
allUp() {
if(this.allUpBtn || this.allDownBtn) {
this.$modal.msgWarning("数据已调整,请先保存数据");
return
}
for(let i = 0; i < this.tableData.length; i++) {
this.tableData[i].target = (this.tableData[i].target * 1.05).toFixed(2)
}
// 强制表格组件刷新
this.tableKey++;
this.allUpBtn = true;
},
// 全部下调5%
allDown() {
if(this.allUpBtn || this.allDownBtn) {
this.$modal.msgWarning("数据已调整,请先保存数据");
return;
}
for(let i = 0; i < this.tableData.length; i++) {
this.tableData[i].target = (this.tableData[i].target * 0.95).toFixed(2)
}
// 强制表格组件刷新
this.tableKey++;
this.allDownBtn = true;
},
// 查询按钮
onSubmit() {
// 清空原有表格数据,重新请求
this.tableData = [];
this.$nextTick(() => {
this.getDataPage();
});
},
// 切换到编辑模式
handleEdit() {
this.isDetail = true;
// 先更新表格配置,再强制表格刷新
this.initTableProps(this.isDetail);
this.tableKey++;
},
// 保存数据使用动态切换的updateData接口
handleSave() {
this.$modal.confirm('是否确认保存数据?').then(() => {
return this.updateData(this.tableData)
}).then(() => {
this.isDetail = false;
// 重置表格配置
this.initTableProps(this.isDetail);
// 清空并重新请求数据,恢复原始状态
this.$nextTick(() => {
this.tableData = [];
this.getDataPage();
});
this.$modal.msgSuccess("保存成功");
this.$emit('updateLeft')
}).catch(() => { });
},
// 请求下拉数据和表格数据使用动态切换的getDataList接口
getData() {
if (!this.getDataList) {
console.warn('当前时间维度异常,无法获取数据');
return;
}
// 1. 请求所属层级下拉数据
getLevelStruc().then((res) => {
this.levelLList = res.data || [];
this.form.levelId = this.levelLList[0].id;
this.$emit('updateLevel', this.levelLList[0].id)
this.getDataPage()
}).catch(err => {
console.error('获取所属层级失败:', err);
this.levelLList = [];
});
this.$emit('updateLeft')
},
getDataPage() {
// 2. 请求表格分页数据(使用动态接口)
this.getDataList({
levelId: this.form.levelId,
startTime: this.form.startTime,
endTime: this.form.endTime,
pageSize: this.form.pageSize,
pageNo: this.form.pageNo
}).then((res) => {
console.log('表格数据:', res);
this.tableData = res.data.map(item => {
// 新增unitLabel字段存储匹配后的显示名称
return {
...item
};
});
}).catch(err => {
console.error('获取表格数据失败:', err);
this.tableData = [];
});
},
handleLevelChange(id) {
this.$emit('updateLevel', id)
},
// 表格单元格数据变更回调
inputChange(val) {
console.log('修改的数据:', val);
// 安全修改:判断索引是否存在,避免数组越界
if (this.tableData[val._pageIndex - 1]) {
this.tableData[val._pageIndex - 1][val.prop] = val[val.prop];
@@ -206,21 +370,31 @@ export default {
this.tableData[val._pageIndex - 1].status = 1;
}
},
// 取消编辑,恢复只读模式
handleCancel() {
this.isDetail = false;
this.allUpBtn = false;
this.allDownBtn = false;
// 重置表格配置
this.initTableProps(this.isDetail);
// 清空并重新请求数据,恢复原始状态
this.$nextTick(() => {
this.tableData = [];
this.getDataPage();
});
},
// 初始化表格列配置核心精准控制inputArea挂载
initTableProps(isEdit) {
console.log('当前编辑状态:', isEdit, '当前时间维度:', this.timeType);
// 基础表格列配置(只读模式使用)
const baseTableProps = [
{ prop: 'type', label: '指标类型', align: 'center' },
// { prop: 'type', label: '指标类型', align: 'center' },
{ prop: 'name', label: '指标名称', align: 'center' },
{ prop: 'unit', label: '单位', align: 'center' },
{ prop: 'target', label: '预值', align: 'center' },
{ prop: 'unit', label: '单位', align: 'center', filter: publicFormatter('lb_dw') },
{ prop: 'target', label: '预值', align: 'center' },
];
if (isEdit) {
// 编辑模式:仅给「预值」列添加inputArea精准挂载避免无效配置
// 编辑模式:仅给「预值」列添加inputArea精准挂载避免无效配置
this.tableProps = baseTableProps.map(item => {
if (item.prop === 'target') { // 只给需要编辑的列添加子组件
return {
@@ -232,75 +406,16 @@ export default {
});
} else {
// 只读模式:深拷贝基础配置,避免引用污染
this.tableProps = JSON.parse(JSON.stringify(baseTableProps));
// this.tableProps = JSON.parse(JSON.stringify(baseTableProps));
this.tableProps = baseTableProps;
}
console.log('表格配置:', this.tableProps);
},
// 切换到编辑模式
handleEdit() {
this.isDetail = true;
// 先更新表格配置,再强制表格刷新(双重保障)
this.initTableProps(this.isDetail);
this.$nextTick(() => {
if (this.$refs.baseTable) {
this.$refs.baseTable.$forceUpdate(); // 强制表格组件刷新
}
});
},
// 保存数据使用动态切换的updateData接口
handleSave() {
// if (!this.updateData) {
// this.$modal.msgWarning('当前时间维度异常,无法保存');
// return;
// }
this.$modal.confirm('是否确认保存数据?').then(() => {
return this.updateData(this.tableData)
}).then(() => {
this.isDetail = false;
// 重置表格配置
this.initTableProps(this.isDetail);
// 清空并重新请求数据,恢复原始状态
this.$nextTick(() => {
this.tableData = [];
this.getData();
});
this.$modal.msgSuccess("保存成功");
}).catch(() => { });
},
// 取消编辑,恢复只读模式
handleCancel() {
this.isDetail = false;
// 重置表格配置
this.initTableProps(this.isDetail);
// 清空并重新请求数据,恢复原始状态
this.$nextTick(() => {
this.tableData = [];
this.getData();
});
console.log('已取消编辑,恢复原始数据');
},
// 清空配置
handleClear() {
this.isDetail = false;
// 重置表格配置
this.initTableProps(this.isDetail);
// 清空并重新请求数据,恢复原始状态
this.$nextTick(() => {
this.tableData = [];
this.getData();
});
},
// 初始化默认日期根据timeType
initDefaultDate() {
const currentDate = new Date();
this.form.date = currentDate;
},
// 计算时间戳根据timeType切换月/年)
calculateTimeStamp(selectDate) {
let targetDate = selectDate || this.form.date;
@@ -330,7 +445,6 @@ export default {
this.form.endTime = endDatePrecise.getTime();
}
},
// 日期选择器变更事件(统一处理月/年变更)
handleDateChange(val) {
if (!val) {
@@ -342,61 +456,65 @@ export default {
// 计算选中日期对应的时间戳
this.calculateTimeStamp(val);
},
getUnitLabel(unitCode) {
// 若字典为空或无匹配编码,返回原编码或空字符串
if (!this.dictData || this.dictData.length === 0) {
return unitCode || '';
}
// 查找匹配的字典项
const matchItem = this.dictData.find(item => item.value == unitCode);
// 返回匹配的label无匹配则返回原unit编码
return matchItem ? matchItem.label : (unitCode || '');
// 导入
importExcel() {
this.upload.open = true
},
// 请求下拉数据和表格数据使用动态切换的getDataList接口
getData() {
if (!this.getDataList) {
console.warn('当前时间维度异常,无法获取数据');
return;
}
// 1. 请求所属层级下拉数据
getLevelStruc().then((res) => {
console.log('所属层级数据:', res);
this.levelLList = res.data || [];
}).catch(err => {
console.error('获取所属层级失败:', err);
this.levelLList = [];
});
// 2. 请求表格分页数据(使用动态接口)
this.getDataList({
levelId: this.form.levelId,
startTime: this.form.startTime,
endTime: this.form.endTime,
pageSize: this.form.pageSize,
pageNo: this.form.pageNo
}).then((res) => {
console.log('表格数据:', res);
this.tableData = res.data.map(item => {
// 新增unitLabel字段存储匹配后的显示名称
return {
...item,
unitLabel: this.getUnitLabel(item.unit)
};
});
}).catch(err => {
console.error('获取表格数据失败:', err);
this.tableData = [];
});
// 文件上传中处理
handleFileUploadProgress(file, fileList) {
console.log('文件上传中:',file, fileList)
this.upload.isUploading = true;
this.upload.fileList = fileList;
this.upload.currentFile = file.raw;
},
// 查询按钮点击事件(可根据需求扩展逻辑)
onSubmit() {
// 清空原有表格数据,重新请求
this.tableData = [];
this.$nextTick(() => {
this.getData();
});
handleFileSuccess() {},
importTemplate() {},
// 提交上传文件
async submitFileForm() {
try {
if (!this.upload.currentFile) {
return this.$message.error('请先选择要上传的文件!')
}
const formData = new FormData()
formData.append('file', this.upload.currentFile) // 文件字段
formData.append('timeDim', this.upload.timeDim) // 年月维度字段
formData.append('reportDate', this.form.endTime) // 时间维度字段
formData.append('levelId', this.form.levelId) // 层级维度字段
const response = await axios({
url: process.env.VUE_APP_BASE_API + '/admin-api/lb/index-target-month/import',
method: 'post',
data: formData,
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': "Bearer " + getAccessToken(),
'tenant-id': getTenantId(),
},
timeout: 30000
})
// 4. 处理响应结果
if (response.data.code === 0) {
this.$message.success('文件上传成功!')
// 重置表单
this.upload.fileList = []
this.upload.timeDim = 2
this.upload.currentFile = null
this.upload.open = false
this.upload.isUploading = false
this.$refs.upload.clearFiles();
this.getDataPage();
this.$emit('updateLeft')
} else {
this.$message.error(`上传失败:${response.data.msg || '未知错误'}`)
}
} catch (error) {
// 5. 异常处理
console.error('文件上传出错:', error)
this.$message.error('上传失败!')
}
},
cancelBtn() {
this.upload.open = false
this.$refs.upload.clearFiles();
}
}
}

View File

@@ -7,6 +7,15 @@
<!-- 右侧区域全屏按钮 -->
<div class="right-content">
<el-dropdown trigger="click">
<el-button type="text" class="logout-btn" :title="'退出'">
<svg-icon style="color: #0B58FF;" icon-class="logout" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native='logout'>退出登录</el-dropdown-item>
<el-dropdown-item @click.native='handleToggle'>切换账号</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-button type="text" class="return-btn" :title="'返回'" @click="handleReturn">
<svg-icon style="color: #0B58FF;" icon-class="returnIcon" />
</el-button>
@@ -35,7 +44,7 @@
<script>
import moment from 'moment'; // 引入moment
import {getPath} from "@/utils/ruoyi";
export default {
name: 'Header',
props: {
@@ -75,6 +84,18 @@ export default {
handleReturn() {
this.$router.go(-1);
},
async logout() {
this.$modal.confirm('确定注销并退出系统吗?', '提示').then(() => {
this.$store.dispatch('LogOut').then(() => {
location.href = getPath('/index');
})
}).catch(() => {});
},
handleToggle() {
this.$store.dispatch('LogOut').then(() => {
location.href = getPath('/index');
})
},
exportPDF() {
this.$emit('exportPDF');
},
@@ -300,6 +321,7 @@ export default {
margin-top: 12px;
margin-right: 10px;
gap: 21px;
height: 35px;
}
// .current-time {
@@ -326,6 +348,7 @@ export default {
color: #00fff0;
font-size: 26px;
padding: 0;
margin: 0;
}
.return-btn {
@@ -336,6 +359,13 @@ export default {
font-size: 26px;
padding: 0;
}
.logout-btn {
width: 28px;
height: 28px;
font-size: 28px;
padding: 0;
}
}
/* 自定义下拉框样式(替换原有日期选择器样式) */

View File

@@ -1,8 +1,8 @@
<template>
<div class="changeBase">
<div class="base-item" @click="handleClick(index)" v-for="(item, index) in buttonList" :key="item"
:style="{ zIndex: activeButton === index ? 10 : 1 }">
<img :src="activeButton === index ? imgMap.bgBase[item] : imgMap.base[item]" :alt="`${item}基地`" :title="item">
<div class="base-item" @click="handleClick(item.id)" v-for="(item) in buttonLevelList" :key="item.id"
:style="{ zIndex: activeButton === item.id ? 10 : 1 }">
<img :src="activeButton === item.id ? item.bgImg : item.img" :alt="`${item.name}基地`" :title="item.name">
</div>
</div>
</template>
@@ -33,80 +33,69 @@ export default {
props: {
factory: {
type: [String, Number],
default: 5, // 新映射中“宜兴”对应序号7
validator: (val) => [5, 2, 7, 3, 8, 9, 10].includes(val) // 校验序号范围匹配新的baseNameToIndexMap
default: undefined,
validator: (val) => [5, 2, 7, 3, 8, 9, 10, 6].includes(val) // 校验序号范围匹配新的baseNameToIndexMap
}
},
// 计算属性响应式levelList变化时会自动更新
computed: {
buttonLevelList() {
// 核心:通过$store.getters获取定义的getter
let arr = []
this.$store.getters.levelList.forEach(item => {
this.buttonList.forEach(item2 => {
if (item2.id === item.id) {
arr.push(item2)
}
})
})
this.activeButton = arr[0].id
return arr
}
},
data() {
return {
activeButton: 5, // 初始化默认选中索引2对应buttonList中的“宜兴”
buttonList: ['合肥', '桐城', '宜兴', '自贡', '漳州', '洛阳', '秦皇岛', '宿迁'], // 匹配截图顺序
imgMap: {
base: {
合肥: baseHefei,
桐城: baseTongcheng,
宜兴: baseYixing,
自贡: baseZigong,
漳州: baseZhangzhou,
洛阳: baseLuoyang,
秦皇岛: baseQinhuangdao,
宿迁: baseSuqian
},
bgBase: {
合肥: bgBaseHefei,
桐城: bgBaseTongcheng,
宜兴: bgBaseYixing,
自贡: bgBaseZigong,
漳州: bgBaseZhangzhou,
洛阳: bgBaseLuoyang,
秦皇岛: bgBaseQinhuangdao,
宿迁: bgBaseSuqian
}
},
baseNameToIndexMap: { // 新的名称→序号映射
宜兴: 7,
漳州: 8,
自贡: 3,
桐城: 2,
洛阳: 9,
合肥: 5,
秦皇岛: 10, // 补充
宿迁: 6 // 补充
}
activeButton: undefined,
buttonList:[
{id: 5, name: '合肥', img: baseHefei, bgImg: bgBaseHefei},
{id: 2, name: '桐城', img: baseTongcheng, bgImg: bgBaseTongcheng},
{id: 7, name: '宜兴', img: baseYixing, bgImg: bgBaseYixing},
{id: 3, name: '自贡', img: baseZigong, bgImg: bgBaseZigong},
{id: 8, name: '漳州', img: baseZhangzhou, bgImg: bgBaseZhangzhou},
{id: 9, name: '洛阳', img: baseLuoyang, bgImg: bgBaseLuoyang},
{id: 10, name: '秦皇岛', img: baseQinhuangdao, bgImg: bgBaseQinhuangdao},
{id: 6, name: '宿迁', img: baseSuqian, bgImg: bgBaseSuqian}
],
};
},
watch: {
// 监听父组件传递的factory变化同步本地选中索引
factory: {
handler(newVal) {
// 根据新的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);
console.log('watch factory=======================:', newVal);
if (newVal) {
this.activeButton = newVal;
}
// // 根据新的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 selectedName = this.buttonList[newVal];
const selectedIndex = this.baseNameToIndexMap[selectedName] || 5; // 默认返回宜兴的序号7
this.$emit('baseChange', selectedIndex);
// immediate: true // 初始化立即执行
}
},
methods: {
handleClick(index) {
this.activeButton = index;
},
getIndexByName(name) {
return this.baseNameToIndexMap[name] || 5;
handleClick(id) {
this.activeButton = id;
this.$emit('baseChange', id);
}
},
mounted() {
// 初始化时触发事件传递默认选中的宜兴序号7
this.$emit('baseChange', 5);
// this.$emit('baseChange', 5);
}
};
</script>

View File

@@ -84,7 +84,7 @@ export default {
return dataMap.map(itemInfo => {
const rawItem = rawData[itemInfo.key] || {};
const progress = Math.max(0, Math.round((rawItem.rate || 0)));
const progress = rawItem.rate || 0;
return {
unit: itemInfo.unit,

View File

@@ -13,7 +13,7 @@
<div class="monthItem" :class="{
'has-data': month.haveData,
'current': index === currentMonthIndex // 本月匹配current样式
}" v-for="(month, index) in monthList" :key="index">
}" v-for="(month, index) in list" :key="index">
{{ month.name }}
</div>
</div>
@@ -41,21 +41,7 @@ export default {
data() {
return {
chart: null,
// 初始化12个月的列表可根据实际需求修改haveData默认值
monthList: [
{ name: '1月', haveData: false, isActive: false },
{ name: '2月', haveData: false, isActive: false },
{ name: '3月', haveData: false, isActive: false },
{ name: '4月', haveData: false, isActive: false },
{ name: '5月', haveData: false, isActive: false },
{ name: '6月', haveData: false, isActive: false },
{ name: '7月', haveData: false, isActive: false },
{ name: '8月', haveData: false, isActive: false },
{ name: '9月', haveData: false, isActive: false },
{ name: '10月', haveData: false, isActive: false },
{ name: '11月', haveData: false, isActive: false },
{ name: '12月', haveData: false, isActive: false }
],
list:[]
}
},
computed: {
@@ -83,19 +69,15 @@ export default {
// 根据calendarList更新monthList的haveData状态
updateMonthHaveData(calendarObj) {
if (!calendarObj || typeof calendarObj !== 'object') return;
// 遍历12个月匹配对应年月
this.monthList.forEach((month, index) => {
// 获取月份数字(索引+1补两位如1→0110→10
const monthNum = (index + 1).toString().padStart(2, '0');
// 拼接成calendarList中的键格式如2025-01
const yearMonthKey = `2025-${monthNum}`; // 若年份不固定可改为props传递年份
// 判断calendarObj中该键对应的值1→true0→false无该键则保持默认false
if (calendarObj.hasOwnProperty(yearMonthKey)) {
month.haveData = calendarObj[yearMonthKey] === 1;
}
});
const keys = Object.keys(calendarObj);
if(keys.length == 0){
return
}
console.log('calendarObj',calendarObj)
this.list = []
for(let i = 0; i < keys.length; i++) {
this.list.push({name:i+1+'月',haveData:calendarObj[keys[i]],isActive:i==new Date().getMonth()})
}
},
}
}

View File

@@ -8,7 +8,7 @@
<div style="width: 4px;height: 16px;background: #0B58FF;border-radius: 1px;margin-top: 10px;"></div>
<el-form :inline="true" :model="form" class="demo-form-inline">
<el-form-item label="所属层级">
<el-select v-model="form.levelId" placeholder="请选择">
<el-select v-model="form.levelId" placeholder="请选择" @change='handleLevelChange'>
<el-option v-for="item in levelLList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
@@ -20,7 +20,7 @@
</el-form-item>
<el-form-item>
<el-button style="background-color: #0B58FF;" type="primary" @click="onSubmit">查询</el-button>
<!-- <el-button type="primary" plain size="medium">导入</el-button> -->
<el-button type="primary" plain size="medium" @click='importExcel'>导入</el-button>
</el-form-item>
</el-form>
</div>
@@ -64,6 +64,22 @@ font-style: normal;">指标详情</div>
></base-table>
</div>
</div>
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" action="#" :disabled="upload.isUploading"
:on-change="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
<span>仅允许导入xlsxlsx格式文件</span>
</div>
<div class="el-upload__tip" slot="tip">
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="cancelBtn"> </el-button>
</div>
</el-dialog>
</Container>
</div>
</template>
@@ -72,7 +88,8 @@ font-style: normal;">指标详情</div>
import Container from './container.vue'
import { getLevelStruc, getRealMonthPage, updateRealMonthData, getDictListData, } from '@/api/cockpit'
import inputArea from './inputArea.vue' // 导入输入组件
import {getAccessToken, getTenantId} from '@/utils/auth'
import axios from 'axios';
export default {
name: 'ProductionStatus',
components: {
@@ -85,7 +102,7 @@ export default {
data() {
return {
form: {
levelId: 1,
levelId: undefined,
pageNo: 1,
pageSize: 100,
month: undefined,
@@ -96,7 +113,17 @@ export default {
isDetail: false, // 编辑状态标识false=只读true=编辑
tableData: [], // 表格数据
levelLList: [], // 所属层级下拉数据
tableProps: [] // 表格列配置
tableProps: [], // 表格列配置
upload: {
// 是否显示弹出层
open: false,
// 弹出层标题
title: "指标填报导入",
// 是否禁用上传
isUploading: false,
fileList:[],
currentFile:null
}
}
},
watch: {
@@ -142,7 +169,7 @@ export default {
// 基础表格列配置(只读模式使用)
const baseTableProps = [
{ prop: 'type', label: '指标类型', align: 'center' },
// { prop: 'type', label: '指标类型', align: 'center' },
{ prop: 'name', label: '指标名称', align: 'center' },
{ prop: 'unitLabel', label: '单位', align: 'center' },
{ prop: 'value', label: '实际值', align: 'center' },
@@ -187,9 +214,10 @@ export default {
// 清空并重新请求数据,恢复原始状态
this.$nextTick(() => {
this.tableData = [];
this.getData();
this.getDataPage();
});
this.$modal.msgSuccess("保存成功");
this.$emit('updateLeft')
}).catch(() => { });
},
// 取消编辑,恢复只读模式
@@ -200,7 +228,7 @@ export default {
// 清空并重新请求数据,恢复原始状态
this.$nextTick(() => {
this.tableData = [];
this.getData();
this.getDataPage();
});
console.log('已取消编辑,恢复原始数据');
},
@@ -211,7 +239,7 @@ export default {
// 清空并重新请求数据,恢复原始状态
this.$nextTick(() => {
this.tableData = [];
this.getData();
this.getDataPage();
});
},
@@ -261,13 +289,17 @@ export default {
getData() {
// 1. 请求所属层级下拉数据
getLevelStruc().then((res) => {
console.log('所属层级数据:', res);
this.levelLList = res.data || [];
this.form.levelId = this.levelLList[0].id;
this.$emit('updateLevel', this.levelLList[0].id)
this.getDataPage()
}).catch(err => {
console.error('获取所属层级失败:', err);
this.levelLList = [];
});
this.$emit('updateLeft')
},
getDataPage() {
// 2. 请求表格分页数据
getRealMonthPage({
levelId: this.form.levelId,
@@ -288,6 +320,10 @@ export default {
console.error('获取表格数据失败:', err);
this.tableData = [];
});
},
handleLevelChange(id) {
this.$emit('updateLevel', id)
},
// 查询按钮点击事件(可根据需求扩展逻辑)
@@ -295,8 +331,66 @@ export default {
// 清空原有表格数据,重新请求
this.tableData = [];
this.$nextTick(() => {
this.getData();
this.getDataPage();
});
},
// 导入
importExcel() {
this.upload.open = true
},
// 文件上传中处理
handleFileUploadProgress(file, fileList) {
console.log('文件上传中:',file, fileList)
this.upload.isUploading = true;
this.upload.fileList = fileList;
this.upload.currentFile = file.raw;
},
handleFileSuccess() {},
importTemplate() {},
// 提交上传文件
async submitFileForm() {
try {
if (!this.upload.currentFile) {
return this.$message.error('请先选择要上传的文件!')
}
const formData = new FormData()
formData.append('file', this.upload.currentFile) // 文件字段
formData.append('reportDate', this.form.endTime) // 时间维度字段
formData.append('levelId', this.form.levelId) // 层级维度字段
const response = await axios({
url: process.env.VUE_APP_BASE_API + '/admin-api/lb/index-real-month/actualIndicatorImport',
method: 'post',
data: formData,
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': "Bearer " + getAccessToken(),
'tenant-id': getTenantId(),
},
timeout: 30000
})
// 4. 处理响应结果
if (response.data.code === 0) {
this.$message.success('文件上传成功!')
// 重置表单
this.upload.fileList = []
this.upload.currentFile = null
this.upload.open = false
this.upload.isUploading = false
this.$refs.upload.clearFiles();
this.getDataPage();
this.$emit('updateLeft')
} else {
this.$message.error(`上传失败:${response.data.msg || '未知错误'}`)
}
} catch (error) {
// 5. 异常处理
console.error('文件上传出错:', error)
this.$message.error('上传失败!')
}
},
cancelBtn(){
this.upload.open = false
this.$refs.upload.clearFiles();
}
}
}

View File

@@ -7,6 +7,15 @@
<!-- 右侧区域全屏按钮 -->
<div class="right-content">
<el-dropdown trigger="click">
<el-button type="text" class="logout-btn" :title="'退出'">
<svg-icon style="color: #0B58FF;" icon-class="logout" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native='logout'>退出登录</el-dropdown-item>
<el-dropdown-item @click.native='handleToggle'>切换账号</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-button type="text" class="return-btn" :title="'返回'" @click="handleReturn">
<svg-icon style="color: #0B58FF;" icon-class="returnIcon" />
</el-button>
@@ -31,7 +40,7 @@
<script>
import moment from 'moment'; // 引入moment
import {getPath} from "@/utils/ruoyi";
export default {
name: 'Header',
props: {
@@ -100,6 +109,18 @@ export default {
this.$router.go(-1);
}
},
async logout() {
this.$modal.confirm('确定注销并退出系统吗?', '提示').then(() => {
this.$store.dispatch('LogOut').then(() => {
location.href = getPath('/index');
})
}).catch(() => {});
},
handleToggle() {
this.$store.dispatch('LogOut').then(() => {
location.href = getPath('/index');
})
},
/**
* 计算时间范围(时间戳格式)
* 固定为月维度当月1日00:00:00 → 当月最后一天23:59:59
@@ -297,6 +318,7 @@ export default {
margin-top: 12px;
margin-right: 10px;
gap: 21px;
height: 35px;
}
.screen-btn {
@@ -305,6 +327,7 @@ export default {
color: #00fff0;
font-size: 26px;
padding: 0;
margin: 0;
}
.home-btn {
@@ -322,6 +345,14 @@ export default {
font-size: 26px;
padding: 0;
}
.logout-btn {
width: 28px;
height: 28px;
font-size: 28px;
padding: 0;
}
}
/* 日期选择器自定义样式 */

View File

@@ -99,7 +99,7 @@ export default {
grid: {
top: 35,
bottom: 20,
right: 25,
right: 13,
},
xAxis: [
{
@@ -222,11 +222,11 @@ export default {
/* (你的样式代码保持不变) */
.legend {
position: absolute;
right: 10px;
top: -5px;
right: 12px;
top: 0px;
display: flex;
/* 使用 flex 布局让两个图例项并排且对齐 */
gap: 20px;
gap: 5px;
}
.legend-item-line {
@@ -237,7 +237,7 @@ export default {
text-align: left;
font-style: normal;
position: relative;
padding-left: 20px;
padding-left: 24px;
/* 为圆点和线条留出空间 */
display: flex;
align-items: center;

View File

@@ -121,7 +121,7 @@ export default {
.lineFour {
top: 5px;
left: 268px;
left: 252px;
}
.item-button {

View File

@@ -89,7 +89,7 @@ export default {
unit: mappingItem.unit,
targetValue: indicatorData.target, // 目标值
currentValue: indicatorData.real, // 实际值
progress: indicatorData.rate ? Math.round(indicatorData.rate) : 0, // 完成率(百分比,四舍五入)
progress: indicatorData.rate || 0, // 完成率
path: mappingItem.path // 路由路径
};
});

View File

@@ -71,7 +71,7 @@ export default {
// 定义一个映射关系,将后端字段名与前端显示信息关联起来
const dataMap = [
{
key: 'processCost',
key: 'totalCost',
unit: '制造成本·元/㎡',
route: '/productionCostAnalysis/productionCostAnalysis'
},
@@ -101,7 +101,7 @@ export default {
return dataMap.map(itemInfo => {
const rawItem = rawData[itemInfo.key] || {};
// 计算进度百分比确保不小于0
const progress = Math.max(0, Math.round((rawItem.rate || 0)));
const progress = rawItem.rate || 0;
return {
unit: itemInfo.unit,

View File

@@ -27,7 +27,7 @@ export default {
chart: null,
// 固定3条默认数据作为展示模板
parentItemList: [
{ name: "制造成本", targetValue: 0, value: 0, proportion: 0, flag: 0 },
{ name: "制造成本", targetValue: 0, value: 0, proportion: 0, flag: 0 },
{ name: "原片成本", targetValue: 0, value: 0, proportion: 0, flag: 0 },
{ name: "加工成本", targetValue: 0, value: 0, proportion: 0, flag: 0 },
]

View File

@@ -114,6 +114,7 @@ export default {
monthAnalysis: [],
ytdAnalysis: [],
trend: [],
factory:null
};
},
@@ -185,7 +186,13 @@ export default {
this.beilv = _this.clientWidth / 1920;
})();
};
this.factory = this.$route.query.factory ? Number(this.$route.query.factory) : 5
if(this.$route.query.factory){
this.factory =Number(this.$route.query.factory)
}else if(this.$store.getters.levelList.length > 0 && this.$store.getters.levelList[0].id !== 1) {
this.factory = this.$store.getters.levelList[0].id
}else{
this.factory = this.$store.getters.levelList[1].id
}
this.dateData = this.$route.query.dateData ? this.$route.query.dateData : undefined
},
methods: {

View File

@@ -61,7 +61,7 @@ export default {
return {
activeButton: 0,
isDropdownShow: false,
selectedProfit: null, // 选中的名称初始为null
selectedProfit: '总费用', // 选中的名称初始为null
profitOptions: [
'总费用',
'管理费用',

View File

@@ -4,7 +4,7 @@
<div :id="id" style="width: 100%; height:100%;"></div>
<div class="bottomTip">
<div class="precent">
<span class="precentNum">{{ detailData.rate || 0 }} </span>
<span class="precentNum">{{ detailData.rate || 0 }}% </span>
</div>
</div>
</div>

View File

@@ -125,7 +125,7 @@ export default {
width: 264px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
// width: 190px;
@@ -144,7 +144,7 @@ export default {
.number {
display: flex;
align-items: center;
gap: 30px;
gap: 6px;
// width: 190px;
height: 32px;
font-family: YouSheBiaoTiHei;
@@ -154,6 +154,7 @@ export default {
letter-spacing: 2px;
text-align: left;
font-style: normal;
white-space: nowrap;
}
.mom {
@@ -167,6 +168,7 @@ export default {
letter-spacing: 1px;
text-align: left;
font-style: normal;
z-index: 1000;
}
}

View File

@@ -157,7 +157,7 @@ getRateFlag(rate, real, target) {
max-width: 300px; // 最大宽度,限制过宽
height: 205px;
background: #F9FCFF;
padding: 16px 16px 0;
padding: 16px 0 0 10px;
margin: 0 4px;
.title {
@@ -201,6 +201,7 @@ getRateFlag(rate, real, target) {
line-height: 18px;
letter-spacing: 1px;
text-align: left;
z-index: 1000;
}
}
</style>

View File

@@ -57,8 +57,8 @@ export default {
return {
activeButton: 0,
isDropdownShow: false,
selectedSort: null, // 选中的label
selectedSortValue: null, // 选中的value用于排序逻辑
selectedSort: '实际值:高~低', // 选中的label
selectedSortValue: 1, // 选中的value用于排序逻辑
profitOptions: [
{ label: '实际值:高~低', value: 1 },
{ label: '实际值:低~高', value: 2 },

View File

@@ -89,7 +89,9 @@ export default {
const baseIndex = this.baseNameToIndexMap[itemName] || 0;
console.log(`你点击了【${itemName}】(序号:${baseIndex})`);
if (itemName === undefined) {
return;
}
this.$router.push({
path: 'expenseAnalysisBase',
query: { // 使用query传递参数推荐也可使用params

View File

@@ -85,9 +85,10 @@ export default {
},
grid: {
top: 30,
bottom: 30,
right: 20,
left: 60,
bottom: 5,
right: 10,
left: 25,
containLabel: true
},
xAxis: [
{

View File

@@ -84,10 +84,11 @@ export default {
// }
},
grid: {
top: 30,
bottom: 50,
right: 20,
left: 40,
top: 25,
bottom: 30,
right: 0,
left: 2,
containLabel: true
},
xAxis: [
{

View File

@@ -95,7 +95,7 @@ export default {
if (rate >= 100) return 1;
// 2. 完成率 = 0 且 (目标值=0 或 实际值=目标值=0) => 达标
if (rate === 0 && target === 0) return 1;
if (real <= target) return 1;
// 其他情况 => 未达标
return 0;

View File

@@ -90,7 +90,7 @@ export default {
if (rate >= 100) return 1;
// 2. 完成率 = 0 且 (目标值=0 或 实际值=目标值=0) => 达标
if (rate === 0 && target === 0) return 1;
if (real <= target) return 1;
// 其他情况 => 未达标
return 0;

View File

@@ -125,7 +125,7 @@ export default {
width: 264px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
// width: 190px;
@@ -167,6 +167,7 @@ export default {
letter-spacing: 1px;
text-align: left;
font-style: normal;
z-index: 1000;
}
}

View File

@@ -94,7 +94,7 @@ getRateFlag(rate, real, target) {
grid: {
top: 10,
bottom: 30,
right: 50,
right: 80,
left: 30,
containLabel: true,
show: false // 隐藏grid背景避免干扰

View File

@@ -158,7 +158,7 @@ getRateFlag(rate, real, target) {
max-width: 300px; // 最大宽度,限制过宽
height: 205px;
background: #F9FCFF;
padding: 16px 16px 0;
padding: 16px 0 0 10px;
margin: 0 4px;
.title {
@@ -202,6 +202,7 @@ getRateFlag(rate, real, target) {
line-height: 18px;
letter-spacing: 1px;
text-align: left;
z-index: 1000;
}
}
</style>

View File

@@ -102,7 +102,7 @@ export default {
beilv: 1,
month: '',
value: 100,
factory: 5,
factory: null,
dateData: {},
monData: {},
totalData: {},
@@ -174,7 +174,13 @@ export default {
this.beilv = _this.clientWidth / 1920;
})();
};
this.factory = this.$route.query.factory ? Number(this.$route.query.factory) : 5
if(this.$route.query.factory){
this.factory =Number(this.$route.query.factory)
}else if(this.$store.getters.levelList.length > 0 && this.$store.getters.levelList[0].id !== 1) {
this.factory = this.$store.getters.levelList[0].id
}else{
this.factory = this.$store.getters.levelList[1].id
}
this.dateData = this.$route.query.dateData ? this.$route.query.dateData : undefined
},
methods: {

View File

@@ -4,7 +4,7 @@
<div :id="id" style="width: 100%; height:100%;"></div>
<div class="bottomTip">
<div class="precent">
<span class="precentNum">{{ detailData.completeRate || 0 }} </span>
<span class="precentNum">{{ detailData.completeRate || 0 }}% </span>
</div>
</div>
</div>

View File

@@ -142,7 +142,7 @@ getRateFlag(rate, real, target) {
width: 264px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
height: 18px;
@@ -157,13 +157,14 @@ getRateFlag(rate, real, target) {
.number {
display: flex;
align-items: center;
gap: 30px;
gap: 6px;
height: 32px;
font-family: YouSheBiaoTiHei;
font-size: 32px;
color: #0B58FF;
line-height: 32px;
letter-spacing: 2px;
white-space: nowrap;
}
.mom {
@@ -178,6 +179,7 @@ getRateFlag(rate, real, target) {
display: flex;
align-items: center; // 箭头和文字垂直居中
gap: 4px; // 文字和箭头间距
z-index: 1000;
}
// 箭头样式优化

View File

@@ -118,7 +118,7 @@ export default {
width: 382px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
// width: 190px;
@@ -137,7 +137,7 @@ export default {
.number {
display: flex;
align-items: center;
gap: 30px;
gap: 6px;
// width: 190px;
height: 32px;
font-family: YouSheBiaoTiHei;
@@ -147,10 +147,11 @@ export default {
letter-spacing: 2px;
text-align: left;
font-style: normal;
white-space: nowrap;
}
.mom {
width: 97px;
width: 120px;
height: 18px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
@@ -160,6 +161,7 @@ export default {
letter-spacing: 1px;
text-align: left;
font-style: normal;
z-index: 1000;
}
}

View File

@@ -57,8 +57,8 @@ export default {
return {
activeButton: 0,
isDropdownShow: false,
selectedSort: null, // 选中的label
selectedSortValue: null, // 选中的value用于排序逻辑
selectedSort: '实际值:高~低', // 选中的label
selectedSortValue: 1, // 选中的value用于排序逻辑
profitOptions: [
{ label: '实际值:高~低', value: 1 },
{ label: '实际值:低~高', value: 2 },

View File

@@ -91,7 +91,9 @@ export default {
const baseIndex = this.baseNameToIndexMap[itemName] || 0;
console.log(`你点击了【${itemName}】(序号:${baseIndex})`);
if (itemName === undefined) {
return;
}
// 路由跳转时携带序号(或名称+序号)
this.$router.push({
path: 'fullCostAnalysisBase',

View File

@@ -85,9 +85,10 @@ export default {
},
grid: {
top: 30,
bottom: 30,
right: 20,
left: 60,
bottom: 5,
right: 10,
left: 25,
containLabel: true
},
xAxis: [
{

View File

@@ -83,11 +83,12 @@ export default {
// return html;
// }
},
grid: {
top: 30,
bottom: 60,
right: 30,
left: 50,
grid: {
top: 25,
bottom: 20,
right: 10,
left: 2,
containLabel: true
},
xAxis: [
{

View File

@@ -88,8 +88,8 @@ getRateFlag(rate, real, target) {
// 1. 完成率 >= 100 => 达标
if (rate >= 100) return 1;
// 2. 完成率 = 0 且 (目标值=0 或 实际值=目标值=0) => 达标
if (rate === 0 && target === 0) return 1;
// 2. 实际小于等于目标) => 达标
if (real <= target) return 1;
// 其他情况 => 未达标
return 0;

View File

@@ -163,7 +163,7 @@ export default {
// const flags = flags || [];
const currentDiff = diff || 0;
const currentFlag = flags[0] || 0;
const currentFlag = data?.flags[0] || 0;
// const prefix = currentFlag === 1 ? '+' : '';
// 根据标志位选择不同的样式类
if (currentFlag === 1) {

View File

@@ -202,8 +202,7 @@ getRateFlag(rate, real, target) {
width: 310px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
// width: 190px;
height: 18px;
@@ -221,7 +220,7 @@ getRateFlag(rate, real, target) {
.number {
display: flex;
align-items: center;
gap: 30px;
gap: 6px;
// width: 190px;
height: 32px;
font-family: YouSheBiaoTiHei;
@@ -231,10 +230,11 @@ getRateFlag(rate, real, target) {
letter-spacing: 2px;
text-align: left;
font-style: normal;
white-space: nowrap;
}
.mom {
width: 97px;
width: 120px;
height: 18px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
@@ -244,6 +244,7 @@ getRateFlag(rate, real, target) {
letter-spacing: 1px;
text-align: left;
font-style: normal;
z-index: 1000;
}
}

View File

@@ -153,7 +153,7 @@ getRateFlag(rate, real, target) {
width: 264px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
// width: 190px;
@@ -172,7 +172,7 @@ getRateFlag(rate, real, target) {
.number {
display: flex;
align-items: center;
gap: 30px;
gap: 6px;
// width: 190px;
height: 32px;
font-family: YouSheBiaoTiHei;
@@ -182,6 +182,7 @@ getRateFlag(rate, real, target) {
letter-spacing: 2px;
text-align: left;
font-style: normal;
white-space: nowrap;
}
.mom {
@@ -195,6 +196,7 @@ getRateFlag(rate, real, target) {
letter-spacing: 1px;
text-align: left;
font-style: normal;
z-index: 1000;
}
}

View File

@@ -77,7 +77,7 @@ export default {
grid: {
top: 10,
bottom: 30,
right: 50,
right: 80,
left: 30,
containLabel: true,
show: false

View File

@@ -118,8 +118,7 @@ export default {
width: 382px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
// width: 190px;
height: 18px;
@@ -137,7 +136,7 @@ export default {
.number {
display: flex;
align-items: center;
gap: 30px;
gap: 6px;
// width: 190px;
height: 32px;
font-family: YouSheBiaoTiHei;
@@ -147,10 +146,11 @@ export default {
letter-spacing: 2px;
text-align: left;
font-style: normal;
white-space: nowrap;
}
.mom {
width: 97px;
width: 120px;
height: 18px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
@@ -160,6 +160,7 @@ export default {
letter-spacing: 1px;
text-align: left;
font-style: normal;
z-index: 1000;
}
}

View File

@@ -111,7 +111,7 @@ export default {
dateData:{},
levelId:undefined,
index: '毛利率',
factory: 1,
factory: null,
monthData: {},
ytdData: {},
monthAnalysis: [],
@@ -188,7 +188,13 @@ export default {
this.beilv = _this.clientWidth / 1920;
})();
};
this.factory = this.$route.query.factory ? Number(this.$route.query.factory) : 5
if(this.$route.query.factory){
this.factory =Number(this.$route.query.factory)
}else if(this.$store.getters.levelList.length > 0 && this.$store.getters.levelList[0].id !== 1) {
this.factory = this.$store.getters.levelList[0].id
}else{
this.factory = this.$store.getters.levelList[1].id
}
this.dateData = this.$route.query.dateData ? this.$route.query.dateData : undefined
},
methods: {

View File

@@ -61,7 +61,7 @@ export default {
return {
activeButton: 0,
isDropdownShow: false,
selectedProfit: null, // 选中的名称初始为null
selectedProfit: '毛利率', // 选中的名称初始为null
profitOptions: [
'毛利率',
'营业收入',

View File

@@ -4,7 +4,7 @@
<div :id="id" style="width: 100%; height:100%;"></div>
<div class="bottomTip">
<div class="precent">
<span class="precentNum">{{ detailData.rate || 0 }} </span>
<span class="precentNum">{{ detailData.rate || 0 }}% </span>
</div>
</div>
</div>

View File

@@ -126,7 +126,7 @@ export default {
width: 264px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
// width: 190px;
@@ -145,7 +145,7 @@ export default {
.number {
display: flex;
align-items: center;
gap: 30px;
gap: 6px;
// width: 190px;
height: 32px;
font-family: YouSheBiaoTiHei;
@@ -155,6 +155,7 @@ export default {
letter-spacing: 2px;
text-align: left;
font-style: normal;
white-space: nowrap;
}
.mom {
@@ -168,6 +169,7 @@ export default {
letter-spacing: 1px;
text-align: left;
font-style: normal;
z-index: 1000;
}
}

View File

@@ -153,7 +153,7 @@ getRateFlag(rate, real, target) {
min-width: 300px;
height: 205px;
background: #F9FCFF;
padding: 16px 16px 0;
padding: 16px 0 0 10px;
margin: 0 4px;
.title {
@@ -196,6 +196,7 @@ getRateFlag(rate, real, target) {
line-height: 18px;
letter-spacing: 1px;
text-align: left;
z-index: 1000;
}
}

View File

@@ -57,8 +57,8 @@ export default {
return {
activeButton: 0,
isDropdownShow: false,
selectedSort: null, // 选中的label
selectedSortValue: null, // 选中的value用于排序逻辑
selectedSort: '实际值:高~低', // 选中的label
selectedSortValue: 1, // 选中的value用于排序逻辑
profitOptions: [
{ label: '实际值:高~低', value: 1 },
{ label: '实际值:低~高', value: 2 },

View File

@@ -102,7 +102,9 @@ export default {
const baseIndex = this.baseNameToIndexMap[itemName] || 0;
console.log(`你点击了【${itemName}】(序号:${baseIndex})`);
if (itemName === undefined) {
return;
}
// 路由跳转时携带序号(或名称+序号)
this.$router.push({
path: 'grossMarginBase',

View File

@@ -85,9 +85,10 @@ export default {
},
grid: {
top: 30,
bottom: 30,
right: 20,
left: 60,
bottom: 5,
right: 10,
left: 25,
containLabel: true
},
xAxis: [
{

View File

@@ -83,11 +83,12 @@ export default {
// return html;
// }
},
grid: {
top: 30,
bottom: 60,
right: 30,
left: 50,
grid: {
top: 25,
bottom: 30,
right: 0,
left: 2,
containLabel: true
},
xAxis: [
{

View File

@@ -125,7 +125,7 @@ export default {
width: 264px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
// width: 190px;
@@ -167,6 +167,7 @@ export default {
letter-spacing: 1px;
text-align: left;
font-style: normal;
z-index: 1000;
}
}

View File

@@ -94,7 +94,7 @@ getRateFlag(rate, real, target) {
grid: {
top: 10,
bottom: 30,
right: 50,
right: 80,
left: 30,
containLabel: true,
show: false // 隐藏grid背景避免干扰

View File

@@ -157,7 +157,7 @@ export default {
min-width: 300px; // 最小宽度,防止挤压
height: 205px;
background: #F9FCFF;
padding: 16px 16px 0; // 左右内边距一致
padding: 16px 0 0 10px;// 左右内边距一致
margin: 0 4px; // 左右间距
.title {
@@ -201,6 +201,7 @@ export default {
line-height: 18px;
letter-spacing: 1px;
text-align: left;
z-index: 1000;
}
}

View File

@@ -45,7 +45,7 @@ import { getOperateCockpit, getOrderDetail } from '@/api/cockpit'
import { Sidebar } from "../../layout/components";
import { mapState } from "vuex";
export default {
name: 'DayReport',
name: 'JtHome',
components: { ReportHeader, coreSalesKPIs, keyProductionIndicators, coreBottomLeft, keyWork, orderProgress, financeCosts, Sidebar },
data() {
return {

View File

@@ -17,7 +17,7 @@
grid-template-columns:416px 1192px;
">
<indicatorCalendar :calendarList="calendarList" />
<indicatorDetails />
<indicatorDetails @updateLeft='getData' @updateLevel='getLevel'/>
</div>
</div>
<!-- <div class="top" style="margin-top: -20px; display: flex; gap: 16px">
@@ -78,6 +78,7 @@ export default {
monthData: {},
ytdData: {},
calendarList:{},
levelId:null
};
},
@@ -143,35 +144,20 @@ export default {
this.beilv = _this.clientWidth / 1920;
})();
};
this.getData()
},
methods: {
// sortChange(value) {
// this.sort = value
// this.getData()
// },
// 层级变动
getLevel(id) {
this.levelId = id
this.getData()
},
getData() {
getRealMonthCalendar().then((res) => {
getRealMonthCalendar({
levelId: this.levelId
}).then((res) => {
console.log(res, 'res');
this.calendarList = res.data
})
// getSalesRevenueGroupData({
// startTime: this.dateData.startTime,
// endTime: this.dateData.endTime,
// sort: this.sort,
// index: undefined,
// factory: undefined
// // timeDim: obj.mode
// }).then((res) => {
// console.log(res);
// this.monthData= res.data.month
// this.ytdData = res.data.ytd
// })
},
handleTimeChange(obj) {
console.log(obj, 'obj');
this.dateData= obj
this.getData()
},
handleClickOutside() {
this.$store.dispatch("app/closeSideBar", { withoutAnimation: false });

View File

@@ -104,7 +104,7 @@ export default {
beilv: 1,
month: '',
value: 100,
factory: 5,
factory: null,
dateData: {},
index: '加工成品率',
monthData: undefined,
@@ -184,7 +184,13 @@ export default {
this.beilv = _this.clientWidth / 1920;
})();
};
this.factory = this.$route.query.factory ? Number(this.$route.query.factory) : 5
if(this.$route.query.factory){
this.factory =Number(this.$route.query.factory)
}else if(this.$store.getters.levelList.length > 0 && this.$store.getters.levelList[0].id !== 1) {
this.factory = this.$store.getters.levelList[0].id
}else{
this.factory = this.$store.getters.levelList[1].id
}
this.dateData = this.$route.query.dateData ? this.$route.query.dateData : undefined
},
methods: {

View File

@@ -61,7 +61,7 @@ export default {
return {
activeButton: 0,
isDropdownShow: false,
selectedProfit: null, // 选中的名称初始为null
selectedProfit: '加工成品率', // 选中的名称初始为null
profitOptions: [
'加工成品率',
'领用量',

View File

@@ -4,7 +4,7 @@
<div :id="id" style="width: 100%; height:100%;"></div>
<div class="bottomTip">
<div class="precent">
<span class="precentNum">{{ detailData.rate || 0 }} </span>
<span class="precentNum">{{ detailData.rate || 0 }}% </span>
</div>
</div>
</div>

View File

@@ -125,7 +125,7 @@ export default {
width: 264px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
// width: 190px;
@@ -144,7 +144,7 @@ export default {
.number {
display: flex;
align-items: center;
gap: 30px;
gap: 6px;
// width: 190px;
height: 32px;
font-family: YouSheBiaoTiHei;
@@ -154,6 +154,7 @@ export default {
letter-spacing: 2px;
text-align: left;
font-style: normal;
white-space: nowrap;
}
.mom {
@@ -167,6 +168,7 @@ export default {
letter-spacing: 1px;
text-align: left;
font-style: normal;
z-index: 1000;
}
}

View File

@@ -143,7 +143,7 @@ getRateFlag(rate, real, target) {
min-width: 300px; // 最小宽度限制
height: 205px;
background: #F9FCFF;
padding: 16px 16px 0;
padding: 16px 0 0 10px;
margin: 0 4px;
.title {
@@ -187,6 +187,7 @@ getRateFlag(rate, real, target) {
line-height: 18px;
letter-spacing: 1px;
text-align: left;
z-index: 1000;
}
}

View File

@@ -57,8 +57,8 @@ export default {
return {
activeButton: 0,
isDropdownShow: false,
selectedSort: null, // 选中的label
selectedSortValue: null, // 选中的value用于排序逻辑
selectedSort: '实际值:高~低', // 选中的label
selectedSortValue: 1, // 选中的value用于排序逻辑
profitOptions: [
{ label: '实际值:高~低', value: 1 },
{ label: '实际值:低~高', value: 2 },

View File

@@ -90,7 +90,9 @@ export default {
const baseIndex = this.baseNameToIndexMap[itemName] || 0;
console.log(`你点击了【${itemName}】(序号:${baseIndex})`);
if (itemName === undefined) {
return;
}
// 路由跳转时携带序号(或名称+序号)
this.$router.push({

View File

@@ -85,9 +85,10 @@ export default {
},
grid: {
top: 30,
bottom: 30,
right: 20,
left: 60,
bottom: 5,
right: 10,
left: 25,
containLabel: true
},
xAxis: [
{

View File

@@ -84,10 +84,11 @@ export default {
// }
},
grid: {
top: 30,
bottom: 60,
right: 30,
left: 50,
top: 25,
bottom: 30,
right: 0,
left: 2,
containLabel: true
},
xAxis: [
{

View File

@@ -125,8 +125,7 @@ export default {
width: 264px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
// width: 190px;
height: 18px;
@@ -167,6 +166,7 @@ export default {
letter-spacing: 1px;
text-align: left;
font-style: normal;
z-index: 1000;
}
}

View File

@@ -94,7 +94,7 @@ getRateFlag(rate, real, target) {
grid: {
top: 10,
bottom: 30,
right: 50,
right: 80,
left: 30,
containLabel: true,
show: false // 隐藏grid背景避免干扰

View File

@@ -143,7 +143,7 @@ getRateFlag(rate, real, target) {
min-width: 300px; // 最小宽度限制
height: 205px;
background: #F9FCFF;
padding: 16px 16px 0;
padding: 16px 0 0 10px;
margin: 0 4px;
.title {
@@ -187,6 +187,7 @@ getRateFlag(rate, real, target) {
line-height: 18px;
letter-spacing: 1px;
text-align: left;
z-index: 1000;
}
}

View File

@@ -104,7 +104,7 @@ export default {
beilv: 1,
month: '',
value: 100,
factory: 5,
factory: null,
dateData: {},
monData: {},
relatedMon: {},
@@ -178,7 +178,13 @@ export default {
this.beilv = _this.clientWidth / 1920;
})();
};
this.factory = this.$route.query.factory ? Number(this.$route.query.factory) : 5
if(this.$route.query.factory){
this.factory =Number(this.$route.query.factory)
}else if(this.$store.getters.levelList.length > 0 && this.$store.getters.levelList[0].id !== 1) {
this.factory = this.$store.getters.levelList[0].id
}else{
this.factory = this.$store.getters.levelList[1].id
}
this.dateData = this.$route.query.dateData ? this.$route.query.dateData : undefined
},
methods: {

View File

@@ -4,7 +4,7 @@
<div :id="id" style="width: 100%; height:100%;"></div>
<div class="bottomTip">
<div class="precent">
<span class="precentNum">{{ detailData.completeRate || 0 }} </span>
<span class="precentNum">{{ detailData.completeRate || 0 }}% </span>
</div>
</div>
</div>

View File

@@ -142,8 +142,7 @@ getRateFlag(rate, real, target) {
width: 264px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
height: 18px;
font-family: PingFangSC, PingFang SC;
@@ -157,13 +156,14 @@ getRateFlag(rate, real, target) {
.number {
display: flex;
align-items: center;
gap: 30px;
gap: 6px;
height: 32px;
font-family: YouSheBiaoTiHei;
font-size: 32px;
color: #0B58FF;
line-height: 32px;
letter-spacing: 2px;
white-space: nowrap;
}
.mom {
@@ -178,6 +178,7 @@ getRateFlag(rate, real, target) {
display: flex;
align-items: center; // 箭头和文字垂直居中
gap: 4px; // 文字和箭头间距
z-index: 1000;
}
// 箭头样式优化

View File

@@ -160,7 +160,7 @@ getRateFlag(rate, real, target) {
width: 382px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
// width: 190px;
@@ -179,7 +179,7 @@ getRateFlag(rate, real, target) {
.number {
display: flex;
align-items: center;
gap: 30px;
gap: 6px;
// width: 190px;
height: 32px;
font-family: YouSheBiaoTiHei;
@@ -189,10 +189,11 @@ getRateFlag(rate, real, target) {
letter-spacing: 2px;
text-align: left;
font-style: normal;
white-space: nowrap;
}
.mom {
width: 97px;
width: 120px;
height: 18px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
@@ -202,6 +203,7 @@ getRateFlag(rate, real, target) {
letter-spacing: 1px;
text-align: left;
font-style: normal;
z-index: 1000;
}
}

View File

@@ -57,8 +57,8 @@ export default {
return {
activeButton: 0,
isDropdownShow: false,
selectedSort: null, // 选中的label
selectedSortValue: null, // 选中的value用于排序逻辑
selectedSort: '实际值:高~低', // 选中的label
selectedSortValue: 1, // 选中的value用于排序逻辑
profitOptions: [
{ label: '实际值:高~低', value: 1 },
{ label: '实际值:低~高', value: 2 },

View File

@@ -90,7 +90,9 @@ export default {
const baseIndex = this.baseNameToIndexMap[itemName] || 0;
console.log(`你点击了【${itemName}】(序号:${baseIndex})`);
if (itemName === undefined) {
return;
}
// 路由跳转时携带序号(或名称+序号)
this.$router.push({
path: 'netPriceAnalysisBase',

View File

@@ -85,9 +85,10 @@ export default {
},
grid: {
top: 30,
bottom: 30,
right: 20,
left: 60,
bottom: 5,
right: 10,
left: 25,
containLabel: true
},
xAxis: [
{

View File

@@ -83,11 +83,12 @@ export default {
// return html;
// }
},
grid: {
top: 30,
bottom: 60,
right: 30,
left: 50,
grid: {
top: 25,
bottom: 20,
right: 10,
left: 2,
containLabel: true
},
xAxis: [
{

View File

@@ -153,7 +153,7 @@ getRateFlag(rate, real, target) {
width: 264px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
// width: 190px;
@@ -172,7 +172,7 @@ getRateFlag(rate, real, target) {
.number {
display: flex;
align-items: center;
gap: 30px;
gap: 6px;
// width: 190px;
height: 32px;
font-family: YouSheBiaoTiHei;
@@ -182,6 +182,7 @@ getRateFlag(rate, real, target) {
letter-spacing: 2px;
text-align: left;
font-style: normal;
white-space: nowrap;
}
.mom {
@@ -195,6 +196,7 @@ getRateFlag(rate, real, target) {
letter-spacing: 1px;
text-align: left;
font-style: normal;
z-index: 1000;
}
}

View File

@@ -75,7 +75,7 @@ export default {
grid: {
top: 10,
bottom: 30,
right: 50,
right: 80,
left: 30,
containLabel: true,
show: false

View File

@@ -155,7 +155,7 @@ getRateFlag(rate, real, target) {
width: 382px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 16px;
padding: 16px 0 0 10px;
.title {
// width: 190px;
@@ -174,7 +174,7 @@ getRateFlag(rate, real, target) {
.number {
display: flex;
align-items: center;
gap: 30px;
gap: 6px;
// width: 190px;
height: 32px;
font-family: YouSheBiaoTiHei;
@@ -184,10 +184,11 @@ getRateFlag(rate, real, target) {
letter-spacing: 2px;
text-align: left;
font-style: normal;
white-space: nowrap;
}
.mom {
width: 97px;
width: 120px;
height: 18px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
@@ -197,6 +198,7 @@ getRateFlag(rate, real, target) {
letter-spacing: 1px;
text-align: left;
font-style: normal;
z-index: 1000;
}
}

View File

@@ -61,7 +61,7 @@ export default {
return {
activeButton: 0,
isDropdownShow: false,
selectedProfit: null, // 选中的名称初始为null
selectedProfit: '营业收入', // 选中的名称初始为null
profitOptions: [
'营业收入',
'单价',

View File

@@ -4,7 +4,7 @@
<div :id="id" style="width: 100%; height:100%;"></div>
<div class="bottomTip">
<div class="precent">
<span class="precentNum">{{ detailData.rate || 0 }} </span>
<span class="precentNum">{{ detailData.rate || 0 }}% </span>
</div>
</div>
</div>

Some files were not shown because too many files have changed in this diff Show More