¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢å
¬åå表 |
| | | export function listNotice(query) { |
| | | return request({ |
| | | url: '/collaborativeApproval/notice/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢å
¬åè¯¦ç» |
| | | export function getNotice(noticeId) { |
| | | return request({ |
| | | url: '/collaborativeApproval/notice/' + noticeId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢å
Œ |
| | | export function addNotice(data) { |
| | | return request({ |
| | | url: '/collaborativeApproval/notice', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹å
Œ |
| | | export function updateNotice(data) { |
| | | return request({ |
| | | url: '/collaborativeApproval/notice', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // å é¤å
Œ |
| | | export function delNotice(noticeId) { |
| | | return request({ |
| | | url: '/collaborativeApproval/notice/' + noticeId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // æ¹éå é¤å
Œ |
| | | export function delNoticeBatch(noticeIds) { |
| | | return request({ |
| | | url: '/collaborativeApproval/notice/batch', |
| | | method: 'delete', |
| | | data: noticeIds |
| | | }) |
| | | } |
| | | |
| | | // åå¸å
Œ |
| | | export function publishNotice(noticeId) { |
| | | return request({ |
| | | url: '/collaborativeApproval/notice/publish/' + noticeId, |
| | | method: 'put' |
| | | }) |
| | | } |
| | | |
| | | // ä¸çº¿å
Œ |
| | | export function offlineNotice(noticeId) { |
| | | return request({ |
| | | url: '/collaborativeApproval/notice/offline/' + noticeId, |
| | | method: 'put' |
| | | }) |
| | | } |
| | |
| | | // 设å¤è½è-å页æ¥è¯¢ |
| | | export function equipmentEnergyListPage(query) { |
| | | return request({ |
| | | url: '/equipmentEnergyConsumption/listPage', |
| | | method: 'get', |
| | | url: "/equipmentEnergyConsumption/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }) |
| | | }); |
| | | } |
| | | // -è½æºè¶å¿-å页æ¥è¯¢ |
| | | export function listPageByTrend(query) { |
| | | return request({ |
| | | url: '/equipmentEnergyConsumption/listPageByTrend', |
| | | method: 'get', |
| | | url: "/equipmentEnergyConsumption/listPageByTrend", |
| | | method: "get", |
| | | params: query, |
| | | }) |
| | | }); |
| | | } |
| | | // åºå-å页æ¥è¯¢ |
| | | export function areaListPage(query) { |
| | | return request({ |
| | | url: '/electricityConsumptionArea/listPage', |
| | | method: 'get', |
| | | url: "/electricityConsumptionArea/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | // åºå-æ |
| | | export function areaListTree(query) { |
| | | return request({ |
| | | url: "/electricityConsumptionArea/list", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | // æ¶é´å¨æ-å页æ¥è¯¢ |
| | | export function periodListPage(query) { |
| | | return request({ |
| | | url: '/energyPeriod/listPage', |
| | | method: 'get', |
| | | url: "/energyPeriod/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | // 设å¤è½è-å é¤ |
| | | export function equipmentEnergyDelete(query) { |
| | | return request({ |
| | | url: '/equipmentEnergyConsumption/delete', |
| | | method: 'delete', |
| | | url: "/equipmentEnergyConsumption/delete", |
| | | method: "delete", |
| | | data: query, |
| | | }) |
| | | }); |
| | | } |
| | | // åºå-å é¤ |
| | | export function areaDelete(query) { |
| | | return request({ |
| | | url: '/electricityConsumptionArea/delete', |
| | | method: 'delete', |
| | | url: "/electricityConsumptionArea/delete", |
| | | method: "delete", |
| | | data: query, |
| | | }) |
| | | }); |
| | | } |
| | | // æ¶é´å¨æ-å é¤ |
| | | export function periodDelete(query) { |
| | | return request({ |
| | | url: '/energyPeriod/delete', |
| | | method: 'delete', |
| | | url: "/energyPeriod/delete", |
| | | method: "delete", |
| | | data: query, |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | |
| | | // 设å¤è½è-æ°å¢ |
| | | export function equipmentEnergyAdd(query) { |
| | | return request({ |
| | | url: '/equipmentEnergyConsumption/add', |
| | | method: 'post', |
| | | url: "/equipmentEnergyConsumption/add", |
| | | method: "post", |
| | | data: query, |
| | | }) |
| | | }); |
| | | } |
| | | // åºå-æ°å¢ |
| | | export function areaAdd(query) { |
| | | return request({ |
| | | url: '/electricityConsumptionArea/add', |
| | | method: 'post', |
| | | url: "/electricityConsumptionArea/add", |
| | | method: "post", |
| | | data: query, |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | // æ¶é´å¨æ-æ°å¢ |
| | | export function periodAdd(query) { |
| | | return request({ |
| | | url: '/energyPeriod/add', |
| | | method: 'post', |
| | | url: "/energyPeriod/add", |
| | | method: "post", |
| | | data: query, |
| | | }) |
| | | }); |
| | | } |
| | | // 设å¤è½è-ä¿®æ¹ |
| | | export function equipmentEnergyUpdate(query) { |
| | | return request({ |
| | | url: '/equipmentEnergyConsumption/update', |
| | | method: 'post', |
| | | url: "/equipmentEnergyConsumption/update", |
| | | method: "post", |
| | | data: query, |
| | | }) |
| | | }); |
| | | } |
| | | //åºå-ä¿®æ¹ |
| | | export function areaUpdate(query) { |
| | | return request({ |
| | | url: '/electricityConsumptionArea/update', |
| | | method: 'post', |
| | | url: "/electricityConsumptionArea/update", |
| | | method: "post", |
| | | data: query, |
| | | }) |
| | | }); |
| | | } |
| | | // æ¶é´å¨æ-ä¿®æ¹ |
| | | export function periodUpdate(query) { |
| | | return request({ |
| | | url: '/energyPeriod/update', |
| | | method: 'post', |
| | | url: "/energyPeriod/update", |
| | | method: "post", |
| | | data: query, |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | |
| | | // 设å¤ä¸ææ¡æ¥è¯¢ |
| | | export function deviceList(query) { |
| | | return request({ |
| | | url: '/equipmentEnergyConsumption/deviceList', |
| | | method: 'get', |
| | | }) |
| | | } |
| | | url: "/equipmentEnergyConsumption/deviceList", |
| | | method: "get", |
| | | }); |
| | | } |
| | |
| | | import { createWebHistory, createRouter } from 'vue-router'
|
| | | /* Layout */
|
| | | import Layout from '@/layout'
|
| | |
|
| | | /**
|
| | | * Note: è·¯ç±é
置项
|
| | | *
|
| | | * hidden: true // å½è®¾ç½® true çæ¶å该路ç±ä¸ä¼åä¾§è¾¹æ åºç° å¦401ï¼loginç页é¢ï¼æè
å¦ä¸äºç¼è¾é¡µé¢/edit/1
|
| | | * alwaysShow: true // å½ä½ ä¸ä¸ªè·¯ç±ä¸é¢ç children 声æçè·¯ç±å¤§äº1个æ¶ï¼èªå¨ä¼åæåµå¥ç模å¼--å¦ç»ä»¶é¡µé¢
|
| | | * // åªæä¸ä¸ªæ¶ï¼ä¼å°é£ä¸ªåè·¯ç±å½åæ ¹è·¯ç±æ¾ç¤ºå¨ä¾§è¾¹æ --å¦å¼å¯¼é¡µé¢
|
| | | * // è¥ä½ æ³ä¸ç®¡è·¯ç±ä¸é¢ç children 声æç个æ°é½æ¾ç¤ºä½ çæ ¹è·¯ç±
|
| | | * // ä½ å¯ä»¥è®¾ç½® alwaysShow: trueï¼è¿æ ·å®å°±ä¼å¿½ç¥ä¹åå®ä¹çè§åï¼ä¸ç´æ¾ç¤ºæ ¹è·¯ç±
|
| | | * redirect: noRedirect // å½è®¾ç½® noRedirect çæ¶å该路ç±å¨é¢å
å±å¯¼èªä¸ä¸å¯è¢«ç¹å»
|
| | | * name:'router-name' // 设å®è·¯ç±çååï¼ä¸å®è¦å¡«åä¸ç¶ä½¿ç¨<keep-alive>æ¶ä¼åºç°åç§é®é¢
|
| | | * query: '{"id": 1, "name": "ry"}' // 访é®è·¯ç±çé»è®¤ä¼ éåæ°
|
| | | * roles: ['admin', 'common'] // 访é®è·¯ç±çè§è²æé
|
| | | * permissions: ['a:a:a', 'b:b:b'] // 访é®è·¯ç±çèåæé
|
| | | * meta : {
|
| | | noCache: true // å¦æè®¾ç½®ä¸ºtrueï¼åä¸ä¼è¢« <keep-alive> ç¼å(é»è®¤ false)
|
| | | title: 'title' // 设置该路ç±å¨ä¾§è¾¹æ åé¢å
å±ä¸å±ç¤ºçåå
|
| | | icon: 'svg-name' // 设置该路ç±ç徿 ï¼å¯¹åºè·¯å¾src/assets/icons/svg
|
| | | breadcrumb: false // å¦æè®¾ç½®ä¸ºfalseï¼åä¸ä¼å¨breadcrumbé¢å
å±ä¸æ¾ç¤º
|
| | | activeMenu: '/system/user' // å½è·¯ç±è®¾ç½®äºè¯¥å±æ§ï¼åä¼é«äº®ç¸å¯¹åºçä¾§è¾¹æ ã
|
| | | }
|
| | | */
|
| | |
|
| | | // å
Œ
±è·¯ç±
|
| | | export const constantRoutes = [
|
| | | {
|
| | | path: '/redirect',
|
| | | component: Layout,
|
| | | hidden: true,
|
| | | children: [
|
| | | {
|
| | | path: '/redirect/:path(.*)',
|
| | | component: () => import('@/views/redirect/index.vue')
|
| | | }
|
| | | ]
|
| | | },
|
| | | {
|
| | | path: '/login',
|
| | | component: () => import('@/views/login'),
|
| | | hidden: true
|
| | | },
|
| | | {
|
| | | path: '/register',
|
| | | component: () => import('@/views/register'),
|
| | | hidden: true
|
| | | },
|
| | | {
|
| | | path: "/:pathMatch(.*)*",
|
| | | component: () => import('@/views/error/404'),
|
| | | hidden: true
|
| | | },
|
| | | {
|
| | | path: '/401',
|
| | | component: () => import('@/views/error/401'),
|
| | | hidden: true
|
| | | },
|
| | |
|
| | | {
|
| | | path: '',
|
| | | component: Layout,
|
| | | redirect: '/index',
|
| | | children: [
|
| | | {
|
| | | path: '/index',
|
| | | component: () => import('@/views/index'),
|
| | | name: 'Index',
|
| | | meta: { title: 'é¦é¡µ', icon: 'dashboard', affix: true }
|
| | | }
|
| | | ]
|
| | | },
|
| | | // {
|
| | | // path: '/equipment',
|
| | | // component: Layout,
|
| | | // redirect: '/equipment/iot-monitor',
|
| | | // children: [
|
| | | // {
|
| | | // path: 'iot-monitor',
|
| | | // component: () => import('@/views/equipmentManagement/iotMonitor/index.vue'),
|
| | | // name: 'IoTMonitor',
|
| | | // meta: { title: 'IoTçæ§', icon: 'monitor', noCache: true }
|
| | | // }
|
| | | // ]
|
| | | // },
|
| | | // {
|
| | | // path: '/main/MobileChat',
|
| | | // component: Layout,
|
| | | // redirect: '',
|
| | | // hidden: true,
|
| | | // children: [
|
| | | // {
|
| | | // path: '',
|
| | | // component: () => import('@/views/chatHome/chatHomeIndex/MobileChat'),
|
| | | // name: 'MobileChat',
|
| | | // meta: { title: 'AI对è¯', icon: 'dashboard', affix: true}
|
| | | // }
|
| | | // ]
|
| | | // },
|
| | | {
|
| | | path: '/user',
|
| | | component: Layout,
|
| | | hidden: true,
|
| | | redirect: 'noredirect',
|
| | | children: [
|
| | | {
|
| | | path: 'profile',
|
| | | component: () => import('@/views/system/user/profile/index'),
|
| | | name: 'Profile',
|
| | | meta: { title: '个人ä¸å¿', icon: 'user' }
|
| | | }
|
| | | ]
|
| | | }
|
| | | ]
|
| | |
|
| | | // å¨æè·¯ç±ï¼åºäºç¨æ·æé卿å»å è½½
|
| | | export const dynamicRoutes = [
|
| | | {
|
| | | path: '/system/user-auth',
|
| | | component: Layout,
|
| | | hidden: true,
|
| | | permissions: ['system:user:edit'],
|
| | | children: [
|
| | | {
|
| | | path: 'role/:userId(\\d+)',
|
| | | component: () => import('@/views/system/user/authRole'),
|
| | | name: 'AuthRole',
|
| | | meta: { title: 'åé
è§è²', activeMenu: '/system/user' }
|
| | | }
|
| | | ]
|
| | | },
|
| | | {
|
| | | path: '/system/role-auth',
|
| | | component: Layout,
|
| | | hidden: true,
|
| | | permissions: ['system:role:edit'],
|
| | | children: [
|
| | | {
|
| | | path: 'user/:roleId(\\d+)',
|
| | | component: () => import('@/views/system/role/authUser'),
|
| | | name: 'AuthUser',
|
| | | meta: { title: 'åé
ç¨æ·', activeMenu: '/system/role' }
|
| | | }
|
| | | ]
|
| | | },
|
| | | {
|
| | | path: '/system/dict-data',
|
| | | component: Layout,
|
| | | hidden: true,
|
| | | permissions: ['system:dict:list'],
|
| | | children: [
|
| | | {
|
| | | path: 'index/:dictId(\\d+)',
|
| | | component: () => import('@/views/system/dict/data'),
|
| | | name: 'Data',
|
| | | meta: { title: 'åå
¸æ°æ®', activeMenu: '/system/dict' }
|
| | | }
|
| | | ]
|
| | | },
|
| | | {
|
| | | path: '/monitor/job-log',
|
| | | component: Layout,
|
| | | hidden: true,
|
| | | permissions: ['monitor:job:list'],
|
| | | children: [
|
| | | {
|
| | | path: 'index/:jobId(\\d+)',
|
| | | component: () => import('@/views/monitor/job/log'),
|
| | | name: 'JobLog',
|
| | | meta: { title: 'è°åº¦æ¥å¿', activeMenu: '/monitor/job' }
|
| | | }
|
| | | ]
|
| | | },
|
| | | {
|
| | | path: '/tool/gen-edit',
|
| | | component: Layout,
|
| | | hidden: true,
|
| | | permissions: ['tool:gen:edit'],
|
| | | children: [
|
| | | {
|
| | | path: 'index/:tableId(\\d+)',
|
| | | component: () => import('@/views/tool/gen/editTable'),
|
| | | name: 'GenEdit',
|
| | | meta: { title: 'ä¿®æ¹çæé
ç½®', activeMenu: '/tool/gen' }
|
| | | }
|
| | | ]
|
| | | }
|
| | | ]
|
| | |
|
| | | const router = createRouter({
|
| | | history: createWebHistory(),
|
| | | routes: constantRoutes,
|
| | | scrollBehavior(to, from, savedPosition) {
|
| | | if (savedPosition) {
|
| | | return savedPosition
|
| | | }
|
| | | return { top: 0 }
|
| | | },
|
| | | })
|
| | |
|
| | | export default router
|
| | | import { createWebHistory, createRouter } from 'vue-router' |
| | | /* Layout */ |
| | | import Layout from '@/layout' |
| | | |
| | | /** |
| | | * Note: è·¯ç±é
置项 |
| | | * |
| | | * hidden: true // å½è®¾ç½® true çæ¶å该路ç±ä¸ä¼åä¾§è¾¹æ åºç° å¦401ï¼loginç页é¢ï¼æè
å¦ä¸äºç¼è¾é¡µé¢/edit/1 |
| | | * alwaysShow: true // å½ä½ ä¸ä¸ªè·¯ç±ä¸é¢ç children 声æçè·¯ç±å¤§äº1个æ¶ï¼èªå¨ä¼åæåµå¥ç模å¼--å¦ç»ä»¶é¡µé¢ |
| | | * // åªæä¸ä¸ªæ¶ï¼ä¼å°é£ä¸ªåè·¯ç±å½åæ ¹è·¯ç±æ¾ç¤ºå¨ä¾§è¾¹æ --å¦å¼å¯¼é¡µé¢ |
| | | * // è¥ä½ æ³ä¸ç®¡è·¯ç±ä¸é¢ç children 声æç个æ°é½æ¾ç¤ºä½ çæ ¹è·¯ç± |
| | | * // ä½ å¯ä»¥è®¾ç½® alwaysShow: trueï¼è¿æ ·å®å°±ä¼å¿½ç¥ä¹åå®ä¹çè§åï¼ä¸ç´æ¾ç¤ºæ ¹è·¯ç± |
| | | * redirect: noRedirect // å½è®¾ç½® noRedirect çæ¶å该路ç±å¨é¢å
å±å¯¼èªä¸ä¸å¯è¢«ç¹å» |
| | | * name:'router-name' // 设å®è·¯ç±çååï¼ä¸å®è¦å¡«åä¸ç¶ä½¿ç¨<keep-alive>æ¶ä¼åºç°åç§é®é¢ |
| | | * query: '{"id": 1, "name": "ry"}' // 访é®è·¯ç±çé»è®¤ä¼ éåæ° |
| | | * roles: ['admin', 'common'] // 访é®è·¯ç±çè§è²æé |
| | | * permissions: ['a:a:a', 'b:b:b'] // 访é®è·¯ç±çèåæé |
| | | * meta : { |
| | | noCache: true // å¦æè®¾ç½®ä¸ºtrueï¼åä¸ä¼è¢« <keep-alive> ç¼å(é»è®¤ false) |
| | | title: 'title' // 设置该路ç±å¨ä¾§è¾¹æ åé¢å
å±ä¸å±ç¤ºçåå |
| | | icon: 'svg-name' // 设置该路ç±ç徿 ï¼å¯¹åºè·¯å¾src/assets/icons/svg |
| | | breadcrumb: false // å¦æè®¾ç½®ä¸ºfalseï¼åä¸ä¼å¨breadcrumbé¢å
å±ä¸æ¾ç¤º |
| | | activeMenu: '/system/user' // å½è·¯ç±è®¾ç½®äºè¯¥å±æ§ï¼åä¼é«äº®ç¸å¯¹åºçä¾§è¾¹æ ã |
| | | } |
| | | */ |
| | | |
| | | // å
Œ
±è·¯ç± |
| | | export const constantRoutes = [ |
| | | { |
| | | path: '/redirect', |
| | | component: Layout, |
| | | hidden: true, |
| | | children: [ |
| | | { |
| | | path: '/redirect/:path(.*)', |
| | | component: () => import('@/views/redirect/index.vue') |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/login', |
| | | component: () => import('@/views/login'), |
| | | hidden: true |
| | | }, |
| | | { |
| | | path: '/register', |
| | | component: () => import('@/views/register'), |
| | | hidden: true |
| | | }, |
| | | { |
| | | path: "/:pathMatch(.*)*", |
| | | component: () => import('@/views/error/404'), |
| | | hidden: true |
| | | }, |
| | | { |
| | | path: '/401', |
| | | component: () => import('@/views/error/401'), |
| | | hidden: true |
| | | }, |
| | | |
| | | { |
| | | path: '', |
| | | component: Layout, |
| | | redirect: '/index', |
| | | children: [ |
| | | { |
| | | path: '/index', |
| | | component: () => import('@/views/index'), |
| | | name: 'Index', |
| | | meta: { title: 'é¦é¡µ', icon: 'dashboard', affix: true } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/user', |
| | | component: Layout, |
| | | hidden: true, |
| | | redirect: 'noredirect', |
| | | children: [ |
| | | { |
| | | path: 'profile', |
| | | component: () => import('@/views/system/user/profile/index'), |
| | | name: 'Profile', |
| | | meta: { title: '个人ä¸å¿', icon: 'user' } |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | |
| | | // å¨æè·¯ç±ï¼åºäºç¨æ·æé卿å»å è½½ |
| | | export const dynamicRoutes = [ |
| | | { |
| | | path: '/system/user-auth', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:user:edit'], |
| | | children: [ |
| | | { |
| | | path: 'role/:userId(\\d+)', |
| | | component: () => import('@/views/system/user/authRole'), |
| | | name: 'AuthRole', |
| | | meta: { title: 'åé
è§è²', activeMenu: '/system/user' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/main/MobileChat', |
| | | component: Layout, |
| | | redirect: '', |
| | | hidden: true, |
| | | permissions: ['MobileChat:edit'], |
| | | children: [ |
| | | { |
| | | path: '', |
| | | component: () => import('@/views/chatHome/chatHomeIndex/MobileChat'), |
| | | name: 'MobileChat', |
| | | meta: { title: 'AI对è¯', activeMenu: '/chatHome/chatHomeIndex'} |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/system/role-auth', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:role:edit'], |
| | | children: [ |
| | | { |
| | | path: 'user/:roleId(\\d+)', |
| | | component: () => import('@/views/system/role/authUser'), |
| | | name: 'AuthUser', |
| | | meta: { title: 'åé
ç¨æ·', activeMenu: '/system/role' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/system/dict-data', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:dict:list'], |
| | | children: [ |
| | | { |
| | | path: 'index/:dictId(\\d+)', |
| | | component: () => import('@/views/system/dict/data'), |
| | | name: 'Data', |
| | | meta: { title: 'åå
¸æ°æ®', activeMenu: '/system/dict' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/monitor/job-log', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['monitor:job:list'], |
| | | children: [ |
| | | { |
| | | path: 'index/:jobId(\\d+)', |
| | | component: () => import('@/views/monitor/job/log'), |
| | | name: 'JobLog', |
| | | meta: { title: 'è°åº¦æ¥å¿', activeMenu: '/monitor/job' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/tool/gen-edit', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['tool:gen:edit'], |
| | | children: [ |
| | | { |
| | | path: 'index/:tableId(\\d+)', |
| | | component: () => import('@/views/tool/gen/editTable'), |
| | | name: 'GenEdit', |
| | | meta: { title: 'ä¿®æ¹çæé
ç½®', activeMenu: '/tool/gen' } |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | |
| | | const router = createRouter({ |
| | | history: createWebHistory(), |
| | | routes: constantRoutes, |
| | | scrollBehavior(to, from, savedPosition) { |
| | | if (savedPosition) { |
| | | return savedPosition |
| | | } |
| | | return { top: 0 } |
| | | }, |
| | | }) |
| | | |
| | | export default router |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="container"> |
| | | <!-- å¼å
¥index.vueç»ä»¶å¹¶ä¼ éåæ° --> |
| | | <ApprovalProcessIndex :approveType="1" /> |
| | | </div> |
| | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .app-container { |
| | | .container { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="container"> |
| | | <!-- å¼å
¥index.vueç»ä»¶å¹¶ä¼ éåæ° --> |
| | | <ApprovalProcessIndex :approveType="2" /> |
| | | </div> |
| | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .app-container { |
| | | .container { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="container"> |
| | | <!-- å¼å
¥index.vueç»ä»¶å¹¶ä¼ éåæ° --> |
| | | <ApprovalProcessIndex :approveType="3" /> |
| | | </div> |
| | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .app-container { |
| | | .container { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="container"> |
| | | <!-- å¼å
¥index.vueç»ä»¶å¹¶ä¼ éåæ° --> |
| | | <ApprovalProcessIndex :approveType="4" /> |
| | | </div> |
| | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .app-container { |
| | | .container { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <!-- 页颿 é¢ --> |
| | | <div class="page-header"> |
| | | <h2>ä¼è®®çæ¿</h2> |
| | | <!-- <el-button type="primary" @click="createMeeting">å建ä¼è®®</el-button>--> |
| | | </div> |
| | | |
| | | <!-- ä¼è®®ç»è®¡å¡ç --> |
| | | <div class="stats-cards"> |
| | | <el-card class="stat-card"> |
| | | <div class="stat-content"> |
| | | <div class="stat-number">{{ stats.total }}</div> |
| | | <div class="stat-label">æ»ä¼è®®æ°</div> |
| | | </div> |
| | | </el-card> |
| | | <el-card class="stat-card"> |
| | | <div class="stat-content"> |
| | | <div class="stat-number">{{ stats.ongoing }}</div> |
| | | <div class="stat-label">è¿è¡ä¸</div> |
| | | </div> |
| | | </el-card> |
| | | <el-card class="stat-card"> |
| | | <div class="stat-content"> |
| | | <div class="stat-number">{{ stats.completed }}</div> |
| | | <div class="stat-label">已宿</div> |
| | | </div> |
| | | </el-card> |
| | | <el-card class="stat-card"> |
| | | <div class="stat-content"> |
| | | <div class="stat-number">{{ stats.upcoming }}</div> |
| | | <div class="stat-label">å³å°å¼å§</div> |
| | | </div> |
| | | </el-card> |
| | | </div> |
| | | |
| | | <!-- ä¼è®®å表 --> |
| | | <div class="meeting-list"> |
| | | <el-card v-for="meeting in meetings" :key="meeting.id" class="meeting-card"> |
| | | <div class="meeting-header"> |
| | | <div class="meeting-title"> |
| | | <h3>{{ meeting.title }}</h3> |
| | | <el-tag :type="getStatusType(meeting.status)" size="small"> |
| | | {{ getStatusText(meeting.status) }} |
| | | </el-tag> |
| | | </div> |
| | | <div class="meeting-time"> |
| | | <el-icon><Clock /></el-icon> |
| | | {{ formatTime(meeting.startTime) }} - {{ formatTime(meeting.endTime) }} |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="meeting-info"> |
| | | <div class="info-item"> |
| | | <el-icon><Location /></el-icon> |
| | | <span>{{ meeting.location }}</span> |
| | | </div> |
| | | <div class="info-item"> |
| | | <el-icon><User /></el-icon> |
| | | <span>主æäºº: {{ meeting.host }}</span> |
| | | </div> |
| | | <div class="info-item"> |
| | | <el-icon><UserFilled /></el-icon> |
| | | <span>åä¼äººæ°: {{ meeting.participants.length }}人</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="meeting-agenda"> |
| | | <h4>è®®ç¨å®æ</h4> |
| | | <div class="agenda-list"> |
| | | <div |
| | | v-for="(agenda, index) in meeting.agenda" |
| | | :key="index" |
| | | class="agenda-item" |
| | | :class="{ 'active': agenda.status === 'active', 'completed': agenda.status === 'completed' }" |
| | | > |
| | | <span class="agenda-time">{{ agenda.time }}</span> |
| | | <span class="agenda-content">{{ agenda.content }}</span> |
| | | <el-tag |
| | | :type="getAgendaStatusType(agenda.status)" |
| | | size="small" |
| | | > |
| | | {{ getAgendaStatusText(agenda.status) }} |
| | | </el-tag> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- <div class="meeting-actions">--> |
| | | <!-- <el-button type="primary" size="small" @click="joinMeeting(meeting)">--> |
| | | <!-- å å
¥ä¼è®®--> |
| | | <!-- </el-button>--> |
| | | <!-- <el-button type="info" size="small" @click="viewDetails(meeting)">--> |
| | | <!-- æ¥ç详æ
--> |
| | | <!-- </el-button>--> |
| | | <!-- <el-button type="warning" size="small" @click="editMeeting(meeting)">--> |
| | | <!-- ç¼è¾--> |
| | | <!-- </el-button>--> |
| | | <!-- </div>--> |
| | | </el-card> |
| | | </div> |
| | | |
| | | <!-- å建ä¼è®®å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="dialogVisible" title="å建ä¼è®®" width="600px"> |
| | | <el-form :model="meetingForm" label-width="100px"> |
| | | <el-form-item label="ä¼è®®æ é¢"> |
| | | <el-input v-model="meetingForm.title" placeholder="请è¾å
¥ä¼è®®æ é¢" /> |
| | | </el-form-item> |
| | | <el-form-item label="ä¼è®®æ¶é´"> |
| | | <el-date-picker |
| | | v-model="meetingForm.timeRange" |
| | | type="datetimerange" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¶é´" |
| | | end-placeholder="ç»ææ¶é´" |
| | | format="YYYY-MM-DD HH:mm" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ä¼è®®å°ç¹"> |
| | | <el-input v-model="meetingForm.location" placeholder="请è¾å
¥ä¼è®®å°ç¹" /> |
| | | </el-form-item> |
| | | <el-form-item label="主æäºº"> |
| | | <el-input v-model="meetingForm.host" placeholder="请è¾å
¥ä¸»æäººå§å" /> |
| | | </el-form-item> |
| | | <el-form-item label="ä¼è®®æè¿°"> |
| | | <el-input |
| | | v-model="meetingForm.description" |
| | | type="textarea" |
| | | :rows="3" |
| | | placeholder="请è¾å
¥ä¼è®®æè¿°" |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="dialogVisible = false">åæ¶</el-button> |
| | | <el-button type="primary" @click="submitMeeting">ç¡®å®</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from 'vue' |
| | | import { ElMessage } from 'element-plus' |
| | | import { Clock, Location, User, UserFilled } from '@element-plus/icons-vue' |
| | | |
| | | // ç»è®¡æ°æ® |
| | | const stats = reactive({ |
| | | total: 12, |
| | | ongoing: 3, |
| | | completed: 7, |
| | | upcoming: 2 |
| | | }) |
| | | |
| | | // ä¼è®®æ°æ® |
| | | const meetings = ref([ |
| | | { |
| | | id: 1, |
| | | title: '产åå¼åå¨ä¼', |
| | | status: 'ongoing', |
| | | startTime: '2024-01-15 09:00:00', |
| | | endTime: '2024-01-15 10:30:00', |
| | | location: 'ä¼è®®å®¤A', |
| | | host: 'å¼ ç»ç', |
| | | participants: ['å¼ ç»ç', 'æå·¥ç¨å¸', 'ç设计å¸', 'èµµæµè¯å'], |
| | | agenda: [ |
| | | { time: '09:00-09:15', content: 'ä¸å¨å·¥ä½æ»ç»', status: 'completed' }, |
| | | { time: '09:15-09:45', content: 'æ¬å¨å¼å计å', status: 'active' }, |
| | | { time: '09:45-10:00', content: 'ææ¯é¾ç¹è®¨è®º', status: 'pending' }, |
| | | { time: '10:00-10:30', content: 'é®é¢åé¦ä¸è§£å³', status: 'pending' } |
| | | ] |
| | | }, |
| | | { |
| | | id: 2, |
| | | title: '客æ·éæ±è¯å®¡ä¼', |
| | | status: 'upcoming', |
| | | startTime: '2024-01-15 14:00:00', |
| | | endTime: '2024-01-15 15:00:00', |
| | | location: '线ä¸ä¼è®®', |
| | | host: 'éæ»ç', |
| | | participants: ['éæ»ç', 'å产åç»ç', 'å客æ·ç»ç', '客æ·ä»£è¡¨'], |
| | | agenda: [ |
| | | { time: '14:00-14:20', content: 'éæ±èæ¯ä»ç»', status: 'pending' }, |
| | | { time: '14:20-14:40', content: 'åè½éæ±åæ', status: 'pending' }, |
| | | { time: '14:40-15:00', content: 'ææ¯å¯è¡æ§è¯ä¼°', status: 'pending' } |
| | | ] |
| | | }, |
| | | { |
| | | id: 3, |
| | | title: 'å¢é建设活å¨', |
| | | status: 'completed', |
| | | startTime: '2024-01-14 16:00:00', |
| | | endTime: '2024-01-14 18:00:00', |
| | | location: 'å
¬å¸å¤§å
', |
| | | host: '人äºé¨', |
| | | participants: ['å
¨ä½åå·¥'], |
| | | agenda: [ |
| | | { time: '16:00-16:30', content: 'å¢é游æ', status: 'completed' }, |
| | | { time: '16:30-17:00', content: 'ç»éªå享', status: 'completed' }, |
| | | { time: '17:00-18:00', content: 'èªç±äº¤æµ', status: 'completed' } |
| | | ] |
| | | } |
| | | ]) |
| | | |
| | | // å¯¹è¯æ¡ç¸å
³ |
| | | const dialogVisible = ref(false) |
| | | const meetingForm = reactive({ |
| | | title: '', |
| | | timeRange: [], |
| | | location: '', |
| | | host: '', |
| | | description: '' |
| | | }) |
| | | |
| | | // è·åç¶æç±»å |
| | | const getStatusType = (status) => { |
| | | const statusMap = { |
| | | 'ongoing': 'success', |
| | | 'upcoming': 'warning', |
| | | 'completed': 'info' |
| | | } |
| | | return statusMap[status] || 'info' |
| | | } |
| | | |
| | | // è·åç¶æææ¬ |
| | | const getStatusText = (status) => { |
| | | const statusMap = { |
| | | 'ongoing': 'è¿è¡ä¸', |
| | | 'upcoming': 'å³å°å¼å§', |
| | | 'completed': '已宿' |
| | | } |
| | | return statusMap[status] || 'æªç¥' |
| | | } |
| | | |
| | | // è·åè®®ç¨ç¶æç±»å |
| | | const getAgendaStatusType = (status) => { |
| | | const statusMap = { |
| | | 'completed': 'success', |
| | | 'active': 'warning', |
| | | 'pending': 'info' |
| | | } |
| | | return statusMap[status] || 'info' |
| | | } |
| | | |
| | | // è·åè®®ç¨ç¶æææ¬ |
| | | const getAgendaStatusText = (status) => { |
| | | const statusMap = { |
| | | 'completed': '已宿', |
| | | 'active': 'è¿è¡ä¸', |
| | | 'pending': 'å¾
å¼å§' |
| | | } |
| | | return statusMap[status] || 'æªç¥' |
| | | } |
| | | |
| | | // æ ¼å¼åæ¶é´ |
| | | const formatTime = (timeStr) => { |
| | | const date = new Date(timeStr) |
| | | return date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }) |
| | | } |
| | | |
| | | // å建ä¼è®® |
| | | const createMeeting = () => { |
| | | dialogVisible.value = true |
| | | // é置表å |
| | | Object.assign(meetingForm, { |
| | | title: '', |
| | | timeRange: [], |
| | | location: '', |
| | | host: '', |
| | | description: '' |
| | | }) |
| | | } |
| | | |
| | | // æäº¤ä¼è®® |
| | | const submitMeeting = () => { |
| | | if (!meetingForm.title || !meetingForm.timeRange.length || !meetingForm.location || !meetingForm.host) { |
| | | ElMessage.warning('请填å宿´çä¼è®®ä¿¡æ¯') |
| | | return |
| | | } |
| | | |
| | | // å建æ°ä¼è®® |
| | | const newMeeting = { |
| | | id: Date.now(), |
| | | title: meetingForm.title, |
| | | status: 'upcoming', |
| | | startTime: meetingForm.timeRange[0], |
| | | endTime: meetingForm.timeRange[1], |
| | | location: meetingForm.location, |
| | | host: meetingForm.host, |
| | | participants: [meetingForm.host], |
| | | agenda: [ |
| | | { time: 'å¾
å®', content: 'è®®ç¨å¾
å®', status: 'pending' } |
| | | ] |
| | | } |
| | | |
| | | meetings.value.unshift(newMeeting) |
| | | stats.total++ |
| | | stats.upcoming++ |
| | | |
| | | ElMessage.success('ä¼è®®å建æå') |
| | | dialogVisible.value = false |
| | | } |
| | | |
| | | // å å
¥ä¼è®® |
| | | const joinMeeting = (meeting) => { |
| | | ElMessage.success(`å·²å å
¥ä¼è®®ï¼${meeting.title}`) |
| | | } |
| | | |
| | | // æ¥ç详æ
|
| | | const viewDetails = (meeting) => { |
| | | ElMessage.info(`æ¥çä¼è®®è¯¦æ
ï¼${meeting.title}`) |
| | | } |
| | | |
| | | // ç¼è¾ä¼è®® |
| | | const editMeeting = (meeting) => { |
| | | ElMessage.info(`ç¼è¾ä¼è®®ï¼${meeting.title}`) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | console.log('ä¼è®®çæ¿é¡µé¢å è½½å®æ') |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .app-container { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .page-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .page-header h2 { |
| | | margin: 0; |
| | | color: #303133; |
| | | } |
| | | |
| | | .stats-cards { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); |
| | | gap: 20px; |
| | | margin-bottom: 30px; |
| | | } |
| | | |
| | | .stat-card { |
| | | text-align: center; |
| | | } |
| | | |
| | | .stat-content { |
| | | padding: 10px; |
| | | } |
| | | |
| | | .stat-number { |
| | | font-size: 32px; |
| | | font-weight: bold; |
| | | color: #409eff; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .stat-label { |
| | | font-size: 14px; |
| | | color: #606266; |
| | | } |
| | | |
| | | .meeting-list { |
| | | display: grid; |
| | | gap: 20px; |
| | | } |
| | | |
| | | .meeting-card { |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | .meeting-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: flex-start; |
| | | margin-bottom: 15px; |
| | | } |
| | | |
| | | .meeting-title { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 10px; |
| | | } |
| | | |
| | | .meeting-title h3 { |
| | | margin: 0; |
| | | color: #303133; |
| | | } |
| | | |
| | | .meeting-time { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 5px; |
| | | color: #606266; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .meeting-info { |
| | | display: flex; |
| | | gap: 20px; |
| | | margin-bottom: 20px; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .info-item { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 5px; |
| | | color: #606266; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .meeting-agenda { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .meeting-agenda h4 { |
| | | margin: 0 0 15px 0; |
| | | color: #303133; |
| | | font-size: 16px; |
| | | } |
| | | |
| | | .agenda-list { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 10px; |
| | | } |
| | | |
| | | .agenda-item { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 15px; |
| | | padding: 10px; |
| | | border-radius: 6px; |
| | | background-color: #f5f7fa; |
| | | } |
| | | |
| | | .agenda-item.active { |
| | | background-color: #fdf6ec; |
| | | border-left: 3px solid #e6a23c; |
| | | } |
| | | |
| | | .agenda-item.completed { |
| | | background-color: #f0f9ff; |
| | | border-left: 3px solid #409eff; |
| | | } |
| | | |
| | | .agenda-time { |
| | | font-weight: bold; |
| | | color: #606266; |
| | | min-width: 80px; |
| | | } |
| | | |
| | | .agenda-content { |
| | | flex: 1; |
| | | color: #303133; |
| | | } |
| | | |
| | | .meeting-actions { |
| | | display: flex; |
| | | gap: 10px; |
| | | justify-content: flex-end; |
| | | } |
| | | |
| | | .dialog-footer { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | gap: 10px; |
| | | } |
| | | |
| | | @media (max-width: 768px) { |
| | | .stats-cards { |
| | | grid-template-columns: repeat(2, 1fr); |
| | | } |
| | | |
| | | .meeting-header { |
| | | flex-direction: column; |
| | | gap: 10px; |
| | | } |
| | | |
| | | .meeting-info { |
| | | flex-direction: column; |
| | | gap: 10px; |
| | | } |
| | | |
| | | .meeting-actions { |
| | | flex-direction: column; |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <!-- æç´¢è¡¨å --> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">å
¬åæ é¢ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.noticeTitle" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥å
¬åæ é¢æç´¢" |
| | | @change="handleQuery" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | /> |
| | | <span class="search_title ml10">å
¬åç±»åï¼</span> |
| | | <el-select v-model="searchForm.noticeType" clearable @change="handleQuery" style="width: 240px"> |
| | | <el-option label="æ¾åéç¥" value="1" /> |
| | | <el-option label="设å¤ç»´ä¿®éç¥" value="2" /> |
| | | </el-select> |
| | | <span class="search_title ml10">ç¶æï¼</span> |
| | | <el-select v-model="searchForm.status" clearable @change="handleQuery" style="width: 240px"> |
| | | <el-option label="è稿" value="0" /> |
| | | <el-option label="å·²åå¸" value="1" /> |
| | | <el-option label="å·²ä¸çº¿" value="2" /> |
| | | </el-select> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | <el-button @click="resetQuery" style="margin-left: 10px">éç½®</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')">æ°å¢å
Œ</el-button> |
| | | <el-button type="danger" plain @click="handleDelete" :disabled="!selectedIds.length">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- éç¥å
¬åæ¿ --> |
| | | <div class="notice-board"> |
| | | <!-- æ¾åéç¥åºå --> |
| | | <div class="notice-section" v-if="holidayNotices.length > 0"> |
| | | <div class="section-header"> |
| | | <h3>ð
æ¾åéç¥</h3> |
| | | <span class="section-count">{{ holidayNotices.length }}æ¡</span> |
| | | </div> |
| | | <div class="notice-cards"> |
| | | <div |
| | | v-for="notice in holidayNotices" |
| | | :key="notice.id" |
| | | class="notice-card holiday-card" |
| | | :class="{ 'urgent': notice.priority === '3' }" |
| | | > |
| | | <div class="card-header"> |
| | | <div class="card-title"> |
| | | <el-icon class="holiday-icon"><Calendar /></el-icon> |
| | | {{ notice.noticeTitle }} |
| | | </div> |
| | | <div class="card-actions"> |
| | | <el-button link type="primary" @click="handleEdit(notice)">ç¼è¾</el-button> |
| | | <el-button link type="danger" @click="handleDelete(notice.id)">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="card-content"> |
| | | <p>{{ notice.noticeContent }}</p> |
| | | </div> |
| | | <div class="card-footer"> |
| | | <div class="card-meta"> |
| | | <span class="priority" :class="'priority-' + notice.priority"> |
| | | {{ getPriorityText(notice.priority) }} |
| | | </span> |
| | | <span class="status" :class="'status-' + notice.status"> |
| | | {{ getStatusText(notice.status) }} |
| | | </span> |
| | | </div> |
| | | <div class="card-info"> |
| | | <span class="creator">{{ notice.createBy }}</span> |
| | | <span class="time">{{ notice.createTime }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="card-remark" v-if="notice.remark"> |
| | | <el-icon><InfoFilled /></el-icon> |
| | | <span>{{ notice.remark }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 设å¤ç»´ä¿®éç¥åºå --> |
| | | <div class="notice-section" v-if="maintenanceNotices.length > 0"> |
| | | <div class="section-header"> |
| | | <h3>ð§ 设å¤ç»´ä¿®éç¥</h3> |
| | | <span class="section-count">{{ maintenanceNotices.length }}æ¡</span> |
| | | </div> |
| | | <div class="notice-cards"> |
| | | <div |
| | | v-for="notice in maintenanceNotices" |
| | | :key="notice.id" |
| | | class="notice-card maintenance-card" |
| | | :class="{ 'urgent': notice.priority === '3' }" |
| | | > |
| | | <div class="card-header"> |
| | | <div class="card-title"> |
| | | <el-icon class="maintenance-icon"><Tools /></el-icon> |
| | | {{ notice.noticeTitle }} |
| | | </div> |
| | | <div class="card-actions"> |
| | | <el-button link type="primary" @click="handleEdit(notice)">ç¼è¾</el-button> |
| | | <el-button link type="danger" @click="handleDelete(notice.id)">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="card-content"> |
| | | <p>{{ notice.noticeContent }}</p> |
| | | </div> |
| | | <div class="card-footer"> |
| | | <div class="card-meta"> |
| | | <span class="priority" :class="'priority-' + notice.priority"> |
| | | {{ getPriorityText(notice.priority) }} |
| | | </span> |
| | | <span class="status" :class="'status-' + notice.status"> |
| | | {{ getStatusText(notice.status) }} |
| | | </span> |
| | | </div> |
| | | <div class="card-info"> |
| | | <span class="creator">{{ notice.createBy }}</span> |
| | | <span class="time">{{ notice.createTime }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="card-remark" v-if="notice.remark"> |
| | | <el-icon><InfoFilled /></el-icon> |
| | | <span>{{ notice.remark }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- ç©ºç¶æ --> |
| | | <div class="empty-state" v-if="filteredNotices.length === 0"> |
| | | <el-empty description="ææ éç¥å
Œ" /> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- æ°å¢/ç¼è¾å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | :title="dialogTitle" |
| | | v-model="dialogVisible" |
| | | width="800px" |
| | | append-to-body |
| | | @close="resetForm" |
| | | > |
| | | <el-form ref="formRef" :model="form" :rules="rules" label-width="100px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬åæ é¢" prop="noticeTitle"> |
| | | <el-input v-model="form.noticeTitle" placeholder="请è¾å
¥å
¬åæ é¢" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬åç±»å" prop="noticeType"> |
| | | <el-select v-model="form.noticeType" placeholder="è¯·éæ©å
¬åç±»å" style="width: 100%"> |
| | | <el-option label="æ¾åéç¥" value="1" /> |
| | | <el-option label="设å¤ç»´ä¿®éç¥" value="2" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¶æ"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio value="0">è稿</el-radio> |
| | | <el-radio value="1">å·²åå¸</el-radio> |
| | | <el-radio value="2">å·²ä¸çº¿</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¼å
级"> |
| | | <el-select v-model="form.priority" placeholder="è¯·éæ©ä¼å
级" style="width: 100%"> |
| | | <el-option label="æ®é" value="1" /> |
| | | <el-option label="éè¦" value="2" /> |
| | | <el-option label="ç´§æ¥" value="3" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å
¬åå
容" prop="noticeContent"> |
| | | <el-input |
| | | v-model="form.noticeContent" |
| | | type="textarea" |
| | | :rows="6" |
| | | placeholder="请è¾å
¥å
¬åå
容" |
| | | maxlength="500" |
| | | show-word-limit |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="夿³¨"> |
| | | <el-input |
| | | v-model="form.remark" |
| | | type="textarea" |
| | | :rows="3" |
| | | placeholder="请è¾å
¥å¤æ³¨ä¿¡æ¯" |
| | | maxlength="200" |
| | | show-word-limit |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="dialogVisible = false">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { Search, Calendar, Tools, InfoFilled } from "@element-plus/icons-vue"; |
| | | import { onMounted, ref, reactive, toRefs, computed } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | |
| | | const userStore = useUserStore(); |
| | | |
| | | // ååºå¼æ°æ® |
| | | const data = reactive({ |
| | | searchForm: { |
| | | noticeTitle: "", |
| | | noticeType: "", |
| | | status: "", |
| | | }, |
| | | form: { |
| | | id: undefined, |
| | | noticeTitle: "", |
| | | noticeType: "", |
| | | noticeContent: "", |
| | | status: "0", |
| | | priority: "1", |
| | | remark: "", |
| | | createBy: "", |
| | | createTime: "", |
| | | }, |
| | | rules: { |
| | | noticeTitle: [ |
| | | { required: true, message: "å
¬åæ é¢ä¸è½ä¸ºç©º", trigger: "blur" } |
| | | ], |
| | | noticeType: [ |
| | | { required: true, message: "è¯·éæ©å
¬åç±»å", trigger: "change" } |
| | | ], |
| | | noticeContent: [ |
| | | { required: true, message: "å
¬åå
容ä¸è½ä¸ºç©º", trigger: "blur" } |
| | | ] |
| | | } |
| | | }); |
| | | |
| | | const { searchForm, form, rules } = toRefs(data); |
| | | |
| | | // 页é¢ç¶æ |
| | | const dialogVisible = ref(false); |
| | | const dialogTitle = ref(""); |
| | | const selectedIds = ref([]); |
| | | const formRef = ref(); |
| | | |
| | | // æ¨¡ææ°æ® - æ ¹æ®æ³å®èåæ¥è®¾è®¡ |
| | | const mockData = [ |
| | | { |
| | | id: 1, |
| | | noticeTitle: "2024å¹´æ¥èæ¾åéç¥", |
| | | noticeType: "1", |
| | | priority: "2", |
| | | status: "1", |
| | | noticeContent: "æ ¹æ®å½å¡é¢åå
Œ
éç¥ï¼2024å¹´æ¥èæ¾å宿å¦ä¸ï¼2æ10æ¥ï¼åä¸ï¼è³2æ17æ¥ï¼åå
«ï¼æ¾åè°ä¼ï¼å
±8天ã2æ4æ¥ï¼æææ¥ï¼ã2æ18æ¥ï¼æææ¥ï¼ä¸çã请åé¨é¨æåå好工ä½å®æã", |
| | | remark: "æ¾åæé´è¯·ä¿æææºç
éï¼å¦æç´§æ¥äºå¡åæ¶èç³»", |
| | | createBy: "人äºé¨", |
| | | createTime: "2024-01-15 10:30:00" |
| | | }, |
| | | { |
| | | id: 2, |
| | | noticeTitle: "2024å¹´æ¸
æèæ¾åéç¥", |
| | | noticeType: "1", |
| | | priority: "1", |
| | | status: "1", |
| | | noticeContent: "æ ¹æ®å½å¡é¢åå
Œ
éç¥ï¼2024å¹´æ¸
æèæ¾å宿å¦ä¸ï¼4æ4æ¥ï¼ææåï¼è³4æ6æ¥ï¼ææå
ï¼æ¾åè°ä¼ï¼å
±3天ã4æ7æ¥ï¼æææ¥ï¼ä¸çã", |
| | | remark: "请åé¨é¨å好å¼ç宿ï¼ç¡®ä¿èæ¥æé´å项工使£å¸¸è¿è½¬", |
| | | createBy: "è¡æ¿é¨", |
| | | createTime: "2024-01-14 14:20:00" |
| | | }, |
| | | { |
| | | id: 3, |
| | | noticeTitle: "2024å¹´å³å¨èæ¾åéç¥", |
| | | noticeType: "1", |
| | | priority: "1", |
| | | status: "1", |
| | | noticeContent: "æ ¹æ®å½å¡é¢åå
Œ
éç¥ï¼2024å¹´å³å¨èæ¾å宿å¦ä¸ï¼5æ1æ¥ï¼ææä¸ï¼è³5æ5æ¥ï¼æææ¥ï¼æ¾åè°ä¼ï¼å
±5天ã4æ28æ¥ï¼æææ¥ï¼ã5æ11æ¥ï¼ææå
ï¼ä¸çã", |
| | | remark: "æ¾åå请å
³éçµæºï¼é好é¨çªï¼æ³¨æå®å
¨", |
| | | createBy: "è¡æ¿é¨", |
| | | createTime: "2024-01-13 09:15:00" |
| | | }, |
| | | { |
| | | id: 4, |
| | | noticeTitle: "2024年端åèæ¾åéç¥", |
| | | noticeType: "1", |
| | | priority: "1", |
| | | status: "1", |
| | | noticeContent: "æ ¹æ®å½å¡é¢åå
Œ
éç¥ï¼2024年端åèæ¾å宿å¦ä¸ï¼6æ8æ¥ï¼ææå
ï¼è³6æ10æ¥ï¼ææä¸ï¼æ¾åè°ä¼ï¼å
±3天ã6æ11æ¥ï¼ææäºï¼ä¸çã", |
| | | remark: "ç¥å¤§å®¶ç«¯åèå¿«ä¹ï¼é家幸ç¦ï¼", |
| | | createBy: "è¡æ¿é¨", |
| | | createTime: "2024-01-12 16:30:00" |
| | | }, |
| | | { |
| | | id: 5, |
| | | noticeTitle: "2024å¹´ä¸ç§èæ¾åéç¥", |
| | | noticeType: "1", |
| | | priority: "1", |
| | | status: "1", |
| | | noticeContent: "æ ¹æ®å½å¡é¢åå
Œ
éç¥ï¼2024å¹´ä¸ç§èæ¾å宿å¦ä¸ï¼9æ15æ¥ï¼æææ¥ï¼è³9æ17æ¥ï¼ææäºï¼æ¾åè°ä¼ï¼å
±3天ã9æ14æ¥ï¼ææå
ï¼ä¸çã", |
| | | remark: "ä¸ç§ä½³èï¼ç¥å¤§å®¶å¢åç¾æ»¡ï¼å¹¸ç¦å®åº·ï¼", |
| | | createBy: "è¡æ¿é¨", |
| | | createTime: "2024-01-11 11:20:00" |
| | | }, |
| | | { |
| | | id: 6, |
| | | noticeTitle: "2024å¹´å½åºèæ¾åéç¥", |
| | | noticeType: "1", |
| | | priority: "2", |
| | | status: "1", |
| | | noticeContent: "æ ¹æ®å½å¡é¢åå
Œ
éç¥ï¼2024å¹´å½åºèæ¾å宿å¦ä¸ï¼10æ1æ¥ï¼ææäºï¼è³10æ7æ¥ï¼ææä¸ï¼æ¾åè°ä¼ï¼å
±7天ã9æ29æ¥ï¼æææ¥ï¼ã10æ12æ¥ï¼ææå
ï¼ä¸çã", |
| | | remark: "å½åºæé´è¯·åé¨é¨å好å¼ç宿ï¼ç¡®ä¿å®å
¨ç¨³å®", |
| | | createBy: "è¡æ¿é¨", |
| | | createTime: "2024-01-10 15:45:00" |
| | | }, |
| | | { |
| | | id: 7, |
| | | noticeTitle: "A车é´ç产线年度æ£ä¿®éç¥", |
| | | noticeType: "2", |
| | | priority: "2", |
| | | status: "1", |
| | | noticeContent: "A车é´ç产线å°äº2024å¹´1æ20æ¥ï¼å¨å
ï¼è¿è¡å¹´åº¦æ£ä¿®ç»´æ¤ï¼é¢è®¡åå·¥8å°æ¶ãæ£ä¿®å
容å
æ¬ï¼è®¾å¤æ¸
æ´ã润æ»ä¿å
»ãå®å
¨è£
ç½®æ£æ¥çã请ç产é¨é¨æåè°æ´ç产计åã", |
| | | remark: "ç»´ä¿®æé´è¯·ç¸å
³äººåé
åï¼ç¡®ä¿æ£ä¿®å·¥ä½å®å
¨é¡ºå©è¿è¡", |
| | | createBy: "设å¤é¨", |
| | | createTime: "2024-01-14 14:20:00" |
| | | }, |
| | | { |
| | | id: 8, |
| | | noticeTitle: "B车é´è®¾å¤é¢é²æ§ç»´æ¤éç¥", |
| | | noticeType: "2", |
| | | priority: "1", |
| | | status: "1", |
| | | noticeContent: "B车é´å
³é®è®¾å¤å°äº2024å¹´1æ25æ¥è¿è¡é¢é²æ§ç»´æ¤ï¼é¢è®¡åå·¥4å°æ¶ãç»´æ¤å
容å
æ¬ï¼è®¾å¤æ£æ¥ãé¶ä»¶æ´æ¢ãæ§è½æµè¯çã请ç¸å
³é¨é¨é
åã", |
| | | remark: "ç»´æ¤å®æåå°è¿è¡è¯è¿è¡ï¼ç¡®ä¿è®¾å¤æ£å¸¸è¿è¡", |
| | | createBy: "设å¤é¨", |
| | | createTime: "2024-01-13 09:15:00" |
| | | } |
| | | ]; |
| | | |
| | | // 计ç®å±æ§ |
| | | const filteredNotices = computed(() => { |
| | | let filtered = [...mockData]; |
| | | |
| | | if (searchForm.value.noticeTitle) { |
| | | filtered = filtered.filter(item => |
| | | item.noticeTitle.includes(searchForm.value.noticeTitle) |
| | | ); |
| | | } |
| | | if (searchForm.value.noticeType) { |
| | | filtered = filtered.filter(item => |
| | | item.noticeType === searchForm.value.noticeType |
| | | ); |
| | | } |
| | | if (searchForm.value.status !== "") { |
| | | filtered = filtered.filter(item => |
| | | item.status === searchForm.value.status |
| | | ); |
| | | } |
| | | |
| | | return filtered; |
| | | }); |
| | | |
| | | const holidayNotices = computed(() => { |
| | | return filteredNotices.value.filter(notice => notice.noticeType === "1"); |
| | | }); |
| | | |
| | | const maintenanceNotices = computed(() => { |
| | | return filteredNotices.value.filter(notice => notice.noticeType === "2"); |
| | | }); |
| | | |
| | | // æ¹æ³å®ä¹ |
| | | const handleQuery = () => { |
| | | // æç´¢åè½ä¿æä¸åï¼ä½æ°æ®éè¿è®¡ç®å±æ§èªå¨è¿æ»¤ |
| | | }; |
| | | |
| | | const resetQuery = () => { |
| | | searchForm.value = { |
| | | noticeTitle: "", |
| | | noticeType: "", |
| | | status: "" |
| | | }; |
| | | }; |
| | | |
| | | const getPriorityText = (priority) => { |
| | | const priorityMap = { "1": "æ®é", "2": "éè¦", "3": "ç´§æ¥" }; |
| | | return priorityMap[priority] || "æ®é"; |
| | | }; |
| | | |
| | | const getStatusText = (status) => { |
| | | const statusMap = { "0": "è稿", "1": "å·²åå¸", "2": "å·²ä¸çº¿" }; |
| | | return statusMap[status] || "æªç¥"; |
| | | }; |
| | | |
| | | const openForm = (type) => { |
| | | if (type === 'add') { |
| | | dialogTitle.value = "æ°å¢å
Œ"; |
| | | form.value = { |
| | | id: undefined, |
| | | noticeTitle: "", |
| | | noticeType: "", |
| | | noticeContent: "", |
| | | status: "0", |
| | | priority: "1", |
| | | remark: "", |
| | | createBy: userStore.name || "å½åç¨æ·", |
| | | createTime: new Date().toLocaleString() |
| | | }; |
| | | } |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleEdit = (row) => { |
| | | dialogTitle.value = "ç¼è¾å
Œ"; |
| | | form.value = { ...row }; |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | const handleSelectionChange = (selection) => { |
| | | selectedIds.value = selection.map(item => item.id); |
| | | }; |
| | | |
| | | const handleDelete = (id) => { |
| | | ElMessageBox.confirm( |
| | | "确认å é¤è¿æ¡å
¬ååï¼", |
| | | "æç¤º", |
| | | { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | } |
| | | ).then(() => { |
| | | const index = mockData.findIndex(item => item.id === id); |
| | | if (index > -1) { |
| | | mockData.splice(index, 1); |
| | | ElMessage.success("å 餿å"); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const submitForm = () => { |
| | | formRef.value.validate((valid) => { |
| | | if (valid) { |
| | | if (form.value.id) { |
| | | // ç¼è¾æ¨¡å¼ |
| | | const index = mockData.findIndex(item => item.id === form.value.id); |
| | | if (index > -1) { |
| | | mockData[index] = { ...form.value }; |
| | | } |
| | | ElMessage.success("ä¿®æ¹æå"); |
| | | } else { |
| | | // æ°å¢æ¨¡å¼ |
| | | const newId = Math.max(...mockData.map(item => item.id)) + 1; |
| | | const newNotice = { |
| | | ...form.value, |
| | | id: newId, |
| | | createTime: new Date().toLocaleString() |
| | | }; |
| | | mockData.unshift(newNotice); |
| | | ElMessage.success("æ°å¢æå"); |
| | | } |
| | | dialogVisible.value = false; |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const resetForm = () => { |
| | | formRef.value?.resetFields(); |
| | | }; |
| | | |
| | | // çå½å¨æ |
| | | onMounted(() => { |
| | | // 页é¢å è½½å®æ |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .search_form { |
| | | background: #fff; |
| | | padding: 20px; |
| | | margin-bottom: 20px; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .search_title { |
| | | font-weight: 500; |
| | | color: #333; |
| | | margin-right: 8px; |
| | | } |
| | | |
| | | .ml10 { |
| | | margin-left: 10px; |
| | | } |
| | | |
| | | .notice-board { |
| | | background: #f5f7fa; |
| | | padding: 20px; |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | .notice-section { |
| | | margin-bottom: 30px; |
| | | } |
| | | |
| | | .section-header { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-bottom: 20px; |
| | | padding: 0 10px; |
| | | } |
| | | |
| | | .section-header h3 { |
| | | margin: 0; |
| | | color: #303133; |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .section-count { |
| | | margin-left: 10px; |
| | | background: #409eff; |
| | | color: white; |
| | | padding: 2px 8px; |
| | | border-radius: 12px; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .notice-cards { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fill, minmax(400px, 1fr)); |
| | | gap: 20px; |
| | | } |
| | | |
| | | .notice-card { |
| | | background: white; |
| | | border-radius: 12px; |
| | | padding: 20px; |
| | | box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); |
| | | transition: all 0.3s ease; |
| | | border-left: 4px solid transparent; |
| | | } |
| | | |
| | | .notice-card:hover { |
| | | transform: translateY(-2px); |
| | | box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); |
| | | } |
| | | |
| | | .holiday-card { |
| | | border-left-color: #67c23a; |
| | | } |
| | | |
| | | .maintenance-card { |
| | | border-left-color: #e6a23c; |
| | | } |
| | | |
| | | .urgent { |
| | | border-left-color: #f56c6c; |
| | | background: linear-gradient(135deg, #fff5f5 0%, #ffffff 100%); |
| | | } |
| | | |
| | | .card-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: flex-start; |
| | | margin-bottom: 15px; |
| | | } |
| | | |
| | | .card-title { |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | flex: 1; |
| | | } |
| | | |
| | | .holiday-icon { |
| | | color: #67c23a; |
| | | margin-right: 8px; |
| | | font-size: 18px; |
| | | } |
| | | |
| | | .maintenance-icon { |
| | | color: #e6a23c; |
| | | margin-right: 8px; |
| | | font-size: 18px; |
| | | } |
| | | |
| | | .card-actions { |
| | | display: flex; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .card-content { |
| | | margin-bottom: 15px; |
| | | } |
| | | |
| | | .card-content p { |
| | | margin: 0; |
| | | color: #606266; |
| | | line-height: 1.6; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .card-footer { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .card-meta { |
| | | display: flex; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .priority, .status { |
| | | padding: 2px 8px; |
| | | border-radius: 12px; |
| | | font-size: 12px; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .priority-1 { background: #f0f9ff; color: #0369a1; } |
| | | .priority-2 { background: #fef3c7; color: #d97706; } |
| | | .priority-3 { background: #fef2f2; color: #dc2626; } |
| | | |
| | | .status-0 { background: #f3f4f6; color: #6b7280; } |
| | | .status-1 { background: #d1fae5; color: #059669; } |
| | | .status-2 { background: #fef3c7; color: #d97706; } |
| | | |
| | | .card-info { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: flex-end; |
| | | font-size: 12px; |
| | | color: #909399; |
| | | } |
| | | |
| | | .creator { |
| | | font-weight: 500; |
| | | margin-bottom: 2px; |
| | | } |
| | | |
| | | .card-remark { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 6px; |
| | | padding: 8px 12px; |
| | | background: #f8f9fa; |
| | | border-radius: 6px; |
| | | font-size: 12px; |
| | | color: #606266; |
| | | border-left: 3px solid #409eff; |
| | | } |
| | | |
| | | .empty-state { |
| | | text-align: center; |
| | | padding: 60px 20px; |
| | | } |
| | | |
| | | .dialog-footer { |
| | | text-align: right; |
| | | } |
| | | |
| | | /* ååºå¼è®¾è®¡ */ |
| | | @media (max-width: 768px) { |
| | | .notice-cards { |
| | | grid-template-columns: 1fr; |
| | | } |
| | | |
| | | .search_form { |
| | | flex-direction: column; |
| | | gap: 15px; |
| | | } |
| | | |
| | | .search_form > div { |
| | | width: 100%; |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="warning-system"> |
| | | <h2>é¢è¦è卿ºå¶</h2> |
| | | |
| | | <!-- ç»è®¡å¡ç --> |
| | | <div class="stats"> |
| | | <div class="stat-card red"> |
| | | <span class="number">2</span> |
| | | <span class="label">红è²é¢è¦</span> |
| | | </div> |
| | | <div class="stat-card orange"> |
| | | <span class="number">1</span> |
| | | <span class="label">æ©è²é¢è¦</span> |
| | | </div> |
| | | <div class="stat-card yellow"> |
| | | <span class="number">1</span> |
| | | <span class="label">é»è²é¢è¦</span> |
| | | </div> |
| | | <div class="stat-card green"> |
| | | <span class="number">1</span> |
| | | <span class="label">绿è²é¢è¦</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- é¢è¦å表 --> |
| | | <div class="warning-list"> |
| | | <h3>é¢è¦å表</h3> |
| | | <table> |
| | | <thead> |
| | | <tr> |
| | | <th>ç¼å·</th> |
| | | <th>æ é¢</th> |
| | | <th>ç±»å</th> |
| | | <th>ç级</th> |
| | | <th>ç¶æ</th> |
| | | <th>责任人</th> |
| | | <th>æä½</th> |
| | | </tr> |
| | | </thead> |
| | | <tbody> |
| | | <tr v-for="warning in warnings" :key="warning.id"> |
| | | <td>{{ warning.id }}</td> |
| | | <td>{{ warning.title }}</td> |
| | | <td>{{ warning.type }}</td> |
| | | <td> |
| | | <span :class="['level-tag', warning.level]"> |
| | | {{ warning.levelText }} |
| | | </span> |
| | | </td> |
| | | <td> |
| | | <span :class="['status-tag', warning.status]"> |
| | | {{ warning.statusText }} |
| | | </span> |
| | | </td> |
| | | <td>{{ warning.responsible }}</td> |
| | | <td> |
| | | <button @click="viewDetail(warning)">æ¥ç详æ
</button> |
| | | </td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | |
| | | <!-- 详æ
å¯¹è¯æ¡ --> |
| | | <div v-if="showDetail" class="modal"> |
| | | <div class="modal-content"> |
| | | <h3>é¢è¦è¯¦æ
</h3> |
| | | <div v-if="currentWarning"> |
| | | <p><strong>ç¼å·ï¼</strong>{{ currentWarning.id }}</p> |
| | | <p><strong>æ é¢ï¼</strong>{{ currentWarning.title }}</p> |
| | | <p><strong>ç±»åï¼</strong>{{ currentWarning.type }}</p> |
| | | <p><strong>ç级ï¼</strong>{{ currentWarning.levelText }}</p> |
| | | <p><strong>æè¿°ï¼</strong>{{ currentWarning.description }}</p> |
| | | <p><strong>å½±åï¼</strong>{{ currentWarning.impact }}</p> |
| | | <p><strong>建议ï¼</strong>{{ currentWarning.suggestions }}</p> |
| | | </div> |
| | | <button @click="showDetail = false">å
³é</button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'WarningSystem', |
| | | data() { |
| | | return { |
| | | showDetail: false, |
| | | currentWarning: null, |
| | | warnings: [ |
| | | { |
| | | id: 'W001', |
| | | title: '项ç®é¢ç®è¶
æ¯é¢è¦', |
| | | type: 'è´¢å¡é¢è¦', |
| | | level: 'red', |
| | | levelText: '红è²é¢è¦', |
| | | status: 'pending', |
| | | statusText: 'å¾
å¤ç', |
| | | responsible: 'å¼ ç»ç', |
| | | description: 'A项ç®é¢ç®æ§è¡ç已达95%ï¼é¢è®¡å°è¶
åºé¢ç®èå´ã', |
| | | impact: 'å½±åé¡¹ç®æ´ä½è´¢å¡ææ ï¼å¯è½å¯¼è´é¡¹ç®äºæ', |
| | | suggestions: 'æåéå¿
è¦æ¯åºï¼ä¼åèµæºé
ç½®ï¼ç³è¯·é¢ç®è°æ´' |
| | | }, |
| | | { |
| | | id: 'W002', |
| | | title: 'ååå°æé¢è¦', |
| | | type: 'åè§é¢è¦', |
| | | level: 'orange', |
| | | levelText: 'æ©è²é¢è¦', |
| | | status: 'processing', |
| | | statusText: 'å¤çä¸', |
| | | responsible: 'æä¸»ç®¡', |
| | | description: 'ä¸ä¾åºåBçååå°äº2024å¹´1æ25æ¥å°æã', |
| | | impact: 'å½±åä¾åºé¾ç¨³å®æ§ï¼å¯è½å¯¼è´æå¡ä¸æ', |
| | | suggestions: 'è¯ä¼°ä¾åºå表ç°ï¼åå¤ç»ç¾ææï¼å¶å®å¤éæ¹æ¡' |
| | | }, |
| | | { |
| | | id: 'W003', |
| | | title: '设å¤ç»´æ¤é¢è¦', |
| | | type: 'è¿è¥é¢è¦', |
| | | level: 'yellow', |
| | | levelText: 'é»è²é¢è¦', |
| | | status: 'pending', |
| | | statusText: 'å¾
å¤ç', |
| | | responsible: 'çå·¥ç¨å¸', |
| | | description: 'ç产线设å¤Cå·²è¿è¡8000å°æ¶ï¼æ¥è¿ç»´æ¤å¨æã', |
| | | impact: 'å¯è½å½±åç产æçå产åè´¨é', |
| | | suggestions: 'å®æç»´æ¤æ¶é´ï¼åå¤å¤ä»¶ï¼å¶å®ç»´æ¤è®¡å' |
| | | }, |
| | | { |
| | | id: 'W004', |
| | | title: '人åé
ç½®é¢è¦', |
| | | type: 'è¿è¥é¢è¦', |
| | | level: 'green', |
| | | levelText: '绿è²é¢è¦', |
| | | status: 'resolved', |
| | | statusText: '已解å³', |
| | | responsible: 'èµµHR', |
| | | description: 'ææ¯é¨é¨äººåé
ç½®å
è¶³ï¼é¡¹ç®è¿åº¦æ£å¸¸ã', |
| | | impact: 'æ è´é¢å½±å', |
| | | suggestions: 'ç»§ç»çæ§äººåé
ç½®æ
åµ' |
| | | }, |
| | | { |
| | | id: 'W005', |
| | | title: 'è´¨éäºæ
é¢è¦', |
| | | type: 'è¿è¥é¢è¦', |
| | | level: 'red', |
| | | levelText: '红è²é¢è¦', |
| | | status: 'pending', |
| | | statusText: 'å¾
å¤ç', |
| | | responsible: 'éæ»ç', |
| | | description: '产åDå¨å®¢æ·ç°åºåºç°è´¨éé®é¢ã', |
| | | impact: 'å½±åå®¢æ·æ»¡æåº¦ï¼å¯è½é æç»æµæå¤±', |
| | | suggestions: 'ç«å³å¬åé®é¢äº§åï¼åæåå ï¼å¶å®æ¹è¿æªæ½' |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | methods: { |
| | | viewDetail(warning) { |
| | | this.currentWarning = warning |
| | | this.showDetail = true |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .warning-system { |
| | | padding: 20px; |
| | | max-width: 1200px; |
| | | margin: 0 auto; |
| | | } |
| | | |
| | | h2 { |
| | | color: #333; |
| | | margin-bottom: 30px; |
| | | } |
| | | |
| | | .stats { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); |
| | | gap: 20px; |
| | | margin-bottom: 30px; |
| | | } |
| | | |
| | | .stat-card { |
| | | padding: 20px; |
| | | border-radius: 8px; |
| | | color: white; |
| | | text-align: center; |
| | | box-shadow: 0 2px 8px rgba(0,0,0,0.1); |
| | | } |
| | | |
| | | .stat-card.red { background: linear-gradient(135deg, #ff6b6b, #ee5a52); } |
| | | .stat-card.orange { background: linear-gradient(135deg, #ffa726, #ff9800); } |
| | | .stat-card.yellow { background: linear-gradient(135deg, #ffd54f, #ffc107); } |
| | | .stat-card.green { background: linear-gradient(135deg, #66bb6a, #4caf50); } |
| | | |
| | | .stat-card .number { |
| | | display: block; |
| | | font-size: 32px; |
| | | font-weight: bold; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .stat-card .label { |
| | | font-size: 14px; |
| | | opacity: 0.9; |
| | | } |
| | | |
| | | .warning-list h3 { |
| | | margin-bottom: 20px; |
| | | color: #333; |
| | | } |
| | | |
| | | table { |
| | | width: 100%; |
| | | border-collapse: collapse; |
| | | background: white; |
| | | border-radius: 8px; |
| | | overflow: hidden; |
| | | box-shadow: 0 2px 8px rgba(0,0,0,0.1); |
| | | } |
| | | |
| | | th, td { |
| | | padding: 12px; |
| | | text-align: left; |
| | | border-bottom: 1px solid #eee; |
| | | } |
| | | |
| | | th { |
| | | background: #f8f9fa; |
| | | font-weight: 600; |
| | | color: #333; |
| | | } |
| | | |
| | | .level-tag, .status-tag { |
| | | padding: 4px 8px; |
| | | border-radius: 4px; |
| | | font-size: 12px; |
| | | color: white; |
| | | } |
| | | |
| | | .level-tag.red { background: #f56c6c; } |
| | | .level-tag.orange { background: #e6a23c; } |
| | | .level-tag.yellow { background: #e6a23c; } |
| | | .level-tag.green { background: #67c23a; } |
| | | |
| | | .status-tag.pending { background: #f56c6c; } |
| | | .status-tag.processing { background: #e6a23c; } |
| | | .status-tag.resolved { background: #67c23a; } |
| | | |
| | | button { |
| | | padding: 6px 12px; |
| | | margin: 0 4px; |
| | | border: none; |
| | | border-radius: 4px; |
| | | cursor: pointer; |
| | | font-size: 12px; |
| | | background: #409eff; |
| | | color: white; |
| | | } |
| | | |
| | | .modal { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | background: rgba(0,0,0,0.5); |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .modal-content { |
| | | background: white; |
| | | padding: 30px; |
| | | border-radius: 8px; |
| | | max-width: 600px; |
| | | width: 90%; |
| | | max-height: 80vh; |
| | | overflow-y: auto; |
| | | } |
| | | |
| | | .modal-content h3 { |
| | | margin-bottom: 20px; |
| | | color: #333; |
| | | } |
| | | |
| | | .modal-content p { |
| | | margin-bottom: 15px; |
| | | line-height: 1.6; |
| | | } |
| | | |
| | | .modal-content strong { |
| | | color: #333; |
| | | } |
| | | |
| | | .modal-content button { |
| | | background: #409eff; |
| | | color: white; |
| | | padding: 10px 20px; |
| | | font-size: 14px; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-card shadow="never"> |
| | | <div class="toolbar"> |
| | | <el-input |
| | | v-model="query.keyword" |
| | | placeholder="æç´¢åç§°/ç±»å«" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter="handleSearch" |
| | | /> |
| | | <el-select |
| | | v-model="query.status" |
| | | placeholder="ç¶æ" |
| | | clearable |
| | | style="width: 140px; margin-left: 12px" |
| | | > |
| | | <el-option label="å¯ç¨" value="å¯ç¨" /> |
| | | <el-option label="åç¨" value="åç¨" /> |
| | | </el-select> |
| | | <el-button type="primary" style="margin-left: 12px" @click="handleSearch">æ¥è¯¢</el-button> |
| | | <el-button @click="resetQuery">éç½®</el-button> |
| | | <el-button type="success" plain style="float: right" @click="openCreate">æ°å¢</el-button> |
| | | </div> |
| | | |
| | | <el-table :data="pagedList" border style="width: 100%" height="480"> |
| | | <el-table-column prop="id" label="ç¼å·" width="90" sortable /> |
| | | <el-table-column prop="name" label="åç§°" min-width="140" /> |
| | | <el-table-column prop="category" label="ç±»å«" width="120" /> |
| | | <el-table-column prop="stock" label="åºå" width="100" sortable /> |
| | | <el-table-column prop="price" label="åä»·(Â¥)" width="120"> |
| | | <template #default="scope">{{ formatPrice(scope.row.price) }}</template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¶æ" width="120"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.status === 'å¯ç¨' ? 'success' : 'info'">{{ scope.row.status }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="updatedAt" label="æ´æ°æ¶é´" min-width="160" /> |
| | | <el-table-column label="æä½" width="180" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" @click="openEdit(scope.row)">ç¼è¾</el-button> |
| | | <el-button link type="danger" @click="handleDelete(scope.row)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <div class="pagination"> |
| | | <el-pagination |
| | | background |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :total="filteredList.length" |
| | | :page-sizes="[5, 10, 20, 50]" |
| | | :page-size="pager.pageSize" |
| | | :current-page="pager.pageNum" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | /> |
| | | </div> |
| | | </el-card> |
| | | |
| | | <el-dialog v-model="dialogVisible" :title="isEdit ? 'ç¼è¾' : 'æ°å¢'" width="520px"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="90px"> |
| | | <el-form-item label="åç§°" prop="name"> |
| | | <el-input v-model="form.name" placeholder="请è¾å
¥åç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç±»å«" prop="category"> |
| | | <el-select v-model="form.category" placeholder="è¯·éæ©ç±»å«" style="width: 100%"> |
| | | <el-option label="åæ" value="åæ" /> |
| | | <el-option label="åæå" value="åæå" /> |
| | | <el-option label="æå" value="æå" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="åºå" prop="stock"> |
| | | <el-input v-model.number="form.stock" type="number" min="0" /> |
| | | </el-form-item> |
| | | <el-form-item label="åä»·(Â¥)" prop="price"> |
| | | <el-input v-model.number="form.price" type="number" min="0" step="0.01" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio label="å¯ç¨">å¯ç¨</el-radio> |
| | | <el-radio label="åç¨">åç¨</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="dialogVisible = false">å æ¶</el-button> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, computed, nextTick } from 'vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | |
| | | defineOptions({ name: 'FakePage' }) |
| | | |
| | | const query = reactive({ |
| | | keyword: '', |
| | | status: '' |
| | | }) |
| | | |
| | | const pager = reactive({ |
| | | pageNum: 1, |
| | | pageSize: 10 |
| | | }) |
| | | |
| | | const allList = ref(generateMockData()) |
| | | |
| | | const filteredList = computed(() => { |
| | | const keyword = (query.keyword || '').trim() |
| | | const status = query.status |
| | | return allList.value.filter(item => { |
| | | const hitKeyword = !keyword || item.name.includes(keyword) || item.category.includes(keyword) |
| | | const hitStatus = !status || item.status === status |
| | | return hitKeyword && hitStatus |
| | | }) |
| | | }) |
| | | |
| | | const pagedList = computed(() => { |
| | | const start = (pager.pageNum - 1) * pager.pageSize |
| | | const end = start + pager.pageSize |
| | | return filteredList.value.slice(start, end) |
| | | }) |
| | | |
| | | function handleSearch() { |
| | | pager.pageNum = 1 |
| | | } |
| | | |
| | | function resetQuery() { |
| | | query.keyword = '' |
| | | query.status = '' |
| | | pager.pageNum = 1 |
| | | } |
| | | |
| | | function handleSizeChange(size) { |
| | | pager.pageSize = size |
| | | pager.pageNum = 1 |
| | | } |
| | | |
| | | function handleCurrentChange(page) { |
| | | pager.pageNum = page |
| | | } |
| | | |
| | | function formatPrice(val) { |
| | | return Number(val || 0).toFixed(2) |
| | | } |
| | | |
| | | // æ°å¢/ç¼è¾ |
| | | const dialogVisible = ref(false) |
| | | const isEdit = ref(false) |
| | | const formRef = ref() |
| | | const form = reactive({ id: null, name: '', category: '', stock: 0, price: 0, status: 'å¯ç¨' }) |
| | | |
| | | const rules = { |
| | | name: [{ required: true, message: '请è¾å
¥åç§°', trigger: 'blur' }], |
| | | category: [{ required: true, message: 'è¯·éæ©ç±»å«', trigger: 'change' }], |
| | | stock: [{ required: true, message: '请è¾å
¥åºå', trigger: 'blur' }], |
| | | price: [{ required: true, message: '请è¾å
¥åä»·', trigger: 'blur' }] |
| | | } |
| | | |
| | | function openCreate() { |
| | | isEdit.value = false |
| | | Object.assign(form, { id: null, name: '', category: '', stock: 0, price: 0, status: 'å¯ç¨' }) |
| | | dialogVisible.value = true |
| | | nextTick(() => formRef.value?.clearValidate?.()) |
| | | } |
| | | |
| | | function openEdit(row) { |
| | | isEdit.value = true |
| | | Object.assign(form, JSON.parse(JSON.stringify(row))) |
| | | dialogVisible.value = true |
| | | nextTick(() => formRef.value?.clearValidate?.()) |
| | | } |
| | | |
| | | function submitForm() { |
| | | formRef.value?.validate?.((valid) => { |
| | | if (!valid) return |
| | | if (isEdit.value) { |
| | | const index = allList.value.findIndex(x => x.id === form.id) |
| | | if (index > -1) { |
| | | allList.value[index] = { ...form, updatedAt: nowString() } |
| | | ElMessage.success('å·²ä¿å') |
| | | } |
| | | } else { |
| | | const newId = Date.now() |
| | | allList.value.unshift({ ...form, id: newId, updatedAt: nowString() }) |
| | | ElMessage.success('å·²æ°å¢') |
| | | } |
| | | dialogVisible.value = false |
| | | }) |
| | | } |
| | | |
| | | function handleDelete(row) { |
| | | ElMessageBox.confirm(`确认å é¤ã${row.name}ãåï¼`, 'æç¤º', { type: 'warning' }) |
| | | .then(() => { |
| | | allList.value = allList.value.filter(x => x.id !== row.id) |
| | | ElMessage.success('å·²å é¤') |
| | | }) |
| | | .catch(() => {}) |
| | | } |
| | | |
| | | function generateMockData() { |
| | | const categories = ['åæ', 'åæå', 'æå'] |
| | | const statusOptions = ['å¯ç¨', 'åç¨'] |
| | | const list = [] |
| | | for (let i = 1; i <= 36; i++) { |
| | | list.push({ |
| | | id: i, |
| | | name: `ç©æ-${i.toString().padStart(3, '0')}`, |
| | | category: categories[i % categories.length], |
| | | stock: Math.floor(Math.random() * 1000), |
| | | price: (Math.random() * 500 + 10).toFixed(2), |
| | | status: statusOptions[i % 2], |
| | | updatedAt: nowString() |
| | | }) |
| | | } |
| | | return list |
| | | } |
| | | |
| | | function nowString() { |
| | | const d = new Date() |
| | | const yyyy = d.getFullYear() |
| | | const MM = String(d.getMonth() + 1).padStart(2, '0') |
| | | const dd = String(d.getDate()).padStart(2, '0') |
| | | const hh = String(d.getHours()).padStart(2, '0') |
| | | const mm = String(d.getMinutes()).padStart(2, '0') |
| | | const ss = String(d.getSeconds()).padStart(2, '0') |
| | | return `${yyyy}-${MM}-${dd} ${hh}:${mm}:${ss}` |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .toolbar { |
| | | margin-bottom: 12px; |
| | | } |
| | | .pagination { |
| | | margin-top: 12px; |
| | | text-align: right; |
| | | } |
| | | </style> |
| | | |
| | | |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <!-- è¾¹ç¼è®¡ç®ç¶æçæ§ --> |
| | | <el-row :gutter="20" class="status-section"> |
| | | <el-col :span="8"> |
| | | <el-card class="status-card"> |
| | | <div class="status-item"> |
| | | <div class="status-icon"> |
| | | <el-icon><Monitor /></el-icon> |
| | | </div> |
| | | <div class="status-info"> |
| | | <div class="status-title">è¾¹ç¼æå¡å¨ç¶æ</div> |
| | | <div class="status-value" :class="edgeServerStatus.status"> |
| | | {{ edgeServerStatus.status === 'online' ? 'å¨çº¿' : '离线' }} |
| | | </div> |
| | | <div class="status-detail">æåå¿è·³: {{ formatTime(edgeServerStatus.lastHeartbeat) }}</div> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-card class="status-card"> |
| | | <div class="status-item"> |
| | | <div class="status-icon"> |
| | | <el-icon><Cpu /></el-icon> |
| | | </div> |
| | | <div class="status-info"> |
| | | <div class="status-title">模åè¿è¡ç¶æ</div> |
| | | <div class="status-value" :class="modelStatus.status"> |
| | | {{ modelStatus.status === 'running' ? 'è¿è¡ä¸' : '已忢' }} |
| | | </div> |
| | | <div class="status-detail">è¿è¡æ¨¡å: {{ modelStatus.modelCount }}个</div> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-card class="status-card"> |
| | | <div class="status-item"> |
| | | <div class="status-icon"> |
| | | <el-icon><TrendCharts /></el-icon> |
| | | </div> |
| | | <div class="status-info"> |
| | | <div class="status-title">èè½ææ</div> |
| | | <div class="status-value success">{{ energySavingRate.toFixed(1) }}%</div> |
| | | <div class="status-detail">累计èè½: {{ totalEnergySaved.toFixed(1) }}kWh</div> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <!-- 注水泵é¢çä¼åæ§å¶ --> |
| | | <el-card class="control-section"> |
| | | <template #header> |
| | | <span>注水泵é¢çä¼åæ§å¶</span> |
| | | </template> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <div class="pump-control"> |
| | | <h4>宿¶åæ°çæ§</h4> |
| | | <el-form label-width="120px"> |
| | | <el-form-item label="å°å±åå (MPa)"> |
| | | <el-input v-model="pumpData.formationPressure" readonly> |
| | | <template #append>MPa</template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item label="å½åæ³µé (Hz)"> |
| | | <el-input v-model="pumpData.currentFrequency" readonly> |
| | | <template #append>Hz</template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item label="ä¼ååæ³µé (Hz)"> |
| | | <el-input v-model="pumpData.optimizedFrequency" readonly> |
| | | <template #append>Hz</template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item label="è½èéä½"> |
| | | <el-progress |
| | | :percentage="pumpData.energyReduction" |
| | | :color="getProgressColor" |
| | | :format="format => `${format}%`" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="æµé (m³/h)"> |
| | | <el-input v-model="pumpData.flowRate" readonly> |
| | | <template #append>m³/h</template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item label="åç (kW)"> |
| | | <el-input v-model="pumpData.power" readonly> |
| | | <template #append>kW</template> |
| | | </el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </el-col> |
| | | |
| | | <el-col :span="12"> |
| | | <div class="pump-chart"> |
| | | <h4>é¢çä¼åè¶å¿</h4> |
| | | <div ref="frequencyChart" style="height: 300px;"></div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20" class="control-buttons"> |
| | | <el-col :span="24"> |
| | | <el-button |
| | | type="primary" |
| | | :disabled="!canControl" |
| | | @click="applyOptimization" |
| | | > |
| | | åºç¨ä¼å设置 |
| | | </el-button> |
| | | <el-button |
| | | type="warning" |
| | | :disabled="!canControl" |
| | | @click="emergencyStop" |
| | | > |
| | | ç´§æ¥åæ¢ |
| | | </el-button> |
| | | <el-button |
| | | type="info" |
| | | @click="showOptimizationHistory" |
| | | > |
| | | ä¼ååå² |
| | | </el-button> |
| | | <el-button |
| | | type="success" |
| | | @click="toggleAutoRefresh" |
| | | > |
| | | {{ autoRefreshStatus ? '忢èªå¨å·æ°' : 'å¼å¯èªå¨å·æ°' }} |
| | | </el-button> |
| | | </el-col> |
| | | </el-row> |
| | | </el-card> |
| | | |
| | | <!-- è¾¹ç¼è®¡ç®æ¨¡åé
ç½® --> |
| | | <el-card class="model-section"> |
| | | <template #header> |
| | | <span>è¾¹ç¼è®¡ç®æ¨¡åé
ç½®</span> |
| | | </template> |
| | | |
| | | <el-table :data="modelConfigs" style="width: 100%"> |
| | | <el-table-column prop="modelName" label="模ååç§°" /> |
| | | <el-table-column prop="version" label="çæ¬" /> |
| | | <el-table-column prop="status" label="ç¶æ"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'"> |
| | | {{ scope.row.status === 'active' ? 'æ¿æ´»' : 'å¾
æº' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="accuracy" label="åç¡®ç" /> |
| | | <el-table-column prop="lastUpdate" label="æåæ´æ°" /> |
| | | <el-table-column label="æä½"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | size="small" |
| | | @click="updateModel(scope.row)" |
| | | > |
| | | æ´æ°æ¨¡å |
| | | </el-button> |
| | | <el-button |
| | | size="small" |
| | | type="danger" |
| | | @click="deleteModel(scope.row)" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | |
| | | <!-- è½èåæå¾è¡¨ --> |
| | | <el-card class="analysis-section"> |
| | | <template #header> |
| | | <span>è½èåæ</span> |
| | | </template> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <div ref="energyChart" style="height: 400px;"></div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div ref="savingChart" style="height: 400px;"></div> |
| | | </el-col> |
| | | </el-row> |
| | | </el-card> |
| | | |
| | | <!-- ä¼ååå²å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="historyDialogVisible" title="ä¼ååå²è®°å½" width="80%"> |
| | | <el-table :data="optimizationHistory" style="width: 100%"> |
| | | <el-table-column prop="timestamp" label="æ¶é´" /> |
| | | <el-table-column prop="formationPressure" label="å°å±åå (MPa)" /> |
| | | <el-table-column prop="oldFrequency" label="åé¢ç (Hz)" /> |
| | | <el-table-column prop="newFrequency" label="æ°é¢ç (Hz)" /> |
| | | <el-table-column prop="energySaved" label="èè½ (kWh)" /> |
| | | <el-table-column prop="status" label="ç¶æ"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.status === 'success' ? 'success' : 'warning'"> |
| | | {{ scope.row.status === 'success' ? 'æå' : '失败' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted, onUnmounted, computed } from 'vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | import { Monitor, Cpu, TrendCharts } from '@element-plus/icons-vue' |
| | | import * as echarts from 'echarts' |
| | | |
| | | // ååºå¼æ°æ® |
| | | const edgeServerStatus = ref({ status: 'online', lastHeartbeat: Date.now() }) |
| | | const modelStatus = ref({ status: 'running', modelCount: 3 }) |
| | | const energySavingRate = ref(15.8) |
| | | const totalEnergySaved = ref(1250.5) |
| | | const pumpData = ref({ |
| | | formationPressure: 25.6, |
| | | currentFrequency: 45.2, |
| | | optimizedFrequency: 42.1, |
| | | energyReduction: 23, |
| | | flowRate: 180.5, |
| | | power: 85.3 |
| | | }) |
| | | |
| | | const modelConfigs = ref([ |
| | | { |
| | | modelName: '注水泵é¢çä¼å模å', |
| | | version: 'v2.1.0', |
| | | status: 'active', |
| | | accuracy: '94.2%', |
| | | lastUpdate: '2024-01-15 14:30:00' |
| | | }, |
| | | { |
| | | modelName: 'å°å±åå颿µæ¨¡å', |
| | | version: 'v1.8.5', |
| | | status: 'active', |
| | | accuracy: '91.7%', |
| | | lastUpdate: '2024-01-14 09:15:00' |
| | | }, |
| | | { |
| | | modelName: 'è½èåææ¨¡å', |
| | | version: 'v2.0.3', |
| | | status: 'standby', |
| | | accuracy: '89.3%', |
| | | lastUpdate: '2024-01-13 16:45:00' |
| | | } |
| | | ]) |
| | | |
| | | const historyDialogVisible = ref(false) |
| | | const optimizationHistory = ref([]) |
| | | |
| | | // å¾è¡¨å¼ç¨ |
| | | const frequencyChart = ref(null) |
| | | const energyChart = ref(null) |
| | | const savingChart = ref(null) |
| | | |
| | | // èªå¨å·æ°ç¸å
³ |
| | | const autoRefreshStatus = ref(true) |
| | | const autoRefreshTimer = ref(null) |
| | | const chartInstances = ref([]) |
| | | |
| | | // 计ç®å±æ§ |
| | | const canControl = computed(() => { |
| | | return edgeServerStatus.value.status === 'online' && modelStatus.value.status === 'running' |
| | | }) |
| | | |
| | | const getProgressColor = computed(() => { |
| | | return (percentage) => { |
| | | if (percentage < 20) return '#909399' |
| | | if (percentage < 40) return '#E6A23C' |
| | | if (percentage < 60) return '#409EFF' |
| | | return '#67C23A' |
| | | } |
| | | }) |
| | | |
| | | // çææ¨¡ææ°æ® |
| | | const generateMockData = () => { |
| | | // çæéæºå°å±åå (20-30 MPa) |
| | | const formationPressure = 20 + Math.random() * 10 |
| | | |
| | | // æ ¹æ®å°å±åå计ç®ä¼åé¢ç |
| | | const baseFrequency = 40 + (formationPressure - 25) * 2 |
| | | const currentFrequency = baseFrequency + (Math.random() - 0.5) * 4 |
| | | const optimizedFrequency = Math.max(35, baseFrequency - Math.random() * 3) |
| | | |
| | | // 计ç®è½èéä½ |
| | | const energyReduction = Math.round((currentFrequency - optimizedFrequency) / currentFrequency * 100) |
| | | |
| | | // è®¡ç®æµéååç |
| | | const flowRate = 150 + Math.random() * 60 |
| | | const power = 70 + Math.random() * 30 |
| | | |
| | | // æ´æ°æ³µæ°æ® |
| | | pumpData.value = { |
| | | formationPressure: parseFloat(formationPressure.toFixed(1)), |
| | | currentFrequency: parseFloat(currentFrequency.toFixed(1)), |
| | | optimizedFrequency: parseFloat(optimizedFrequency.toFixed(1)), |
| | | energyReduction: Math.min(energyReduction, 35), |
| | | flowRate: parseFloat(flowRate.toFixed(1)), |
| | | power: parseFloat(power.toFixed(1)) |
| | | } |
| | | |
| | | // æ´æ°èè½ææ |
| | | energySavingRate.value = 12 + Math.random() * 8 |
| | | totalEnergySaved.value += Math.random() * 2 |
| | | |
| | | // æ´æ°è¾¹ç¼æå¡å¨ç¶æ |
| | | edgeServerStatus.value.lastHeartbeat = Date.now() |
| | | |
| | | // éæºæ´æ°æ¨¡åç¶æ |
| | | if (Math.random() > 0.95) { |
| | | modelStatus.value.modelCount = Math.max(1, modelStatus.value.modelCount + (Math.random() > 0.5 ? 1 : -1)) |
| | | } |
| | | |
| | | // æ·»å ä¼ååå²è®°å½ |
| | | if (Math.random() > 0.7) { |
| | | addOptimizationHistory() |
| | | } |
| | | |
| | | // æ´æ°å¾è¡¨æ°æ® |
| | | updateCharts() |
| | | } |
| | | |
| | | // æ·»å ä¼ååå²è®°å½ |
| | | const addOptimizationHistory = () => { |
| | | const timestamp = new Date().toLocaleString() |
| | | const record = { |
| | | timestamp, |
| | | formationPressure: pumpData.value.formationPressure, |
| | | oldFrequency: pumpData.value.currentFrequency, |
| | | newFrequency: pumpData.value.optimizedFrequency, |
| | | energySaved: parseFloat((Math.random() * 5 + 1).toFixed(2)), |
| | | status: Math.random() > 0.1 ? 'success' : 'failed' |
| | | } |
| | | |
| | | optimizationHistory.value.unshift(record) |
| | | |
| | | // ä¿ææå¤100æ¡è®°å½ |
| | | if (optimizationHistory.value.length > 100) { |
| | | optimizationHistory.value = optimizationHistory.value.slice(0, 100) |
| | | } |
| | | } |
| | | |
| | | // æ´æ°å¾è¡¨æ°æ® |
| | | const updateCharts = () => { |
| | | chartInstances.value.forEach(instance => { |
| | | if (instance && instance.setOption) { |
| | | // è¿éå¯ä»¥æ´æ°å¾è¡¨æ°æ® |
| | | // 为äºç®åï¼æä»¬åªæ¯éæ°åå§åå¾è¡¨ |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // æ¹æ³ |
| | | const refreshData = () => { |
| | | generateMockData() |
| | | ElMessage.success('æ°æ®å·æ°æå') |
| | | } |
| | | |
| | | const applyOptimization = async () => { |
| | | try { |
| | | await ElMessageBox.confirm('ç¡®å®è¦åºç¨å½åçä¼å设置åï¼', '确认æä½', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }) |
| | | |
| | | // åºç¨ä¼å设置 |
| | | pumpData.value.currentFrequency = pumpData.value.optimizedFrequency |
| | | ElMessage.success('ä¼å设置åºç¨æå') |
| | | refreshData() |
| | | } catch (error) { |
| | | if (error !== 'cancel') { |
| | | ElMessage.error('åºç¨ä¼å设置失败') |
| | | } |
| | | } |
| | | } |
| | | |
| | | const emergencyStop = async () => { |
| | | try { |
| | | await ElMessageBox.confirm('ç¡®å®è¦ç´§æ¥åæ¢æææ³¨æ°´æ³µåï¼', 'ç´§æ¥æä½', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'error' |
| | | }) |
| | | |
| | | // æ§è¡ç´§æ¥åæ¢é»è¾ |
| | | pumpData.value.currentFrequency = 0 |
| | | pumpData.value.optimizedFrequency = 0 |
| | | ElMessage.success('ç´§æ¥åæ¢æ§è¡æå') |
| | | } catch (error) { |
| | | if (error !== 'cancel') { |
| | | ElMessage.error('ç´§æ¥åæ¢æ§è¡å¤±è´¥') |
| | | } |
| | | } |
| | | } |
| | | |
| | | const showOptimizationHistory = () => { |
| | | historyDialogVisible.value = true |
| | | } |
| | | |
| | | const updateModel = (model) => { |
| | | ElMessage.info(`æ´æ°æ¨¡å: ${model.modelName}`) |
| | | } |
| | | |
| | | const deleteModel = async (model) => { |
| | | try { |
| | | await ElMessageBox.confirm(`ç¡®å®è¦å 餿¨¡å ${model.modelName} åï¼`, '确认å é¤', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }) |
| | | |
| | | const index = modelConfigs.value.findIndex(m => m.modelName === model.modelName) |
| | | if (index > -1) { |
| | | modelConfigs.value.splice(index, 1) |
| | | ElMessage.success('模åå 餿å') |
| | | } |
| | | } catch (error) { |
| | | if (error !== 'cancel') { |
| | | ElMessage.error('模åå é¤å¤±è´¥') |
| | | } |
| | | } |
| | | } |
| | | |
| | | const toggleAutoRefresh = () => { |
| | | autoRefreshStatus.value = !autoRefreshStatus.value |
| | | if (autoRefreshStatus.value) { |
| | | startAutoRefresh() |
| | | ElMessage.success('èªå¨å·æ°å·²å¼å¯') |
| | | } else { |
| | | stopAutoRefresh() |
| | | ElMessage.info('èªå¨å·æ°å·²å
³é') |
| | | } |
| | | } |
| | | |
| | | const startAutoRefresh = () => { |
| | | stopAutoRefresh() // å
忢ä¹åç宿¶å¨ |
| | | autoRefreshTimer.value = setInterval(() => { |
| | | generateMockData() |
| | | }, 60000) // 1åé = 60000æ¯«ç§ |
| | | } |
| | | |
| | | const stopAutoRefresh = () => { |
| | | if (autoRefreshTimer.value) { |
| | | clearInterval(autoRefreshTimer.value) |
| | | autoRefreshTimer.value = null |
| | | } |
| | | } |
| | | |
| | | const formatTime = (timestamp) => { |
| | | return new Date(timestamp).toLocaleTimeString() |
| | | } |
| | | |
| | | // åå§åå¾è¡¨ |
| | | const initCharts = () => { |
| | | // é¢çä¼åè¶å¿å¾ |
| | | const frequencyChartInstance = echarts.init(frequencyChart.value) |
| | | const frequencyOption = { |
| | | title: { text: 'æ³µé¢çä¼åè¶å¿' }, |
| | | tooltip: { trigger: 'axis' }, |
| | | legend: { data: ['å½åé¢ç', 'ä¼åé¢ç', 'å°å±åå'] }, |
| | | xAxis: { type: 'category', data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00'] }, |
| | | yAxis: [ |
| | | { type: 'value', name: 'é¢ç (Hz)' }, |
| | | { type: 'value', name: 'åå (MPa)' } |
| | | ], |
| | | series: [ |
| | | { |
| | | name: 'å½åé¢ç', |
| | | type: 'line', |
| | | data: [45.2, 44.8, 45.5, 45.1, 44.9, 45.2] |
| | | }, |
| | | { |
| | | name: 'ä¼åé¢ç', |
| | | type: 'line', |
| | | data: [42.1, 41.8, 42.3, 41.9, 41.7, 42.1] |
| | | }, |
| | | { |
| | | name: 'å°å±åå', |
| | | type: 'line', |
| | | yAxisIndex: 1, |
| | | data: [25.6, 25.8, 26.1, 25.9, 25.7, 25.6] |
| | | } |
| | | ] |
| | | } |
| | | frequencyChartInstance.setOption(frequencyOption) |
| | | chartInstances.value.push(frequencyChartInstance) |
| | | |
| | | // è½èåæå¾ |
| | | const energyChartInstance = echarts.init(energyChart.value) |
| | | const energyOption = { |
| | | title: { text: 'æ¥è½è对æ¯' }, |
| | | tooltip: { trigger: 'item' }, |
| | | legend: { orient: 'vertical', left: 'left',top: 'center' }, |
| | | series: [ |
| | | { |
| | | name: 'è½èåå¸', |
| | | type: 'pie', |
| | | radius: '50%', |
| | | data: [ |
| | | { value: 45, name: '注水泵' }, |
| | | { value: 25, name: 'ç
§æç³»ç»' }, |
| | | { value: 20, name: 'éé£ç³»ç»' }, |
| | | { value: 10, name: 'å
¶ä»è®¾å¤' } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| | | energyChartInstance.setOption(energyOption) |
| | | chartInstances.value.push(energyChartInstance) |
| | | |
| | | // èè½ææå¾ |
| | | const savingChartInstance = echarts.init(savingChart.value) |
| | | const savingOption = { |
| | | title: { text: 'èè½ææè¶å¿' }, |
| | | tooltip: { trigger: 'axis' }, |
| | | xAxis: { type: 'category', data: ['å¨ä¸', 'å¨äº', 'å¨ä¸', 'å¨å', 'å¨äº', 'å¨å
', '卿¥'] }, |
| | | yAxis: { type: 'value', name: 'èè½ç (%)' }, |
| | | series: [ |
| | | { |
| | | name: 'èè½ç', |
| | | type: 'bar', |
| | | data: [12.5, 15.2, 18.7, 16.3, 19.1, 17.8, 15.8] |
| | | } |
| | | ] |
| | | } |
| | | savingChartInstance.setOption(savingOption) |
| | | chartInstances.value.push(savingChartInstance) |
| | | } |
| | | |
| | | // çæåå§å岿°æ® |
| | | const generateInitialHistory = () => { |
| | | for (let i = 0; i < 20; i++) { |
| | | const timestamp = new Date(Date.now() - i * 3600000).toLocaleString() |
| | | const record = { |
| | | timestamp, |
| | | formationPressure: parseFloat((20 + Math.random() * 10).toFixed(1)), |
| | | oldFrequency: parseFloat((40 + Math.random() * 10).toFixed(1)), |
| | | newFrequency: parseFloat((35 + Math.random() * 8).toFixed(1)), |
| | | energySaved: parseFloat((Math.random() * 5 + 1).toFixed(2)), |
| | | status: Math.random() > 0.1 ? 'success' : 'failed' |
| | | } |
| | | optimizationHistory.value.push(record) |
| | | } |
| | | } |
| | | |
| | | // çå½å¨æ |
| | | onMounted(() => { |
| | | initCharts() |
| | | generateInitialHistory() |
| | | refreshData() |
| | | if (autoRefreshStatus.value) { |
| | | startAutoRefresh() |
| | | } |
| | | }) |
| | | |
| | | onUnmounted(() => { |
| | | stopAutoRefresh() |
| | | chartInstances.value.forEach(instance => { |
| | | if (instance && instance.dispose) { |
| | | instance.dispose() |
| | | } |
| | | }) |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .app-container { |
| | | padding: 20px; |
| | | } |
| | | |
| | | |
| | | |
| | | .status-section { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .status-card { |
| | | height: 140px; |
| | | } |
| | | |
| | | .status-item { |
| | | display: flex; |
| | | align-items: center; |
| | | height: 100%; |
| | | } |
| | | |
| | | .status-icon { |
| | | font-size: 48px; |
| | | margin-right: 20px; |
| | | color: #409EFF; |
| | | } |
| | | |
| | | .status-info { |
| | | flex: 1; |
| | | } |
| | | |
| | | .status-title { |
| | | font-size: 14px; |
| | | color: #909399; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .status-value { |
| | | font-size: 24px; |
| | | font-weight: bold; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .status-detail { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | } |
| | | |
| | | .status-value.online, |
| | | .status-value.running { |
| | | color: #67C23A; |
| | | } |
| | | |
| | | .status-value.offline, |
| | | .status-value.stopped { |
| | | color: #F56C6C; |
| | | } |
| | | |
| | | .status-value.success { |
| | | color: #67C23A; |
| | | } |
| | | |
| | | .control-section, |
| | | .model-section, |
| | | .analysis-section { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .pump-control h4, |
| | | .pump-chart h4 { |
| | | margin-bottom: 20px; |
| | | color: #303133; |
| | | } |
| | | |
| | | .control-buttons { |
| | | margin-top: 20px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .control-buttons .el-button { |
| | | margin: 0 10px; |
| | | } |
| | | </style> |
| | |
| | | <div class="app-container product-view"> |
| | | <div class="left"> |
| | | <div> |
| | | <el-input v-model="search" style="width: 210px" placeholder="è¾å
¥å
³é®åè¿è¡æç´¢" @change="searchFilter" |
| | | @clear="searchFilter" clearable prefix-icon="Search" /> |
| | | <el-button type="primary" @click="openProDia('add')" style="margin-left: 10px">æ°å¢ç¶åºå</el-button> |
| | | <el-input |
| | | v-model="search" |
| | | style="width: 210px" |
| | | placeholder="è¾å
¥å
³é®åè¿è¡æç´¢" |
| | | @change="searchFilter" |
| | | @clear="searchFilter" |
| | | clearable |
| | | prefix-icon="Search" |
| | | /> |
| | | <el-button |
| | | type="primary" |
| | | @click="openProDia('addOne')" |
| | | style="margin-left: 10px" |
| | | >æ°å¢ç¶åºå</el-button |
| | | > |
| | | </div> |
| | | <div ref="containerRef"> |
| | | <el-tree ref="tree" v-loading="treeLoad" :data="list" @node-click="handleNodeClick" |
| | | :expand-on-click-node="false" default-expand-all :default-expanded-keys="expandedKeys" :draggable="true" |
| | | :filter-node-method="filterNode" :props="{ children: 'children', label: 'label' }" highlight-current |
| | | node-key="id" style=" |
| | | <el-tree |
| | | ref="tree" |
| | | v-loading="treeLoad" |
| | | :data="list" |
| | | @node-click="handleNodeClick" |
| | | :expand-on-click-node="false" |
| | | default-expand-all |
| | | :default-expanded-keys="expandedKeys" |
| | | :draggable="true" |
| | | :filter-node-method="filterNode" |
| | | :props="{ children: 'children', label: 'label' }" |
| | | highlight-current |
| | | node-key="id" |
| | | style=" |
| | | height: calc(100vh - 190px); |
| | | overflow-y: scroll; |
| | | scrollbar-width: none; |
| | | "> |
| | | margin-top: 10px; |
| | | " |
| | | > |
| | | <template #default="{ node, data }"> |
| | | <div class="custom-tree-node"> |
| | | <span class="tree-node-content"> |
| | | <el-icon class="orange-icon"> |
| | | <component :is="data.children && data.children.length > 0 |
| | | ? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" /> |
| | | ? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" /> |
| | | </el-icon> |
| | | {{ data.fuId==null ? data.id : '' || data.areaName }} |
| | | {{ data.label }} |
| | | </span> |
| | | <div> |
| | | <el-button v-if="node.level < 2" type="primary" link @click="openProDia('edit', data)"> |
| | | <el-button |
| | | type="primary" |
| | | link |
| | | @click="openProDia('edit', data)" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <!-- <el-button v-if="node.level < 2" type="primary" link @click="openProDia('add', data)" :disabled="node.level >= 3"> |
| | | <el-button type="primary" link @click="openModelDia('add','', data.id)"> |
| | | æ·»å ååºå |
| | | </el-button> --> |
| | | <!-- <el-button v-if="!node.childNodes.length" style="margin-left: 4px" type="danger" link |
| | | @click="remove(node, data)"> |
| | | </el-button> |
| | | <el-button |
| | | v-if="!node.childNodes.length" |
| | | style="margin-left: 4px" |
| | | type="danger" |
| | | link |
| | | @click="remove(node, data)" |
| | | > |
| | | å é¤ |
| | | </el-button> --> |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="right"> |
| | | <div style="margin-bottom: 10px"> |
| | | <div style="margin-bottom: 10px" v-if="isShowButton"> |
| | | <el-button type="primary" @click="openModelDia('add')"> |
| | | æ°å¢åºå |
| | | æ°å¢ååºå |
| | | </el-button> |
| | | <ImportExcel @uploadSuccess="getModelList" /> |
| | | <el-button type="danger" @click="handleDelete" style="margin-left: 10px" plain> |
| | | <el-button |
| | | type="danger" |
| | | @click="handleDelete" |
| | | style="margin-left: 10px" |
| | | plain |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | </div> |
| | | <PIMTable rowKey="id" :column="tableColumn" :tableData="tableData" :page="page" :isSelection="true" |
| | | @selection-change="handleSelectionChange" :tableLoading="tableLoading" @pagination="pagination"></PIMTable> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | ></PIMTable> |
| | | </div> |
| | | <el-dialog v-model="productDia" title="åºå" width="400px" @keydown.enter.prevent> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <el-row> |
| | | <el-form |
| | | :model="form" |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="rules" |
| | | ref="formRef" |
| | | > |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="åºåç±»åï¼" prop="areaType"> |
| | | <el-select v-model="form.areaType" placeholder="è¯·éæ©åºåç±»å" clearable @keydown.enter.prevent> |
| | | <el-option v-for="item in areaTypeList" :key="item" :label="item" :value="item" /> |
| | | </el-select> |
| | | <el-form-item label="åºååç§°ï¼" prop="areaName"> |
| | | <el-input |
| | | v-model="form.areaName" |
| | | placeholder="请è¾å
¥äº§ååç§°" |
| | | clearable |
| | | @keydown.enter.prevent |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <!-- <el-button type="primary" @click="submitModelForm">确认</el-button> --> |
| | | <el-button @click="closeProDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <el-dialog v-model="modelDia" title="åºå" width="400px" @close="closeModelDia" @keydown.enter.prevent> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="modelRules" ref="modelFormRef"> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="åºååç§°ï¼" prop="areaName"> |
| | | <el-input v-model="form.areaName" placeholder="请è¾å
¥åºååç§°" clearable @keydown.enter.prevent /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="åºåç±»åï¼" prop="areaType"> |
| | | <el-select v-model="form.areaType" placeholder="è¯·éæ©åºåç±»å" clearable @keydown.enter.prevent> |
| | | <el-option v-for="item in areaTypeList" :key="item" :label="item" :value="item" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="ç¶åºåï¼" prop="fuId"> |
| | | <el-select v-model="form.fuId" placeholder="è¯·éæ©ç¶åºå" clearable @keydown.enter.prevent> |
| | | <el-option v-for="item in list" :key="item.id" :label="item.label" :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-dialog |
| | | v-model="modelDia" |
| | | title="ååºå" |
| | | width="400px" |
| | | @close="closeModelDia" |
| | | @keydown.enter.prevent |
| | | > |
| | | <el-form |
| | | :model="modelForm" |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="modelRules" |
| | | ref="modelFormRef" |
| | | > |
| | | <el-form-item label="ç¶åºåï¼" prop="fuId"> |
| | | <el-cascader v-model="modelForm.fuId" :options="list" :props="{ |
| | | value: 'id', |
| | | label: 'label', |
| | | children: 'children', |
| | | checkStrictly: true, |
| | | }" /> |
| | | </el-form-item> |
| | | <el-form-item label="åºåç±»åï¼" prop="areaType"> |
| | | <el-select v-model="modelForm.areaType" placeholder="è¯·éæ©"> |
| | | <el-option v-for="item in area_type" :key="item.value" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="åºååç§°ï¼" prop="areaName"> |
| | | <el-input |
| | | v-model="modelForm.areaName" |
| | | placeholder="请è¾å
¥åä½" |
| | | clearable |
| | | @keydown.enter.prevent |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted } from "vue"; |
| | | import { ref } from "vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { areaListPage, areaDelete, areaAdd, areaUpdate } from "@/api/energyManagement/index.js"; |
| | | // import ImportExcel from "../../../ImportExcel/index.vue"; |
| | | import { |
| | | areaAdd, |
| | | areaDelete, |
| | | areaListPage, |
| | | areaListTree, |
| | | } from "@/api/energyManagement/index.js"; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | const tree = ref(null); |
| | |
| | | const treeLoad = ref(false); |
| | | const list = ref([]); |
| | | const expandedKeys = ref([]); |
| | | const areaTypeList = ref([ |
| | | "å±
æ°ç¨çµåºå", |
| | | "åä¸ç¨çµåºå", |
| | | "å·¥ä¸ç¨çµåºå", |
| | | "åä¸ç¨çµåºå", |
| | | "å
Œ
±äºä¸ç¨çµåºå", |
| | | "交éç¨çµåºå", |
| | | "ç¹æ®ç¨çµåºå" |
| | | ]) |
| | | const {area_type} = proxy.useDict("area_type") |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "åºåç¼å·", |
| | | prop: "id" |
| | | }, |
| | | { |
| | | label: "åºååç§°", |
| | | prop: "areaName" |
| | | prop: "areaName", |
| | | }, |
| | | { |
| | | label: "åºåç±»å", |
| | | prop: "areaType" |
| | | }, |
| | | { |
| | | label: "ç¶åºå", |
| | | prop: "fuId", |
| | | prop: "areaType", |
| | | dataType: "tag", |
| | | formatData: (row) => { |
| | | return area_type.value.find(item => item.value == row)?.label; |
| | | } |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: 'right', |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | |
| | | const selectedRows = ref([]); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 30, |
| | | size: 10, |
| | | total: 0, |
| | | }); |
| | | const data = reactive({ |
| | | form: { |
| | | id: "", |
| | | areaName: "", |
| | | areaType: "", |
| | | }, |
| | | rules: { |
| | | areaName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | }, |
| | | modelForm: { |
| | | areaName: "", |
| | | fuId: "", |
| | | sort: "" |
| | | }, |
| | | modelRules: { |
| | | model: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | unit: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | areaName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | fuId: [{ required: true, message: "请è¾å
¥", trigger: "change" }], |
| | | }, |
| | | }); |
| | | const { form, rules, modelRules } = toRefs(data); |
| | | // const originalRecords = ref([]); |
| | | // const parentItems = ref([]); |
| | | const { form, rules, modelForm, modelRules } = toRefs(data); |
| | | |
| | | // æ¥è¯¢äº§åæ |
| | | const getProductTeeList = () => { |
| | | const getProductTreeList = () => { |
| | | treeLoad.value = true; |
| | | areaListPage({ |
| | | current: page.current, |
| | | size: page.size, |
| | | }) |
| | | areaListTree() |
| | | .then((res) => { |
| | | const originalRecords = res.data.records; |
| | | console.log(originalRecords); |
| | | // çéfuId为空ç项ä½ä¸ºç¶èç¹ |
| | | list.value = originalRecords.filter(item => !item.fuId); |
| | | // 为æ¯ä¸ªç¶èç¹æ·»å childrenå¹¶å¹é
åèç¹ |
| | | list.value.forEach(parent => { |
| | | parent.children = originalRecords.filter(child => child.fuId === parent.id); |
| | | list.value = res; |
| | | list.value.forEach((a) => { |
| | | expandedKeys.value.push(a.label); |
| | | }); |
| | | // // æ´æ°åè¡¨æ°æ®ä¸ºæ å½¢ç»æ |
| | | // list.value = parentItems.value; |
| | | |
| | | console.log('æ å½¢ç»ææ°æ®:', list.value); |
| | | |
| | | // list.value.forEach((a) => { |
| | | // expandedKeys.value.push(a.label); |
| | | // }); |
| | | treeLoad.value = false; |
| | | }) |
| | | .catch((err) => { |
| | |
| | | // æå¼äº§åå¼¹æ¡ |
| | | const openProDia = (type, data) => { |
| | | operationType.value = type; |
| | | modelOperationType.value = type; |
| | | |
| | | productDia.value = true; |
| | | form.value.areaType = ""; |
| | | form.value.areaName = ""; |
| | | if (type === "edit") { |
| | | form.value.id = data.id; |
| | | form.value.areaName = data.areaName; |
| | | form.value.areaType = data.areaType; |
| | | form.value.fuId = data.fuId; |
| | | form.value.sort = data.sort; |
| | | } |
| | | }; |
| | | // æå¼è§æ ¼åå·å¼¹æ¡ |
| | | const openModelDia = (type, data) => { |
| | | const openModelDia = (type, data,fatherId) => { |
| | | modelOperationType.value = type; |
| | | modelDia.value = true; |
| | | form.value.areaName = ""; |
| | | form.value.areaType = ""; |
| | | form.value.fuId = ""; |
| | | form.value.sort = ""; |
| | | modelForm.value.fuId = ""; |
| | | modelForm.value.areaType = ""; |
| | | modelForm.value.areaName = ""; |
| | | modelForm.value.id = ""; |
| | | modelForm.value.fuId = fatherId; |
| | | if (type === "edit") { |
| | | form.value = { ...data }; |
| | | modelForm.value = { ...data }; |
| | | } |
| | | }; |
| | | // æäº¤äº§ååç§°ä¿®æ¹ |
| | |
| | | proxy.$refs.formRef.validate((valid) => { |
| | | if (valid) { |
| | | if (operationType.value === "add") { |
| | | // form.value.fuId = currentId.value; |
| | | // form.value.id = ""; |
| | | areaAdd(form.value).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeProDia(); |
| | | getProductTeeList(); |
| | | getModelList(); |
| | | |
| | | }); |
| | | }else { |
| | | form.value.parentId = currentId.value; |
| | | form.value.id = ""; |
| | | } else if (operationType.value === "addOne") { |
| | | form.value.id = ""; |
| | | form.value.parentId = ""; |
| | | } else { |
| | | form.value.id = currentId.value; |
| | | areaUpdate(form.value).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeProDia(); |
| | | getModelList(); |
| | | getProductTeeList(); |
| | | }); |
| | | form.value.parentId = ""; |
| | | } |
| | | areaAdd(form.value).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeProDia(); |
| | | getProductTreeList(); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | |
| | | areaDelete(ids) |
| | | .then((res) => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getProductTeeList(); |
| | | getModelList(); |
| | | getProductTreeList(); |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | |
| | | // éæ©äº§å |
| | | const handleNodeClick = (val, node, el) => { |
| | | // 夿æ¯å¦ä¸ºå¶åèç¹ |
| | | // isShowButton.value = !(val.children && val.children.length > 0); |
| | | isShowButton.value = !(val.children && val.children.length > 0); |
| | | // åªæå¶åèç¹ææ§è¡ä»¥ä¸é»è¾ |
| | | currentId.value = val.id; |
| | | currentParentId.value = val.parentId; |
| | | getModelList(); |
| | | getModelList(true); |
| | | }; |
| | | |
| | | // æäº¤åºå |
| | | // æäº¤è§æ ¼åå·ä¿®æ¹ |
| | | const submitModelForm = () => { |
| | | proxy.$refs.modelFormRef.validate((valid) => { |
| | | if (valid) { |
| | | if (modelOperationType.value === "add") { |
| | | form.value.fuId = currentId.value; |
| | | areaAdd(form.value).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | }); |
| | | } |
| | | else { |
| | | // form.value.id = currentId.value; |
| | | areaUpdate(form.value).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | }); |
| | | } |
| | | closeModelDia(); |
| | | getModelList(); |
| | | getProductTeeList(); |
| | | modelForm.value.fuId = currentId.value; |
| | | areaAdd(modelForm.value).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeModelDia(); |
| | | getModelList(); |
| | | getProductTreeList(); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | // æ¥è¯¢åºå |
| | | const getModelList = () => { |
| | | // æ¥è¯¢è§æ ¼åå· |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getModelList(); |
| | | }; |
| | | const getModelList = (val = false) => { |
| | | tableLoading.value = true; |
| | | areaListPage({ |
| | | fuId: currentId.value, |
| | | let obj = { |
| | | id: currentId.value, |
| | | fuId:currentId.value, |
| | | current: page.current, |
| | | size: page.size, |
| | | }).then((res) => { |
| | | size: page.size |
| | | } |
| | | if(val){ |
| | | delete obj.id; |
| | | }else{ |
| | | delete obj.fuId |
| | | } |
| | | areaListPage(obj).then((res) => { |
| | | console.log("res", res); |
| | | const originalRecords = res.data.records; |
| | | // çéfuId为空ç项ä½ä¸ºç¶èç¹ |
| | | tableData.value = originalRecords.filter(item => item.fuId === currentId.value); |
| | | page.total = res.total; |
| | | tableData.value = res.data.records; |
| | | page.total = res.data.total; |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | |
| | | areaDelete(ids) |
| | | .then((res) => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getModelList(); |
| | | getProductTeeList(); |
| | | getModelList(); |
| | | getProductTreeList(); |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | |
| | | // 没å¹é
å°è¿åfalse |
| | | return false; |
| | | }; |
| | | onMounted(() => { |
| | | getProductTeeList(); |
| | | }); |
| | | |
| | | getProductTreeList(); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .product-view { |
| | | display: flex; |
| | | } |
| | | |
| | | .left { |
| | | width: 380px; |
| | | padding: 16px; |
| | | background: #ffffff; |
| | | } |
| | | |
| | | .right { |
| | | width: calc(100% - 380px); |
| | | padding: 16px; |
| | | margin-left: 20px; |
| | | background: #ffffff; |
| | | } |
| | | |
| | | .custom-tree-node { |
| | | flex: 1; |
| | | display: flex; |
| | |
| | | font-size: 14px; |
| | | padding-right: 8px; |
| | | } |
| | | |
| | | .tree-node-content { |
| | | display: flex; |
| | | align-items: center; |
| | | /* åç´å±
ä¸ */ |
| | | align-items: center; /* åç´å±
ä¸ */ |
| | | height: 100%; |
| | | } |
| | | |
| | | .orange-icon { |
| | | color: orange; |
| | | font-size: 18px; |
| | | margin-right: 8px; |
| | | /* 徿 䏿åä¹é´å ç¹é´è· */ |
| | | margin-right: 8px; /* 徿 䏿åä¹é´å ç¹é´è· */ |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¨çµæ¶èåºåï¼" prop="electricityConsumptionAreaId"> |
| | | <el-cascader |
| | | v-model="form.electricityConsumptionAreaId" |
| | | :options="areaList" |
| | | :props="{ |
| | | value: 'id', |
| | | label: 'label', |
| | | children: 'children', |
| | | checkStrictly: true, |
| | | }" |
| | | placeholder="è¯·éæ©åºå" |
| | | clearable |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¯æ¥éå¶çµéï¼" prop="everyNum"> |
| | | <el-input |
| | | v-model="form.everyNum" |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é¢å®åçï¼" prop="powerRating"> |
| | | <el-input |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å®é
åçï¼" prop="powerActual"> |
| | | <el-input |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è¿è¡æ¶é´ï¼" prop="runDate"> |
| | | <el-date-picker |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="彿¥ç¨çµéï¼" prop="dayNum"> |
| | | <el-input |
| | |
| | | <script setup> |
| | | import {ref} from "vue"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import {deviceList, equipmentEnergyAdd, equipmentEnergyUpdate} from "@/api/energyManagement/index.js"; |
| | | import {deviceList, equipmentEnergyAdd, equipmentEnergyUpdate, areaListTree} from "@/api/energyManagement/index.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | const dialogFormVisible = ref(false); |
| | |
| | | powerActual: "", |
| | | runDate: "", |
| | | dayNum: "", |
| | | electricityConsumptionAreaId: "", |
| | | }, |
| | | rules: { |
| | | code: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | |
| | | powerRating: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | powerActual: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | dayNum: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | electricityConsumptionAreaId: [{ required: true, message: "è¯·éæ©åºå", trigger: "change" }], |
| | | }, |
| | | }) |
| | | const { form, rules } = toRefs(data); |
| | | const codeList = ref([]) |
| | | const areaList = ref([]) |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = (type, row) => { |
| | |
| | | // form.value.maintenanceTime = getCurrentDate(); |
| | | form.value = {} |
| | | proxy.resetForm("formRef"); |
| | | |
| | | // è·å设å¤å表 |
| | | deviceList().then((res) => { |
| | | codeList.value = res.data; |
| | | }); |
| | | |
| | | // è·ååºåå表 |
| | | areaListTree().then((res) => { |
| | | areaList.value = res; |
| | | console.log("areaList", res); |
| | | }); |
| | | |
| | | if (type === "edit") { |
| | | form.value = {...row} |
| | | // ç¼è¾æ¶ï¼å°å个ID转æ¢ä¸ºæ°ç»æ ¼å¼ç¨äºåæ¾ |
| | | if (row.electricityConsumptionAreaId) { |
| | | form.value.electricityConsumptionAreaId = [row.electricityConsumptionAreaId]; |
| | | } |
| | | } |
| | | } |
| | | const setName = (code) => { |
| | |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // æäº¤åå¤ç electricityConsumptionAreaIdï¼åæ°ç»çæåä¸ä¸ªå¼ |
| | | const submitData = { ...form.value }; |
| | | if (Array.isArray(submitData.electricityConsumptionAreaId) && submitData.electricityConsumptionAreaId.length > 0) { |
| | | submitData.electricityConsumptionAreaId = submitData.electricityConsumptionAreaId[submitData.electricityConsumptionAreaId.length - 1]; |
| | | } |
| | | |
| | | if (operationType.value === "add") { |
| | | equipmentEnergyAdd(form.value).then(response => { |
| | | equipmentEnergyAdd(submitData).then(response => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå") |
| | | closeDia() |
| | | }) |
| | | } else { |
| | | equipmentEnergyUpdate(form.value).then(response => { |
| | | equipmentEnergyUpdate(submitData).then(response => { |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå") |
| | | closeDia() |
| | | }) |
| | |
| | | } = usePaginationApi( |
| | | getLedgerPage, |
| | | { |
| | | searchText: undefined, |
| | | deviceName: undefined, |
| | | deviceModel: undefined, |
| | | supplierName: undefined, |
| | | unit: undefined, |
| | | entryDateStart: undefined, |
| | | entryDateEnd: undefined, |
| | | }, |
| | | [ |
| | | { |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="éä»¶ææï¼" prop="remark"> |
| | | <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload |
| | | :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError" |
| | | :on-success="handleUploadSuccess" :on-remove="handleRemove"> |
| | | <el-button type="primary" v-if="operationType !== 'view'">ä¸ä¼ </el-button> |
| | | <template #tip v-if="operationType !== 'view'"> |
| | | <div class="el-upload__tip"> |
| | | æä»¶æ ¼å¼æ¯æ |
| | | docï¼docxï¼xlsï¼xlsxï¼pptï¼pptxï¼pdfï¼txtï¼xmlï¼jpgï¼jpegï¼pngï¼gifï¼bmpï¼rarï¼zipï¼7z |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <!-- <el-row :gutter="30">--> |
| | | <!-- <el-col :span="24">--> |
| | | <!-- <el-form-item label="éä»¶ææï¼" prop="remark">--> |
| | | <!-- <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload--> |
| | | <!-- :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"--> |
| | | <!-- :on-success="handleUploadSuccess" :on-remove="handleRemove">--> |
| | | <!-- <el-button type="primary" v-if="operationType !== 'view'">ä¸ä¼ </el-button>--> |
| | | <!-- <template #tip v-if="operationType !== 'view'">--> |
| | | <!-- <div class="el-upload__tip">--> |
| | | <!-- æä»¶æ ¼å¼æ¯æ--> |
| | | <!-- docï¼docxï¼xlsï¼xlsxï¼pptï¼pptxï¼pdfï¼txtï¼xmlï¼jpgï¼jpegï¼pngï¼gifï¼bmpï¼rarï¼zipï¼7z--> |
| | | <!-- </div>--> |
| | | <!-- </template>--> |
| | | <!-- </el-upload>--> |
| | | <!-- </el-form-item>--> |
| | | <!-- </el-col>--> |
| | | <!-- </el-row>--> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="éä»¶ææï¼" prop="remark"> |
| | | <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload |
| | | :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError" |
| | | :on-success="handleUploadSuccess" :on-remove="handleRemove"> |
| | | <el-button type="primary" v-if="operationType !== 'view'">ä¸ä¼ </el-button> |
| | | <template #tip v-if="operationType !== 'view'"> |
| | | <div class="el-upload__tip"> |
| | | æä»¶æ ¼å¼æ¯æ |
| | | docï¼docxï¼xlsï¼xlsxï¼pptï¼pptxï¼pdfï¼txtï¼xmlï¼jpgï¼jpegï¼pngï¼gifï¼bmpï¼rarï¼zipï¼7z |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <!-- <el-row :gutter="30">--> |
| | | <!-- <el-col :span="24">--> |
| | | <!-- <el-form-item label="éä»¶ææï¼" prop="remark">--> |
| | | <!-- <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload--> |
| | | <!-- :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"--> |
| | | <!-- :on-success="handleUploadSuccess" :on-remove="handleRemove">--> |
| | | <!-- <el-button type="primary" v-if="operationType !== 'view'">ä¸ä¼ </el-button>--> |
| | | <!-- <template #tip v-if="operationType !== 'view'">--> |
| | | <!-- <div class="el-upload__tip">--> |
| | | <!-- æä»¶æ ¼å¼æ¯æ--> |
| | | <!-- docï¼docxï¼xlsï¼xlsxï¼pptï¼pptxï¼pdfï¼txtï¼xmlï¼jpgï¼jpegï¼pngï¼gifï¼bmpï¼rarï¼zipï¼7z--> |
| | | <!-- </div>--> |
| | | <!-- </template>--> |
| | | <!-- </el-upload>--> |
| | | <!-- </el-form-item>--> |
| | | <!-- </el-col>--> |
| | | <!-- </el-row>--> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog |
| | | v-model="dialogFormVisible" |
| | | title="ä¸ä¼ éä»¶" |
| | | width="50%" |
| | | @close="closeDia" |
| | | > |
| | | <div style="margin-bottom: 10px;text-align: right"> |
| | | <el-upload |
| | | v-model:file-list="fileList" |
| | | class="upload-demo" |
| | | :action="uploadUrl" |
| | | :on-success="handleUploadSuccess" |
| | | :on-error="handleUploadError" |
| | | name="file" |
| | | :show-file-list="false" |
| | | :headers="headers" |
| | | style="display: inline;margin-right: 10px" |
| | | > |
| | | <el-button type="primary">ä¸ä¼ éä»¶</el-button> |
| | | </el-upload> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :tableLoading="tableLoading" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | height="500" |
| | | > |
| | | </PIMTable> |
| | | <pagination |
| | | style="margin: 10px 0" |
| | | v-show="total > 0" |
| | | @pagination="paginationSearch" |
| | | :total="total" |
| | | :page="page.current" |
| | | :limit="page.size" |
| | | /> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <filePreview ref="filePreviewRef" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref} from "vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {getToken} from "@/utils/auth.js"; |
| | | import filePreview from '@/components/filePreview/index.vue' |
| | | import { |
| | | fileAdd, |
| | | fileDel, |
| | | fileListPage |
| | | } from "@/api/financialManagement/revenueManagement.js"; |
| | | import Pagination from "@/components/PIMTable/Pagination.vue"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | |
| | | const dialogFormVisible = ref(false); |
| | | const currentId = ref('') |
| | | const selectedRows = ref([]); |
| | | const filePreviewRef = ref() |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "æä»¶åç§°", |
| | | prop: "name", |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | operation: [ |
| | | { |
| | | name: "ä¸è½½", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | downLoadFile(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "é¢è§", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | lookFile(row); |
| | | }, |
| | | } |
| | | ], |
| | | }, |
| | | ]); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | }); |
| | | const total = ref(0); |
| | | const tableData = ref([]); |
| | | const fileList = ref([]); |
| | | const tableLoading = ref(false); |
| | | const accountType = ref('') |
| | | const headers = ref({ |
| | | Authorization: "Bearer " + getToken(), |
| | | }); |
| | | const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // ä¸ä¼ çå¾çæå¡å¨å°å |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = (row,type) => { |
| | | accountType.value = type; |
| | | dialogFormVisible.value = true; |
| | | currentId.value = row.id; |
| | | getList() |
| | | } |
| | | const paginationSearch = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | const getList = () => { |
| | | fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => { |
| | | tableData.value = res.data.records; |
| | | total.value = res.data.total; |
| | | }) |
| | | } |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | dialogFormVisible.value = false; |
| | | emit('close') |
| | | }; |
| | | // ä¸ä¼ æåå¤ç |
| | | function handleUploadSuccess(res, file) { |
| | | // 妿ä¸ä¼ æå |
| | | if (res.code == 200) { |
| | | const fileRow = {} |
| | | fileRow.name = res.data.originalName |
| | | fileRow.url = res.data.tempPath |
| | | uploadFile(fileRow) |
| | | } else { |
| | | proxy.$modal.msgError("æä»¶ä¸ä¼ 失败"); |
| | | } |
| | | } |
| | | function uploadFile(file) { |
| | | file.accountId = currentId.value; |
| | | file.accountType = accountType.value; |
| | | fileAdd(file).then(res => { |
| | | proxy.$modal.msgSuccess("æä»¶ä¸ä¼ æå"); |
| | | getList() |
| | | }) |
| | | } |
| | | // ä¸ä¼ 失败å¤ç |
| | | function handleUploadError() { |
| | | proxy.$modal.msgError("æä»¶ä¸ä¼ 失败"); |
| | | } |
| | | // ä¸è½½éä»¶ |
| | | const downLoadFile = (row) => { |
| | | proxy.$download.name(row.url); |
| | | } |
| | | // å é¤ |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | | return; |
| | | } |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(() => { |
| | | fileDel(ids).then((res) => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getList(); |
| | | }); |
| | | }).catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | // é¢è§éä»¶ |
| | | const lookFile = (row) => { |
| | | filePreviewRef.value.open(row.url) |
| | | } |
| | | |
| | | defineExpose({ |
| | | openDialog, |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
| | |
| | | </div> |
| | | <form-dia ref="formDia" @close="handleQuery"></form-dia> |
| | | <calibration-dia ref="calibrationDia" @close="handleQuery"></calibration-dia> |
| | | <files-dia ref="filesDia"></files-dia> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | measuringInstrumentDelete, |
| | | measuringInstrumentListPage |
| | | } from "@/api/equipmentManagement/measurementEquipment.js"; |
| | | import FilesDia from "./filesDia.vue"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const userStore = useUserStore() |
| | | |
| | |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | width: '130', |
| | | fixed: 'right', |
| | | operation: [ |
| | | { |
| | |
| | | name: "éä»¶", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openCalibrationDia("add", row); |
| | | openFilesFormDia(row); |
| | | }, |
| | | }, |
| | | ], |
| | |
| | | ]); |
| | | const tableData = ref([]); |
| | | const tableLoading = ref(false); |
| | | const filesDia = ref() |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | |
| | | }); |
| | | const selectedRows = ref([]); |
| | | |
| | | // æå¼éä»¶å¼¹æ¡ |
| | | const openFilesFormDia = (row) => { |
| | | console.log(row) |
| | | nextTick(() => { |
| | | filesDia.value?.openDialog( row,'计éå¨å
·å°è´¦') |
| | | }) |
| | | }; |
| | | |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | |
| | | } = usePaginationApi( |
| | | getRepairPage, |
| | | { |
| | | searchText: undefined, |
| | | deviceName: undefined, |
| | | deviceModel: undefined, |
| | | remark: undefined, |
| | | maintenanceName: undefined, |
| | | repairTimeStr: undefined, |
| | | maintenanceTimeStr: undefined, |
| | | }, |
| | | [ |
| | | { |
| | |
| | | getTableData, |
| | | resetFilters, |
| | | onCurrentChange, |
| | | } = usePaginationApi(getUpkeepPage, {}, [ |
| | | } = usePaginationApi(getUpkeepPage, { |
| | | deviceName: undefined, |
| | | maintenancePlanTime: undefined, |
| | | maintenanceActuallyTime: undefined, |
| | | maintenanceActuallyName: undefined, |
| | | }, [ |
| | | { |
| | | label: "设å¤åç§°", |
| | | align: "center", |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="filters" :inline="true"> |
| | | <el-form-item label="å½å
¥æ¥æ:"> |
| | | <el-form-item label="æ¯åºæ¥æ:"> |
| | | <el-date-picker v-model="filters.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" |
| | | placeholder="è¯·éæ©" clearable @change="changeDaterange" /> |
| | | </el-form-item> |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="filters" :inline="true"> |
| | | <el-form-item label="å½å
¥æ¥æ:"> |
| | | <el-form-item label="æ¶å
¥æ¥æ:"> |
| | | <el-date-picker v-model="filters.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" |
| | | placeholder="è¯·éæ©" clearable @change="changeDaterange" /> |
| | | </el-form-item> |
| | |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ£éªåï¼" prop="checkName"> |
| | | <el-input v-model="form.checkName" placeholder="请è¾å
¥" clearable/> |
| | | |
| | | <el-select v-model="form.checkName" placeholder="è¯·éæ©" clearable> |
| | | <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" |
| | | :value="item.nickName"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :tableLoading="tableLoading" |
| | | height="400" |
| | | > |
| | | <template #slot="{ row }"> |
| | | <el-input v-model="row.testValue" clearable/> |
| | | </template> |
| | | </PIMTable> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | |
| | | import {getOptions} from "@/api/procurementManagement/procurementLedger.js"; |
| | | import {productTreeList} from "@/api/basicData/product.js"; |
| | | import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js"; |
| | | import {userListNoPage} from "@/api/system/user.js"; |
| | | import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js"; |
| | | import {qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | |
| | |
| | | const { form, rules } = toRefs(data); |
| | | const supplierList = ref([]); |
| | | const productOptions = ref([]); |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "ææ ", |
| | | prop: "parameterItem", |
| | | }, |
| | | { |
| | | label: "åä½", |
| | | prop: "unit", |
| | | }, |
| | | { |
| | | label: "æ åå¼", |
| | | prop: "standardValue", |
| | | }, |
| | | { |
| | | label: "å
æ§å¼", |
| | | prop: "controlValue", |
| | | }, |
| | | { |
| | | label: "æ£éªå¼", |
| | | prop: "testValue", |
| | | dataType: 'slot', |
| | | slot: 'slot', |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | | const tableLoading = ref(false); |
| | | const userList = ref([]); |
| | | const currentProductId = ref(0); |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = (type, row) => { |
| | | const openDialog = async (type, row) => { |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | getOptions().then((res) => { |
| | | supplierList.value = res.data; |
| | | }); |
| | | let userLists = await userListNoPage(); |
| | | userList.value = userLists.data; |
| | | form.value = {} |
| | | getProductOptions(); |
| | | if (operationType.value === 'edit') { |
| | | form.value = {...row} |
| | | currentProductId.value = row.productId || 0 |
| | | getQualityInspectParamList(row.id) |
| | | } |
| | | } |
| | | const getProductOptions = () => { |
| | |
| | | }); |
| | | }; |
| | | const getModels = (value) => { |
| | | currentProductId.value = value |
| | | form.value.productName = findNodeById(productOptions.value, value); |
| | | if (currentProductId) { |
| | | getList(); |
| | | } |
| | | }; |
| | | const findNodeById = (nodes, productId) => { |
| | | for (let i = 0; i < nodes.length; i++) { |
| | |
| | | proxy.$refs.formRef.validate(valid => { |
| | | if (valid) { |
| | | form.value.inspectType = 2 |
| | | if (operationType.value === "add") { |
| | | tableData.value.forEach((item) => { |
| | | delete item.id |
| | | }) |
| | | } |
| | | const data = {...form.value, qualityInspectParams: tableData.value} |
| | | if (operationType.value === "add") { |
| | | qualityInspectAdd(form.value).then(res => { |
| | | qualityInspectAdd(data).then(res => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | }) |
| | | } else { |
| | | qualityInspectUpdate(form.value).then(res => { |
| | | qualityInspectUpdate(data).then(res => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | }) |
| | |
| | | } |
| | | }) |
| | | } |
| | | const getList = () => { |
| | | qualityInspectDetailByProductId(currentProductId.value).then(res => { |
| | | tableData.value = res.data; |
| | | }) |
| | | } |
| | | const getQualityInspectParamList = (id) => { |
| | | qualityInspectParamInfo(id).then(res => { |
| | | tableData.value = res.data; |
| | | }) |
| | | } |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | |
| | | <InspectionFormDia ref="inspectionFormDia" @close="handleQuery"></InspectionFormDia> |
| | | <FormDia ref="formDia" @close="handleQuery"></FormDia> |
| | | <files-dia ref="filesDia" @close="handleQuery"></files-dia> |
| | | <el-dialog v-model="dialogFormVisible" title="ç¼è¾æ£éªå" width="30%" |
| | | @close="closeDia"> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <el-form-item label="æ£éªåï¼" prop="checkName"> |
| | | <el-select v-model="form.checkName" placeholder="è¯·éæ©" clearable> |
| | | <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" |
| | | :value="item.nickName"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import InspectionFormDia from "@/views/qualityManagement/finalInspection/components/inspectionFormDia.vue"; |
| | | import FormDia from "@/views/qualityManagement/finalInspection/components/formDia.vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {qualityInspectDel, qualityInspectListPage} from "@/api/qualityManagement/rawMaterialInspection.js"; |
| | | import { |
| | | downloadQualityInspect, |
| | | qualityInspectDel, |
| | | qualityInspectListPage, qualityInspectUpdate, |
| | | submitQualityInspect |
| | | } from "@/api/qualityManagement/rawMaterialInspection.js"; |
| | | import FilesDia from "@/views/qualityManagement/finalInspection/components/filesDia.vue"; |
| | | import dayjs from "dayjs"; |
| | | import {userListNoPage} from "@/api/system/user.js"; |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | |
| | | entryDateStart: dayjs().format("YYYY-MM-DD"), |
| | | entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"), |
| | | }, |
| | | rules: { |
| | | checkName: [{required: true, message: "è¯·éæ©", trigger: "change"}], |
| | | }, |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | | const tableColumn = ref([ |
| | |
| | | } |
| | | }, |
| | | }, |
| | | { |
| | | label: "æäº¤ç¶æ", |
| | | prop: "inspectState", |
| | | formatData: (params) => { |
| | | if (params) { |
| | | return "å·²æäº¤"; |
| | | } else { |
| | | return "æªæäº¤"; |
| | | } |
| | | }, |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 190, |
| | | width: 280, |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "æ°å¢æ£éªè®°å½", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openInspectionForm("edit", row); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.inspectState == 1; |
| | | } |
| | | }, |
| | | { |
| | | name: "éä»¶", |
| | |
| | | openFilesFormDia(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "æäº¤", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | submit(row.id); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.inspectState == 1; |
| | | } |
| | | }, |
| | | { |
| | | name: "åé
æ£éªå", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | if (!row.checkName) { |
| | | open(row) |
| | | } else { |
| | | proxy.$modal.msgError("æ£éªåå·²åå¨"); |
| | | } |
| | | }, |
| | | disabled: (row) => { |
| | | return row.inspectState == 1 || row.checkName; |
| | | } |
| | | }, |
| | | { |
| | | name: "ä¸è½½", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | downLoadFile(row); |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | const currentRow = ref(null) |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | |
| | | const filesDia = ref() |
| | | const inspectionFormDia = ref() |
| | | const { proxy } = getCurrentInstance() |
| | | const userList = ref([]); |
| | | const form = ref({ |
| | | checkName: "" |
| | | }); |
| | | const dialogFormVisible = ref(false); |
| | | |
| | | const changeDaterange = (value) => { |
| | | searchForm.value.entryDateStart = undefined; |
| | |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // æä»· |
| | | const submit = async (id) => { |
| | | const res = await submitQualityInspect({id: id}) |
| | | if (res.code === 200) { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | getList(); |
| | | } |
| | | } |
| | | |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | | dialogFormVisible.value = false; |
| | | }; |
| | | |
| | | const submitForm = () => { |
| | | if (currentRow.value) { |
| | | const data = { |
| | | ...form.value, |
| | | id: currentRow.value.id |
| | | } |
| | | qualityInspectUpdate(data).then(res => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | getList(); |
| | | }) |
| | | } |
| | | }; |
| | | |
| | | const open = async (row) => { |
| | | let userLists = await userListNoPage(); |
| | | userList.value = userLists.data; |
| | | currentRow.value = row |
| | | dialogFormVisible.value = true |
| | | } |
| | | |
| | | const downLoadFile = (row) => { |
| | | downloadQualityInspect({ id: row.id }).then((blobData) => { |
| | | const blob = new Blob([blobData], { |
| | | type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', |
| | | }) |
| | | const downloadUrl = window.URL.createObjectURL(blob) |
| | | |
| | | const link = document.createElement('a') |
| | | link.href = downloadUrl |
| | | link.download = 'åæææ£éªæ¥å.docx' |
| | | document.body.appendChild(link) |
| | | link.click() |
| | | |
| | | document.body.removeChild(link) |
| | | window.URL.revokeObjectURL(downloadUrl) |
| | | }) |
| | | }; |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <filePreview ref="filePreviewRef" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref} from "vue"; |
| | | import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js"; |
| | | import {Search} from "@element-plus/icons-vue"; |
| | | import { |
| | | qualityInspectParamDel, |
| | | qualityInspectParamInfo, |
| | | qualityInspectParamUpdate |
| | | } from "@/api/qualityManagement/qualityInspectParam.js"; |
| | | import filePreview from '@/components/filePreview/index.vue' |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {getToken} from "@/utils/auth.js"; |
| | | import { |
| | |
| | | const dialogFormVisible = ref(false); |
| | | const currentId = ref('') |
| | | const selectedRows = ref([]); |
| | | const filePreviewRef = ref() |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "æä»¶åç§°", |
| | |
| | | clickFun: (row) => { |
| | | downLoadFile(row); |
| | | }, |
| | | } |
| | | }, |
| | | { |
| | | name: "é¢è§", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | lookFile(row); |
| | | }, |
| | | } |
| | | ], |
| | | }, |
| | | ]); |
| | |
| | | function handleUploadError() { |
| | | proxy.$modal.msgError("æä»¶ä¸ä¼ 失败"); |
| | | } |
| | | // é¢è§éä»¶ |
| | | const lookFile = (row) => { |
| | | filePreviewRef.value.open(row.url) |
| | | } |
| | | // å é¤ |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ£éªåï¼" prop="checkName"> |
| | | <el-input v-model="form.checkName" placeholder="请è¾å
¥" clearable/> |
| | | |
| | | <el-select v-model="form.checkName" placeholder="è¯·éæ©" clearable> |
| | | <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" |
| | | :value="item.nickName"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :tableLoading="tableLoading" |
| | | height="400" |
| | | > |
| | | <template #slot="{ row }"> |
| | | <el-input v-model="row.testValue" clearable/> |
| | | </template> |
| | | </PIMTable> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | |
| | | import {getOptions} from "@/api/procurementManagement/procurementLedger.js"; |
| | | import {productTreeList} from "@/api/basicData/product.js"; |
| | | import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js"; |
| | | import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js"; |
| | | import {userListNoPage} from "@/api/system/user.js"; |
| | | import {qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | |
| | |
| | | checkResult: [{ required: true, message: "请è¾å
¥", trigger: "change" }], |
| | | }, |
| | | }); |
| | | const userList = ref([]); |
| | | const { form, rules } = toRefs(data); |
| | | const supplierList = ref([]); |
| | | const productOptions = ref([]); |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "ææ ", |
| | | prop: "parameterItem", |
| | | }, |
| | | { |
| | | label: "åä½", |
| | | prop: "unit", |
| | | }, |
| | | { |
| | | label: "æ åå¼", |
| | | prop: "standardValue", |
| | | }, |
| | | { |
| | | label: "å
æ§å¼", |
| | | prop: "controlValue", |
| | | }, |
| | | { |
| | | label: "æ£éªå¼", |
| | | prop: "testValue", |
| | | dataType: 'slot', |
| | | slot: 'slot', |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | | const tableLoading = ref(false); |
| | | const currentProductId = ref(0); |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = (type, row) => { |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | getOptions().then((res) => { |
| | | supplierList.value = res.data; |
| | | }); |
| | | getProductOptions(); |
| | | if (operationType.value === 'edit') { |
| | | form.value = {...row} |
| | | } |
| | | const openDialog = async (type, row) => { |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | getOptions().then((res) => { |
| | | supplierList.value = res.data; |
| | | }); |
| | | let userLists = await userListNoPage(); |
| | | userList.value = userLists.data; |
| | | form.value = {} |
| | | getProductOptions(); |
| | | if (operationType.value === 'edit') { |
| | | form.value = {...row} |
| | | currentProductId.value = row.productId || 0 |
| | | getQualityInspectParamList(row.id) |
| | | } |
| | | } |
| | | const getProductOptions = () => { |
| | | productTreeList().then((res) => { |
| | |
| | | }); |
| | | }; |
| | | const getModels = (value) => { |
| | | currentProductId.value = value |
| | | form.value.productName = findNodeById(productOptions.value, value); |
| | | if (currentProductId) { |
| | | getList(); |
| | | } |
| | | }; |
| | | const findNodeById = (nodes, productId) => { |
| | | for (let i = 0; i < nodes.length; i++) { |
| | |
| | | proxy.$refs.formRef.validate(valid => { |
| | | if (valid) { |
| | | form.value.inspectType = 1 |
| | | if (operationType.value === "add") { |
| | | tableData.value.forEach((item) => { |
| | | delete item.id |
| | | }) |
| | | } |
| | | const data = {...form.value, qualityInspectParams: tableData.value} |
| | | if (operationType.value === "add") { |
| | | qualityInspectAdd(form.value).then(res => { |
| | | qualityInspectAdd(data).then(res => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | }) |
| | | } else { |
| | | qualityInspectUpdate(form.value).then(res => { |
| | | qualityInspectUpdate(data).then(res => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | }) |
| | |
| | | } |
| | | }) |
| | | } |
| | | const getList = () => { |
| | | qualityInspectDetailByProductId(currentProductId.value).then(res => { |
| | | tableData.value = res.data; |
| | | }) |
| | | } |
| | | const getQualityInspectParamList = (id) => { |
| | | qualityInspectParamInfo(id).then(res => { |
| | | tableData.value = res.data; |
| | | }) |
| | | } |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | |
| | | <InspectionFormDia ref="inspectionFormDia" @close="handleQuery"></InspectionFormDia> |
| | | <FormDia ref="formDia" @close="handleQuery"></FormDia> |
| | | <files-dia ref="filesDia" @close="handleQuery"></files-dia> |
| | | <el-dialog v-model="dialogFormVisible" title="ç¼è¾æ£éªå" width="30%" |
| | | @close="closeDia"> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <el-form-item label="æ£éªåï¼" prop="checkName"> |
| | | <el-select v-model="form.checkName" placeholder="è¯·éæ©" clearable> |
| | | <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" |
| | | :value="item.nickName"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import InspectionFormDia from "@/views/qualityManagement/processInspection/components/inspectionFormDia.vue"; |
| | | import FormDia from "@/views/qualityManagement/processInspection/components/formDia.vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {qualityInspectDel, qualityInspectListPage} from "@/api/qualityManagement/rawMaterialInspection.js"; |
| | | import { |
| | | downloadQualityInspect, |
| | | qualityInspectDel, |
| | | qualityInspectListPage, qualityInspectUpdate, |
| | | submitQualityInspect |
| | | } from "@/api/qualityManagement/rawMaterialInspection.js"; |
| | | import FilesDia from "@/views/qualityManagement/processInspection/components/filesDia.vue"; |
| | | import dayjs from "dayjs"; |
| | | import {userListNoPage} from "@/api/system/user.js"; |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | |
| | | entryDateStart: dayjs().format("YYYY-MM-DD"), |
| | | entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"), |
| | | }, |
| | | rules: { |
| | | checkName: [{required: true, message: "è¯·éæ©", trigger: "change"}], |
| | | }, |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | | const tableColumn = ref([ |
| | |
| | | } |
| | | }, |
| | | }, |
| | | { |
| | | label: "æäº¤ç¶æ", |
| | | prop: "inspectState", |
| | | formatData: (params) => { |
| | | if (params) { |
| | | return "å·²æäº¤"; |
| | | } else { |
| | | return "æªæäº¤"; |
| | | } |
| | | }, |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 190, |
| | | width: 280, |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "æ°å¢æ£éªè®°å½", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openInspectionForm("edit", row); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.inspectState == 1; |
| | | } |
| | | }, |
| | | { |
| | | name: "éä»¶", |
| | |
| | | openFilesFormDia(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "æäº¤", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | submit(row.id); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.inspectState == 1; |
| | | } |
| | | }, |
| | | { |
| | | name: "åé
æ£éªå", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | if (!row.checkName) { |
| | | open(row) |
| | | } else { |
| | | proxy.$modal.msgError("æ£éªåå·²åå¨"); |
| | | } |
| | | }, |
| | | disabled: (row) => { |
| | | return row.inspectState == 1 || row.checkName; |
| | | } |
| | | }, |
| | | { |
| | | name: "ä¸è½½", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | downLoadFile(row); |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | ]); |
| | | const userList = ref([]); |
| | | const currentRow = ref(null) |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | const dialogFormVisible = ref(false); |
| | | const form = ref({ |
| | | checkName: "" |
| | | }); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | |
| | | filesDia.value?.openDialog(type, row) |
| | | }) |
| | | }; |
| | | // æä»· |
| | | const submit = async (id) => { |
| | | const res = await submitQualityInspect({id: id}) |
| | | if (res.code === 200) { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | getList(); |
| | | } |
| | | } |
| | | const open = async (row) => { |
| | | let userLists = await userListNoPage(); |
| | | userList.value = userLists.data; |
| | | currentRow.value = row |
| | | dialogFormVisible.value = true |
| | | } |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | | dialogFormVisible.value = false; |
| | | }; |
| | | const submitForm = () => { |
| | | if (currentRow.value) { |
| | | const data = { |
| | | ...form.value, |
| | | id: currentRow.value.id |
| | | } |
| | | qualityInspectUpdate(data).then(res => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | getList(); |
| | | }) |
| | | } |
| | | }; |
| | | |
| | | // å é¤ |
| | | const handleDelete = () => { |
| | |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | const downLoadFile = (row) => { |
| | | downloadQualityInspect({ id: row.id }).then((blobData) => { |
| | | const blob = new Blob([blobData], { |
| | | type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', |
| | | }) |
| | | const downloadUrl = window.URL.createObjectURL(blob) |
| | | |
| | | const link = document.createElement('a') |
| | | link.href = downloadUrl |
| | | link.download = 'è¿ç¨æ£éªæ¥å.docx' |
| | | document.body.appendChild(link) |
| | | link.click() |
| | | |
| | | document.body.removeChild(link) |
| | | window.URL.revokeObjectURL(downloadUrl) |
| | | }) |
| | | }; |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <filePreview ref="filePreviewRef" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref} from "vue"; |
| | | import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js"; |
| | | import {Search} from "@element-plus/icons-vue"; |
| | | import { |
| | | qualityInspectParamDel, |
| | | qualityInspectParamInfo, |
| | | qualityInspectParamUpdate |
| | | } from "@/api/qualityManagement/qualityInspectParam.js"; |
| | | import filePreview from '@/components/filePreview/index.vue' |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {getToken} from "@/utils/auth.js"; |
| | | import { |
| | |
| | | clickFun: (row) => { |
| | | downLoadFile(row); |
| | | }, |
| | | } |
| | | }, |
| | | { |
| | | name: "é¢è§", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | lookFile(row); |
| | | }, |
| | | } |
| | | ], |
| | | }, |
| | | ]); |
| | |
| | | const tableData = ref([]); |
| | | const fileList = ref([]); |
| | | const tableLoading = ref(false); |
| | | const filePreviewRef = ref() |
| | | const headers = ref({ |
| | | Authorization: "Bearer " + getToken(), |
| | | }); |
| | |
| | | const downLoadFile = (row) => { |
| | | proxy.$download.name(row.url); |
| | | } |
| | | // é¢è§éä»¶ |
| | | const lookFile = (row) => { |
| | | filePreviewRef.value.open(row.url) |
| | | } |
| | | // å é¤ |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div style="margin-bottom: 10px;text-align: right"> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | <!-- <div style="margin-bottom: 10px;text-align: right">--> |
| | | <!-- <el-button type="danger" plain @click="handleDelete">å é¤</el-button>--> |
| | | <!-- </div>--> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :tableLoading="tableLoading" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | height="400" |
| | | > |
| | | <template #slot="{ row }"> |
| | |
| | | getOptions().then((res) => { |
| | | supplierList.value = res.data; |
| | | }); |
| | | form.value = {} |
| | | getProductOptions(); |
| | | if (operationType.value === 'edit') { |
| | | form.value = {...row} |
| | |
| | | proxy.$refs.formRef.validate(valid => { |
| | | if (valid) { |
| | | form.value.inspectType = 0 |
| | | if (operationType.value === "add") { |
| | | tableData.value.forEach((item) => { |
| | | delete item.id |
| | | }) |
| | | } |
| | | const data = {...form.value, qualityInspectParams: tableData.value} |
| | | if (operationType.value === "add") { |
| | | qualityInspectAdd(data).then(res => { |
| | |
| | | } |
| | | }) |
| | | } |
| | | |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | | return; |
| | | } |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | qualityInspectParamDel(ids).then((res) => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getList(); |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | const getList = () => { |
| | | qualityInspectDetailByProductId(currentProductId.value).then(res => { |
| | |
| | | <InspectionFormDia ref="inspectionFormDia" @close="handleQuery"></InspectionFormDia> |
| | | <FormDia ref="formDia" @close="handleQuery"></FormDia> |
| | | <files-dia ref="filesDia" @close="handleQuery"></files-dia> |
| | | <el-dialog v-model="dialogFormVisible" title="ç¼è¾æ£éªå" width="70%" |
| | | <el-dialog v-model="dialogFormVisible" title="ç¼è¾æ£éªå" width="30%" |
| | | @close="closeDia"> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <el-form-item label="æ£éªåï¼" prop="checkName"> |
| | |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 250, |
| | | width: 280, |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.inspectState; |
| | | } |
| | | disabled: (row) => { |
| | | return row.inspectState == 1; |
| | | } |
| | | }, |
| | | { |
| | | name: "éä»¶", |
| | |
| | | clickFun: (row) => { |
| | | submit(row.id); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.inspectState == 1; |
| | | } |
| | | }, |
| | | { |
| | | name: "åé
æ£éªå", |
| | |
| | | proxy.$modal.msgError("æ£éªåå·²åå¨"); |
| | | } |
| | | }, |
| | | disabled: (row) => { |
| | | return row.inspectState; |
| | | } |
| | | disabled: (row) => { |
| | | return row.inspectState == 1 || row.checkName; |
| | | } |
| | | }, |
| | | { |
| | | name: "ä¸è½½", |
| | |
| | | const openForm = (type, row) => { |
| | | nextTick(() => { |
| | | formDia.value?.openDialog(type, row) |
| | | }) |
| | | }; |
| | | // æå¼æ°å¢æ£éªå¼¹æ¡ |
| | | const openInspectionForm = (type, row) => { |
| | | nextTick(() => { |
| | | inspectionFormDia.value?.openDialog(type, row) |
| | | }) |
| | | }; |
| | | // æå¼éä»¶å¼¹æ¡ |
| | |
| | | |
| | | const link = document.createElement('a') |
| | | link.href = downloadUrl |
| | | link.download = 'æ£éªæ¥å.docx' |
| | | link.download = 'åæææ£éªæ¥å.docx' |
| | | document.body.appendChild(link) |
| | | link.click() |
| | | |