已复制1个文件
已添加310个文件
已重命名12个文件
已修改148个文件
已删除13个文件
| | |
| | | # 页颿 é¢
|
| | | VITE_APP_TITLE = è¯å¯¼äºï¼ç®¡çä¿¡æ¯ç³»ç»ï¼
|
| | | VITE_APP_TITLE = ä¸å°ä¼ä¸æ°åå转åäºçº§å¥é¤å
|
| | |
|
| | | # å¼åç¯å¢é
ç½®
|
| | | VITE_APP_ENV = 'development'
|
| | |
|
| | | # è¯å¯¼äºï¼ç®¡çä¿¡æ¯ç³»ç»ï¼/å¼åç¯å¢
|
| | | # ä¸å°ä¼ä¸æ°åå转åäºçº§å¥é¤å
/å¼åç¯å¢
|
| | | VITE_APP_BASE_API = '/dev-api'
|
| | |
| | | # 页颿 é¢
|
| | | VITE_APP_TITLE =è¯å¯¼-ä»å¨ç©æµç³»ç»
|
| | | #10.136.58.65 è¯å¯¼-è´¢å¡ç®¡çç³»ç» cwglxt
|
| | | #10.136.58.66 è¯å¯¼-设å¤ç®¡çç³»ç» sbglxt
|
| | | #10.136.58.67 è¯å¯¼-ç产管æ§ç³»ç» scgkxt
|
| | | #10.136.58.68 è¯å¯¼-åååå
¬ç³»ç» xtbgxt
|
| | | #10.136.58.69 è¯å¯¼-éè´ç®¡çç³»ç» cgglxt
|
| | | #10.136.58.70 è¯å¯¼-ä»å¨ç©æµç³»ç» ccwlxt
|
| | | #10.136.58.71 è¯å¯¼-è¥é管çç³»ç» yxglxt
|
| | | #10.136.58.72 è¯å¯¼-人åèµæºç³»ç» rlzyxt
|
| | | VITE_APP_TITLE = MIS管çç³»ç»
|
| | |
|
| | | # ç产ç¯å¢é
ç½®
|
| | | VITE_APP_ENV = 'production'
|
| | |
| | | # 页颿 é¢
|
| | | VITE_APP_TITLE = è¯å¯¼äºï¼ç®¡çä¿¡æ¯ç³»ç»ï¼
|
| | | VITE_APP_TITLE = ä¸å°ä¼ä¸æ°åå转åäºçº§å¥é¤å
|
| | |
|
| | | # ç产ç¯å¢é
ç½®
|
| | | VITE_APP_ENV = 'staging'
|
| | |
|
| | | # è¯å¯¼äºï¼ç®¡çä¿¡æ¯ç³»ç»ï¼/ç产ç¯å¢
|
| | | # ä¸å°ä¼ä¸æ°åå转åäºçº§å¥é¤å
/ç产ç¯å¢
|
| | | VITE_APP_BASE_API = '/stage-api'
|
| | |
|
| | | # æ¯å¦å¨æå
æ¶å¼å¯åç¼©ï¼æ¯æ gzip å brotli
|
| | | VITE_BUILD_COMPRESS = gzip |
| | | VITE_BUILD_COMPRESS = gzip
|
| | |
| | |
|
| | | # æå»ºæµè¯ç¯å¢ yarn build:stage
|
| | | # æå»ºç产ç¯å¢ yarn build:prod
|
| | | # æå»ºç产ç¯å¢ yarn build:prod -- --company="AAA"
|
| | | # å端访é®å°å http://localhost:80
|
| | | ```
|
| | |
|
| | |
| | | <!DOCTYPE html>
|
| | | <html>
|
| | |
|
| | | <head>
|
| | | <meta charset="utf-8">
|
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
| | | <meta name="renderer" content="webkit">
|
| | | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
| | | <link rel="icon" href="/favicon.ico">
|
| | | <title>%VITE_APP_TITLE%</title>
|
| | | <!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
|
| | | <style>
|
| | | html,
|
| | | body,
|
| | | #app {
|
| | | height: 100%;
|
| | | margin: 0px;
|
| | | padding: 0px;
|
| | | }
|
| | |
|
| | | .chromeframe {
|
| | | margin: 0.2em 0;
|
| | | background: #ccc;
|
| | | color: #000;
|
| | | padding: 0.2em 0;
|
| | | }
|
| | |
|
| | | #loader-wrapper {
|
| | | position: fixed;
|
| | | top: 0;
|
| | | left: 0;
|
| | | width: 100%;
|
| | | height: 100%;
|
| | | z-index: 999999;
|
| | | }
|
| | |
|
| | | #loader {
|
| | | display: block;
|
| | | position: relative;
|
| | | left: 50%;
|
| | | top: 50%;
|
| | | width: 150px;
|
| | | height: 150px;
|
| | | margin: -75px 0 0 -75px;
|
| | | border-radius: 50%;
|
| | | border: 3px solid transparent;
|
| | | border-top-color: #FFF;
|
| | | -webkit-animation: spin 2s linear infinite;
|
| | | -ms-animation: spin 2s linear infinite;
|
| | | -moz-animation: spin 2s linear infinite;
|
| | | -o-animation: spin 2s linear infinite;
|
| | | animation: spin 2s linear infinite;
|
| | | z-index: 1001;
|
| | | }
|
| | |
|
| | | #loader:before {
|
| | | content: "";
|
| | | position: absolute;
|
| | | top: 5px;
|
| | | left: 5px;
|
| | | right: 5px;
|
| | | bottom: 5px;
|
| | | border-radius: 50%;
|
| | | border: 3px solid transparent;
|
| | | border-top-color: #FFF;
|
| | | -webkit-animation: spin 3s linear infinite;
|
| | | -moz-animation: spin 3s linear infinite;
|
| | | -o-animation: spin 3s linear infinite;
|
| | | -ms-animation: spin 3s linear infinite;
|
| | | animation: spin 3s linear infinite;
|
| | | }
|
| | |
|
| | | #loader:after {
|
| | | content: "";
|
| | | position: absolute;
|
| | | top: 15px;
|
| | | left: 15px;
|
| | | right: 15px;
|
| | | bottom: 15px;
|
| | | border-radius: 50%;
|
| | | border: 3px solid transparent;
|
| | | border-top-color: #FFF;
|
| | | -moz-animation: spin 1.5s linear infinite;
|
| | | -o-animation: spin 1.5s linear infinite;
|
| | | -ms-animation: spin 1.5s linear infinite;
|
| | | -webkit-animation: spin 1.5s linear infinite;
|
| | | animation: spin 1.5s linear infinite;
|
| | | }
|
| | |
|
| | |
|
| | | @-webkit-keyframes spin {
|
| | | 0% {
|
| | | -webkit-transform: rotate(0deg);
|
| | | -ms-transform: rotate(0deg);
|
| | | transform: rotate(0deg);
|
| | | <head>
|
| | | <meta charset="utf-8" />
|
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
| | | <meta name="renderer" content="webkit" />
|
| | | <meta
|
| | | name="viewport"
|
| | | content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
|
| | | />
|
| | | <link rel="icon" href="/favicon.ico" />
|
| | | <title>%VITE_APP_TITLE%</title>
|
| | | <!--[if lt IE 11
|
| | | ]><script>
|
| | | window.location.href = "/html/ie.html";
|
| | | </script><!
|
| | | [endif]-->
|
| | | <style>
|
| | | html,
|
| | | body,
|
| | | #app {
|
| | | height: 100%;
|
| | | margin: 0px;
|
| | | padding: 0px;
|
| | | }
|
| | |
|
| | | 100% {
|
| | | -webkit-transform: rotate(360deg);
|
| | | -ms-transform: rotate(360deg);
|
| | | transform: rotate(360deg);
|
| | | }
|
| | | }
|
| | |
|
| | | @keyframes spin {
|
| | | 0% {
|
| | | -webkit-transform: rotate(0deg);
|
| | | -ms-transform: rotate(0deg);
|
| | | transform: rotate(0deg);
|
| | | .chromeframe {
|
| | | margin: 0.2em 0;
|
| | | background: #ccc;
|
| | | color: #000;
|
| | | padding: 0.2em 0;
|
| | | }
|
| | |
|
| | | 100% {
|
| | | -webkit-transform: rotate(360deg);
|
| | | -ms-transform: rotate(360deg);
|
| | | transform: rotate(360deg);
|
| | | #loader-wrapper {
|
| | | position: fixed;
|
| | | top: 0;
|
| | | left: 0;
|
| | | width: 100%;
|
| | | height: 100%;
|
| | | z-index: 999999;
|
| | | }
|
| | | }
|
| | |
|
| | | #loader {
|
| | | display: block;
|
| | | position: relative;
|
| | | left: 50%;
|
| | | top: 50%;
|
| | | width: 150px;
|
| | | height: 150px;
|
| | | margin: -75px 0 0 -75px;
|
| | | border-radius: 50%;
|
| | | border: 3px solid transparent;
|
| | | border-top-color: #fff;
|
| | | -webkit-animation: spin 2s linear infinite;
|
| | | -ms-animation: spin 2s linear infinite;
|
| | | -moz-animation: spin 2s linear infinite;
|
| | | -o-animation: spin 2s linear infinite;
|
| | | animation: spin 2s linear infinite;
|
| | | z-index: 1001;
|
| | | }
|
| | |
|
| | | #loader-wrapper .loader-section {
|
| | | position: fixed;
|
| | | top: 0;
|
| | | width: 51%;
|
| | | height: 100%;
|
| | | background: #7171C6;
|
| | | z-index: 1000;
|
| | | -webkit-transform: translateX(0);
|
| | | -ms-transform: translateX(0);
|
| | | transform: translateX(0);
|
| | | }
|
| | | #loader:before {
|
| | | content: "";
|
| | | position: absolute;
|
| | | top: 5px;
|
| | | left: 5px;
|
| | | right: 5px;
|
| | | bottom: 5px;
|
| | | border-radius: 50%;
|
| | | border: 3px solid transparent;
|
| | | border-top-color: #fff;
|
| | | -webkit-animation: spin 3s linear infinite;
|
| | | -moz-animation: spin 3s linear infinite;
|
| | | -o-animation: spin 3s linear infinite;
|
| | | -ms-animation: spin 3s linear infinite;
|
| | | animation: spin 3s linear infinite;
|
| | | }
|
| | |
|
| | | #loader-wrapper .loader-section.section-left {
|
| | | left: 0;
|
| | | }
|
| | | #loader:after {
|
| | | content: "";
|
| | | position: absolute;
|
| | | top: 15px;
|
| | | left: 15px;
|
| | | right: 15px;
|
| | | bottom: 15px;
|
| | | border-radius: 50%;
|
| | | border: 3px solid transparent;
|
| | | border-top-color: #fff;
|
| | | -moz-animation: spin 1.5s linear infinite;
|
| | | -o-animation: spin 1.5s linear infinite;
|
| | | -ms-animation: spin 1.5s linear infinite;
|
| | | -webkit-animation: spin 1.5s linear infinite;
|
| | | animation: spin 1.5s linear infinite;
|
| | | }
|
| | |
|
| | | #loader-wrapper .loader-section.section-right {
|
| | | right: 0;
|
| | | }
|
| | | @-webkit-keyframes spin {
|
| | | 0% {
|
| | | -webkit-transform: rotate(0deg);
|
| | | -ms-transform: rotate(0deg);
|
| | | transform: rotate(0deg);
|
| | | }
|
| | |
|
| | | 100% {
|
| | | -webkit-transform: rotate(360deg);
|
| | | -ms-transform: rotate(360deg);
|
| | | transform: rotate(360deg);
|
| | | }
|
| | | }
|
| | |
|
| | | .loaded #loader-wrapper .loader-section.section-left {
|
| | | -webkit-transform: translateX(-100%);
|
| | | -ms-transform: translateX(-100%);
|
| | | transform: translateX(-100%);
|
| | | -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
|
| | | transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
|
| | | }
|
| | | @keyframes spin {
|
| | | 0% {
|
| | | -webkit-transform: rotate(0deg);
|
| | | -ms-transform: rotate(0deg);
|
| | | transform: rotate(0deg);
|
| | | }
|
| | |
|
| | | .loaded #loader-wrapper .loader-section.section-right {
|
| | | -webkit-transform: translateX(100%);
|
| | | -ms-transform: translateX(100%);
|
| | | transform: translateX(100%);
|
| | | -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
|
| | | transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
|
| | | }
|
| | | 100% {
|
| | | -webkit-transform: rotate(360deg);
|
| | | -ms-transform: rotate(360deg);
|
| | | transform: rotate(360deg);
|
| | | }
|
| | | }
|
| | |
|
| | | .loaded #loader {
|
| | | opacity: 0;
|
| | | -webkit-transition: all 0.3s ease-out;
|
| | | transition: all 0.3s ease-out;
|
| | | }
|
| | | #loader-wrapper .loader-section {
|
| | | position: fixed;
|
| | | top: 0;
|
| | | width: 51%;
|
| | | height: 100%;
|
| | | background: #7171c6;
|
| | | z-index: 1000;
|
| | | -webkit-transform: translateX(0);
|
| | | -ms-transform: translateX(0);
|
| | | transform: translateX(0);
|
| | | }
|
| | |
|
| | | .loaded #loader-wrapper {
|
| | | visibility: hidden;
|
| | | -webkit-transform: translateY(-100%);
|
| | | -ms-transform: translateY(-100%);
|
| | | transform: translateY(-100%);
|
| | | -webkit-transition: all 0.3s 1s ease-out;
|
| | | transition: all 0.3s 1s ease-out;
|
| | | }
|
| | | #loader-wrapper .loader-section.section-left {
|
| | | left: 0;
|
| | | }
|
| | |
|
| | | .no-js #loader-wrapper {
|
| | | display: none;
|
| | | }
|
| | | #loader-wrapper .loader-section.section-right {
|
| | | right: 0;
|
| | | }
|
| | |
|
| | | .no-js h1 {
|
| | | color: #222222;
|
| | | }
|
| | | .loaded #loader-wrapper .loader-section.section-left {
|
| | | -webkit-transform: translateX(-100%);
|
| | | -ms-transform: translateX(-100%);
|
| | | transform: translateX(-100%);
|
| | | -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
| | | transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
| | | }
|
| | |
|
| | | #loader-wrapper .load_title {
|
| | | font-family: 'Open Sans';
|
| | | color: #FFF;
|
| | | font-size: 19px;
|
| | | width: 100%;
|
| | | text-align: center;
|
| | | z-index: 9999999999999;
|
| | | position: absolute;
|
| | | top: 60%;
|
| | | opacity: 1;
|
| | | line-height: 30px;
|
| | | }
|
| | | .loaded #loader-wrapper .loader-section.section-right {
|
| | | -webkit-transform: translateX(100%);
|
| | | -ms-transform: translateX(100%);
|
| | | transform: translateX(100%);
|
| | | -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
| | | transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
| | | }
|
| | |
|
| | | #loader-wrapper .load_title span {
|
| | | font-weight: normal;
|
| | | font-style: italic;
|
| | | font-size: 13px;
|
| | | color: #FFF;
|
| | | opacity: 0.5;
|
| | | }
|
| | | </style>
|
| | | </head>
|
| | | .loaded #loader {
|
| | | opacity: 0;
|
| | | -webkit-transition: all 0.3s ease-out;
|
| | | transition: all 0.3s ease-out;
|
| | | }
|
| | |
|
| | | <body>
|
| | | <div id="app">
|
| | | <div id="loader-wrapper">
|
| | | <div id="loader"></div>
|
| | | <div class="loader-section section-left"></div>
|
| | | <div class="loader-section section-right"></div>
|
| | | <div class="load_title">æ£å¨å 载系ç»èµæºï¼è¯·èå¿çå¾
</div>
|
| | | .loaded #loader-wrapper {
|
| | | visibility: hidden;
|
| | | -webkit-transform: translateY(-100%);
|
| | | -ms-transform: translateY(-100%);
|
| | | transform: translateY(-100%);
|
| | | -webkit-transition: all 0.3s 1s ease-out;
|
| | | transition: all 0.3s 1s ease-out;
|
| | | }
|
| | |
|
| | | .no-js #loader-wrapper {
|
| | | display: none;
|
| | | }
|
| | |
|
| | | .no-js h1 {
|
| | | color: #222222;
|
| | | }
|
| | |
|
| | | #loader-wrapper .load_title {
|
| | | font-family: "Open Sans";
|
| | | color: #fff;
|
| | | font-size: 19px;
|
| | | width: 100%;
|
| | | text-align: center;
|
| | | z-index: 9999999999999;
|
| | | position: absolute;
|
| | | top: 60%;
|
| | | opacity: 1;
|
| | | line-height: 30px;
|
| | | }
|
| | |
|
| | | #loader-wrapper .load_title span {
|
| | | font-weight: normal;
|
| | | font-style: italic;
|
| | | font-size: 13px;
|
| | | color: #fff;
|
| | | opacity: 0.5;
|
| | | }
|
| | | </style>
|
| | | </head>
|
| | |
|
| | | <body>
|
| | | <div id="app">
|
| | | <div id="loader-wrapper">
|
| | | <div id="loader"></div>
|
| | | <div class="loader-section section-left"></div>
|
| | | <div class="loader-section section-right"></div>
|
| | | <div class="load_title">æ£å¨å 载系ç»èµæºï¼è¯·èå¿çå¾
</div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | <script type="module" src="/src/main.js"></script>
|
| | | </body>
|
| | |
|
| | | <script type="module" src="/src/main.js"></script>
|
| | | </body>
|
| | | </html>
|
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "default": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "è¯å¯¼äºï¼ç®¡çä¿¡æ¯ç³»ç»ï¼" |
| | | }, |
| | | "screen": "screen/JZYJView.png", |
| | | "logo": "logo/HYSNLogo.png", |
| | | "favicon": "favicon/HYSNico.ico" |
| | | }, |
| | | "TEST": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "ä¸å°ä¼ä¸æ°åå转åäºçº§å¥é¤å
", |
| | | "VITE_BASE_API": "http://1.15.17.182:9003", |
| | | "VITE_JAVA_API": "http://1.15.17.182:9002" |
| | | }, |
| | | "screen": "screen/HYSNView.png", |
| | | "logo": "logo/ZGLTLogo.png", |
| | | "favicon": "favicon/favicon.ico" |
| | | }, |
| | | "screen": "/src/assets/images/login-background.png", |
| | | "logo": "/src/assets/logo/logo.png", |
| | | "favicon": "/public/favicon.ico" |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import fs from 'fs/promises'; |
| | | import fsSync from 'fs'; |
| | | import path from 'path'; |
| | | import { fileURLToPath } from 'url'; |
| | | import { execSync } from "child_process"; |
| | | |
| | | // è·å __dirname |
| | | const __filename = fileURLToPath(import.meta.url); |
| | | const __dirname = path.dirname(__filename); |
| | | |
| | | // 读å JSON é
ç½® |
| | | const data = await fs.readFile(path.join(__dirname, 'config.json'), 'utf-8'); |
| | | const config = JSON.parse(data); |
| | | |
| | | // 项ç®è·¯å¾ |
| | | const rootPath = path.resolve(__dirname, '..'); |
| | | const resourcePath = path.join(rootPath, 'multiple', 'assets'); |
| | | const replacePath = path.join(rootPath, 'replace'); |
| | | |
| | | // è·åå½ä»¤è¡åæ° |
| | | const params = parseArgs(process.argv); |
| | | const company = params["company"] ?? "default"; |
| | | const companyMap = config[company]; |
| | | |
| | | const envFilePath = path.join(process.cwd(), '.env.production.local'); |
| | | |
| | | try { |
| | | // 1ï¸â£ çæ .env |
| | | console.log("=======çæ.env======="); |
| | | const envContent = Object.entries(companyMap.env) |
| | | .map(([key, value]) => `${key}='${value}'`) |
| | | .join('\n') + '\n'; |
| | | await fs.writeFile(envFilePath, envContent, 'utf-8'); |
| | | |
| | | // 2ï¸â£ å¤ä»½åå§èµæºå¹¶æ¿æ¢ |
| | | console.log("=======ä¿®æ¹èµæº======="); |
| | | for (const [key, value] of Object.entries(companyMap)) { |
| | | if (key === 'env') continue; |
| | | |
| | | const originFile = path.join(rootPath, config[key]); |
| | | const backupFile = path.join(replacePath, config[key]); |
| | | const replaceFile = path.join(resourcePath, companyMap[key]); |
| | | |
| | | await fs.mkdir(path.dirname(backupFile), { recursive: true }); |
| | | await fs.copyFile(originFile, backupFile); |
| | | await fs.copyFile(replaceFile, originFile); |
| | | } |
| | | |
| | | console.log("=====å¼å§æå
======"); |
| | | execSync("vite build", { stdio: "inherit" }); |
| | | console.log("=====æå
宿======"); |
| | | } finally { |
| | | console.log("=====æ¢å¤èµæº======"); |
| | | |
| | | // å é¤ä¸´æ¶ .env æä»¶ |
| | | if (fsSync.existsSync(envFilePath)) { |
| | | await fs.unlink(envFilePath); |
| | | console.log(`ðï¸ å·²å é¤ ${envFilePath}`); |
| | | } |
| | | |
| | | // æ¢å¤èµæºæä»¶ |
| | | if (fsSync.existsSync(replacePath)) { |
| | | for (const [key, value] of Object.entries(companyMap)) { |
| | | if (key === 'env') continue; |
| | | |
| | | const originFile = path.join(rootPath, config[key]); |
| | | const backupFile = path.join(replacePath, config[key]); |
| | | |
| | | await fs.copyFile(backupFile, originFile); |
| | | } |
| | | await fs.rm(replacePath, { recursive: true, force: true }); |
| | | console.log(`ðï¸ å·²å é¤ ${replacePath}`); |
| | | } |
| | | } |
| | | |
| | | // ç®åå½ä»¤è¡åæ°è§£æ |
| | | function parseArgs(argv) { |
| | | const params = {}; |
| | | for (const arg of argv.slice(2)) { |
| | | if (arg.startsWith('--')) { |
| | | const [key, value] = arg.slice(2).split('='); |
| | | params[key] = value ?? true; |
| | | } |
| | | } |
| | | return params; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request.js"; |
| | | |
| | | export function findAllStockRecordTypeOptions() { |
| | | return request({ |
| | | url: '/basic/enum/stockRecordType', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | |
| | | export function findAllQualifiedStockRecordTypeOptions() { |
| | | return request({ |
| | | url: '/basic/enum/StockQualifiedRecordTypeEnum', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | export function findAllUnqualifiedStockRecordTypeOptions() { |
| | | return request({ |
| | | url: '/basic/enum/StockUnQualifiedRecordTypeEnum', |
| | | method: 'get' |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request.js"; |
| | | |
| | | export function productModelList(query) { |
| | | return request({ |
| | | url: '/basic/product/pageModel', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // å·¥åºå表å页æ¥è¯¢ |
| | | export function productProcessListPage(query) { |
| | | return request({ |
| | | url: '/productProcess/listPage', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | |
| | | data: ids |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢éä»¶å表 |
| | | export function fileListPage(query) { |
| | | return request({ |
| | | url: "/basic/supplierManageFile/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | // ä¿åéä»¶å表 |
| | | export function fileAdd(query) { |
| | | return request({ |
| | | url: "/basic/supplierManageFile/add", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | // å é¤éä»¶å表 |
| | | export function fileDel(query) { |
| | | return request({ |
| | | url: "/basic/supplierManageFile/del", |
| | | method: "delete", |
| | | data: query, |
| | | }); |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢åæè®¾ç½®å表 |
| | | export function listHolidaySettings(query) { |
| | | return request({ |
| | | url: "/holidaySettings/getList", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/getList", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | //æ¥è¯¢å¹´åè§åå表 |
| | | export function listAnnualLeaveSettingList(query) { |
| | | return request({ |
| | | url: "/holidaySettings/getAnnualLeaveSettingList", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/getAnnualLeaveSettingList", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | //æ¥è¯¢å çè§åå表 |
| | | export function listOvertimeSettingList(query) { |
| | | return request({ |
| | | url: "/holidaySettings/getOvertimeSettingList", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/getOvertimeSettingList", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | //æ¥è¯¢å·¥ä½æ¶é´è§åå表 |
| | | export function listWorkingHoursSettingList(query) { |
| | | return request({ |
| | | url: "/holidaySettings/getWorkingHoursSettingList", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/getWorkingHoursSettingList", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢åæè®¾ç½® |
| | | export function addHolidaySettings(data) { |
| | | return request({ |
| | | url: "/holidaySettings/add", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/add", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | //æ°å¢å¹´åè§å |
| | | export function addAnnualLeaveSetting(data) { |
| | | return request({ |
| | | url: "/holidaySettings/addAnnualLeaveSetting", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/addAnnualLeaveSetting", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | //æ°å¢å çè§å |
| | | export function addOvertimeSetting(data) { |
| | | return request({ |
| | | url: "/holidaySettings/addOvertimeSetting", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/addOvertimeSetting", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | //æ°å¢å·¥ä½æ¶é´è§å |
| | | export function addWorkingHoursSetting(data) { |
| | | return request({ |
| | | url: "/holidaySettings/addWorkingHoursSetting", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/addWorkingHoursSetting", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | |
| | | // ä¿®æ¹åæè®¾ç½® |
| | | export function updateHolidaySettings(data) { |
| | | return request({ |
| | | url: "/holidaySettings/update", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/update", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | // ä¿®æ¹å¹´åè§å |
| | | export function updateAnnualLeaveSetting(data) { |
| | | return request({ |
| | | url: "/holidaySettings/updateAnnualLeaveSetting", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/updateAnnualLeaveSetting", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | // ä¿®æ¹å çè§å |
| | | export function updateOvertimeSetting(data) { |
| | | return request({ |
| | | url: "/holidaySettings/updateOvertimeSetting", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/updateOvertimeSetting", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | // ä¿®æ¹å·¥ä½æ¶é´è§å |
| | | export function updateWorkingHoursSetting(data) { |
| | | return request({ |
| | | url: "/holidaySettings/updateWorkingHoursSetting", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/updateWorkingHoursSetting", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // æ¹éå é¤åæè®¾ç½® |
| | | export function delHolidaySettings(query) { |
| | | return request({ |
| | | url: "/holidaySettings/delete", |
| | | method: "delete", |
| | | data: query, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/delete", |
| | | method: "delete", |
| | | data: query, |
| | | }); |
| | | } |
| | | // æ¹éå é¤å¹´åè§å |
| | | export function delAnnualLeaveSetting(query) { |
| | | return request({ |
| | | url: "/holidaySettings/deleteAnnualLeaveSetting", |
| | | method: "delete", |
| | | data: query, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/deleteAnnualLeaveSetting", |
| | | method: "delete", |
| | | data: query, |
| | | }); |
| | | } |
| | | // æ¹éå é¤å çè§å |
| | | export function delOvertimeSetting(query) { |
| | | return request({ |
| | | url: "/holidaySettings/deleteOvertimeSetting", |
| | | method: "delete", |
| | | data: query, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/deleteOvertimeSetting", |
| | | method: "delete", |
| | | data: query, |
| | | }); |
| | | } |
| | | // æ¹éå é¤å·¥ä½æ¶é´è§å |
| | | export function delWorkingHoursSetting(query) { |
| | | return request({ |
| | | url: "/holidaySettings/deleteWorkingHoursSetting", |
| | | method: "delete", |
| | | data: query, |
| | | }); |
| | | return request({ |
| | | url: "/holidaySettings/deleteWorkingHoursSetting", |
| | | method: "delete", |
| | | data: query, |
| | | }); |
| | | } |
| | | |
| | | |
| | |
| | | // æ¥è¯¢ä¸ªäººéè®¯å½ |
| | | // 个人é讯å½é常æ¯ç¨æ·æ¶èæé¢ç¹èç³»ç人å |
| | | export function getPersonalContacts(page,query) { |
| | | return request({ |
| | | url: '/staffContactsPersonal/getList', |
| | | method: 'get', |
| | | params: { |
| | | ...page, |
| | | ...query |
| | | } |
| | | }) |
| | | return request({ |
| | | url: '/staffContactsPersonal/getList', |
| | | method: 'get', |
| | | params: { |
| | | ...page, |
| | | ...query |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // æ·»å è系人å°ä¸ªäººéè®¯å½ |
| | | export function addPersonalContact(data) { |
| | | return request({ |
| | | url: '/staffContactsPersonal/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | return request({ |
| | | url: '/staffContactsPersonal/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ä»ä¸ªäººé讯å½ç§»é¤è系人 |
| | | export function removePersonalContact(id) { |
| | | return request({ |
| | | url: '/staffContactsPersonal/delete/' + id, |
| | | method: 'delete' |
| | | }) |
| | | return request({ |
| | | url: '/staffContactsPersonal/delete/' + id, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢å
Œ
±éè®¯å½ |
| | | // å
Œ
±é讯å½éå¸¸æ¯ææåå·¥å¯è§çèç³»æ¹å¼ |
| | | export function getPublicContacts(query) { |
| | | return request({ |
| | | url: '/staff/contacts/public/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | return request({ |
| | | url: '/staff/contacts/public/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢åä½éè®¯å½ |
| | | // åä½é讯å½é常æé¨é¨ç»ç»çåå·¥èç³»æ¹å¼ |
| | | export function getCompanyContacts(query) { |
| | | return request({ |
| | | url: '/staff/contacts/company/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | return request({ |
| | | url: '/staff/contacts/company/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢é¨é¨éè®¯å½æ ç»æ |
| | | export function getDepartmentTree() { |
| | | return request({ |
| | | url: '/staff/contacts/department/tree', |
| | | method: 'get' |
| | | }) |
| | | return request({ |
| | | url: '/staff/contacts/department/tree', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // è·åå工详ç»ä¿¡æ¯ |
| | | export function getEmployeeDetail(employeeId) { |
| | | return request({ |
| | | url: '/staff/staffOnJob/' + employeeId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | return request({ |
| | | url: '/staff/staffOnJob/' + employeeId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | |
| | | import request from '@/utils/request' |
| | | import request from "@/utils/request"; |
| | | |
| | | // æ¥è¯¢å
¬åå表 |
| | | export function listNotice(query) { |
| | | return request({ |
| | | url: '/collaborativeApproval/notice/page', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | return request({ |
| | | url: "/collaborativeApproval/notice/page", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢å
¬åè¯¦ç» |
| | | export function getNotice(noticeId) { |
| | | return request({ |
| | | url: '/collaborativeApproval/notice/' + noticeId, |
| | | method: 'get' |
| | | }) |
| | | return request({ |
| | | url: "/collaborativeApproval/notice/" + noticeId, |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢å
Œ |
| | | export function addNotice(data) { |
| | | return request({ |
| | | url: '/collaborativeApproval/notice/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | return request({ |
| | | url: "/collaborativeApproval/notice/add", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹å
Œ |
| | | export function updateNotice(data) { |
| | | return request({ |
| | | url: '/collaborativeApproval/notice/update', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | return request({ |
| | | url: "/collaborativeApproval/notice/update", |
| | | method: "put", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // å é¤å
Œ |
| | | export function delNotice(ids) { |
| | | return request({ |
| | | url: '/collaborativeApproval/notice/' + ids, |
| | | method: 'delete', |
| | | }) |
| | | return request({ |
| | | url: "/collaborativeApproval/notice/" + ids, |
| | | method: "delete", |
| | | }); |
| | | } |
| | | |
| | | // è·åå
¬åæ°é |
| | | export function getCount() { |
| | | return request({ |
| | | url: '/collaborativeApproval/notice/count', |
| | | method: 'get', |
| | | }) |
| | | return request({ |
| | | url: "/collaborativeApproval/notice/count", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢å
¬åç±»åå表 |
| | | export function listNoticeType() { |
| | | return request({ |
| | | url: '/noticeType/list', |
| | | method: 'get' |
| | | }) |
| | | return request({ |
| | | url: "/noticeType/list", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢å
¬åç±»å |
| | | export function addNoticeType(data) { |
| | | return request({ |
| | | url: '/noticeType/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | return request({ |
| | | url: "/noticeType/add", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // å é¤å
¬åç±»å |
| | | export function delNoticeType(id) { |
| | | return request({ |
| | | url: '/noticeType/del', |
| | | method: 'delete', |
| | | data: { id } |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/noticeType/del", |
| | | method: "delete", |
| | | data: [id], |
| | | }); |
| | | } |
| | |
| | | // æ¥è¯¢RPAå表 |
| | | export function listRpa(query) { |
| | | return request({ |
| | | url: "/collaborativeApproval/rpa/list", |
| | | url: "/rpaProcessAutomation/getList", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | |
| | | // æ°å¢RPA |
| | | export function addRpa(data) { |
| | | return request({ |
| | | url: "/collaborativeApproval/rpa", |
| | | url: "/rpaProcessAutomation/add", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | |
| | | // ä¿®æ¹RPA |
| | | export function updateRpa(data) { |
| | | return request({ |
| | | url: "/collaborativeApproval/rpa", |
| | | method: "put", |
| | | url: "/rpaProcessAutomation/update", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // å é¤RPA |
| | | export function delRpa(rpaId) { |
| | | export function delRpa(query) { |
| | | return request({ |
| | | url: "/collaborativeApproval/rpa/" + rpaId, |
| | | url: "/rpaProcessAutomation/delete", |
| | | method: "delete", |
| | | data: query, |
| | | }); |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // åè´§å®¡æ¹ |
| | | import request from "@/utils/request"; |
| | | |
| | | // è·åå货审æ¹å表 |
| | | export function getShipmentApprovalList(query) { |
| | | return request({ |
| | | url: '/shipmentApproval/listPage', |
| | | method: 'get', |
| | | params: query, |
| | | }) |
| | | } |
| | | |
| | | // åè´§ç³è¯·æ¹å |
| | | // /shipmentApproval/update |
| | | export function approveShipment(query) { |
| | | return request({ |
| | | url: '/shipmentApproval/update', |
| | | method: 'post', |
| | | data: query, |
| | | }) |
| | | } |
| | |
| | | method: 'post', |
| | | data: query, |
| | | }) |
| | | } |
| | | |
| | | // 临æå®å管ç-å页æ¥è¯¢ |
| | | export function expiryAfterSalesListPage(query) { |
| | | return request({ |
| | | url: '/expiryAfterSales/listPage', |
| | | method: 'get', |
| | | params: query, |
| | | }) |
| | | } |
| | | |
| | | // 临æå®å管ç-æ°å¢ |
| | | export function expiryAfterSalesAdd(query) { |
| | | return request({ |
| | | url: '/expiryAfterSales/add', |
| | | method: 'post', |
| | | data: query, |
| | | }) |
| | | } |
| | | |
| | | // 临æå®å管ç-æ´æ° |
| | | export function expiryAfterSalesUpdate(query) { |
| | | return request({ |
| | | url: '/expiryAfterSales/update', |
| | | method: 'post', |
| | | data: query, |
| | | }) |
| | | } |
| | | |
| | | // 临æå®å管ç-å é¤ |
| | | export function expiryAfterSalesDelete(query) { |
| | | return request({ |
| | | url: '/expiryAfterSales/delete', |
| | | method: 'delete', |
| | | data: query, |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // 设å¤åç管ç - æ¬å°åæ°æ® APIï¼ä½¿ç¨ localStorage æä¹
åï¼ |
| | | |
| | | const STORAGE_KEY = 'EQUIPMENT_BRANDS'; |
| | | |
| | | function readStore() { |
| | | try { |
| | | const raw = localStorage.getItem(STORAGE_KEY); |
| | | if (raw) { |
| | | const parsed = JSON.parse(raw); |
| | | if (Array.isArray(parsed)) return parsed; |
| | | } |
| | | } catch (e) { |
| | | // ignore |
| | | } |
| | | // åå§åä¸äºç¤ºä¾æ°æ® |
| | | const initial = [ |
| | | { id: 1, name: '西é¨å', country: 'å¾·å½', description: 'å·¥ä¸èªå¨åä¸çµæ°å·¥ç¨åç', createdAt: Date.now() - 86400000 * 10 }, |
| | | { id: 2, name: 'æ½èå¾·', country: 'æ³å½', description: 'è½æºç®¡çä¸èªå¨å', createdAt: Date.now() - 86400000 * 7 }, |
| | | { id: 3, name: 'ä¸è±çµæº', country: 'æ¥æ¬', description: 'çµæ°ä¸èªå¨å设å¤', createdAt: Date.now() - 86400000 * 3 }, |
| | | ]; |
| | | localStorage.setItem(STORAGE_KEY, JSON.stringify(initial)); |
| | | return initial; |
| | | } |
| | | |
| | | function writeStore(list) { |
| | | localStorage.setItem(STORAGE_KEY, JSON.stringify(list)); |
| | | } |
| | | |
| | | function nextId(list) { |
| | | const maxId = list.reduce((max, item) => Math.max(max, Number(item.id) || 0), 0); |
| | | return maxId + 1; |
| | | } |
| | | |
| | | export function getBrandPage(params = {}) { |
| | | const { current = 1, size = 10, name } = params; |
| | | const list = readStore(); |
| | | let filtered = list; |
| | | if (name) { |
| | | const kw = String(name).trim(); |
| | | filtered = filtered.filter((b) => |
| | | (b.name && b.name.includes(kw)) || (b.country && b.country.includes(kw)) |
| | | ); |
| | | } |
| | | const start = (current - 1) * size; |
| | | const end = start + Number(size); |
| | | const records = filtered.slice(start, end); |
| | | return Promise.resolve({ |
| | | code: 200, |
| | | data: { |
| | | total: filtered.length, |
| | | records, |
| | | }, |
| | | msg: 'ok', |
| | | }); |
| | | } |
| | | |
| | | export function getBrandById(id) { |
| | | const list = readStore(); |
| | | const item = list.find((i) => String(i.id) === String(id)); |
| | | return Promise.resolve({ code: 200, data: item || null, msg: 'ok' }); |
| | | } |
| | | |
| | | export function addBrand(data) { |
| | | const list = readStore(); |
| | | const item = { ...data }; |
| | | item.id = nextId(list); |
| | | item.createdAt = Date.now(); |
| | | list.unshift(item); |
| | | writeStore(list); |
| | | return Promise.resolve({ code: 200, data: item, msg: 'æ°å¢æå' }); |
| | | } |
| | | |
| | | export function editBrand(data) { |
| | | const list = readStore(); |
| | | const index = list.findIndex((i) => String(i.id) === String(data.id)); |
| | | if (index !== -1) { |
| | | list[index] = { ...list[index], ...data }; |
| | | writeStore(list); |
| | | return Promise.resolve({ code: 200, data: list[index], msg: 'ä¿®æ¹æå' }); |
| | | } |
| | | return Promise.resolve({ code: 404, data: null, msg: 'æªæ¾å°è¯¥åç' }); |
| | | } |
| | | |
| | | export function delBrand(idOrIds) { |
| | | const list = readStore(); |
| | | const ids = Array.isArray(idOrIds) ? idOrIds.map(String) : [String(idOrIds)]; |
| | | const newList = list.filter((i) => !ids.includes(String(i.id))); |
| | | writeStore(newList); |
| | | return Promise.resolve({ code: 200, data: null, msg: 'å 餿å' }); |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | // å é¤è®°å½ |
| | | export function ledgerRecordDelete(ids) { |
| | | return request({ |
| | | url: "/measuringInstrumentLedgerRecord/delete", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request'; |
| | | |
| | | // ç»è®°ç¼ºé· |
| | | export function registerDefect(data) { |
| | | return request({ |
| | | url: '/defect/add', |
| | | method: 'post', |
| | | data |
| | | }); |
| | | } |
| | | |
| | | // è·å缺é·å表 |
| | | export function getDefectList() { |
| | | return request({ |
| | | url: '/defect/page', |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ¶é¤ç¼ºé·-ä¿®æ¹ç¶æ |
| | | export function eliminateDefect(data) { |
| | | return request({ |
| | | url: '/defect/update', |
| | | method: 'post', |
| | | data |
| | | }); |
| | | } |
| | | //å é¤ |
| | | export function deleteDefect(id) { |
| | | return request({ |
| | | url: '/defect/delete', |
| | | method: 'delete', |
| | | id |
| | | }); |
| | | } |
| | | |
| | | |
| | | // è·å缺é·è®¾å¤å°è´¦ |
| | | export function getDefectLedger(deviceLedgerId) { |
| | | return request({ |
| | | url: '/defect//find/' + deviceLedgerId, |
| | | method: 'get' |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // è·å设å¤åºæ¬ä¿¡æ¯ |
| | | export function getDeviceInfo(params) { |
| | | return request({ |
| | | url: "/device/ledger/scanDevice", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | } |
| | |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | |
| | | // 计éå¨å
·å°è´¦-æ°å¢ |
| | | // /measuringInstrumentLedger/add |
| | | export function addMeasuringInstrumentLedger(data){ |
| | | return request({ |
| | | url:"/measuringInstrumentLedger/add", |
| | | method:"post", |
| | | data |
| | | }) |
| | | } |
| | | |
| | | // 计éå¨å
·å°è´¦-ç¼è¾ |
| | | // /measuringInstrumentLedger/update |
| | | export function updateMeasuringInstrumentLedger(data){ |
| | | return request({ |
| | | url:"/measuringInstrumentLedger/update", |
| | | method:"post", |
| | | data |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | /** |
| | | * å¤ä»¶åç±»-æ å表 |
| | | */ |
| | | export const getSparePartsTree = (params) => { |
| | | return request({ |
| | | url: "/spareParts/getTree", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | /** |
| | | * å¤ä»¶åç±»-å页æ¥è¯¢å表 |
| | | */ |
| | | export const getSparePartsList = (params) => { |
| | | return request({ |
| | | url: "/spareParts/listPage", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * @desc æ°å¢ |
| | | */ |
| | | export const addSparePart = (data) => { |
| | | return request({ |
| | | url: "/spareParts/add", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * @desc ç¼è¾ |
| | | */ |
| | | export const editSparePart = (data) => { |
| | | return request({ |
| | | url: "/spareParts/update", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * @desc å 餿¥ä¿® |
| | | * @param {ç¼å·} ids |
| | | * @returns |
| | | */ |
| | | export const delSparePart = (id) => { |
| | | return request({ |
| | | url: '/spareParts/delete/'+id, |
| | | method: "delete", |
| | | |
| | | }); |
| | | }; |
| | | |
| | | |
| | |
| | | method: "delete", |
| | | }); |
| | | }; |
| | | // æ·»å 设å¤ä¿å
»å®æ¶ä»»å¡ |
| | | export const deviceMaintenanceTaskAdd = (params) => { |
| | | return request({ |
| | | url: '/deviceMaintenanceTask/add', |
| | | method: "post", |
| | | data: params, |
| | | }); |
| | | }; |
| | | // ä¿®æ¹è®¾å¤ä¿å
»å®æ¶ä»»å¡ |
| | | export const deviceMaintenanceTaskEdit = (params) => { |
| | | return request({ |
| | | url: '/deviceMaintenanceTask/update', |
| | | method: "post", |
| | | data: params, |
| | | }); |
| | | }; |
| | | // 设å¤ä¿å
»å®æ¶ä»»å¡å表 |
| | | export const deviceMaintenanceTaskList = (params) => { |
| | | return request({ |
| | | url: '/deviceMaintenanceTask/listPage', |
| | | method: "get", |
| | | params: params, |
| | | }); |
| | | }; |
| | | // 设å¤ä¿å
»å®æ¶ä»»å¡å表 |
| | | export const deviceMaintenanceTaskDel = (params) => { |
| | | return request({ |
| | | url: '/deviceMaintenanceTask/delete', |
| | | method: "delete", |
| | | data: params, |
| | | }); |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | /** |
| | | * 书æ¶ç®¡çç¸å
³APIæ¥å£ |
| | | * å
å«ä»åºç®¡çãè´§æ¶ç®¡çãå¾ä¹¦ç®¡ççåè½çæ¥å£ |
| | | */ |
| | | |
| | | /** |
| | | * è·åä»åºå表 |
| | | * @description è·åææä»åºçåºæ¬ä¿¡æ¯å表 |
| | | * @returns {Promise} è¿åä»åºåè¡¨æ°æ® |
| | | */ |
| | | export function getWarehouseList() { |
| | | return request({ |
| | | url: "/warehouse/tree", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢ä»åº |
| | | * @description å建æ°çä»åºè®°å½ |
| | | * @param {Object} data ä»åºä¿¡æ¯å¯¹è±¡ï¼å
å«ä»åºåç§°çåæ®µ |
| | | * @returns {Promise} è¿åæ°å¢ç»æ |
| | | */ |
| | | export function addWarehouse(data) { |
| | | return request({ |
| | | url: "/warehouse/add", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * æ´æ°ä»åºä¿¡æ¯ |
| | | * @description ä¿®æ¹ç°æä»åºçåºæ¬ä¿¡æ¯ |
| | | * @param {Object} data ä»åºä¿¡æ¯å¯¹è±¡ï¼å¿
é¡»å
å«ä»åºID |
| | | * @returns {Promise} è¿åæ´æ°ç»æ |
| | | */ |
| | | export function updateWarehouse(data) { |
| | | return request({ |
| | | url: "/warehouse/update", |
| | | method: "put", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * å é¤ä»åº |
| | | * @description æ ¹æ®ä»åºIDå 餿å®çä»åºè®°å½ |
| | | * @param {string|number} id ä»åºID |
| | | * @returns {Promise} è¿åå é¤ç»æ |
| | | */ |
| | | export function deleteWarehouse(data) { |
| | | return request({ |
| | | url: `/warehouse/delete/`, |
| | | method: "delete", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * è·åè´§æ¶å表 |
| | | * @description æ ¹æ®ä»åºIDè·å该ä»åºä¸çææè´§æ¶ä¿¡æ¯ |
| | | * @param {string|number} warehouseId ä»åºID |
| | | * @returns {Promise} è¿åè´§æ¶åè¡¨æ°æ® |
| | | */ |
| | | export function getShelfList(warehouseId) { |
| | | return request({ |
| | | url: `/shelf/list/${warehouseId}`, |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢è´§æ¶ |
| | | * @description 卿å®ä»åºä¸å建æ°çè´§æ¶è®°å½ |
| | | * @param {Object} data è´§æ¶ä¿¡æ¯å¯¹è±¡ï¼å
å«è´§æ¶åç§°ã屿°ãåæ°çåæ®µ |
| | | * @returns {Promise} è¿åæ°å¢ç»æ |
| | | */ |
| | | export function addShelf(data) { |
| | | return request({ |
| | | url: "/warehouse/goodsShelves/add", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * æ´æ°è´§æ¶ä¿¡æ¯ |
| | | * @description ä¿®æ¹ç°æè´§æ¶çåºæ¬ä¿¡æ¯ |
| | | * @param {Object} data è´§æ¶ä¿¡æ¯å¯¹è±¡ï¼å¿
é¡»å
å«è´§æ¶ID |
| | | * @returns {Promise} è¿åæ´æ°ç»æ |
| | | */ |
| | | export function updateShelf(data) { |
| | | return request({ |
| | | url: "/warehouse/goodsShelves/update", |
| | | method: "put", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * å é¤è´§æ¶ |
| | | * @description æ ¹æ®è´§æ¶IDå 餿å®çè´§æ¶è®°å½ |
| | | * @param {string|number} id è´§æ¶ID |
| | | * @returns {Promise} è¿åå é¤ç»æ |
| | | */ |
| | | export function deleteShelf(id) { |
| | | return request({ |
| | | url: `/warehouse/goodsShelves/delete/${id}`, |
| | | method: "delete", |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * è·åä»åºç»æ |
| | | * @description è·åæå®ä»åºç宿´ç»æä¿¡æ¯ï¼å
æ¬è´§æ¶ã屿°ãåæ°ç |
| | | * @param {string|number} warehouseId ä»åºID |
| | | * @returns {Promise} è¿åä»åºç宿´ç»ææ°æ® |
| | | */ |
| | | export function getWarehouseStructure(data) { |
| | | return request({ |
| | | url: `/warehouse/goodsShelvesRowcol/list`, |
| | | method: "get", |
| | | params: data, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // ææ¡£åé
管çç¸å
³æ¥å£ |
| | | |
| | | // è·åææ¡£å表ï¼ç¨äºåé
书ç±éæ©ï¼ |
| | | export function getDocumentList() { |
| | | return request({ |
| | | url: "/documentation/list", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // åé
å页æ¥è¯¢ |
| | | export function getBorrowList(params) { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/listPage", |
| | | method: "get", |
| | | params: params, |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢åé
|
| | | export function addBorrow(data) { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/add", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // æ´æ°åé
|
| | | export function updateBorrow(data) { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/update", |
| | | method: "put", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // å é¤åé
|
| | | export function deleteBorrow(ids) { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/delete", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // è·ååç±»æ |
| | | export function getCategoryTree() { |
| | | return request({ |
| | | url: "/warehouse/documentClassification/getList", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢åç±» |
| | | export function addCategory(data) { |
| | | return request({ |
| | | url: "/warehouse/documentClassification/add", |
| | | method: "post", |
| | | data: { |
| | | category: data.category, |
| | | parentId: data.parentId, |
| | | }, |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹åç±» |
| | | export function updateCategory(data) { |
| | | return request({ |
| | | url: "/warehouse/documentClassification/update", |
| | | method: "put", |
| | | data: { |
| | | id: data.id, |
| | | category: data.category, |
| | | }, |
| | | }); |
| | | } |
| | | |
| | | // å é¤åç±» |
| | | export function deleteCategory(ids) { |
| | | return request({ |
| | | url: "/warehouse/documentClassification/delete", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | } |
| | | |
| | | // è·åææ¡£å表ï¼åé¡µï¼ |
| | | export function getDocumentList(query) { |
| | | return request({ |
| | | url: "/documentation/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢ææ¡£ |
| | | export function addDocument(data) { |
| | | return request({ |
| | | url: "/documentation/add", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹ææ¡£ |
| | | export function updateDocument(data) { |
| | | return request({ |
| | | url: "/documentation/update", |
| | | method: "put", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // å é¤ææ¡£ |
| | | export function deleteDocument(ids) { |
| | | return request({ |
| | | url: "/documentation/delete", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | } |
| | | |
| | | // è·åææ¡£è¯¦æ
|
| | | export function getDocumentDetail(id) { |
| | | return request({ |
| | | url: "/document/" + id, |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // æç´¢ææ¡£ |
| | | export function searchDocument(query) { |
| | | return request({ |
| | | url: "/document/search", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // è·åä»åºç»æ |
| | | export function getWarehouseStructure() { |
| | | return request({ |
| | | url: "/document/warehouse/structure", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // é件管çç¸å
³æ¥å£ |
| | | // æ·»å éä»¶ |
| | | export function addDocumentationFile(data) { |
| | | return request({ |
| | | url: "/documentation/documentationFile/add", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // è·åéä»¶å表 |
| | | export function getDocumentationFileList(params) { |
| | | return request({ |
| | | url: "/documentation/documentationFile/listPage", |
| | | method: "get", |
| | | params: params, |
| | | }); |
| | | } |
| | | |
| | | // å é¤éä»¶ |
| | | export function deleteDocumentationFile(ids) { |
| | | return request({ |
| | | url: "/documentation/documentationFile/del", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | } |
| | | |
| | | // ææ¡£åé
管çç¸å
³æ¥å£ |
| | | export function getBorrowList(params) { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/listPage", |
| | | method: "get", |
| | | params: params, |
| | | }); |
| | | } |
| | | |
| | | export function addBorrow(data) { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/add", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | export function updateBorrow(data) { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/update", |
| | | method: "put", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | export function deleteBorrow(ids) { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/delete", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | } |
| | | |
| | | // ç»è®¡ç¸å
³æ¥å£ |
| | | // è·åæ»ä½ç»è®¡æ°æ® |
| | | export function getDocumentationOverview() { |
| | | return request({ |
| | | url: "/documentation/overview", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // è·ååç±»ç»è®¡æ°æ® |
| | | export function getDocumentationCategoryStats() { |
| | | return request({ |
| | | url: "/documentation/category", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // è·åç¶æç»è®¡æ°æ® |
| | | export function getDocumentationStatusStats() { |
| | | return request({ |
| | | url: "/documentation/status", |
| | | method: "get", |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢å½è¿è®°å½ |
| | | export function getReturnListPage(query) { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/listPageReturn", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // å½è¿æä½ |
| | | export function returnDocument(data) { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/revent", |
| | | method: "put", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // å é¤å½è¿è®°å½ |
| | | export function deleteReturn(ids) { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/reventDelete", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | } |
| | | //æ ¹æ®ä¹¦ç±idæ¥è¯¢åé
è®°å½ |
| | | export function getBorrowListByDocumentationId(id) { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/getByDocumentationId/"+id, |
| | | method: "get" |
| | | }); |
| | | } |
| | | |
| | | // æ´æ°åé
è®°å½ |
| | | export function updateBorrow(data) { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/update", |
| | | method: "put", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // å½è¿æ´æ° |
| | | export function reventUpdate(data) { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/reventUpdate", |
| | | method: "put", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // è·åææ¡£å表 |
| | | export function getDocumentList() { |
| | | return request({ |
| | | url: "/documentationBorrowManagement/list", |
| | | method: "get", |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // è·åæ¡£æ¡æ»ä½ç»è®¡ |
| | | export function getDocumentStatistics() { |
| | | return request({ |
| | | url: "/fileManagement/statistics/overview", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // è·åæ¡£æ¡åç±»ç»è®¡ |
| | | export function getCategoryStatistics() { |
| | | return request({ |
| | | url: "/fileManagement/statistics/category", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // è·åæ¡£æ¡ç¶æç»è®¡ |
| | | export function getStatusStatistics() { |
| | | return request({ |
| | | url: "/fileManagement/statistics/status", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // è·åæ¡£æ¡åé
ç»è®¡ |
| | | export function getBorrowStatistics() { |
| | | return request({ |
| | | url: "/fileManagement/statistics/borrow", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // è·åæ¡£æ¡å¹´åº¦ç»è®¡ |
| | | export function getYearStatistics() { |
| | | return request({ |
| | | url: "/fileManagement/statistics/year", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // è·åæ¡£æ¡ä½ç½®ç»è®¡ |
| | | export function getLocationStatistics() { |
| | | return request({ |
| | | url: "/fileManagement/statistics/location", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // è·åæ¡£æ¡è¶å¿ç»è®¡ |
| | | export function getTrendStatistics(params) { |
| | | return request({ |
| | | url: "/fileManagement/statistics/trend", |
| | | method: "get", |
| | | params: params, |
| | | }); |
| | | } |
| | | |
| | | // è·åæ¡£æ¡åé
æè¡ |
| | | export function getBorrowRanking() { |
| | | return request({ |
| | | url: "/fileManagement/statistics/borrowRanking", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // è·åæ¡£æ¡å类详æ
ç»è®¡ |
| | | export function getCategoryDetailStatistics(categoryId) { |
| | | return request({ |
| | | url: `/fileManagement/statistics/categoryDetail/${categoryId}`, |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // è·ååºå®èµäº§æ±æ»ä¿¡æ¯ |
| | | export const getAccountingTotal = (params) => { |
| | | return request({ |
| | | url: "/accounting/total", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // è·å设å¤ç±»åå叿°æ®ï¼é¥¼å¾åæçº¿å¾ï¼ |
| | | export const getDeviceTypeDistribution = (params) => { |
| | | return request({ |
| | | url: "/accounting/deviceTypeDistribution", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // è·åææ§è®¡ç®æ°æ®ï¼è¡¨æ ¼æ°æ®ï¼ |
| | | export const getCalculateDepreciation = (params) => { |
| | | return request({ |
| | | url: "/accounting/calculateDepreciation", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | |
| | | params, |
| | | }); |
| | | }; |
| | | export const listPageAnalysis = (params) => { |
| | | return request({ |
| | | url: "/account/accountExpense/report/analysis", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // æ°å¢ |
| | | export function add(data) { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // æ¥è¯¢å表 |
| | | export const listPage = (params) => { |
| | | return request({ |
| | | url: "/borrowInfo/listPage", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // æ°å¢ |
| | | export function add(data) { |
| | | return request({ |
| | | url: "/borrowInfo/add", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // ç¼è¾ |
| | | export function update(data) { |
| | | return request({ |
| | | url: "/borrowInfo/update", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // å é¤ |
| | | export const delAccountLoan = (data) => { |
| | | return request({ |
| | | url: "/borrowInfo/delete", |
| | | method: "delete", |
| | | data, |
| | | }); |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // å·¡æ£ç®¡ç |
| | | import request from '@/utils/request' |
| | | |
| | | // å·¡æ£ä»»å¡è¡¨è¡¨æ¥è¯¢ |
| | | export function inspectionTaskList(query) { |
| | | return request({ |
| | | url: '/inspectionTask/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | // å·¡æ£ä»»å¡è¡¨æ°å¢ä¿®æ¹ |
| | | export function addOrEditInspectionTask(query) { |
| | | return request({ |
| | | url: '/inspectionTask/addOrEditInspectionTask', |
| | | method: 'post', |
| | | data: query |
| | | }) |
| | | } |
| | | // å·¡æ£ä»»å¡è¡¨å é¤ |
| | | export function delInspectionTask(query) { |
| | | return request({ |
| | | url: '/inspectionTask/delInspectionTask', |
| | | method: 'delete', |
| | | data: query |
| | | }) |
| | | } |
| | | // 宿¶å·¡æ£ä»»å¡è¡¨å é¤ |
| | | export function delTimingTask(query) { |
| | | return request({ |
| | | url: '/timingTask/delTimingTask', |
| | | method: 'delete', |
| | | data: query |
| | | }) |
| | | } |
| | | |
| | | // /inspectionTask/addOrEditInspectionTask |
| | | // å·¡æ£ä¸ä¼ |
| | | export function uploadInspectionTask(query) { |
| | | return request({ |
| | | url: '/inspectionTask/addOrEditInspectionTask', |
| | | method: 'post', |
| | | data: query |
| | | }) |
| | | } |
| | | // 宿¶å·¡æ£ä»»å¡è¡¨æ¥è¯¢ |
| | | export function timingTaskList(query) { |
| | | return request({ |
| | | url: '/timingTask/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | // 宿¶å·¡æ£ä»»å¡è¡¨æ°å¢ä¿®æ¹ |
| | | export function addOrEditTimingTask(query) { |
| | | return request({ |
| | | url: '/timingTask/addOrEditTimingTask', |
| | | method: 'post', |
| | | data: query |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // å·¡æ£ä¸ä¼ |
| | | import request from '@/utils/request' |
| | | |
| | | // äºç»´ç 管ç表æ¥è¯¢ |
| | | export function qrCodeList(query) { |
| | | return request({ |
| | | url: '/qrCode/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | // äºç»´ç æ«ç è®°å½è¡¨æ¥è¯¢ |
| | | export function qrCodeScanRecordList(query) { |
| | | return request({ |
| | | url: '/qrCodeScanRecord/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | // äºç»´ç 管ç表æ°å¢ä¿®æ¹ |
| | | export function addOrEditQrCode(query) { |
| | | return request({ |
| | | url: '/qrCode/addOrEditQrCode', |
| | | method: 'post', |
| | | data: query |
| | | }) |
| | | } |
| | | // äºç»´ç æ«ç è®°å½è¡¨æ°å¢ä¿®æ¹ |
| | | export function addOrEditQrCodeRecord(query) { |
| | | return request({ |
| | | url: '/qrCodeScanRecord/addOrEditQrCodeRecord', |
| | | method: 'post', |
| | | data: query |
| | | }) |
| | | } |
| | | // äºç»´ç æ«ç è®°å½è¡¨æ°å¢ä¿®æ¹ |
| | | export function delQrCode(query) { |
| | | return request({ |
| | | url: '/qrCode/delQrCode', |
| | | method: 'delete', |
| | | data: query |
| | | }) |
| | | } |
| | |
| | | }); |
| | | }; |
| | | |
| | | // æ¥è¯¢ç产å
¥åºä¿¡æ¯å表 |
| | | export const getStockInPageByProductProduction = (params) => { |
| | | return request({ |
| | | url: "/stockin/listPageByProductProduction", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // åºåºå°è´¦-æ¥è¯¢èªå®ä¹å
¥åºä¿¡æ¯å表 |
| | | export const getStockInPageByCustom = (params) => { |
| | | return request({ |
| | |
| | | } |
| | | |
| | | |
| | | // |
| | | //æ¥è¯¢åºåå¾è¡¨æ°æ® |
| | | export function getStockInChartData() { |
| | | return request({ |
| | | url: '/stockin/listReport', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // æ¥è¯¢å
¥åºä¿¡æ¯å表 |
| | | export const getStockInRecordListPage = (params) => { |
| | | return request({ |
| | | url: "/stockInRecord/listPage", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | |
| | | export const updateStockInRecord = (id, data) => { |
| | | return request({ |
| | | url: "/stockInRecord/" + id, |
| | | method: "put", |
| | | data: data, |
| | | }); |
| | | }; |
| | | |
| | | export const batchDeleteStockInRecords = (ids) => { |
| | | return request({ |
| | | url: "/stockInRecord", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request.js"; |
| | | // å页æ¥è¯¢åºåè®°å½å表 |
| | | export const getStockInventoryListPage = (params) => { |
| | | return request({ |
| | | url: "/stockInventory/pagestockInventory", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // å建åºåè®°å½ |
| | | export const createStockInventory = (params) => { |
| | | return request({ |
| | | url: "/stockInventory/addstockInventory", |
| | | method: "post", |
| | | data: params, |
| | | }); |
| | | }; |
| | | |
| | | // åå°åºåè®°å½ |
| | | export const subtractStockInventory = (params) => { |
| | | return request({ |
| | | url: "/stockInventory/subtractStockInventory", |
| | | method: "post", |
| | | data: params, |
| | | }); |
| | | }; |
| | | |
| | | export const exportStockInventory = (params) => { |
| | | return request({ |
| | | url: "/stockInventory/exportStockInventory", |
| | | method: "post", |
| | | data: params, |
| | | }); |
| | | }; |
| | | |
| | | |
| | |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // æ¥è¯¢æååºåä¿¡æ¯å表 |
| | | export const getStockManageProduction = (params) => { |
| | | return request({ |
| | | url: "/stockin/listPageProductionStock", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | // æ¥è¯¢èªå®ä¹å
¥åºåºåä¿¡æ¯å表 |
| | | export const getStockManagePageByCustom = (params) => { |
| | | return request({ |
| | |
| | | // åºåºå°è´¦-éè´åºåºæ¥è¯¢åºåºå表 |
| | | export const getStockOutPage = (params) => { |
| | | return request({ |
| | | url: "/stockmanagement/listPage", |
| | | url: "/stockOutRecord/listPage", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | //æ°å¢åºåºä¿¡æ¯ |
| | | export const addStockOut = (data) => { |
| | | return request({ |
| | | url: '/stockout/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | //ä¿®æ¹åºåºä¿¡æ¯ |
| | | export const updateStockOut = (data) => { |
| | | return request({ |
| | | url: "/stockout/update", |
| | | method: "put", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | //å é¤åºåºä¿¡æ¯ |
| | | export const delStockOut = (ids) => { |
| | | return request({ |
| | | url: '/stockmanagement/del', |
| | | method: 'post', |
| | | data: ids |
| | | }) |
| | | url: "/stockOutRecord", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request.js"; |
| | | // å页æ¥è¯¢åºåè®°å½å表 |
| | | export const getStockUninventoryListPage = (params) => { |
| | | return request({ |
| | | url: "/stockUninventory/pagestockUninventory", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // å建åºåè®°å½ |
| | | export const createStockUnInventory = (params) => { |
| | | return request({ |
| | | url: "/stockUninventory/addstockUninventory", |
| | | method: "post", |
| | | data: params, |
| | | }); |
| | | }; |
| | | |
| | | // åå°åºåè®°å½ |
| | | export const subtractStockUnInventory = (params) => { |
| | | return request({ |
| | | url: "/stockUninventory/subtractstockUninventory", |
| | | method: "post", |
| | | data: params, |
| | | }); |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | import { parseStrEmpty } from "@/utils/ruoyi"; |
| | | |
| | | // æ¥è¯¢é¡¹ç®å表 |
| | | export function listProject(query) { |
| | | return request({ |
| | | url: "/oA/project/listPage", |
| | | method: "get", |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢é¡¹ç®åè¡¨è¯¦ç» |
| | | export function getProject(query) { |
| | | return request({ |
| | | url: "oA/project/getList", |
| | | method: "get" |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢é¡¹ç® |
| | | export function addProject(data) { |
| | | return request({ |
| | | url: "/oA/project/add", |
| | | method: "post", |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹é¡¹ç® |
| | | export function updateProject(data) { |
| | | return request({ |
| | | url: "/oA/project/update", |
| | | method: "post", |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // å é¤é¡¹ç® |
| | | export function delProject(projectId) { |
| | | return request({ |
| | | url: "/oA/project/delete/" + projectId, |
| | | method: "delete" |
| | | }); |
| | | } |
| | | // 导åºé¡¹ç® |
| | | export function exportProject(data) { |
| | | return request({ |
| | | url: "/oA/project/export", |
| | | method: "post", |
| | | data: data |
| | | }); |
| | | } |
| | | // // æ¹éå é¤é¡¹ç® |
| | | // export function delProjectBatch(projectIds) { |
| | | // return request({ |
| | | // url: "/oaSystem/project/batch", |
| | | // method: "delete", |
| | | // data: projectIds |
| | | // }); |
| | | // } |
| | | |
| | | // æ ¹æ®é¡¹ç®é¶æ®µidæ¥è¯¢é¡¹ç®é¶æ®µä»»å¡å表 |
| | | export function listProjectTask(phaseId) { |
| | | return request({ |
| | | url: "/oA/projectPhaseTask/listByPhaseId/"+ phaseId, |
| | | method: "get" |
| | | }); |
| | | } |
| | | |
| | | // // æ¥è¯¢é¡¹ç®ä»»å¡è¯¦ç» |
| | | // export function getProjectTask(taskId) { |
| | | // return request({ |
| | | // url: "/oaSystem/project/task/" + taskId, |
| | | // method: "get" |
| | | // }); |
| | | // } |
| | | |
| | | // æ°å¢é¡¹ç®é¶æ®µä»»å¡ |
| | | export function addProjectTask(data) { |
| | | return request({ |
| | | url: "/oA/projectPhaseTask/add", |
| | | method: "post", |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹é¡¹ç®é¶æ®µä»»å¡ |
| | | export function updateProjectTask(data) { |
| | | return request({ |
| | | url: "/oA/projectPhaseTask/update", |
| | | method: "post", |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // å é¤é¡¹ç®é¶æ®µä»»å¡ |
| | | export function delProjectTask(taskId) { |
| | | return request({ |
| | | url: "/oA/projectPhaseTask/delete/" + taskId, |
| | | method: "delete" |
| | | }); |
| | | } |
| | | |
| | | // 项ç®idæ¥è¯¢é¡¹ç®é¶æ®µå表 |
| | | export function listProjectPhase(projectId) { |
| | | return request({ |
| | | url: "/oA/projectPhase/listByProjectId/" + projectId, |
| | | method: "get" |
| | | }); |
| | | } |
| | | // æ°å¢é¡¹ç®é¶æ®µ |
| | | export function addProjectPhase(data) { |
| | | return request({ |
| | | url: "/oA/projectPhase/add", |
| | | method: "post", |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹é¡¹ç®é¶æ®µ |
| | | export function updateProjectPhase(data) { |
| | | return request({ |
| | | url: "/oA/projectPhase/update", |
| | | method: "post", |
| | | data: data |
| | | }); |
| | | |
| | | } |
| | | // å é¤é¡¹ç®é¶æ®µ |
| | | export function delProjectPhase(phaseId) { |
| | | return request({ |
| | | url: "/oA/projectPhase/delete/" + phaseId, |
| | | method: "delete" |
| | | }) |
| | | } |
| | | // |
| | | |
| | | // // æ¥è¯¢é¡¹ç®éç¨ç¢å表 |
| | | // export function listProjectMilestone(query) { |
| | | // return request({ |
| | | // url: "/oaSystem/project/milestone/list", |
| | | // method: "get", |
| | | // params: query |
| | | // }); |
| | | // } |
| | | |
| | | // // 项ç®ç»è®¡ä¿¡æ¯ |
| | | // export function getProjectStatistics() { |
| | | // return request({ |
| | | // url: "/oaSystem/project/statistics", |
| | | // method: "get" |
| | | // }); |
| | | // } |
| | |
| | | method: 'get', |
| | | params: query, |
| | | }) |
| | | } |
| | | |
| | | // 导åºåå坿¬ |
| | | export function staffOnJobExportCopy(data) { |
| | | return request({ |
| | | url: '/staff/staffOnJob/exportCopy', |
| | | method: 'post', |
| | | data: data, |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // æç管ç |
| | | import request from "@/utils/request"; |
| | | |
| | | export function save(data) { |
| | | return request({ |
| | | url: "/staff/staffScheduling/save", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | export function del(id) { |
| | | return request({ |
| | | url: "/staff/staffScheduling/del/"+id, |
| | | method: "delete", |
| | | }); |
| | | } |
| | | |
| | | export function delByIds(data) { |
| | | return request({ |
| | | url: "/staff/staffScheduling/save", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | export function listPage(data){ |
| | | return request({ |
| | | url: "/staff/staffScheduling/listPage", |
| | | method: "post", |
| | | data: data |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // èªé
¬ç®¡ç |
| | | import request from "@/utils/request"; |
| | | |
| | | // æ¥è¯¢èå¤å表 |
| | | export function personalAttendanceRecordsListPage(query) { |
| | | return request({ |
| | | url: "/staff/personalAttendanceRecords/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | // æ¥è¯¢åæç³è¯·å表 |
| | | export function holidayApplicationListPage(query) { |
| | | return request({ |
| | | url: "/staff/holidayApplication/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | // æ°å¢ |
| | | export function personalAttendanceRecordsAdd(query) { |
| | | return request({ |
| | | url: "/staff/personalAttendanceRecords/add", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | // æ°å¢åæç³è¯· |
| | | export function holidayApplicationAdd(query) { |
| | | return request({ |
| | | url: "/staff/holidayApplication/add", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | // ä¿®æ¹ |
| | | export function personalAttendanceRecordsUpdate(query) { |
| | | return request({ |
| | | url: "/staff/personalAttendanceRecords/update", |
| | | method: "put", |
| | | data: query, |
| | | }); |
| | | } |
| | | // ä¿®æ¹åæç³è¯· |
| | | export function holidayApplicationUpdate(query) { |
| | | return request({ |
| | | url: "/staff/holidayApplication/update", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | // å é¤ |
| | | export function personalAttendanceRecordsDelete(id) { |
| | | return request({ |
| | | url: "/staff/personalAttendanceRecords/delete/"+id, |
| | | method: "delete", |
| | | }); |
| | | } |
| | | // å é¤åæç³è¯· |
| | | export function holidayApplicationDelete(id) { |
| | | return request({ |
| | | url: "/staff/holidayApplication/delete/"+id, |
| | | method: "delete", |
| | | }); |
| | | } |
| | | // export function del(id) { |
| | | // return request({ |
| | | // url: "/staff/staffScheduling/del/"+id, |
| | | // method: "delete", |
| | | // }); |
| | | // } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request.js"; |
| | | |
| | | // 离èåå åæ |
| | | export function findStaffLeaveReasonAnalysis() { |
| | | return request({ |
| | | url: "/staff/analytics/reason", |
| | | method: "get" |
| | | }); |
| | | } |
| | | |
| | | // 12个æåå·¥æµå¨æµå¤±çåæ |
| | | export function findStaffAnalysisMonthlyTurnoverRateFor12Months() { |
| | | return request({ |
| | | url: "/staff/analytics/monthly_turnover_rate", |
| | | method: "get" |
| | | }); |
| | | } |
| | | |
| | | export function findStaffAnalysisTotalStatistic() { |
| | | return request({ |
| | | url: "/staff/analytics/total_statistic", |
| | | method: "get" |
| | | }); |
| | | } |
| | | |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request.js"; |
| | | |
| | | |
| | | export function findStaffContractListPage(query) { |
| | | return request({ |
| | | url: "/staff/staffContract/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request.js"; |
| | | |
| | | export function findStaffLeaveListPage(query) { |
| | | return request({ |
| | | url: "/staff/staffLeave/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | export function createStaffLeave(data) { |
| | | return request({ |
| | | url: "/staff/staffLeave", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | export function updateStaffLeave(id, data) { |
| | | return request({ |
| | | url: "/staff/staffLeave/" + id, |
| | | method: "put", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | export function batchDeleteStaffLeaves(data) { |
| | | return request({ |
| | | url: "/staff/staffLeave/del", |
| | | method: "delete", |
| | | data: data, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // é«çº§éè´ä»·æ ¼ç®¡çAPIæ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ä»·æ ¼å表 |
| | | export function listPage(query) { |
| | | return request({ |
| | | url: "/procurementPriceManagement/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢ä»·æ ¼ |
| | | export function add(data) { |
| | | return request({ |
| | | url: "/procurementPriceManagement/add", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // æ´æ°ä»·æ ¼ |
| | | export function update(data) { |
| | | return request({ |
| | | url: "/procurementPriceManagement/update", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // å é¤ä»·æ ¼ |
| | | export function del(data) { |
| | | return request({ |
| | | url: `/procurementPriceManagement/del`, |
| | | method: "delete", |
| | | data |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // éå®å°è´¦é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function listPage(query) { |
| | | return request({ |
| | | url: "/inboundManagement/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | export function listPageCopy(query) { |
| | | return request({ |
| | | url: "/inboundManagement/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | // æ°å¢ |
| | | export function add(data) { |
| | | return request({ |
| | | url: "/inboundManagement/add", |
| | | method: "post", |
| | | data |
| | | }); |
| | | } |
| | | // ä¿®æ¹ |
| | | export function update(data) { |
| | | return request({ |
| | | url: "/inboundManagement/update", |
| | | method: "post", |
| | | data |
| | | }); |
| | | } |
| | | // å é¤éå®å°è´¦ |
| | | export function del(data) { |
| | | return request({ |
| | | url: "/inboundManagement/del", |
| | | method: "delete", |
| | | data |
| | | }); |
| | | } |
| | |
| | | // æ¥è¯¢å表 |
| | | export function invoiceListPage(query) { |
| | | return request({ |
| | | url: "/purchase/registration/listPage", |
| | | url: "/sales/product/listPagePurchaseLedger", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | |
| | | }); |
| | | } |
| | | |
| | | export function getProductRecordById(params) { |
| | | // export function getProductRecordById(params) { |
| | | // return request({ |
| | | // url: "/purchase/registration/getProductRecordById", |
| | | // method: "get", |
| | | // params: params, |
| | | // }); |
| | | // } |
| | | export function getProductRecordById(data) { |
| | | return request({ |
| | | url: "/purchase/registration/getProductRecordById", |
| | | method: "get", |
| | | params: params, |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | |
| | | }); |
| | | } |
| | | |
| | | // ä¿åéè´æ¨¡æ¿ |
| | | // /purchase/ledger/addPurchaseTemplate |
| | | export function addPurchaseTemplate(data) { |
| | | return request({ |
| | | url: "/purchase/ledger/addPurchaseTemplate", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢éè´æ¨¡æ¿ |
| | | // /purchase/ledger/getPurchaseTemplateList |
| | | export function getPurchaseTemplateList(query) { |
| | |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // ä¿åéè´æ¨¡æ¿ |
| | | // /purchase/ledger/addPurchaseTemplate |
| | | export function addPurchaseTemplate(data) { |
| | | return request({ |
| | | url: "/purchase/ledger/addPurchaseTemplate", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢éè´è®¡åå表 |
| | | export function listPage(query) { |
| | | return request({ |
| | | url: "/procurementPlan/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢éè´è®¡å |
| | | export function add(data) { |
| | | return request({ |
| | | url: "/procurementPlan/add", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹éè´è®¡å |
| | | export function update(data) { |
| | | return request({ |
| | | url: "/procurementPlan/update", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | // å é¤éè´è®¡å |
| | | export function del(data) { |
| | | return request({ |
| | | url: "/procurementPlan/del", |
| | | method: "delete", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | // å é¤éè´è®¡å |
| | | export function listPageCopy(query) { |
| | | return request({ |
| | | url: "/stockin/listPageCopy", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // éè´æ¥è¡¨é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // éè´ä¸å¡æ±æ»è¡¨å页æ¥è¯¢ |
| | | export function procurementBusinessSummaryListPage(query) { |
| | | return request({ |
| | | url: "/procurementBusinessSummary/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // éå®å°è´¦é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function listPage(query) { |
| | | return request({ |
| | | url: "/returnManagement/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | // æ°å¢ |
| | | export function add(data) { |
| | | return request({ |
| | | url: "/returnManagement/add", |
| | | method: "post", |
| | | data |
| | | }); |
| | | } |
| | | // ä¿®æ¹ |
| | | export function update(data) { |
| | | return request({ |
| | | url: "/returnManagement/update", |
| | | method: "post", |
| | | data |
| | | }); |
| | | } |
| | | // å é¤éå®å°è´¦ |
| | | export function del(data) { |
| | | return request({ |
| | | url: "/returnManagement/del", |
| | | method: "delete", |
| | | data |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function getPurchaseOrders(query) { |
| | | return request({ |
| | | url: "/purchase/ledger/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | // |
| | | export function confirmReceipt(query) { |
| | | return request({ |
| | | url: "", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | // 墿·»éè´å¼å¸¸è®°å½ |
| | | export function addPurchaseException(query) { |
| | | return request({ |
| | | url: "/procurementExceptionRecord/add", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | // ä¿®æ¹éè´å¼å¸¸è®°å½ |
| | | export function updatePurchaseException(query) { |
| | | return request({ |
| | | url: "/procurementExceptionRecord/update", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // å·¥èºè·¯çº¿é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function listPage(query) { |
| | | return request({ |
| | | url: "/processRoute/page", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | export function add(data) { |
| | | return request({ |
| | | url: "/processRoute", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | export function del(ids) { |
| | | return request({ |
| | | url: '/processRoute/' + ids, |
| | | method: 'delete', |
| | | }) |
| | | } |
| | | |
| | | export function update(data) { |
| | | return request({ |
| | | url: '/processRoute', |
| | | method: 'put', |
| | | data: data, |
| | | }) |
| | | } |
| | | |
| | | // è·å详æ
|
| | | export function getById(id) { |
| | | return request({ |
| | | url: `/processRoute/${id}`, |
| | | method: 'get', |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // å·¥èºè·¯çº¿é¡¹ç®é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å表æ¥è¯¢ |
| | | export function findProcessRouteItemList(query) { |
| | | return request({ |
| | | url: "/processRouteItem/list", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | export function addOrUpdateProcessRouteItem(data) { |
| | | return request({ |
| | | url: "/processRouteItem", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // æåºæ¥å£ |
| | | export function sortProcessRouteItem(data) { |
| | | return request({ |
| | | url: "/processRouteItem/sort", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // æ¹éå 餿¥å£ |
| | | export function batchDeleteProcessRouteItem(ids) { |
| | | // å°idæ°ç»è½¬æ¢ä¸ºéå·åéçåç¬¦ä¸²ï¼æ¼æ¥å°URLåé¢ |
| | | const idsStr = Array.isArray(ids) ? ids.join(",") : ids; |
| | | return request({ |
| | | url: `/processRouteItem/batchDelete/${idsStr}`, |
| | | method: "delete", |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // 产åBOM页颿¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function listPage(query) { |
| | | return request({ |
| | | url: "/productBom/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢ |
| | | export function add(data) { |
| | | return request({ |
| | | url: "/productBom/add", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹ |
| | | export function update(data) { |
| | | return request({ |
| | | url: "/productBom/update", |
| | | method: "put", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // æ¹éå é¤ |
| | | export function batchDelete(ids) { |
| | | return request({ |
| | | url: "/productBom/batchDelete", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | } |
| | | |
| | | // æ ¹æ®äº§ååå·IDæ¥è¯¢BOM |
| | | export function getByModel(productModelId) { |
| | | return request({ |
| | | url: "/productBom/getByModel", |
| | | method: "get", |
| | | params: { productModelId }, |
| | | }); |
| | | } |
| | | |
| | | // 导åºBOM |
| | | export function exportBom(bomId) { |
| | | return request({ |
| | | url: "/productBom/exportBom", |
| | | method: "post", |
| | | params: { bomId }, |
| | | responseType: "blob", |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // å·¥èºè·¯çº¿é¡¹ç®é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å表æ¥è¯¢ |
| | | export function findProductProcessRouteItemList(query) { |
| | | return request({ |
| | | url: "/productProcessRoute/list", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | export function addOrUpdateProductProcessRouteItem(data) { |
| | | return request({ |
| | | url: "/productProcessRoute/updateRouteItem", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // ç产订åä¸ï¼æ°å¢å·¥èºè·¯çº¿é¡¹ç® |
| | | export function addRouteItem(data) { |
| | | return request({ |
| | | url: "/productProcessRoute/addRouteItem", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | // è·åç产订åå
³èçå·¥èºè·¯çº¿ä¸»ä¿¡æ¯ |
| | | export function listMain(orderId) { |
| | | return request({ |
| | | url: "/productProcessRoute/listMain", |
| | | method: "get", |
| | | params: { orderId }, |
| | | }); |
| | | } |
| | | |
| | | // å é¤å·¥èºè·¯çº¿é¡¹ç®ï¼è·¯ç±åæ¼æ¥ idï¼ |
| | | export function deleteRouteItem(id) { |
| | | return request({ |
| | | url: `/productProcessRoute/deleteRouteItem/${id}`, |
| | | method: "delete", |
| | | }); |
| | | } |
| | | |
| | | // ç产订åä¸ï¼æåºå·¥èºè·¯çº¿é¡¹ç® |
| | | export function sortRouteItem(data) { |
| | | return request({ |
| | | url: "/productProcessRoute/sortRouteItem", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // 产åç»æé¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function queryList(id) { |
| | | return request({ |
| | | url: "/productStructure/listBybomId/" + id, |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | export function add(data) { |
| | | return request({ |
| | | url: "/productStructure", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | |
| | | // å页æ¥è¯¢ |
| | | export function schedulingListPage(query) { |
| | | return request({ |
| | | url: "/productionOrder/listPage", |
| | | url: "/salesLedger/scheduling/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | export function productOrderListPage(query) { |
| | | return request({ |
| | | url: "/productOrder/page", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // ç产订å-æäº§ååå·æ¥è¯¢å¯ç¨å·¥èºè·¯çº¿å表 |
| | | export function listProcessRoute(query) { |
| | | return request({ |
| | | url: "/productOrder/listProcessRoute", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // ç产订å-ç»å®å·¥èºè·¯çº¿ |
| | | export function bindingRoute(data) { |
| | | return request({ |
| | | url: "/productOrder/bindingRoute", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | // ç产订å-æ¥è¯¢äº§åç»æå表 |
| | | export function listProcessBom(query) { |
| | | return request({ |
| | | url: "/productOrder/listProcessBom", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // è·åçæºæ£å¨å·¥ä½éæ°æ® |
| | | export function schedulingList(query) { |
| | | return request({ |
| | | url: "/salesLedger/scheduling/list", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // ä¿åçæºè®¾ç½® |
| | | export function addSpeculatTrading(data) { |
| | | return request({ |
| | | url: "/salesLedger/scheduling/addSpeculatTrading", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹çæºè®¾ç½® |
| | | export function updateSpeculatTrading(data) { |
| | | return request({ |
| | | url: "/salesLedger/scheduling/updateSpeculatTrading", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // ç产派工 |
| | | export function productionDispatch(query) { |
| | | return request({ |
| | |
| | | data: query, |
| | | }); |
| | | } |
| | | // èªå¨æ´¾å·¥ |
| | | export function productionDispatchList(query) { |
| | | return request({ |
| | | url: "/salesLedger/scheduling/productionDispatchList", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢ç产订å |
| | | export function addProductionOrder(query) { |
| | | // æ¥è¯¢æèç |
| | | export function getLossRate() { |
| | | return request({ |
| | | url: "/productionOrder/addProductionOrder", |
| | | method: "post", |
| | | data: query, |
| | | url: "/salesLedger/scheduling/loss", |
| | | method: "get", |
| | | }); |
| | | } |
| | | // ä¿®æ¹ç产订å |
| | | export function updateProductionOrder(query) { |
| | | |
| | | // æ°å¢æèç |
| | | export function addLossRate(data) { |
| | | return request({ |
| | | url: "/productionOrder/updateProductionOrder", |
| | | url: "/salesLedger/scheduling/addLoss", |
| | | method: "post", |
| | | data: query, |
| | | data: data, |
| | | }); |
| | | } |
| | | // å é¤ç产订å |
| | | export function deleteProductionOrder(query) { |
| | | |
| | | // ä¿®æ¹æèç |
| | | export function updateLossRate(data) { |
| | | return request({ |
| | | url: "/productionOrder/deleteProductionOrder", |
| | | method: "delete", |
| | | data: query, |
| | | url: "/salesLedger/scheduling/updateLoss", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // å·¥åºé¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function listPage(query) { |
| | | return request({ |
| | | url: "/productProcess/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | export function processList(query) { |
| | | return request({ |
| | | url: "/productProcess/list", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | export function add(data) { |
| | | return request({ |
| | | url: "/productProcess", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | export function del(data) { |
| | | return request({ |
| | | url: '/productProcess/batchDelete', |
| | | method: 'delete', |
| | | data: data, |
| | | }) |
| | | } |
| | | |
| | | export function update(data) { |
| | | return request({ |
| | | url: '/productProcess/update', |
| | | method: 'put', |
| | | data: data, |
| | | }) |
| | | } |
| | | |
| | | // å·¥åºæ¥è¯¢ |
| | | export function list() { |
| | | return request({ |
| | | url: "/productProcess/list", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // 导å
¥æ°æ® |
| | | export function importData(data) { |
| | | return request({ |
| | | url: "/productProcess/importData", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // ä¸è½½æ¨¡æ¿ |
| | | export function downloadTemplate() { |
| | | return request({ |
| | | url: "/productProcess/downloadTemplate", |
| | | method: "post", |
| | | responseType: "blob", |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // ç产æå
¥é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function productionProductInputListPage(query) { |
| | | return request({ |
| | | url: "/productionProductInput/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // ç产æ¥å·¥é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function productionProductMainListPage(query) { |
| | | return request({ |
| | | url: "/productionProductMain/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // ç产产åºé¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function productionProductOutputListPage(query) { |
| | | return request({ |
| | | url: "/productionProductOutput/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | } |
| | | // ç产æ¥å·¥-å é¤ |
| | | export function productionReportDelete(query) { |
| | | return request({ |
| | | url: "/productionProductMain/delete", |
| | | method: "delete", |
| | | data: query, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | export function productWorkOrderPage(query) { |
| | | return request({ |
| | | url: "/productWorkOrder/page", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | export function updateProductWorkOrder(data) { |
| | | return request({ |
| | | url: "/productWorkOrder/updateProductWorkOrder", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | export function addProductMain(data) { |
| | | return request({ |
| | | url: "/productionProductMain/addProductMain", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // ææ¡£ç®¡ç |
| | | import request from '@/utils/request' |
| | | |
| | | |
| | | // /system/user/listAll |
| | | // æ¥è¯¢ææç¨æ·å表 |
| | | export function userListAll() { |
| | | return request({ |
| | | url: '/system/user/listAll', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // /equipmentManagement/equipmentList |
| | | // æ¥è¯¢è®¾å¤å表 |
| | | export function getEquipmentList(query) { |
| | | return request({ |
| | | url: '/equipmentManagement/equipmentList', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // /coalInfo/coalInfoList |
| | | // æ¥è¯¢ç
¤ç§å表 |
| | | export function getCoalInfoList(query) { |
| | | return request({ |
| | | url: '/coalInfo/coalInfoList', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // /coalField/coalFieldList |
| | | // æ¥è¯¢ç
¤è´¨å段å表 |
| | | export function getCoalFieldList(query) { |
| | | return request({ |
| | | url: '/coalField/coalFieldList', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | |
| | | import request from '@/utils/request' |
| | | import request from "@/utils/request"; |
| | | |
| | | // æ¥è¯¢ææ å表 |
| | | export function qualityTestStandardListPage(query) { |
| | | return request({ |
| | | url: '/quality/qualityTestStandard/listPage', |
| | | method: 'get', |
| | | params: query, |
| | | }) |
| | | return request({ |
| | | url: "/qualityTestStandard/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢ææ å表 |
| | | export function qualityTestStandardAdd(query) { |
| | | return request({ |
| | | url: '/quality/qualityTestStandard/add', |
| | | method: 'post', |
| | | data: query, |
| | | }) |
| | | return request({ |
| | | url: "/qualityTestStandard/add", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹ææ å表 |
| | | export function qualityTestStandardUpdate(query) { |
| | | return request({ |
| | | url: '/quality/qualityTestStandard/update', |
| | | method: 'post', |
| | | data: query, |
| | | }) |
| | | return request({ |
| | | url: "/qualityTestStandard/update", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | |
| | | // å 餿æ å表 |
| | | export function qualityTestStandardDel(query) { |
| | | return request({ |
| | | url: '/quality/qualityTestStandard/del', |
| | | method: 'delete', |
| | | data: query, |
| | | }) |
| | | return request({ |
| | | url: "/qualityTestStandard/del", |
| | | method: "delete", |
| | | data: query, |
| | | }); |
| | | } |
| | | |
| | | // å 餿æ å表 |
| | | export function qualityInspectDetailByProductId(productId) { |
| | | return request({ |
| | | url: '/quality/qualityTestStandard/product/' + productId, |
| | | method: 'get', |
| | | }) |
| | | } |
| | | export function qualityInspectDetailByProductId(params) { |
| | | return request({ |
| | | url: "/qualityTestStandard/getQualityTestStandardByProductId", |
| | | method: "get", |
| | | params: params, |
| | | }); |
| | | } |
| | | |
| | | // å¤å¶æ ååæ° |
| | | export function qualityTestStandardCopyParam(id) { |
| | | return request({ |
| | | url: "/qualityTestStandard/copyParam", |
| | | method: "post", |
| | | data: { id }, |
| | | }); |
| | | } |
| | | |
| | | // æ¹éå®¡æ ¸ï¼ç¶æï¼1=éè¿/æ¹åï¼2=æ¤éï¼ |
| | | // ä¼ åï¼[{ id, state }] |
| | | export function qualityTestStandardAudit(data) { |
| | | return request({ |
| | | url: "/qualityTestStandard/qualityTestStandardAudit", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | // æ ååæ°ï¼å表ï¼ä¸åé¡µï¼ |
| | | export function qualityTestStandardParamList(query) { |
| | | return request({ |
| | | url: "/qualityTestStandardParam/list", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ ååæ°ï¼æ°å¢ |
| | | export function qualityTestStandardParamAdd(data) { |
| | | return request({ |
| | | url: "/qualityTestStandardParam/add", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | // æ ååæ°ï¼ä¿®æ¹ |
| | | export function qualityTestStandardParamUpdate(data) { |
| | | return request({ |
| | | url: "/qualityTestStandardParam/update", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | // æ ååæ°ï¼å é¤ï¼ä¼ id æ°ç»ï¼ |
| | | export function qualityTestStandardParamDel(ids) { |
| | | return request({ |
| | | url: "/qualityTestStandardParam/del", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | } |
| | | |
| | | // æ ¹æ®æ åIDè·åæ ååæ° |
| | | export function getQualityTestStandardParamByTestStandardId(testStandardId) { |
| | | return request({ |
| | | url: "/qualityTestStandard/getQualityTestStandardParamByTestStandardId", |
| | | method: "get", |
| | | params: { testStandardId }, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢ä¸´æéåå°è´¦å表 |
| | | export function nearExpiryReturnListPage(query) { |
| | | return request({ |
| | | url: '/quality/nearExpiryReturn/listPage', |
| | | method: 'get', |
| | | params: query, |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢ä¸´æéåå°è´¦ |
| | | export function nearExpiryReturnAdd(data) { |
| | | return request({ |
| | | url: '/quality/nearExpiryReturn/add', |
| | | method: 'post', |
| | | data: data, |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹ä¸´æéåå°è´¦ |
| | | export function nearExpiryReturnUpdate(data) { |
| | | return request({ |
| | | url: '/quality/nearExpiryReturn/update', |
| | | method: 'post', |
| | | data: data, |
| | | }) |
| | | } |
| | | |
| | | // å é¤ä¸´æéåå°è´¦ |
| | | export function nearExpiryReturnDel(ids) { |
| | | return request({ |
| | | url: '/quality/nearExpiryReturn/del', |
| | | method: 'delete', |
| | | data: ids, |
| | | }) |
| | | } |
| | | |
| | | // è·å临æéåå°è´¦è¯¦æ
|
| | | export function nearExpiryReturnDetail(id) { |
| | | return request({ |
| | | url: '/quality/nearExpiryReturn/' + id, |
| | | method: 'get', |
| | | }) |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // ç»å®å表ï¼ä¸åé¡µï¼ |
| | | export function qualityTestStandardBindingList(query) { |
| | | return request({ |
| | | url: "/qualityTestStandardBinding/list", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢ç»å®ï¼æ¯ææ¹éï¼ |
| | | export function qualityTestStandardBindingAdd(data) { |
| | | return request({ |
| | | url: "/qualityTestStandardBinding/add", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | // å é¤ç»å®ï¼ä¼ id æ°ç»ï¼ |
| | | export function qualityTestStandardBindingDel(ids) { |
| | | return request({ |
| | | url: "/qualityTestStandardBinding/del", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // è·ååç±»å宿æ°é |
| | | export function getInspectStatistics() { |
| | | return request({ |
| | | url: '/qualityReport/getInspectStatistics', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // è·åè´¨æ£åæ ¼çç»è®¡ |
| | | export function getPassRateStatistics() { |
| | | return request({ |
| | | url: '/qualityReport/getPassRateStatistics', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // è·åæåº¦åæ ¼çç»è®¡æ°æ® |
| | | export function getMonthlyPassRateStatistics(year) { |
| | | return request({ |
| | | url: '/qualityReport/getMonthlyPassRateStatistics', |
| | | method: 'get', |
| | | params: { year } |
| | | }) |
| | | } |
| | | |
| | | // è·å年度æ»åæ ¼çç»è®¡æ°æ® |
| | | export function getYearlyPassRateStatistics(year) { |
| | | return request({ |
| | | url: '/qualityReport/getYearlyPassRateStatistics', |
| | | method: 'get', |
| | | params: { year } |
| | | }) |
| | | } |
| | | // è·åæåº¦å®ææç»æ°æ® |
| | | export function getMonthlyCompletionDetails(year) { |
| | | return request({ |
| | | url: '/qualityReport/getMonthlyCompletionDetails', |
| | | method: 'get', |
| | | params: { year } |
| | | }) |
| | | } |
| | | |
| | | // è·åçç¹æ£æµææ ç»è®¡ |
| | | export function getTopParameters(inspectType) { |
| | | return request({ |
| | | url: '/qualityReport/getTopParameters', |
| | | method: 'get', |
| | | params: { inspectType } |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // åè´§å°è´¦é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function deliveryLedgerListPage(query) { |
| | | return request({ |
| | | url: "/shippingInfo/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹åè´§å°è´¦ |
| | | export function addOrUpdateDeliveryLedger(query) { |
| | | return request({ |
| | | url: "/shippingInfo/update", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | |
| | | // å é¤åè´§å°è´¦ |
| | | export function delDeliveryLedger(query) { |
| | | return request({ |
| | | url: "/shippingInfo/delete", |
| | | method: "delete", |
| | | data: query, |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢åè´§ä¿¡æ¯ |
| | | export function addShippingInfo(data) { |
| | | return request({ |
| | | url: "/shippingInfo/add", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // ææ ç»è®¡é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // 头é¨ç»è®¡æ¥å£ |
| | | export function getTotalStatistics(query) { |
| | | return request({ |
| | | url: "/metricStatistics/total", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ±ç¶å¾æ°æ®æ¥å£ |
| | | export function getStatisticsTable(query) { |
| | | return request({ |
| | | url: "/metricStatistics/statisticsTable", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // éå®å°è´¦é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function listPage(query) { |
| | | return request({ |
| | | url: "/paymentShipping/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | // æ°å¢ |
| | | export function add(data) { |
| | | return request({ |
| | | url: "/paymentShipping/add", |
| | | method: "post", |
| | | data |
| | | }); |
| | | } |
| | | // ä¿®æ¹ |
| | | export function update(data) { |
| | | return request({ |
| | | url: "/paymentShipping/update", |
| | | method: "post", |
| | | data |
| | | }); |
| | | } |
| | | // å é¤éå®å°è´¦ |
| | | export function deletePaymentShipping(data) { |
| | | return request({ |
| | | url: "/paymentShipping/delete", |
| | | method: "delete", |
| | | data |
| | | }); |
| | | } |
| | |
| | | // æ¥è¯¢å·²ç»ç»å®å票çå¼ç¥¨å°è´¦ |
| | | export function bindInvoiceNoRegPage(query) { |
| | | return request({ |
| | | url: '/receiptPayment/bindInvoiceNoRegPage', |
| | | url: '/sales/product/listPageSalesLedger', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | |
| | | params: query, |
| | | }); |
| | | } |
| | | // éå®å°è´¦é¡µé¢åè´§ï¼æ¥è¯¢åºåæ¯å¦å
è¶³ |
| | | export function getProductInventory(query) { |
| | | return request({ |
| | | url: "/sales/ledger/getProductInventory", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // éå®å°è´¦é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function listPage(query) { |
| | | return request({ |
| | | url: "/salespersonManagement/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | // æ°å¢ |
| | | export function add(data) { |
| | | return request({ |
| | | url: "/salespersonManagement/add", |
| | | method: "post", |
| | | data |
| | | }); |
| | | } |
| | | // ä¿®æ¹ |
| | | export function update(data) { |
| | | return request({ |
| | | url: "/salespersonManagement/update", |
| | | method: "post", |
| | | data |
| | | }); |
| | | } |
| | | // å é¤éå®å°è´¦ |
| | | export function deleteSalespersonManagement(data) { |
| | | return request({ |
| | | url: "/salespersonManagement/delete", |
| | | method: "delete", |
| | | data |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // çç¥ç®¡æ§é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // ========== ä»·æ ¼çç¥é
ç½® ========== |
| | | |
| | | // å页æ¥è¯¢ä»·æ ¼çç¥å表 |
| | | export function getPriceStrategyList(query) { |
| | | return request({ |
| | | url: "/sales/priceStrategy/list", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢ä»·æ ¼çç¥è¯¦æ
|
| | | export function getPriceStrategyDetail(id) { |
| | | return request({ |
| | | url: "/sales/priceStrategy/detail", |
| | | method: "get", |
| | | params: { id }, |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢ä»·æ ¼çç¥ |
| | | export function addPriceStrategy(data) { |
| | | return request({ |
| | | url: "/sales/priceStrategy/add", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹ä»·æ ¼çç¥ |
| | | export function updatePriceStrategy(data) { |
| | | return request({ |
| | | url: "/sales/priceStrategy/update", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // å é¤ä»·æ ¼çç¥ |
| | | export function deletePriceStrategy(id) { |
| | | return request({ |
| | | url: "/sales/priceStrategy/delete", |
| | | method: "delete", |
| | | params: { id }, |
| | | }); |
| | | } |
| | | |
| | | // å¯ç¨/ç¦ç¨ä»·æ ¼çç¥ |
| | | export function togglePriceStrategy(data) { |
| | | return request({ |
| | | url: "/sales/priceStrategy/toggle", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // ========== ååæ§è¡çæ§ ========== |
| | | |
| | | // è·åååæ§è¡ç»è®¡æ°æ® |
| | | export function getContractStats(query) { |
| | | return request({ |
| | | url: "/sales/contract/stats", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // å页æ¥è¯¢ååæ§è¡å表 |
| | | export function getContractExecutionList(query) { |
| | | return request({ |
| | | url: "/sales/contract/executionList", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢ååæ§è¡è¯¦æ
|
| | | export function getContractExecutionDetail(contractNo) { |
| | | return request({ |
| | | url: "/sales/contract/executionDetail", |
| | | method: "get", |
| | | params: { contractNo }, |
| | | }); |
| | | } |
| | | |
| | | // æ´æ°ååæ§è¡è¿åº¦ |
| | | export function updateContractProgress(data) { |
| | | return request({ |
| | | url: "/sales/contract/updateProgress", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // ========== å岿¯ä»·åæ ========== |
| | | |
| | | // æ¥è¯¢åå²ä»·æ ¼å¯¹æ¯æ°æ® |
| | | export function getPriceComparisonList(query) { |
| | | return request({ |
| | | url: "/sales/priceComparison/list", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // è·åä»·æ ¼è¶å¿å¾è¡¨æ°æ® |
| | | export function getPriceTrendChart(query) { |
| | | return request({ |
| | | url: "/sales/priceComparison/trendChart", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // 导åºå岿¯ä»·æ°æ® |
| | | export function exportPriceComparison(query) { |
| | | return request({ |
| | | url: "/sales/priceComparison/export", |
| | | method: "get", |
| | | params: query, |
| | | responseType: "blob", |
| | | }); |
| | | } |
| | | |
| | | // ========== 婿¶¦åæ ========== |
| | | |
| | | // è·å婿¶¦ç»è®¡æ°æ® |
| | | export function getProfitStats(query) { |
| | | return request({ |
| | | url: "/sales/profit/stats", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // å页æ¥è¯¢å©æ¶¦åæå表 |
| | | export function getProfitAnalysisList(query) { |
| | | return request({ |
| | | url: "/sales/profit/analysisList", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // è·å婿¶¦è¶å¿å¾è¡¨æ°æ® |
| | | export function getProfitTrendChart(query) { |
| | | return request({ |
| | | url: "/sales/profit/trendChart", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // è®¡ç®æ¯å©ç |
| | | export function calculateGrossProfit(data) { |
| | | return request({ |
| | | url: "/sales/profit/calculate", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // 导åºå©æ¶¦åææ¥è¡¨ |
| | | export function exportProfitAnalysis(query) { |
| | | return request({ |
| | | url: "/sales/profit/export", |
| | | method: "get", |
| | | params: query, |
| | | responseType: "blob", |
| | | }); |
| | | } |
| | | |
| | | // ========== å
Œ
±æ¥å£ ========== |
| | | |
| | | // æ¥è¯¢å®¢æ·å表ï¼ç¨äºä¸æéæ©ï¼ |
| | | export function getCustomerOptions() { |
| | | return request({ |
| | | url: "/basic/customer/options", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢äº§åå表ï¼ç¨äºä¸æéæ©ï¼ |
| | | export function getProductOptions(query) { |
| | | return request({ |
| | | url: "/basic/product/options", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢éå®åºåå表 |
| | | export function getRegionOptions() { |
| | | return request({ |
| | | url: "/basic/region/options", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // æ¥è¯¢æ¶æ¯éç¥å表 |
| | | export function listMessage(query) { |
| | | return request({ |
| | | url: "/system/notice/list", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢æªè¯»æ¶æ¯æ°é |
| | | export function getUnreadCount(consigneeId) { |
| | | return request({ |
| | | url: "/system/notice/getCount", |
| | | method: "get", |
| | | params: { consigneeId }, |
| | | }); |
| | | } |
| | | |
| | | // æ è®°æ¶æ¯ä¸ºå·²è¯» |
| | | export function markAsRead(noticeId, status) { |
| | | return request({ |
| | | url: "/system/notice", |
| | | method: "put", |
| | | data: { noticeId, status }, |
| | | }); |
| | | } |
| | | |
| | | // ä¸é®æ è®°æææ¶æ¯ä¸ºå·²è¯» |
| | | export function markAllAsRead() { |
| | | return request({ |
| | | url: "/system/notice/readAll", |
| | | method: "post", |
| | | }); |
| | | } |
| | | |
| | | // ç¡®è®¤æ¶æ¯ |
| | | export function confirmMessage(noticeId, status) { |
| | | return request({ |
| | | url: "/system/notice", |
| | | method: "put", |
| | | data: { noticeId, status }, |
| | | }); |
| | | } |
| | |
| | | })
|
| | | }
|
| | |
|
| | | export function findPostOptions(query) {
|
| | | return request({
|
| | | url: '/system/post/optionselect',
|
| | | method: 'get',
|
| | | params: query
|
| | | })
|
| | | }
|
| | |
|
| | |
|
| | | // æ¥è¯¢å²ä½è¯¦ç»
|
| | | export function getPost(postId) {
|
| | | return request({
|
| | |
| | | url: '/sales/ledger/getAmountHalfYear', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // åç产订åç宿è¿åº¦ç»è®¡ |
| | | // /home/progressStatistics |
| | | export const getProgressStatistics = ()=>{ |
| | | return request({ |
| | | url: '/home/progressStatistics', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | //å¨å¶åå¨è½¬æ
åµ |
| | | //home/workInProcessTurnover |
| | | export const getWorkInProcessTurnover= ()=>{ |
| | | return request({ |
| | | url: '/home/workInProcessTurnover', |
| | | method: 'get' |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="40" height="40" viewBox="0 0 40 40"><defs><mask id="master_svg0_88_35670" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="40" height="40"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#FFFFFF" fill-opacity="1"/></mask><clipPath id="master_svg1_88_35666"><rect x="7" y="7" width="27" height="27" rx="0"/></clipPath><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg2_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg3_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient></defs><g mask="url(#master_svg0_88_35670)"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#0092FF" fill-opacity="1"/><g clip-path="url(#master_svg1_88_35666)"><path d="M21.175671875,27.58515925L14.263672875000001,27.58515925C13.750673275,27.58515925,13.426672974999999,27.24765625,13.426672974999999,26.74815725C13.426672974999999,26.23515525,13.764173075,25.911160250000002,14.263672875000001,25.911160250000002L21.351173875,25.911160250000002C21.688676875,24.89865825,22.188173875,23.88615425,22.863174875,23.211156250000002L14.263672875000001,23.211156250000002C13.750673275,23.211156250000002,13.426672974999999,22.87365525,13.426672974999999,22.37415225C13.426672974999999,21.87465325,13.764173075,21.537155249999998,14.263672875000001,21.537155249999998L25.738675875,21.537155249999998C26.251674875,21.37515325,26.751174875,21.37515325,27.088676875,21.37515325C28.438678875,21.37515325,29.626676875,21.88815525,30.625678875,22.549656249999998L30.625678875,13.072656349999999C30.625678875,11.38515625,29.275674875,10.03515625,27.588174875,10.03515625L27.075177875,10.03515625L27.075177875,13.24815675C27.075177875,14.935656550000001,25.725173875,16.285657450000002,24.037676875000002,16.285657450000002L16.113174475,16.285657450000002C14.425674475000001,16.272157149999998,13.075673375000001,14.922158249999999,13.075673375000001,13.23465635L13.075673375000001,10.03515625L12.238672475,10.03515625C10.551171974999999,10.03515625,9.201171875,11.38515625,9.201171875,13.072656349999999L9.201171875,29.94765825C9.201171875,31.63515625,10.551171974999999,32.985161250000004,12.238672475,32.985161250000004L25.576673875,32.985161250000004C23.200674875,32.485662250000004,21.337675875000002,30.28515825,21.175671875,27.58515925Z" fill="url(#master_svg2_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/><path d="M16.1124145625,14.764538762499999L24.0504169625,14.764538762499999C24.8874170625,14.764538762499999,25.5624140625,14.0895385625,25.5624140625,13.252537762500001L25.5624140625,10.0395388625L22.5249171625,10.0395388625C22.3629159625,8.8650390625,21.3369150625,7.8525390625,19.986915562500002,7.8525390625C18.7989153625,7.8525390625,17.7864150625,8.8650390625,17.6244149625,10.0395388625L14.5869140625,10.0395388625L14.5869140625,13.252537762500001C14.5869140625,14.0895385625,15.2619143725,14.764538762499999,16.1124145625,14.764538762499999ZM30.7869150625,24.3900370625C29.9499160625,23.3775360625,28.5999220625,22.7025380625,27.2499170625,22.7025380625L26.412916062500003,22.7025380625C25.8999180625,22.7025380625,25.5759160625,22.8780390625,25.0629190625,23.2155400625C24.0504169625,23.7285370625,23.1999158625,24.7275330625,22.700415562499998,25.9155390625C22.5384173625,26.4285390625,22.5384173625,26.9280380625,22.5384173625,27.4275380625L22.5384173625,27.5895390625C22.700415562499998,30.1275410625,24.7254170625,31.9770390625,27.1014200625,31.9770390625C28.4514180625,31.9770390625,29.8014230625,31.3020400625,30.6384180625,30.2895320625C31.3134210625,29.4525340625,31.6509170625,28.4265380625,31.6509170625,27.2520330625C31.8129160625,26.2395310625,31.2999250625,25.2270370625,30.7869150625,24.3900370625ZM29.7879200625,26.5770380625L27.0879160625,29.2770390625C26.7504160625,29.6145400625,26.412916062500003,29.6145400625,26.0754160625,29.2770390625L24.387915562499998,27.5895390625C24.0504169625,27.2520370625,24.0504169625,26.9145390625,24.387915562499998,26.5770380625C24.725415062499998,26.2395380625,25.0629150625,26.2395400625,25.4004160625,26.5770380625L26.2374170625,27.4140400625L26.5749150625,27.7515370625L28.7619150625,25.5645350625C29.0994140625,25.2270370625,29.4369190625,25.2270370625,29.774416062500002,25.5645350625C30.1119160625,25.9020370625,30.1119160625,26.2395380625,29.7879200625,26.5770380625Z" fill="url(#master_svg3_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="40" height="40" viewBox="0 0 40 40"><defs><mask id="master_svg0_88_35670" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="40" height="40"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#FFFFFF" fill-opacity="1"/></mask><clipPath id="master_svg1_88_35666"><rect x="7" y="7" width="27" height="27" rx="0"/></clipPath><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg2_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg3_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient></defs><g mask="url(#master_svg0_88_35670)"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#5EB334" fill-opacity="1"/><g clip-path="url(#master_svg1_88_35666)"><path d="M21.175671875,27.58515925L14.263672875000001,27.58515925C13.750673275,27.58515925,13.426672974999999,27.24765625,13.426672974999999,26.74815725C13.426672974999999,26.23515525,13.764173075,25.911160250000002,14.263672875000001,25.911160250000002L21.351173875,25.911160250000002C21.688676875,24.89865825,22.188173875,23.88615425,22.863174875,23.211156250000002L14.263672875000001,23.211156250000002C13.750673275,23.211156250000002,13.426672974999999,22.87365525,13.426672974999999,22.37415225C13.426672974999999,21.87465325,13.764173075,21.537155249999998,14.263672875000001,21.537155249999998L25.738675875,21.537155249999998C26.251674875,21.37515325,26.751174875,21.37515325,27.088676875,21.37515325C28.438678875,21.37515325,29.626676875,21.88815525,30.625678875,22.549656249999998L30.625678875,13.072656349999999C30.625678875,11.38515625,29.275674875,10.03515625,27.588174875,10.03515625L27.075177875,10.03515625L27.075177875,13.24815675C27.075177875,14.935656550000001,25.725173875,16.285657450000002,24.037676875000002,16.285657450000002L16.113174475,16.285657450000002C14.425674475000001,16.272157149999998,13.075673375000001,14.922158249999999,13.075673375000001,13.23465635L13.075673375000001,10.03515625L12.238672475,10.03515625C10.551171974999999,10.03515625,9.201171875,11.38515625,9.201171875,13.072656349999999L9.201171875,29.94765825C9.201171875,31.63515625,10.551171974999999,32.985161250000004,12.238672475,32.985161250000004L25.576673875,32.985161250000004C23.200674875,32.485662250000004,21.337675875000002,30.28515825,21.175671875,27.58515925Z" fill="url(#master_svg2_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/><path d="M16.1124145625,14.764538762499999L24.0504169625,14.764538762499999C24.8874170625,14.764538762499999,25.5624140625,14.0895385625,25.5624140625,13.252537762500001L25.5624140625,10.0395388625L22.5249171625,10.0395388625C22.3629159625,8.8650390625,21.3369150625,7.8525390625,19.986915562500002,7.8525390625C18.7989153625,7.8525390625,17.7864150625,8.8650390625,17.6244149625,10.0395388625L14.5869140625,10.0395388625L14.5869140625,13.252537762500001C14.5869140625,14.0895385625,15.2619143725,14.764538762499999,16.1124145625,14.764538762499999ZM30.7869150625,24.3900370625C29.9499160625,23.3775360625,28.5999220625,22.7025380625,27.2499170625,22.7025380625L26.412916062500003,22.7025380625C25.8999180625,22.7025380625,25.5759160625,22.8780390625,25.0629190625,23.2155400625C24.0504169625,23.7285370625,23.1999158625,24.7275330625,22.700415562499998,25.9155390625C22.5384173625,26.4285390625,22.5384173625,26.9280380625,22.5384173625,27.4275380625L22.5384173625,27.5895390625C22.700415562499998,30.1275410625,24.7254170625,31.9770390625,27.1014200625,31.9770390625C28.4514180625,31.9770390625,29.8014230625,31.3020400625,30.6384180625,30.2895320625C31.3134210625,29.4525340625,31.6509170625,28.4265380625,31.6509170625,27.2520330625C31.8129160625,26.2395310625,31.2999250625,25.2270370625,30.7869150625,24.3900370625ZM29.7879200625,26.5770380625L27.0879160625,29.2770390625C26.7504160625,29.6145400625,26.412916062500003,29.6145400625,26.0754160625,29.2770390625L24.387915562499998,27.5895390625C24.0504169625,27.2520370625,24.0504169625,26.9145390625,24.387915562499998,26.5770380625C24.725415062499998,26.2395380625,25.0629150625,26.2395400625,25.4004160625,26.5770380625L26.2374170625,27.4140400625L26.5749150625,27.7515370625L28.7619150625,25.5645350625C29.0994140625,25.2270370625,29.4369190625,25.2270370625,29.774416062500002,25.5645350625C30.1119160625,25.9020370625,30.1119160625,26.2395380625,29.7879200625,26.5770380625Z" fill="url(#master_svg3_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="40" height="40" viewBox="0 0 40 40"><defs><mask id="master_svg0_88_35670" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="40" height="40"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#FFFFFF" fill-opacity="1"/></mask><clipPath id="master_svg1_88_35666"><rect x="7" y="7" width="27" height="27" rx="0"/></clipPath><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg2_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg3_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient></defs><g mask="url(#master_svg0_88_35670)"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#8000FF" fill-opacity="1"/><g clip-path="url(#master_svg1_88_35666)"><path d="M21.175671875,27.58515925L14.263672875000001,27.58515925C13.750673275,27.58515925,13.426672974999999,27.24765625,13.426672974999999,26.74815725C13.426672974999999,26.23515525,13.764173075,25.911160250000002,14.263672875000001,25.911160250000002L21.351173875,25.911160250000002C21.688676875,24.89865825,22.188173875,23.88615425,22.863174875,23.211156250000002L14.263672875000001,23.211156250000002C13.750673275,23.211156250000002,13.426672974999999,22.87365525,13.426672974999999,22.37415225C13.426672974999999,21.87465325,13.764173075,21.537155249999998,14.263672875000001,21.537155249999998L25.738675875,21.537155249999998C26.251674875,21.37515325,26.751174875,21.37515325,27.088676875,21.37515325C28.438678875,21.37515325,29.626676875,21.88815525,30.625678875,22.549656249999998L30.625678875,13.072656349999999C30.625678875,11.38515625,29.275674875,10.03515625,27.588174875,10.03515625L27.075177875,10.03515625L27.075177875,13.24815675C27.075177875,14.935656550000001,25.725173875,16.285657450000002,24.037676875000002,16.285657450000002L16.113174475,16.285657450000002C14.425674475000001,16.272157149999998,13.075673375000001,14.922158249999999,13.075673375000001,13.23465635L13.075673375000001,10.03515625L12.238672475,10.03515625C10.551171974999999,10.03515625,9.201171875,11.38515625,9.201171875,13.072656349999999L9.201171875,29.94765825C9.201171875,31.63515625,10.551171974999999,32.985161250000004,12.238672475,32.985161250000004L25.576673875,32.985161250000004C23.200674875,32.485662250000004,21.337675875000002,30.28515825,21.175671875,27.58515925Z" fill="url(#master_svg2_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/><path d="M16.1124145625,14.764538762499999L24.0504169625,14.764538762499999C24.8874170625,14.764538762499999,25.5624140625,14.0895385625,25.5624140625,13.252537762500001L25.5624140625,10.0395388625L22.5249171625,10.0395388625C22.3629159625,8.8650390625,21.3369150625,7.8525390625,19.986915562500002,7.8525390625C18.7989153625,7.8525390625,17.7864150625,8.8650390625,17.6244149625,10.0395388625L14.5869140625,10.0395388625L14.5869140625,13.252537762500001C14.5869140625,14.0895385625,15.2619143725,14.764538762499999,16.1124145625,14.764538762499999ZM30.7869150625,24.3900370625C29.9499160625,23.3775360625,28.5999220625,22.7025380625,27.2499170625,22.7025380625L26.412916062500003,22.7025380625C25.8999180625,22.7025380625,25.5759160625,22.8780390625,25.0629190625,23.2155400625C24.0504169625,23.7285370625,23.1999158625,24.7275330625,22.700415562499998,25.9155390625C22.5384173625,26.4285390625,22.5384173625,26.9280380625,22.5384173625,27.4275380625L22.5384173625,27.5895390625C22.700415562499998,30.1275410625,24.7254170625,31.9770390625,27.1014200625,31.9770390625C28.4514180625,31.9770390625,29.8014230625,31.3020400625,30.6384180625,30.2895320625C31.3134210625,29.4525340625,31.6509170625,28.4265380625,31.6509170625,27.2520330625C31.8129160625,26.2395310625,31.2999250625,25.2270370625,30.7869150625,24.3900370625ZM29.7879200625,26.5770380625L27.0879160625,29.2770390625C26.7504160625,29.6145400625,26.412916062500003,29.6145400625,26.0754160625,29.2770390625L24.387915562499998,27.5895390625C24.0504169625,27.2520370625,24.0504169625,26.9145390625,24.387915562499998,26.5770380625C24.725415062499998,26.2395380625,25.0629150625,26.2395400625,25.4004160625,26.5770380625L26.2374170625,27.4140400625L26.5749150625,27.7515370625L28.7619150625,25.5645350625C29.0994140625,25.2270370625,29.4369190625,25.2270370625,29.774416062500002,25.5645350625C30.1119160625,25.9020370625,30.1119160625,26.2395380625,29.7879200625,26.5770380625Z" fill="url(#master_svg3_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | :title="title" |
| | | :width="width" |
| | | :before-close="handleClose" |
| | | > |
| | | <div class="file-list-toolbar" v-if="showToolbar"> |
| | | <template v-if="useBuiltInUpload"> |
| | | <el-upload |
| | | v-model:file-list="uploadFileList" |
| | | class="upload-demo" |
| | | :action="uploadAction" |
| | | :headers="uploadHeaders" |
| | | :show-file-list="false" |
| | | :on-success="handleDefaultUploadSuccess" |
| | | :on-error="handleDefaultUploadError" |
| | | > |
| | | <el-button |
| | | v-if="showUploadButton" |
| | | type="primary" |
| | | size="small" |
| | | > |
| | | ä¸ä¼ éä»¶ |
| | | </el-button> |
| | | </el-upload> |
| | | </template> |
| | | <template v-else> |
| | | <el-button |
| | | v-if="showUploadButton" |
| | | type="primary" |
| | | size="small" |
| | | @click="handleUpload" |
| | | > |
| | | æ°å¢éä»¶ |
| | | </el-button> |
| | | </template> |
| | | </div> |
| | | <el-table :data="tableData" border :height="tableHeight"> |
| | | <el-table-column |
| | | :label="nameColumnLabel" |
| | | :prop="nameColumnProp" |
| | | :min-width="nameColumnMinWidth" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | v-if="showActions" |
| | | fixed="right" |
| | | label="æä½" |
| | | :width="actionColumnWidth" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | <el-button |
| | | v-if="showDownload" |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | @click="handleDownload(scope.row)" |
| | | > |
| | | ä¸è½½ |
| | | </el-button> |
| | | <el-button |
| | | v-if="showPreview" |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | @click="handlePreview(scope.row)" |
| | | > |
| | | é¢è§ |
| | | </el-button> |
| | | <el-button |
| | | v-if="showDeleteButton" |
| | | link |
| | | type="danger" |
| | | size="small" |
| | | @click="handleDelete(scope.row, scope.$index)" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | <slot name="actions" :row="scope.row"></slot> |
| | | </template> |
| | | </el-table-column> |
| | | <slot name="columns"></slot> |
| | | </el-table> |
| | | </el-dialog> |
| | | <filePreview v-if="showPreview" ref="filePreviewRef" /> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, getCurrentInstance } from 'vue' |
| | | import { ElMessage } from 'element-plus' |
| | | import filePreview from '@/components/filePreview/index.vue' |
| | | import { getToken } from '@/utils/auth' |
| | | |
| | | const props = defineProps({ |
| | | modelValue: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | title: { |
| | | type: String, |
| | | default: 'éä»¶' |
| | | }, |
| | | width: { |
| | | type: String, |
| | | default: '40%' |
| | | }, |
| | | tableHeight: { |
| | | type: String, |
| | | default: '40vh' |
| | | }, |
| | | nameColumnLabel: { |
| | | type: String, |
| | | default: 'éä»¶åç§°' |
| | | }, |
| | | nameColumnProp: { |
| | | type: String, |
| | | default: 'name' |
| | | }, |
| | | nameColumnMinWidth: { |
| | | type: [String, Number], |
| | | default: 400 |
| | | }, |
| | | actionColumnWidth: { |
| | | type: [String, Number], |
| | | default: 160 |
| | | }, |
| | | showActions: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | showDownload: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | showPreview: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | showUploadButton: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | showDeleteButton: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | urlField: { |
| | | type: String, |
| | | default: 'url' |
| | | }, |
| | | downloadMethod: { |
| | | type: Function, |
| | | default: null |
| | | }, |
| | | previewMethod: { |
| | | type: Function, |
| | | default: null |
| | | }, |
| | | uploadMethod: { |
| | | type: Function, |
| | | default: null |
| | | }, |
| | | deleteMethod: { |
| | | type: Function, |
| | | default: null |
| | | }, |
| | | rulesRegulationsManagementId: { |
| | | type: [String, Number], |
| | | default: '' |
| | | }, |
| | | uploadUrl: { |
| | | type: String, |
| | | default: `${import.meta.env.VITE_APP_BASE_API}/file/upload` |
| | | } |
| | | }) |
| | | |
| | | const emit = defineEmits(['update:modelValue', 'close', 'download', 'preview', 'upload', 'delete']) |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const filePreviewRef = ref(null) |
| | | const uploadFileList = ref([]) |
| | | |
| | | const dialogVisible = computed({ |
| | | get: () => props.modelValue, |
| | | set: (val) => emit('update:modelValue', val) |
| | | }) |
| | | |
| | | const tableData = ref([]) |
| | | const showToolbar = computed(() => props.showUploadButton) |
| | | const useBuiltInUpload = computed(() => !props.uploadMethod) |
| | | const uploadAction = computed(() => props.uploadUrl) |
| | | const uploadHeaders = computed(() => ({ |
| | | Authorization: `Bearer ${getToken()}` |
| | | })) |
| | | |
| | | const handleClose = () => { |
| | | emit('close') |
| | | dialogVisible.value = false |
| | | } |
| | | |
| | | const handleDownload = (row) => { |
| | | if (props.downloadMethod) { |
| | | props.downloadMethod(row) |
| | | } else { |
| | | // é»è®¤ä¸è½½æ¹æ³ |
| | | proxy.$download.name(row[props.urlField]) |
| | | } |
| | | emit('download', row) |
| | | } |
| | | |
| | | const handlePreview = (row) => { |
| | | if (props.previewMethod) { |
| | | props.previewMethod(row) |
| | | } else { |
| | | // é»è®¤é¢è§æ¹æ³ |
| | | if (filePreviewRef.value) { |
| | | filePreviewRef.value.open(row[props.urlField]) |
| | | } |
| | | } |
| | | emit('preview', row) |
| | | } |
| | | |
| | | const open = (list) => { |
| | | dialogVisible.value = true |
| | | tableData.value = list || [] |
| | | } |
| | | |
| | | const handleUpload = async () => { |
| | | if (props.uploadMethod) { |
| | | // 妿æä¾äºèªå®ä¹ä¸ä¼ æ¹æ³ï¼ç±ç¶ç»ä»¶è´è´£æ´æ°å表ï¼éè¿ setListï¼ |
| | | // è¿éä¸åèªå¨æ·»å ï¼é¿å
ä¸ç¶ç»ä»¶ç setList éå¤ |
| | | await props.uploadMethod() |
| | | } |
| | | emit('upload') |
| | | } |
| | | |
| | | const handleDelete = async (row, index) => { |
| | | if (props.deleteMethod) { |
| | | const result = await props.deleteMethod(row, index) |
| | | if (result === false) { |
| | | return |
| | | } |
| | | // 妿æä¾äº deleteMethodï¼ç±ç¶ç»ä»¶è´è´£å·æ°å表ï¼ä¸å¨è¿éå é¤ |
| | | } else { |
| | | // å¦ææ²¡ææä¾ deleteMethodï¼æå¨ç»ä»¶å
é¨å é¤ |
| | | removeAttachment(index) |
| | | } |
| | | emit('delete', row) |
| | | } |
| | | |
| | | const addAttachment = (item) => { |
| | | tableData.value = [...tableData.value, item] |
| | | } |
| | | |
| | | const handleDefaultUploadSuccess = async (res, file) => { |
| | | if (res?.code !== 200) { |
| | | ElMessage.error(res?.msg || 'æä»¶ä¸ä¼ 失败') |
| | | return |
| | | } |
| | | if (!props.rulesRegulationsManagementId) { |
| | | ElMessage.error('缺å°è§ç« å¶åº¦IDï¼æ æ³ä¿åéä»¶') |
| | | return |
| | | } |
| | | const fileName = res?.data?.originalName || file?.name |
| | | const fileUrl = res?.data?.tempPath || res?.data?.url |
| | | const payload = { |
| | | fileName, |
| | | fileUrl, |
| | | rulesRegulationsManagementId: props.rulesRegulationsManagementId, |
| | | raw: res?.data || {} |
| | | } |
| | | emit('upload', payload) |
| | | } |
| | | |
| | | const handleDefaultUploadError = () => { |
| | | ElMessage.error('æä»¶ä¸ä¼ 失败') |
| | | } |
| | | |
| | | const removeAttachment = (index) => { |
| | | if (index > -1 && index < tableData.value.length) { |
| | | const newList = [...tableData.value] |
| | | newList.splice(index, 1) |
| | | tableData.value = newList |
| | | } |
| | | } |
| | | |
| | | const setList = (list) => { |
| | | tableData.value = list || [] |
| | | } |
| | | |
| | | defineExpose({ |
| | | open, |
| | | addAttachment, |
| | | removeAttachment, |
| | | setList, |
| | | handleUpload, |
| | | handleDelete |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .file-list-toolbar { |
| | | margin-bottom: 8px; |
| | | text-align: right; |
| | | } |
| | | </style> |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | :title="computedTitle" |
| | | :width="width" |
| | | @close="handleClose" |
| | | > |
| | | <slot></slot> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleConfirm">确认</el-button> |
| | | <el-button @click="handleCancel">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed } from 'vue' |
| | | |
| | | const props = defineProps({ |
| | | modelValue: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | title: { |
| | | type: [String, Function], |
| | | default: '' |
| | | }, |
| | | operationType: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | width: { |
| | | type: String, |
| | | default: '70%' |
| | | } |
| | | }) |
| | | |
| | | const emit = defineEmits(['update:modelValue', 'close', 'confirm', 'cancel']) |
| | | |
| | | const dialogVisible = computed({ |
| | | get: () => props.modelValue, |
| | | set: (val) => emit('update:modelValue', val) |
| | | }) |
| | | |
| | | const computedTitle = computed(() => { |
| | | if (typeof props.title === 'function') { |
| | | return props.title(props.operationType) |
| | | } |
| | | return props.title |
| | | }) |
| | | |
| | | const handleClose = () => { |
| | | emit('close') |
| | | } |
| | | |
| | | const handleConfirm = () => { |
| | | emit('confirm') |
| | | } |
| | | |
| | | const handleCancel = () => { |
| | | emit('cancel') |
| | | dialogVisible.value = false |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .dialog-footer { |
| | | text-align: center; |
| | | } |
| | | </style> |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog |
| | | :title="title" |
| | | v-model="dialogVisible" |
| | | :width="width" |
| | | :append-to-body="appendToBody" |
| | | @close="handleClose" |
| | | > |
| | | <el-upload |
| | | ref="uploadRef" |
| | | :limit="limit" |
| | | :accept="accept" |
| | | :headers="headers" |
| | | :action="action" |
| | | :disabled="disabled" |
| | | :before-upload="beforeUpload" |
| | | :on-progress="onProgress" |
| | | :on-success="onSuccess" |
| | | :on-error="onError" |
| | | :on-change="onChange" |
| | | :auto-upload="autoUpload" |
| | | drag |
| | | > |
| | | <el-icon class="el-icon--upload"><UploadFilled /></el-icon> |
| | | <div class="el-upload__text">å°æä»¶æå°æ¤å¤ï¼æ<em>ç¹å»ä¸ä¼ </em></div> |
| | | <template #tip> |
| | | <div class="el-upload__tip text-center"> |
| | | <span>{{ tipText }}</span> |
| | | <el-link |
| | | v-if="showDownloadTemplate" |
| | | type="primary" |
| | | :underline="false" |
| | | style="font-size: 12px; vertical-align: baseline; margin-left: 5px;" |
| | | @click="handleDownloadTemplate" |
| | | >ä¸è½½æ¨¡æ¿</el-link |
| | | > |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleConfirm">ç¡® å®</el-button> |
| | | <el-button @click="handleCancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, ref } from 'vue' |
| | | import { UploadFilled } from '@element-plus/icons-vue' |
| | | |
| | | const props = defineProps({ |
| | | modelValue: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | title: { |
| | | type: String, |
| | | default: '导å
¥' |
| | | }, |
| | | width: { |
| | | type: String, |
| | | default: '400px' |
| | | }, |
| | | appendToBody: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | limit: { |
| | | type: Number, |
| | | default: 1 |
| | | }, |
| | | accept: { |
| | | type: String, |
| | | default: '.xlsx, .xls' |
| | | }, |
| | | headers: { |
| | | type: Object, |
| | | default: () => ({}) |
| | | }, |
| | | action: { |
| | | type: String, |
| | | required: true |
| | | }, |
| | | disabled: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | autoUpload: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | tipText: { |
| | | type: String, |
| | | default: 'ä»
å
许导å
¥xlsãxlsxæ ¼å¼æä»¶ã' |
| | | }, |
| | | showDownloadTemplate: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | beforeUpload: { |
| | | type: Function, |
| | | default: null |
| | | }, |
| | | onProgress: { |
| | | type: Function, |
| | | default: null |
| | | }, |
| | | onSuccess: { |
| | | type: Function, |
| | | default: null |
| | | }, |
| | | onError: { |
| | | type: Function, |
| | | default: null |
| | | }, |
| | | onChange: { |
| | | type: Function, |
| | | default: null |
| | | } |
| | | }) |
| | | |
| | | const emit = defineEmits(['update:modelValue', 'close', 'confirm', 'cancel', 'download-template']) |
| | | |
| | | const dialogVisible = computed({ |
| | | get: () => props.modelValue, |
| | | set: (val) => emit('update:modelValue', val) |
| | | }) |
| | | |
| | | const uploadRef = ref(null) |
| | | |
| | | const handleClose = () => { |
| | | emit('close') |
| | | } |
| | | |
| | | const handleConfirm = () => { |
| | | emit('confirm') |
| | | } |
| | | |
| | | const submit = () => { |
| | | if (uploadRef.value) { |
| | | uploadRef.value.submit() |
| | | } |
| | | } |
| | | |
| | | const handleCancel = () => { |
| | | emit('cancel') |
| | | dialogVisible.value = false |
| | | } |
| | | |
| | | const handleDownloadTemplate = () => { |
| | | emit('download-template') |
| | | } |
| | | |
| | | defineExpose({ |
| | | uploadRef, |
| | | submit, |
| | | clearFiles: () => { |
| | | if (uploadRef.value) { |
| | | uploadRef.value.clearFiles() |
| | | } |
| | | } |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .dialog-footer { |
| | | text-align: center; |
| | | } |
| | | </style> |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="dynamic-table-container"> |
| | | <el-table |
| | | ref="tableRef" |
| | | v-loading="loading" |
| | | :data="tableData" |
| | | :border="border" |
| | | :height="height" |
| | | :header-cell-style="{ background: '#F0F1F5', color: '#333333' }" |
| | | style="width: 100%" |
| | | @selection-change="handleSelectionChange" |
| | | @row-click="handleRowClick" |
| | | > |
| | | <!-- éæ©å --> |
| | | <el-table-column |
| | | v-if="showSelection" |
| | | align="center" |
| | | type="selection" |
| | | width="55" |
| | | /> |
| | | |
| | | <!-- åºå·å --> |
| | | <el-table-column |
| | | v-if="showIndex" |
| | | align="center" |
| | | label="åºå·" |
| | | type="index" |
| | | width="60" |
| | | /> |
| | | |
| | | <!-- åºå®åï¼é¨é¨ --> |
| | | <el-table-column |
| | | label="é¨é¨" |
| | | prop="department" |
| | | width="120" |
| | | show-overflow-tooltip |
| | | align="center" |
| | | /> |
| | | |
| | | <!-- åºå®åï¼å§å --> |
| | | <el-table-column |
| | | label="å§å" |
| | | prop="name" |
| | | width="100" |
| | | show-overflow-tooltip |
| | | align="center" |
| | | /> |
| | | |
| | | <!-- åºå®åï¼å·¥å· --> |
| | | <el-table-column |
| | | label="å·¥å·" |
| | | prop="employeeId" |
| | | width="100" |
| | | show-overflow-tooltip |
| | | align="center" |
| | | /> |
| | | |
| | | <!-- 卿åï¼æ ¹æ®åå
¸æ¸²æ --> |
| | | <el-table-column |
| | | v-for="(dictItem, index) in dynamicColumns" |
| | | :key="dictItem.value" |
| | | :label="dictItem.label" |
| | | :prop="dictItem.value" |
| | | :width="dictItem.width || 120" |
| | | show-overflow-tooltip |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | <!-- æ ¹æ®åå
¸ç±»å渲æä¸åçæ¾ç¤ºæ¹å¼ --> |
| | | <template v-if="dictItem.renderType === 'tag'"> |
| | | <el-tag |
| | | :type="getTagType(scope.row[dictItem.value])" |
| | | size="small" |
| | | > |
| | | {{ getDictValueLabel(dictItem.dictType, scope.row[dictItem.value]) }} |
| | | </el-tag> |
| | | </template> |
| | | <template v-else-if="dictItem.renderType === 'select'"> |
| | | <el-select |
| | | v-model="scope.row[dictItem.value]" |
| | | placeholder="è¯·éæ©" |
| | | size="small" |
| | | @change="handleSelectChange(scope.row, dictItem.value, $event)" |
| | | > |
| | | <el-option |
| | | v-for="option in dictItem.options" |
| | | :key="option.value" |
| | | :label="option.label" |
| | | :value="option.value" |
| | | /> |
| | | </el-select> |
| | | </template> |
| | | <template v-else-if="dictItem.renderType === 'input'"> |
| | | <el-input |
| | | v-model="scope.row[dictItem.value]" |
| | | size="small" |
| | | placeholder="请è¾å
¥" |
| | | @blur="handleInputChange(scope.row, dictItem.value, $event)" |
| | | /> |
| | | </template> |
| | | <template v-else> |
| | | <span>{{ getDictValueLabel(dictItem.dictType, scope.row[dictItem.value]) }}</span> |
| | | </template> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <!-- æä½å --> |
| | | <el-table-column |
| | | v-if="showActions" |
| | | label="æä½" |
| | | width="150" |
| | | align="center" |
| | | fixed="right" |
| | | > |
| | | <template #default="scope"> |
| | | <el-button |
| | | type="primary" |
| | | link |
| | | size="small" |
| | | @click="handleEdit(scope.row, scope.$index)" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | link |
| | | size="small" |
| | | @click="handleDelete(scope.row, scope.$index)" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- å页ç»ä»¶ --> |
| | | <div v-if="showPagination" class="pagination-container"> |
| | | <el-pagination |
| | | v-model:current-page="pagination.current" |
| | | v-model:page-size="pagination.size" |
| | | :page-sizes="[10, 20, 50, 100]" |
| | | :total="pagination.total" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, onMounted, watch } from 'vue' |
| | | import { useDict } from '@/utils/dict' |
| | | |
| | | // å®ä¹ç»ä»¶å±æ§ |
| | | const props = defineProps({ |
| | | // è¡¨æ ¼æ°æ® |
| | | data: { |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | // åå
¸ç±»åæ°ç»ï¼ç¨äºå¨æçæå |
| | | dictTypes: { |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | // æ¯å¦æ¾ç¤ºéæ©å |
| | | showSelection: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // æ¯å¦æ¾ç¤ºåºå·å |
| | | showIndex: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // æ¯å¦æ¾ç¤ºæä½å |
| | | showActions: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // æ¯å¦æ¾ç¤ºå页 |
| | | showPagination: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // è¡¨æ ¼é«åº¦ |
| | | height: { |
| | | type: [String, Number], |
| | | default: 'auto' |
| | | }, |
| | | // æ¯å¦æ¾ç¤ºè¾¹æ¡ |
| | | border: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // å è½½ç¶æ |
| | | loading: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // å页é
ç½® |
| | | pagination: { |
| | | type: Object, |
| | | default: () => ({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0 |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | // å®ä¹äºä»¶ |
| | | const emit = defineEmits([ |
| | | 'selection-change', |
| | | 'row-click', |
| | | 'edit', |
| | | 'delete', |
| | | 'select-change', |
| | | 'input-change', |
| | | 'size-change', |
| | | 'current-change' |
| | | ]) |
| | | |
| | | // ååºå¼æ°æ® |
| | | const tableRef = ref(null) |
| | | const tableData = ref([]) |
| | | |
| | | // è·ååå
¸æ°æ® |
| | | const dictData = ref({}) |
| | | |
| | | // 卿åé
ç½® |
| | | const dynamicColumns = computed(() => { |
| | | const columns = [] |
| | | |
| | | props.dictTypes.forEach(dictType => { |
| | | const dictItems = dictData.value[dictType] || [] |
| | | // 为æ¯ä¸ªåå
¸ç±»åå建ä¸ä¸ªåï¼è䏿¯ä¸ºæ¯ä¸ªåå
¸é¡¹å建å |
| | | if (dictItems.length > 0) { |
| | | columns.push({ |
| | | label: getDictLabel(dictType), // è·ååå
¸ç±»åçæ¾ç¤ºåç§° |
| | | value: dictType, // 使ç¨åå
¸ç±»åä½ä¸ºå段å |
| | | width: 120, |
| | | renderType: 'tag', // é»è®¤ä½¿ç¨æ ç¾æ¾ç¤º |
| | | options: dictItems, // æä¾é项 |
| | | dictType: dictType |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | return columns |
| | | }) |
| | | |
| | | // è·ååå
¸ç±»åçæ¾ç¤ºåç§° |
| | | const getDictLabel = (dictType) => { |
| | | const labelMap = { |
| | | 'sys_normal_disable': 'ç¶æ', |
| | | 'sys_user_level': '级å«', |
| | | 'sys_user_position': 'èä½', |
| | | 'sys_yes_no': 'æ¯å¦', |
| | | 'sys_user_sex': 'æ§å«', |
| | | 'sys_lavor_issue': 'å³å¡é®é¢' // æ·»å å³å¡é®é¢åå
¸ |
| | | } |
| | | return labelMap[dictType] || dictType |
| | | } |
| | | |
| | | // è·ååå
¸æ°æ® |
| | | const loadDictData = async () => { |
| | | try { |
| | | const dictPromises = props.dictTypes.map(async (dictType) => { |
| | | const { getDicts } = await import('@/api/system/dict/data') |
| | | const response = await getDicts(dictType) |
| | | return { |
| | | type: dictType, |
| | | data: response.data.map(item => ({ |
| | | label: item.dictLabel, |
| | | value: item.dictValue, |
| | | elTagType: item.listClass, |
| | | elTagClass: item.cssClass |
| | | })) |
| | | } |
| | | }) |
| | | |
| | | const results = await Promise.all(dictPromises) |
| | | results.forEach(result => { |
| | | dictData.value[result.type] = result.data |
| | | }) |
| | | } catch (error) { |
| | | console.error('å è½½åå
¸æ°æ®å¤±è´¥:', error) |
| | | // 妿åå
¸å 载失败ï¼ä½¿ç¨é»è®¤æ°æ® |
| | | props.dictTypes.forEach(dictType => { |
| | | if (!dictData.value[dictType]) { |
| | | dictData.value[dictType] = [] |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | // è·åæ ç¾ç±»å |
| | | const getTagType = (value) => { |
| | | // æ ¹æ®å¼è¿åä¸åçæ ç¾ç±»å |
| | | if (value === '1' || value === 'true' || value === 'æ¯') return 'success' |
| | | if (value === '0' || value === 'false' || value === 'å¦') return 'danger' |
| | | if (value === '2' || value === 'warning') return 'warning' |
| | | return 'info' |
| | | } |
| | | |
| | | // è·ååå
¸å¼çæ ç¾ |
| | | const getDictValueLabel = (dictType, value) => { |
| | | if (!value) return '-' |
| | | const dictItems = dictData.value[dictType] || [] |
| | | const item = dictItems.find(item => item.value === value) |
| | | return item ? item.label : value |
| | | } |
| | | |
| | | // äºä»¶å¤ç彿° |
| | | const handleSelectionChange = (selection) => { |
| | | emit('selection-change', selection) |
| | | } |
| | | |
| | | const handleRowClick = (row, column, event) => { |
| | | emit('row-click', row, column, event) |
| | | } |
| | | |
| | | const handleEdit = (row, index) => { |
| | | emit('edit', row, index) |
| | | } |
| | | |
| | | const handleDelete = (row, index) => { |
| | | emit('delete', row, index) |
| | | } |
| | | |
| | | const handleSelectChange = (row, prop, value) => { |
| | | emit('select-change', row, prop, value) |
| | | } |
| | | |
| | | const handleInputChange = (row, prop, event) => { |
| | | emit('input-change', row, prop, event.target.value) |
| | | } |
| | | |
| | | const handleSizeChange = (size) => { |
| | | emit('size-change', size) |
| | | } |
| | | |
| | | const handleCurrentChange = (current) => { |
| | | emit('current-change', current) |
| | | } |
| | | |
| | | // ç嬿°æ®åå |
| | | watch(() => props.data, (newData) => { |
| | | tableData.value = newData |
| | | }, { immediate: true }) |
| | | |
| | | // çå¬åå
¸ç±»ååå |
| | | watch(() => props.dictTypes, () => { |
| | | loadDictData() |
| | | }, { immediate: true }) |
| | | |
| | | // ç»ä»¶æè½½æ¶å è½½åå
¸æ°æ® |
| | | onMounted(() => { |
| | | loadDictData() |
| | | }) |
| | | |
| | | // æ´é²æ¹æ³ç»ç¶ç»ä»¶ |
| | | defineExpose({ |
| | | tableRef, |
| | | getSelection: () => tableRef.value?.getSelectionRows() || [], |
| | | clearSelection: () => tableRef.value?.clearSelection(), |
| | | toggleRowSelection: (row, selected) => tableRef.value?.toggleRowSelection(row, selected), |
| | | setCurrentRow: (row) => tableRef.value?.setCurrentRow(row) |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .dynamic-table-container { |
| | | width: 100%; |
| | | } |
| | | |
| | | .pagination-container { |
| | | margin-top: 20px; |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | } |
| | | |
| | | :deep(.el-table .el-table__header-wrapper th) { |
| | | background-color: #F0F1F5 !important; |
| | | color: #333333; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | :deep(.el-table .el-table__body-wrapper td) { |
| | | padding: 8px 0; |
| | | } |
| | | |
| | | :deep(.el-select) { |
| | | width: 100%; |
| | | } |
| | | |
| | | :deep(.el-input) { |
| | | width: 100%; |
| | | } |
| | | </style> |
| | |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | visualMap: { |
| | | type: Object, |
| | | default: () => ({}) |
| | | }, |
| | | option: { |
| | | type: Object, |
| | | default: () => ({}) |
| | |
| | | const option = { |
| | | color: props.color.length ? props.color : undefined, |
| | | backgroundColor: props.options.backgroundColor || '#fff', |
| | | textStyle: props.options.textStyle || { color: '#333' }, |
| | | xAxis: props.xAxis, |
| | | yAxis: props.yAxis, |
| | | dataset: props.dataset, |
| | |
| | | grid: props.grid, |
| | | legend: props.legend, |
| | | tooltip: props.tooltip, |
| | | visualMap: Object.keys(props.visualMap).length ? props.visualMap : undefined, |
| | | } |
| | | |
| | | chartInstance.clear() |
| | |
| | | |
| | | // Watch all reactive props that affect the chart |
| | | watch( |
| | | () => [props.xAxis, props.series, props.legend, props.tooltip], |
| | | () => [props.xAxis, props.yAxis, props.series, props.legend, props.tooltip, props.visualMap], |
| | | () => { |
| | | if (chartInstance) { |
| | | renderChart() |
| | |
| | | :row-class-name="rowClassName" |
| | | :row-style="rowStyle" |
| | | :row-key="rowKey" |
| | | style="width: 100%" |
| | | :style="tableStyle" |
| | | tooltip-effect="dark" |
| | | :expand-row-keys="expandRowKeys" |
| | | :show-summary="isShowSummary" |
| | |
| | | :fixed="item.fixed" |
| | | :label="item.label" |
| | | :prop="item.prop" |
| | | show-overflow-tooltip |
| | | :show-overflow-tooltip="item.dataType !== 'action' && item.dataType !== 'slot'" |
| | | :align="item.align" |
| | | :sortable="!!item.sortable" |
| | | :type="item.type" |
| | | :width="item.width" |
| | | > |
| | | <template #header="scope"> |
| | | <div class="pim-table-header-cell"> |
| | | <div class="pim-table-header-title"> |
| | | {{ item.label }} |
| | | </div> |
| | | <div v-if="item.headerSlot" class="pim-table-header-extra"> |
| | | <slot :name="item.headerSlot" :column="scope.column" /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <template |
| | | v-if="item.hasOwnProperty('colunmTemplate')" |
| | | #[item.colunmTemplate]="scope" |
| | |
| | | </div> |
| | | |
| | | <!-- æé® --> |
| | | <div v-else-if="item.dataType == 'action'"> |
| | | <div v-else-if="item.dataType == 'action'" @click.stop> |
| | | <template v-for="(o, key) in item.operation" :key="key"> |
| | | <el-button |
| | | v-show="o.type != 'upload'" |
| | | size="small" |
| | | v-if="o.showHide ? o.showHide(scope.row) : true" |
| | | :disabled="o.disabled ? o.disabled(scope.row) : false" |
| | | :plain="o.plain" |
| | |
| | | : o.color, |
| | | }" |
| | | link |
| | | @click="o.clickFun(scope.row)" |
| | | @click.stop="o.clickFun(scope.row)" |
| | | :key="key" |
| | | > |
| | | {{ o.name }} |
| | |
| | | (o.uploadIdFun ? o.uploadIdFun(scope.row) : scope.row.id) |
| | | " |
| | | ref="uploadRef" |
| | | size="small" |
| | | :multiple="o.multiple ? o.multiple : false" |
| | | :limit="1" |
| | | :disabled="o.disabled ? o.disabled(scope.row) : false" |
| | |
| | | :show-file-list="false" |
| | | > |
| | | <el-button |
| | | :size="o.size ? o.size : 'small'" |
| | | link |
| | | type="primary" |
| | | :disabled="o.disabled ? o.disabled(scope.row) : false" |
| | |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | v-if="page.total > 0" |
| | | v-if="isShowPagination" |
| | | :total="page.total" |
| | | :layout="page.layout" |
| | | :page="page.current" |
| | |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | isShowPagination: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | isShowSummary: { |
| | | type: Boolean, |
| | | default: false, |
| | |
| | | total: { |
| | | type: Number, |
| | | default: 0, |
| | | }, |
| | | tableStyle: { |
| | | type: [String, Object], |
| | | default: () => ({ width: "100%" }), |
| | | }, |
| | | }); |
| | | |
| | |
| | | padding-right: 0 !important; |
| | | padding-left: 0 !important; |
| | | } |
| | | |
| | | .pim-table-header-extra :deep(.el-input), |
| | | .pim-table-header-extra :deep(.el-select) { |
| | | width: 100%; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="page-header-wrapper"> |
| | | <el-page-header @back="handleBack" :content="content"> |
| | | <template #icon v-if="$slots.icon"> |
| | | <slot name="icon"></slot> |
| | | </template> |
| | | <template #title v-if="$slots.title"> |
| | | <slot name="title"></slot> |
| | | </template> |
| | | <template #content v-if="$slots.content"> |
| | | <slot name="content"></slot> |
| | | </template> |
| | | <template #extra> |
| | | <slot name="extra"> |
| | | <slot name="right-button"></slot> |
| | | </slot> |
| | | </template> |
| | | </el-page-header> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { useRouter } from 'vue-router' |
| | | |
| | | const props = defineProps({ |
| | | content: { |
| | | type: String, |
| | | default: '' |
| | | } |
| | | }) |
| | | |
| | | const emit = defineEmits(['back']) |
| | | |
| | | const router = useRouter() |
| | | |
| | | const handleBack = () => { |
| | | emit('back') |
| | | // é»è®¤è¿åå°ä¸ä¸çº§ |
| | | router.back() |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .page-header-wrapper { |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .page-header-wrapper :deep(.el-page-header__extra) { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="qr-code-generator"> |
| | | <!-- äºç»´ç çæè¡¨å --> |
| | | <el-form :model="form" |
| | | :rules="rules" |
| | | ref="formRef" |
| | | label-width="120px" |
| | | class="qr-form"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ è¯ç±»å" |
| | | prop="type"> |
| | | <el-select v-model="form.type" |
| | | placeholder="è¯·éæ©æ è¯ç±»å" |
| | | style="width: 100%"> |
| | | <el-option label="äºç»´ç " |
| | | value="qrcode"></el-option> |
| | | <el-option label="é²ä¼ªç " |
| | | value="security"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
容" |
| | | prop="content"> |
| | | <el-input v-model="form.content" |
| | | placeholder="请è¾å
¥è¦ç¼ç çå
容" |
| | | :type="form.type === 'security' ? 'textarea' : 'text'" |
| | | :rows="form.type === 'security' ? 3 : 1"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="尺寸" |
| | | prop="size"> |
| | | <el-input-number v-model="form.size" |
| | | :min="100" |
| | | :max="500" |
| | | :step="50" |
| | | style="width: 100%"></el-input-number> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è¾¹è·" |
| | | prop="margin"> |
| | | <el-input-number v-model="form.margin" |
| | | :min="0" |
| | | :max="10" |
| | | :step="1" |
| | | style="width: 100%"></el-input-number> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="忝è²" |
| | | prop="foregroundColor"> |
| | | <el-color-picker v-model="form.foregroundColor" |
| | | style="width: 100%"></el-color-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èæ¯è²" |
| | | prop="backgroundColor"> |
| | | <el-color-picker v-model="form.backgroundColor" |
| | | style="width: 100%"></el-color-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="24"> |
| | | <el-form-item> |
| | | <el-button type="primary" |
| | | @click="generateCode" |
| | | :loading="generating"> |
| | | çæ{{ form.type === 'qrcode' ? 'äºç»´ç ' : 'é²ä¼ªç ' }} |
| | | </el-button> |
| | | <el-button @click="resetForm">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <!-- çæçç æ¾ç¤ºåºå --> |
| | | <div v-if="generatedCodeUrl" |
| | | class="code-display"> |
| | | <el-divider content-position="center"> |
| | | {{ form.type === 'qrcode' ? 'çæçäºç»´ç ' : 'çæçé²ä¼ªç ' }} |
| | | </el-divider> |
| | | <div class="code-container"> |
| | | <div class="code-image"> |
| | | <img :src="generatedCodeUrl" |
| | | :alt="form.type === 'qrcode' ? 'äºç»´ç ' : 'é²ä¼ªç '" /> |
| | | </div> |
| | | <div class="code-info"> |
| | | <p><strong>å
容ï¼</strong>{{ form.content }}</p> |
| | | <p><strong>ç±»åï¼</strong>{{ form.type === 'qrcode' ? 'äºç»´ç ' : 'é²ä¼ªç ' }}</p> |
| | | <p><strong>尺寸ï¼</strong>{{ form.size }}x{{ form.size }}px</p> |
| | | <p><strong>çææ¶é´ï¼</strong>{{ generateTime }}</p> |
| | | </div> |
| | | </div> |
| | | <div class="code-actions"> |
| | | <el-button type="success" |
| | | @click="downloadCode" |
| | | icon="Download"> |
| | | ä¸è½½å¾ç |
| | | </el-button> |
| | | <el-button type="primary" |
| | | @click="copyToClipboard" |
| | | icon="CopyDocument"> |
| | | å¤å¶å
容 |
| | | </el-button> |
| | | <el-button @click="printCode" |
| | | icon="Printer"> |
| | | æå° |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | <!-- æ¹éçæå¯¹è¯æ¡ --> |
| | | <el-dialog v-model="batchDialogVisible" |
| | | title="æ¹éçæ" |
| | | width="600px"> |
| | | <el-form :model="batchForm" |
| | | label-width="120px"> |
| | | <el-form-item label="çææ°é"> |
| | | <el-input-number v-model="batchForm.quantity" |
| | | :min="1" |
| | | :max="100" |
| | | style="width: 100%"></el-input-number> |
| | | </el-form-item> |
| | | <el-form-item label="åç¼"> |
| | | <el-input v-model="batchForm.prefix" |
| | | placeholder="请è¾å
¥åç¼ï¼å¦ï¼PROD_"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="èµ·å§ç¼å·"> |
| | | <el-input-number v-model="batchForm.startNumber" |
| | | :min="1" |
| | | style="width: 100%"></el-input-number> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" |
| | | @click="generateBatchCodes">å¼å§çæ</el-button> |
| | | <el-button @click="batchDialogVisible = false">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- æ¹éçæç»æ --> |
| | | <div v-if="batchCodes.length > 0" |
| | | class="batch-results"> |
| | | <el-divider content-position="center">æ¹éçæç»æ</el-divider> |
| | | <div class="batch-grid"> |
| | | <div v-for="(code, index) in batchCodes" |
| | | :key="index" |
| | | class="batch-item"> |
| | | <img :src="code.url" |
| | | :alt="code.content" /> |
| | | <p class="batch-content">{{ code.content }}</p> |
| | | <el-button size="small" |
| | | @click="downloadSingleCode(code)">ä¸è½½</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="batch-actions"> |
| | | <el-button type="success" |
| | | @click="downloadAllCodes">ä¸è½½å
¨é¨</el-button> |
| | | <el-button @click="clearBatchCodes">æ¸
ç©ºç»æ</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, computed, onMounted } from "vue"; |
| | | import QRCode from "qrcode"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import { Download, CopyDocument, Printer } from "@element-plus/icons-vue"; |
| | | |
| | | // å®ä¹ç»ä»¶åç§° |
| | | defineOptions({ |
| | | name: "QRCodeGenerator", |
| | | }); |
| | | |
| | | // è¡¨åæ°æ® |
| | | const form = reactive({ |
| | | type: "qrcode", |
| | | content: "", |
| | | size: 200, |
| | | margin: 2, |
| | | foregroundColor: "#000000", |
| | | backgroundColor: "#FFFFFF", |
| | | }); |
| | | |
| | | // 表åéªè¯è§å |
| | | const rules = { |
| | | type: [{ required: true, message: "è¯·éæ©æ è¯ç±»å", trigger: "change" }], |
| | | content: [{ required: true, message: "请è¾å
¥å
容", trigger: "blur" }], |
| | | }; |
| | | |
| | | // ååºå¼æ°æ® |
| | | const formRef = ref(); |
| | | const generating = ref(false); |
| | | const generatedCodeUrl = ref(""); |
| | | const generateTime = ref(""); |
| | | const batchDialogVisible = ref(false); |
| | | const batchForm = reactive({ |
| | | quantity: 10, |
| | | prefix: "", |
| | | startNumber: 1, |
| | | }); |
| | | const batchCodes = ref([]); |
| | | |
| | | // çæäºç»´ç æé²ä¼ªç |
| | | const generateCode = async () => { |
| | | try { |
| | | await formRef.value.validate(); |
| | | |
| | | if (!form.content.trim()) { |
| | | ElMessage.warning("请è¾å
¥è¦ç¼ç çå
容"); |
| | | return; |
| | | } |
| | | |
| | | generating.value = true; |
| | | |
| | | if (form.type === "qrcode") { |
| | | // çæäºç»´ç |
| | | generatedCodeUrl.value = await QRCode.toDataURL(form.content, { |
| | | width: form.size, |
| | | margin: form.margin, |
| | | color: { |
| | | dark: form.foregroundColor, |
| | | light: form.backgroundColor, |
| | | }, |
| | | errorCorrectionLevel: "M", |
| | | }); |
| | | } else { |
| | | // çæé²ä¼ªç ï¼ä½¿ç¨äºç»´ç ææ¯ï¼ä½å
å®¹æ ¼å¼ä¸åï¼ |
| | | const securityContent = generateSecurityCode(form.content); |
| | | generatedCodeUrl.value = await QRCode.toDataURL(securityContent, { |
| | | width: form.size, |
| | | margin: form.margin, |
| | | color: { |
| | | dark: form.foregroundColor, |
| | | light: form.backgroundColor, |
| | | }, |
| | | errorCorrectionLevel: "H", // é²ä¼ªç ä½¿ç¨æé«çº éçº§å« |
| | | }); |
| | | } |
| | | |
| | | generateTime.value = new Date().toLocaleString(); |
| | | ElMessage.success("çææåï¼"); |
| | | } catch (error) { |
| | | console.error("çæå¤±è´¥:", error); |
| | | ElMessage.error("çæå¤±è´¥ï¼" + error.message); |
| | | } finally { |
| | | generating.value = false; |
| | | } |
| | | }; |
| | | |
| | | // çæé²ä¼ªç å
容 |
| | | const generateSecurityCode = content => { |
| | | const timestamp = Date.now(); |
| | | const random = Math.random().toString(36).substr(2, 8); |
| | | return `SEC_${content}_${timestamp}_${random}`; |
| | | }; |
| | | |
| | | // ä¸è½½çæçç |
| | | const downloadCode = () => { |
| | | if (!generatedCodeUrl.value) { |
| | | ElMessage.warning("请å
çæç "); |
| | | return; |
| | | } |
| | | |
| | | const a = document.createElement("a"); |
| | | a.href = generatedCodeUrl.value; |
| | | a.download = `${ |
| | | form.type === "qrcode" ? "äºç»´ç " : "é²ä¼ªç " |
| | | }_${new Date().getTime()}.png`; |
| | | document.body.appendChild(a); |
| | | a.click(); |
| | | document.body.removeChild(a); |
| | | ElMessage.success("ä¸è½½æåï¼"); |
| | | }; |
| | | |
| | | // å¤å¶å
容å°åªè´´æ¿ |
| | | const copyToClipboard = async () => { |
| | | try { |
| | | await navigator.clipboard.writeText(form.content); |
| | | ElMessage.success("å
容已å¤å¶å°åªè´´æ¿"); |
| | | } catch (error) { |
| | | // éçº§æ¹æ¡ |
| | | const textArea = document.createElement("textarea"); |
| | | textArea.value = form.content; |
| | | document.body.appendChild(textArea); |
| | | textArea.select(); |
| | | document.execCommand("copy"); |
| | | document.body.removeChild(textArea); |
| | | ElMessage.success("å
容已å¤å¶å°åªè´´æ¿"); |
| | | } |
| | | }; |
| | | |
| | | // æå°ç |
| | | const printCode = () => { |
| | | if (!generatedCodeUrl.value) { |
| | | ElMessage.warning("请å
çæç "); |
| | | return; |
| | | } |
| | | |
| | | const printWindow = window.open("", "_blank"); |
| | | printWindow.document.write(` |
| | | <html> |
| | | <head> |
| | | <title>æå°${form.type === "qrcode" ? "äºç»´ç " : "é²ä¼ªç "}</title> |
| | | <style> |
| | | body { text-align: center; padding: 20px; } |
| | | img { max-width: 100%; height: auto; } |
| | | .info { margin: 20px 0; } |
| | | </style> |
| | | </head> |
| | | <body> |
| | | <h2>${form.type === "qrcode" ? "äºç»´ç " : "é²ä¼ªç "}</h2> |
| | | <img src="${generatedCodeUrl.value}" alt="${ |
| | | form.type === "qrcode" ? "äºç»´ç " : "é²ä¼ªç " |
| | | }" /> |
| | | <div class="info"> |
| | | <p><strong>å
容ï¼</strong>${form.content}</p> |
| | | <p><strong>çææ¶é´ï¼</strong>${generateTime.value}</p> |
| | | </div> |
| | | </body> |
| | | </html> |
| | | `); |
| | | printWindow.document.close(); |
| | | printWindow.print(); |
| | | }; |
| | | |
| | | // é置表å |
| | | const resetForm = () => { |
| | | formRef.value.resetFields(); |
| | | generatedCodeUrl.value = ""; |
| | | generateTime.value = ""; |
| | | batchCodes.value = []; |
| | | }; |
| | | |
| | | // æ¹éçæ |
| | | const generateBatchCodes = async () => { |
| | | if (!batchForm.prefix.trim()) { |
| | | ElMessage.warning("请è¾å
¥åç¼"); |
| | | return; |
| | | } |
| | | |
| | | batchCodes.value = []; |
| | | generating.value = true; |
| | | |
| | | try { |
| | | for (let i = 0; i < batchForm.quantity; i++) { |
| | | const number = batchForm.startNumber + i; |
| | | const content = `${batchForm.prefix}${number |
| | | .toString() |
| | | .padStart(6, "0")}`; |
| | | |
| | | let codeUrl; |
| | | if (form.type === "qrcode") { |
| | | codeUrl = await QRCode.toDataURL(content, { |
| | | width: form.size, |
| | | margin: form.margin, |
| | | color: { |
| | | dark: form.foregroundColor, |
| | | light: form.backgroundColor, |
| | | }, |
| | | }); |
| | | } else { |
| | | const securityContent = generateSecurityCode(content); |
| | | codeUrl = await QRCode.toDataURL(securityContent, { |
| | | width: form.size, |
| | | margin: form.margin, |
| | | color: { |
| | | dark: form.foregroundColor, |
| | | light: form.backgroundColor, |
| | | }, |
| | | }); |
| | | } |
| | | |
| | | batchCodes.value.push({ |
| | | content, |
| | | url: codeUrl, |
| | | }); |
| | | } |
| | | |
| | | ElMessage.success(`æ¹éçæå®æï¼å
±çæ ${batchForm.quantity} 个ç `); |
| | | batchDialogVisible.value = false; |
| | | } catch (error) { |
| | | console.error("æ¹éçæå¤±è´¥:", error); |
| | | ElMessage.error("æ¹éçæå¤±è´¥ï¼" + error.message); |
| | | } finally { |
| | | generating.value = false; |
| | | } |
| | | }; |
| | | |
| | | // ä¸è½½å个æ¹éçæçç |
| | | const downloadSingleCode = code => { |
| | | const a = document.createElement("a"); |
| | | a.href = code.url; |
| | | a.download = `${code.content}.png`; |
| | | document.body.appendChild(a); |
| | | a.click(); |
| | | document.body.removeChild(a); |
| | | }; |
| | | |
| | | // ä¸è½½æææ¹éçæçç |
| | | const downloadAllCodes = async () => { |
| | | if (batchCodes.value.length === 0) { |
| | | ElMessage.warning("没æå¯ä¸è½½çç "); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | // 使ç¨JSZipæå
ä¸è½½ |
| | | const JSZip = await import("jszip"); |
| | | const zip = new JSZip.default(); |
| | | |
| | | batchCodes.value.forEach((code, index) => { |
| | | // å°base64转æ¢ä¸ºblob |
| | | const base64Data = code.url.split(",")[1]; |
| | | const byteCharacters = atob(base64Data); |
| | | const byteNumbers = new Array(byteCharacters.length); |
| | | for (let i = 0; i < byteCharacters.length; i++) { |
| | | byteNumbers[i] = byteCharacters.charCodeAt(i); |
| | | } |
| | | const byteArray = new Uint8Array(byteNumbers); |
| | | |
| | | zip.file(`${code.content}.png`, byteArray); |
| | | }); |
| | | |
| | | const content = await zip.generateAsync({ type: "blob" }); |
| | | const a = document.createElement("a"); |
| | | a.href = URL.createObjectURL(content); |
| | | a.download = `æ¹é${ |
| | | form.type === "qrcode" ? "äºç»´ç " : "é²ä¼ªç " |
| | | }_${new Date().getTime()}.zip`; |
| | | document.body.appendChild(a); |
| | | a.click(); |
| | | document.body.removeChild(a); |
| | | URL.revokeObjectURL(a.href); |
| | | |
| | | ElMessage.success("æ¹éä¸è½½å®æï¼"); |
| | | } catch (error) { |
| | | console.error("æ¹éä¸è½½å¤±è´¥:", error); |
| | | ElMessage.error("æ¹éä¸è½½å¤±è´¥ï¼è¯·é个ä¸è½½"); |
| | | } |
| | | }; |
| | | |
| | | // æ¸
空æ¹éçæç»æ |
| | | const clearBatchCodes = () => { |
| | | batchCodes.value = []; |
| | | }; |
| | | |
| | | // æ´é²æ¹æ³ç»ç¶ç»ä»¶ |
| | | defineExpose({ |
| | | generateCode, |
| | | downloadCode, |
| | | resetForm, |
| | | form, |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .qr-code-generator { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .qr-form { |
| | | background: #f8f9fa; |
| | | padding: 20px; |
| | | border-radius: 8px; |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .code-display { |
| | | margin-top: 30px; |
| | | } |
| | | |
| | | .code-container { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: flex-start; |
| | | gap: 40px; |
| | | margin: 20px 0; |
| | | } |
| | | |
| | | .code-image img { |
| | | border: 2px solid #e0e0e0; |
| | | border-radius: 8px; |
| | | box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .code-info { |
| | | text-align: left; |
| | | min-width: 200px; |
| | | } |
| | | |
| | | .code-info p { |
| | | margin: 8px 0; |
| | | color: #666; |
| | | } |
| | | |
| | | .code-actions { |
| | | text-align: center; |
| | | margin: 20px 0; |
| | | } |
| | | |
| | | .code-actions .el-button { |
| | | margin: 0 10px; |
| | | } |
| | | |
| | | .batch-results { |
| | | margin-top: 30px; |
| | | } |
| | | |
| | | .batch-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); |
| | | gap: 20px; |
| | | margin: 20px 0; |
| | | } |
| | | |
| | | .batch-item { |
| | | text-align: center; |
| | | padding: 15px; |
| | | border: 1px solid #e0e0e0; |
| | | border-radius: 8px; |
| | | background: #fff; |
| | | } |
| | | |
| | | .batch-item img { |
| | | width: 100px; |
| | | height: 100px; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .batch-content { |
| | | font-size: 12px; |
| | | color: #666; |
| | | margin: 10px 0; |
| | | word-break: break-all; |
| | | } |
| | | |
| | | .batch-actions { |
| | | text-align: center; |
| | | margin: 20px 0; |
| | | } |
| | | |
| | | .batch-actions .el-button { |
| | | margin: 0 10px; |
| | | } |
| | | |
| | | @media (max-width: 768px) { |
| | | .code-container { |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | |
| | | .batch-grid { |
| | | grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <section class="app-main">
|
| | | <router-view v-slot="{ Component, route }">
|
| | | <transition name="fade-transform" mode="out-in">
|
| | | <keep-alive :include="tagsViewStore.cachedViews">
|
| | | <component v-if="!route.meta.link" :is="Component" :key="route.path"/>
|
| | | </keep-alive>
|
| | | <div v-if="!route.meta.link" class="route-view-wrapper">
|
| | | <keep-alive :include="tagsViewStore.cachedViews">
|
| | | <component :is="Component" :key="route.path"/>
|
| | | </keep-alive>
|
| | | </div>
|
| | | <div v-else class="route-view-wrapper"></div>
|
| | | </transition>
|
| | | </router-view>
|
| | | <iframe-toggle />
|
| | |
| | | background: #F5F7FB;
|
| | | }
|
| | |
|
| | | .route-view-wrapper {
|
| | | width: 100%;
|
| | | height: 100%;
|
| | | }
|
| | |
|
| | | .fixed-header + .app-main {
|
| | | padding-top: 50px;
|
| | | }
|
| | |
| | | <breadcrumb v-if="!settingsStore.topNav" id="breadcrumb-container" class="breadcrumb-container" />
|
| | | </div>
|
| | | <!-- <top-nav v-if="settingsStore.topNav" id="topmenu-container" class="topmenu-container" />-->
|
| | | <div class="center-menu">
|
| | | <span class="label">{{ userStore.currentFactoryName }}</span>
|
| | | <el-dropdown @command="handleFactoryChange" class="right-menu-item hover-effect" trigger="click">
|
| | | <div>
|
| | | <el-icon size="20">
|
| | | <Switch />
|
| | | </el-icon>
|
| | | </div>
|
| | | <template #dropdown>
|
| | | <el-dropdown-menu>
|
| | | <el-dropdown-item v-for="item in factoryList" :key="item.deptId" :command="item">
|
| | | {{ item.deptName }}
|
| | | </el-dropdown-item>
|
| | | </el-dropdown-menu>
|
| | | </template>
|
| | | </el-dropdown>
|
| | | </div>
|
| | | <div class="right-menu">
|
| | | <!-- æ¶æ¯éç¥ -->
|
| | | <el-popover
|
| | | v-model:visible="notificationVisible"
|
| | | :width="500"
|
| | | placement="bottom-end"
|
| | | trigger="click"
|
| | | :popper-options="{ modifiers: [{ name: 'offset', options: { offset: [0, 10] } }] }"
|
| | | popper-class="notification-popover"
|
| | | >
|
| | | <template #reference>
|
| | | <div class="notification-container right-menu-item hover-effect">
|
| | | <el-badge :value="unreadCount" :hidden="unreadCount === 0" class="notification-badge">
|
| | | <el-icon :size="20" style="cursor: pointer;">
|
| | | <Bell />
|
| | | </el-icon>
|
| | | </el-badge>
|
| | | </div>
|
| | | </template>
|
| | | <NotificationCenter
|
| | | @unreadCountChange="handleUnreadCountChange"
|
| | | ref="notificationCenterRef"
|
| | | />
|
| | | </el-popover>
|
| | | <div class="avatar-container">
|
| | | <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
|
| | | <div class="avatar-wrapper">
|
| | |
| | |
|
| | | <script setup>
|
| | | import { ElMessageBox } from 'element-plus'
|
| | | import { Bell } from '@element-plus/icons-vue'
|
| | | import Breadcrumb from '@/components/Breadcrumb'
|
| | | import TopNav from '@/components/TopNav'
|
| | | import Hamburger from '@/components/Hamburger'
|
| | |
| | | import HeaderSearch from '@/components/HeaderSearch'
|
| | | import RuoYiGit from '@/components/RuoYi/Git'
|
| | | import RuoYiDoc from '@/components/RuoYi/Doc'
|
| | | import NotificationCenter from './NotificationCenter/index.vue'
|
| | | import useAppStore from '@/store/modules/app'
|
| | | import useUserStore from '@/store/modules/user'
|
| | | import useSettingsStore from '@/store/modules/settings'
|
| | | import { userLoginFacotryList } from "@/api/system/user.js"
|
| | | import Cookies from "js-cookie";
|
| | | import { decrypt } from "@/utils/jsencrypt"
|
| | |
|
| | | const appStore = useAppStore()
|
| | | const userStore = useUserStore()
|
| | | const settingsStore = useSettingsStore()
|
| | | const factoryList = ref([])
|
| | | const notificationVisible = ref(false)
|
| | | const notificationCenterRef = ref(null)
|
| | | const unreadCount = ref(0)
|
| | | function toggleSideBar() {
|
| | | appStore.toggleSideBar()
|
| | | }
|
| | |
| | | settingsStore.toggleTheme()
|
| | | }
|
| | |
|
| | | function getUserLoginFacotryList() {
|
| | | if (userStore.id) {
|
| | | userLoginFacotryList({ userId: userStore.id }).then(res => {
|
| | | console.log('res', res)
|
| | | factoryList.value = res.data
|
| | | })
|
| | | } else {
|
| | | factoryList.value = []
|
| | | }
|
| | | // æ¶æ¯éç¥ç¸å
³
|
| | | function handleUnreadCountChange(count) {
|
| | | unreadCount.value = count
|
| | | }
|
| | |
|
| | | function handleFactoryChange(command) {
|
| | | console.log('command', command)
|
| | | handleLogin(command.deptId);
|
| | | }
|
| | |
|
| | | function handleLogin(currentFatoryId) {
|
| | | const loginForm = {
|
| | | username: Cookies.get("username"),
|
| | | password: Cookies.get("password") === undefined ? null : decrypt(Cookies.get("password")),
|
| | | currentFatoryId: currentFatoryId
|
| | | }
|
| | | userStore.loginCheckFactory(loginForm).then(res => {
|
| | | forceReload();
|
| | | }).catch((err) => {
|
| | | console.log(err)
|
| | | // ç»ä»¶æè½½æ¶å è½½æªè¯»æ°éå宿¶å·æ°
|
| | | let unreadCountTimer = null
|
| | | onMounted(() => {
|
| | | // å»¶è¿å è½½ï¼ç¡®ä¿ç»ä»¶å·²æ¸²æ
|
| | | nextTick(() => {
|
| | | if (notificationCenterRef.value) {
|
| | | notificationCenterRef.value.loadUnreadCount()
|
| | | }
|
| | | })
|
| | | }
|
| | | function forceReload() {
|
| | | const currentUrl = window.location.origin + window.location.pathname;
|
| | | const timestamp = new Date().getTime();
|
| | | window.location.href = `${currentUrl}?reload=${timestamp}`;
|
| | | }
|
| | | // 宿¶å·æ°æªè¯»æ°éï¼æ¯30ç§ï¼
|
| | | unreadCountTimer = setInterval(() => {
|
| | | if (notificationCenterRef.value) {
|
| | | notificationCenterRef.value.loadUnreadCount()
|
| | | }
|
| | | }, 30000)
|
| | | })
|
| | |
|
| | | getUserLoginFacotryList();
|
| | | // çå¬ popover æ¾ç¤ºç¶æï¼æå¼æ¶å è½½æ¶æ¯å表
|
| | | watch(notificationVisible, (val) => {
|
| | | if (val && notificationCenterRef.value) {
|
| | | nextTick(() => {
|
| | | notificationCenterRef.value.loadMessages()
|
| | | })
|
| | | }
|
| | | })
|
| | |
|
| | | onUnmounted(() => {
|
| | | if (unreadCountTimer) {
|
| | | clearInterval(unreadCountTimer)
|
| | | }
|
| | | })
|
| | | </script>
|
| | |
|
| | | <style lang='scss' scoped>
|
| | |
| | | position: relative;
|
| | | background: var(--navbar-bg);
|
| | | box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
| | |
|
| | | .center-menu {
|
| | | line-height: 50px;
|
| | | position: absolute;
|
| | | left: 50%;
|
| | | transform: translateX(-50%);
|
| | | display: flex;
|
| | | align-items: center;
|
| | |
|
| | | .label {
|
| | | font-weight: bold;
|
| | | font-size: 18px;
|
| | | color: #333333;
|
| | | margin-right: 10px;
|
| | | }
|
| | | }
|
| | |
|
| | | .hamburger-container {
|
| | | line-height: 46px;
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | .notification-container {
|
| | | margin-right: 20px;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | cursor: pointer;
|
| | |
|
| | | .notification-badge {
|
| | | :deep(.el-badge__content) {
|
| | | border: none;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | .avatar-container {
|
| | | margin-right: 40px;
|
| | |
|
| | |
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | </style>
|
| | |
|
| | | <style lang="scss">
|
| | | .notification-popover {
|
| | | padding: 0 !important;
|
| | | |
| | | .el-popover__title {
|
| | | display: none;
|
| | | }
|
| | | |
| | | .el-popover__body {
|
| | | padding: 0 !important;
|
| | | }
|
| | | }
|
| | | .el-badge__content.is-fixed{
|
| | | top: 12px;
|
| | | }
|
| | | </style>
|
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="notification-popover-content"> |
| | | <div class="popover-header"> |
| | | <span class="popover-title">æ¶æ¯éç¥</span> |
| | | <el-button type="primary" size="small" @click="handleMarkAllAsRead" :disabled="unreadCount === 0"> |
| | | ä¸é®å·²è¯» |
| | | </el-button> |
| | | </div> |
| | | |
| | | <div class="notification-content"> |
| | | <el-tabs v-model="activeTab" @tab-change="handleTabChange"> |
| | | <el-tab-pane :label="`æªè¯»(${unreadCount})`" name="unread"> |
| | | <div v-if="unreadList.length === 0" class="empty-state"> |
| | | <el-empty description="ææ æªè¯»æ¶æ¯" /> |
| | | </div> |
| | | <div v-else class="notification-list"> |
| | | <div |
| | | v-for="item in unreadList" |
| | | :key="item.id" |
| | | class="notification-item" |
| | | > |
| | | <div class="notification-icon"> |
| | | <el-icon :size="24" color="#67C23A"> |
| | | <Bell /> |
| | | </el-icon> |
| | | </div> |
| | | <div class="notification-content-wrapper"> |
| | | <div class="notification-title">{{ item.noticeTitle }}</div> |
| | | <div class="notification-detail">{{ item.noticeContent }}</div> |
| | | <div class="notification-time">{{ item.createTime }}</div> |
| | | </div> |
| | | <div class="notification-action"> |
| | | <el-button type="primary" size="small" @click="handleConfirm(item)"> |
| | | 确认 |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-tab-pane> |
| | | <el-tab-pane label="已读" name="read"> |
| | | <div v-if="readList.length === 0" class="empty-state"> |
| | | <el-empty description="ææ å·²è¯»æ¶æ¯" /> |
| | | </div> |
| | | <div v-else class="notification-list"> |
| | | <div |
| | | v-for="item in readList" |
| | | :key="item.id" |
| | | class="notification-item read" |
| | | > |
| | | <div class="notification-icon"> |
| | | <el-icon :size="24" color="#909399"> |
| | | <Bell /> |
| | | </el-icon> |
| | | </div> |
| | | <div class="notification-content-wrapper"> |
| | | <div class="notification-title">{{ item.noticeTitle }}</div> |
| | | <div class="notification-detail">{{ item.noticeContent }}</div> |
| | | <div class="notification-time">{{ item.createTime }}</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | |
| | | <!-- å页 --> |
| | | <div class="pagination-wrapper" v-if="total > 0"> |
| | | <el-pagination |
| | | v-model:current-page="pageNum" |
| | | v-model:page-size="pageSize" |
| | | :page-sizes="[10, 20, 50, 100]" |
| | | :total="total" |
| | | layout="prev, pager, next, sizes" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handlePageChange" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { Bell } from '@element-plus/icons-vue' |
| | | import { listMessage, markAsRead, markAllAsRead, confirmMessage, getUnreadCount } from '@/api/system/message' |
| | | import { ElMessage } from 'element-plus' |
| | | import useUserStore from '@/store/modules/user' |
| | | import { useRouter } from 'vue-router' |
| | | |
| | | const userStore = useUserStore() |
| | | const router = useRouter() |
| | | const emit = defineEmits(['unreadCountChange']) |
| | | |
| | | const activeTab = ref('unread') |
| | | const unreadList = ref([]) |
| | | const readList = ref([]) |
| | | const unreadCount = ref(0) |
| | | const total = ref(0) |
| | | const pageNum = ref(1) |
| | | const pageSize = ref(10) |
| | | |
| | | // å è½½æ¶æ¯å表 |
| | | const loadMessages = async () => { |
| | | try { |
| | | const consigneeId = userStore.id |
| | | if (!consigneeId) { |
| | | console.warn('æªè·åå°å½åç»å½ç¨æ·ID') |
| | | return |
| | | } |
| | | const params = { |
| | | consigneeId: consigneeId, |
| | | current: pageNum.value, |
| | | size: pageSize.value, |
| | | status: activeTab.value === 'read' ? 1 : 0 |
| | | } |
| | | const res = await listMessage(params) |
| | | if (res.code === 200) { |
| | | if (activeTab.value === 'unread') { |
| | | unreadList.value = res.data.records || [] |
| | | } else { |
| | | readList.value = res.data.records || [] |
| | | } |
| | | total.value = res.data.total || 0 |
| | | } |
| | | } catch (error) { |
| | | console.error('å è½½æ¶æ¯å表失败:', error) |
| | | } |
| | | } |
| | | |
| | | // å è½½æªè¯»æ°é |
| | | const loadUnreadCount = async () => { |
| | | try { |
| | | const consigneeId = userStore.id |
| | | if (!consigneeId) { |
| | | console.warn('æªè·åå°å½åç»å½ç¨æ·ID') |
| | | return |
| | | } |
| | | const res = await getUnreadCount(consigneeId) |
| | | if (res.code === 200) { |
| | | unreadCount.value = res.data || 0 |
| | | emit('unreadCountChange', unreadCount.value) |
| | | } |
| | | } catch (error) { |
| | | console.error('å è½½æªè¯»æ°é失败:', error) |
| | | } |
| | | } |
| | | |
| | | // æ ç¾é¡µåæ¢ |
| | | const handleTabChange = (tab) => { |
| | | pageNum.value = 1 |
| | | loadMessages() |
| | | } |
| | | |
| | | // ç¡®è®¤æ¶æ¯ |
| | | const handleConfirm = async (item) => { |
| | | try { |
| | | console.log('item', item) |
| | | const res = await confirmMessage(item.noticeId, 1) |
| | | if (res.code === 200) { |
| | | ElMessage.success('确认æå') |
| | | // éæ°å è½½æ°æ® |
| | | loadMessages() |
| | | loadUnreadCount() |
| | | |
| | | // æ ¹æ® jumpPath è¿è¡é¡µé¢è·³è½¬ |
| | | if (item.jumpPath) { |
| | | try { |
| | | // è§£æ jumpPathï¼å离路å¾åæ¥è¯¢åæ° |
| | | const [path, queryString] = item.jumpPath.split('?') |
| | | let query = {} |
| | | |
| | | if (queryString) { |
| | | // è§£ææ¥è¯¢åæ° |
| | | queryString.split('&').forEach(param => { |
| | | const [key, value] = param.split('=') |
| | | if (key && value) { |
| | | query[key] = decodeURIComponent(value) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // è·³è½¬å°æå®é¡µé¢ |
| | | router.push({ |
| | | path: path, |
| | | query: query |
| | | }) |
| | | } catch (error) { |
| | | console.error('页é¢è·³è½¬å¤±è´¥:', error) |
| | | } |
| | | } |
| | | } |
| | | } catch (error) { |
| | | console.error('ç¡®è®¤æ¶æ¯å¤±è´¥:', error) |
| | | ElMessage.error('确认失败') |
| | | } |
| | | } |
| | | |
| | | // ä¸é®å·²è¯» |
| | | const handleMarkAllAsRead = async () => { |
| | | try { |
| | | const res = await markAllAsRead() |
| | | if (res.code === 200) { |
| | | ElMessage.success('å·²å
¨é¨æ 记为已读') |
| | | loadMessages() |
| | | loadUnreadCount() |
| | | } |
| | | } catch (error) { |
| | | console.error('ä¸é®å·²è¯»å¤±è´¥:', error) |
| | | ElMessage.error('æä½å¤±è´¥') |
| | | } |
| | | } |
| | | |
| | | // å页大尿¹å |
| | | const handleSizeChange = (size) => { |
| | | pageSize.value = size |
| | | pageNum.value = 1 |
| | | loadMessages() |
| | | } |
| | | |
| | | // é¡µç æ¹å |
| | | const handlePageChange = (page) => { |
| | | pageNum.value = page |
| | | loadMessages() |
| | | } |
| | | |
| | | // ç»ä»¶æè½½æ¶å è½½æªè¯»æ°é |
| | | onMounted(() => { |
| | | loadUnreadCount() |
| | | }) |
| | | |
| | | // çå¬ç¶ç»ä»¶ä¼ éç visible ç¶æï¼éè¿ watch å¨ Navbar ä¸å¤çï¼ |
| | | // è¿éåªè´è´£æ°æ®å è½½ï¼ä¸æ§å¶æ¾ç¤º |
| | | |
| | | // æ´é²æ¹æ³ä¾å¤é¨è°ç¨ |
| | | defineExpose({ |
| | | loadUnreadCount, |
| | | loadMessages |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .notification-popover-content { |
| | | display: flex; |
| | | flex-direction: column; |
| | | width: 500px; |
| | | padding: 16px; |
| | | } |
| | | |
| | | .popover-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | width: 100%; |
| | | margin-bottom: 16px; |
| | | padding-bottom: 12px; |
| | | border-bottom: 1px solid #f0f0f0; |
| | | |
| | | .popover-title { |
| | | font-size: 18px; |
| | | font-weight: 500; |
| | | color: #303133; |
| | | } |
| | | } |
| | | |
| | | .notification-content { |
| | | max-height: 60vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | :deep(.el-tabs) { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | min-height: 0; |
| | | |
| | | .el-tabs__header { |
| | | margin-bottom: 0; |
| | | flex-shrink: 0; |
| | | padding: 0; |
| | | } |
| | | |
| | | .el-tabs__content { |
| | | flex: 1; |
| | | overflow-y: auto; |
| | | min-height: 0; |
| | | padding-top: 16px; |
| | | } |
| | | |
| | | .el-tab-pane { |
| | | height: 100%; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .empty-state { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | min-height: 300px; |
| | | padding: 40px 0; |
| | | } |
| | | |
| | | .notification-list { |
| | | .notification-item { |
| | | display: flex; |
| | | padding: 12px 0; |
| | | border-bottom: 1px solid #f0f0f0; |
| | | transition: background-color 0.3s; |
| | | |
| | | &:hover { |
| | | background-color: #f5f7fa; |
| | | } |
| | | |
| | | &.read { |
| | | opacity: 0.7; |
| | | } |
| | | |
| | | .notification-icon { |
| | | flex-shrink: 0; |
| | | width: 40px; |
| | | height: 40px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | background-color: #f0f9ff; |
| | | border-radius: 50%; |
| | | margin-right: 12px; |
| | | } |
| | | |
| | | .notification-content-wrapper { |
| | | flex: 1; |
| | | min-width: 0; |
| | | |
| | | .notification-title { |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | color: #303133; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .notification-detail { |
| | | font-size: 13px; |
| | | color: #606266; |
| | | line-height: 1.5; |
| | | margin-bottom: 8px; |
| | | word-break: break-all; |
| | | } |
| | | |
| | | .notification-time { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | } |
| | | } |
| | | |
| | | .notification-action { |
| | | flex-shrink: 0; |
| | | margin-left: 12px; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .pagination-wrapper { |
| | | margin-top: 16px; |
| | | padding-top: 16px; |
| | | border-top: 1px solid #f0f0f0; |
| | | display: flex; |
| | | justify-content: center; |
| | | padding-left: 0; |
| | | padding-right: 0; |
| | | } |
| | | </style> |
| | | |
| | |
| | | <transition name="sidebarLogoFade">
|
| | | <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
|
| | | <img v-if="logoUrl" :src="logoUrl" class="sidebar-logo" @error="handleImageError" alt="å
¬å¸Logo" />
|
| | | <h1 v-else class="sidebar-title">{{ title }}</h1>
|
| | | <h1 class="sidebar-title">{{ title }}</h1>
|
| | | </router-link>
|
| | | <router-link v-else key="expand" class="sidebar-logo-link" to="/">
|
| | | <img v-if="logoUrl" :src="logoUrl" class="sidebar-logo" @error="handleImageError" alt="å
¬å¸Logo" />
|
| | | <h1 v-else class="sidebar-title">{{ title }}</h1>
|
| | | <h1 class="sidebar-title">{{ title }}</h1>
|
| | | </router-link>
|
| | | </transition>
|
| | | </div>
|
| | |
| | | }
|
| | | }
|
| | | }
|
| | | </style> |
| | | </style>
|
| | |
| | | const sideTheme = computed(() => settingsStore.sideTheme)
|
| | | const theme = computed(() => settingsStore.theme)
|
| | | const isCollapse = computed(() => !appStore.sidebar.opened)
|
| | | console.log(44444, settingsStore.isDark, sideTheme.value)
|
| | |
|
| | | // è·åèåèæ¯è²
|
| | | const getMenuBackground = computed(() => {
|
| | |
| | | export { default as Navbar } from './Navbar'
|
| | | export { default as Settings } from './Settings'
|
| | | export { default as TagsView } from './TagsView/index.vue'
|
| | | export { default as NotificationCenter } from './NotificationCenter/index.vue'
|
| | |
| | | import { createApp } from "vue";
|
| | |
|
| | | import Cookies from "js-cookie";
|
| | |
|
| | | import ElementPlus from "element-plus";
|
| | | import "element-plus/dist/index.css";
|
| | | import "element-plus/theme-chalk/dark/css-vars.css";
|
| | | import locale from "element-plus/es/locale/lang/zh-cn";
|
| | |
|
| | | import "@/assets/styles/index.scss"; // global css
|
| | |
|
| | | import App from "./App";
|
| | | import store from "./store";
|
| | | import router from "./router";
|
| | | import directive from "./directive"; // directive
|
| | |
|
| | | // 注åæä»¤
|
| | | import plugins from "./plugins"; // plugins
|
| | | import { download } from "@/utils/request";
|
| | |
|
| | | // svg徿
|
| | | import "virtual:svg-icons-register";
|
| | | import SvgIcon from "@/components/SvgIcon";
|
| | | import elementIcons from "@/components/SvgIcon/svgicon";
|
| | | import "./assets/fonts/font.css";
|
| | |
|
| | | import "./permission"; // permission control
|
| | |
|
| | | import { useDict } from "@/utils/dict";
|
| | | import {
|
| | | parseTime,
|
| | | resetForm,
|
| | | addDateRange,
|
| | | handleTree,
|
| | | selectDictLabel,
|
| | | selectDictLabels,
|
| | | } from "@/utils/ruoyi";
|
| | |
|
| | | // å页ç»ä»¶
|
| | | import Pagination from "@/components/Pagination";
|
| | | // èªå®ä¹è¡¨æ ¼å·¥å
·ç»ä»¶
|
| | | import RightToolbar from "@/components/RightToolbar";
|
| | | // 坿æ¬ç»ä»¶
|
| | | import Editor from "@/components/Editor";
|
| | | // æä»¶ä¸ä¼ ç»ä»¶
|
| | | import FileUpload from "@/components/FileUpload";
|
| | | // å¾çä¸ä¼ ç»ä»¶
|
| | | import ImageUpload from "@/components/ImageUpload";
|
| | | // å¾çé¢è§ç»ä»¶
|
| | | import ImagePreview from "@/components/ImagePreview";
|
| | | // åå
¸æ ç¾ç»ä»¶
|
| | | import DictTag from "@/components/DictTag";
|
| | | // è¡¨æ ¼ç»ä»¶
|
| | | import PIMTable from "@/components/PIMTable/PIMTable.vue";
|
| | |
|
| | | import { getToken } from "@/utils/auth";
|
| | | import {
|
| | | calculateTaxExclusiveTotalPrice,
|
| | | summarizeTable,
|
| | | calculateTaxIncludeTotalPrice,
|
| | | } from "@/utils/summarizeTable.js";
|
| | |
|
| | | const app = createApp(App);
|
| | |
|
| | | // å
¨å±æ¹æ³æè½½
|
| | | app.config.globalProperties.useDict = useDict;
|
| | | app.config.globalProperties.download = download;
|
| | | app.config.globalProperties.parseTime = parseTime;
|
| | | app.config.globalProperties.resetForm = resetForm;
|
| | | app.config.globalProperties.summarizeTable = summarizeTable;
|
| | | app.config.globalProperties.calculateTaxExclusiveTotalPrice =
|
| | | calculateTaxExclusiveTotalPrice;
|
| | | app.config.globalProperties.calculateTaxIncludeTotalPrice =
|
| | | calculateTaxIncludeTotalPrice;
|
| | | app.config.globalProperties.handleTree = handleTree;
|
| | | app.config.globalProperties.addDateRange = addDateRange;
|
| | | app.config.globalProperties.selectDictLabel = selectDictLabel;
|
| | | app.config.globalProperties.selectDictLabels = selectDictLabels;
|
| | | app.config.globalProperties.javaApi = "http://114.132.189.42:7004";
|
| | | app.config.globalProperties.HaveJson = (val) => {
|
| | | return JSON.parse(JSON.stringify(val));
|
| | | };
|
| | | app.config.globalProperties.uploadHeader = {
|
| | | Authorization: "Bearer " + getToken(),
|
| | | };
|
| | |
|
| | | // å
¨å±ç»ä»¶æè½½
|
| | | app.component("DictTag", DictTag);
|
| | | app.component("Pagination", Pagination);
|
| | | app.component("FileUpload", FileUpload);
|
| | | app.component("ImageUpload", ImageUpload);
|
| | | app.component("ImagePreview", ImagePreview);
|
| | | app.component("RightToolbar", RightToolbar);
|
| | | app.component("Editor", Editor);
|
| | | app.component("PIMTable", PIMTable);
|
| | |
|
| | | app.use(router);
|
| | | app.use(store);
|
| | | app.use(plugins);
|
| | | app.use(elementIcons);
|
| | | app.component("svg-icon", SvgIcon);
|
| | |
|
| | | directive(app);
|
| | |
|
| | | // 使ç¨element-plus å¹¶ä¸è®¾ç½®å
¨å±ç大å°
|
| | | app.use(ElementPlus, {
|
| | | locale: locale,
|
| | | // æ¯æ largeãdefaultãsmall
|
| | | size: Cookies.get("size") || "default",
|
| | | });
|
| | | app._context.components.ElDialog.props.closeOnClickModal.default = false;
|
| | |
|
| | | app.mount("#app");
|
| | | import { createApp } from "vue"; |
| | | |
| | | import Cookies from "js-cookie"; |
| | | |
| | | import ElementPlus from "element-plus"; |
| | | import "element-plus/dist/index.css"; |
| | | import "element-plus/theme-chalk/dark/css-vars.css"; |
| | | import locale from "element-plus/es/locale/lang/zh-cn"; |
| | | |
| | | import "@/assets/styles/index.scss"; // global css |
| | | |
| | | import App from "./App"; |
| | | import store from "./store"; |
| | | import router from "./router"; |
| | | import directive from "./directive"; // directive |
| | | |
| | | // 注åæä»¤ |
| | | import plugins from "./plugins"; // plugins |
| | | import { download } from "@/utils/request"; |
| | | |
| | | // svg徿 |
| | | import "virtual:svg-icons-register"; |
| | | import SvgIcon from "@/components/SvgIcon"; |
| | | import elementIcons from "@/components/SvgIcon/svgicon"; |
| | | import "./assets/fonts/font.css"; |
| | | |
| | | import "./permission"; // permission control |
| | | |
| | | import { useDict } from "@/utils/dict"; |
| | | import { |
| | | parseTime, |
| | | resetForm, |
| | | addDateRange, |
| | | handleTree, |
| | | selectDictLabel, |
| | | selectDictLabels, |
| | | } from "@/utils/ruoyi"; |
| | | |
| | | // å页ç»ä»¶ |
| | | import Pagination from "@/components/Pagination"; |
| | | // èªå®ä¹è¡¨æ ¼å·¥å
·ç»ä»¶ |
| | | import RightToolbar from "@/components/RightToolbar"; |
| | | // 坿æ¬ç»ä»¶ |
| | | import Editor from "@/components/Editor"; |
| | | // æä»¶ä¸ä¼ ç»ä»¶ |
| | | import FileUpload from "@/components/FileUpload"; |
| | | // å¾çä¸ä¼ ç»ä»¶ |
| | | import ImageUpload from "@/components/ImageUpload"; |
| | | // å¾çé¢è§ç»ä»¶ |
| | | import ImagePreview from "@/components/ImagePreview"; |
| | | // åå
¸æ ç¾ç»ä»¶ |
| | | import DictTag from "@/components/DictTag"; |
| | | // è¡¨æ ¼ç»ä»¶ |
| | | import PIMTable from "@/components/PIMTable/PIMTable.vue"; |
| | | // 页é¢å¤´é¨ç»ä»¶ |
| | | import PageHeader from "@/components/PageHeader/index.vue"; |
| | | |
| | | import { getToken } from "@/utils/auth"; |
| | | import { |
| | | calculateTaxExclusiveTotalPrice, |
| | | summarizeTable, |
| | | calculateTaxIncludeTotalPrice, |
| | | } from "@/utils/summarizeTable.js"; |
| | | |
| | | const app = createApp(App); |
| | | |
| | | // å
¨å±æ¹æ³æè½½ |
| | | app.config.globalProperties.useDict = useDict; |
| | | app.config.globalProperties.download = download; |
| | | app.config.globalProperties.parseTime = parseTime; |
| | | app.config.globalProperties.resetForm = resetForm; |
| | | app.config.globalProperties.summarizeTable = summarizeTable; |
| | | app.config.globalProperties.calculateTaxExclusiveTotalPrice = |
| | | calculateTaxExclusiveTotalPrice; |
| | | app.config.globalProperties.calculateTaxIncludeTotalPrice = |
| | | calculateTaxIncludeTotalPrice; |
| | | app.config.globalProperties.handleTree = handleTree; |
| | | app.config.globalProperties.addDateRange = addDateRange; |
| | | app.config.globalProperties.selectDictLabel = selectDictLabel; |
| | | app.config.globalProperties.selectDictLabels = selectDictLabels; |
| | | app.config.globalProperties.javaApi = "http://127.0.0.1:7003"; |
| | | app.config.globalProperties.HaveJson = (val) => { |
| | | return JSON.parse(JSON.stringify(val)); |
| | | }; |
| | | app.config.globalProperties.uploadHeader = { |
| | | Authorization: "Bearer " + getToken(), |
| | | }; |
| | | |
| | | // å
¨å±ç»ä»¶æè½½ |
| | | app.component("DictTag", DictTag); |
| | | app.component("Pagination", Pagination); |
| | | app.component("FileUpload", FileUpload); |
| | | app.component("ImageUpload", ImageUpload); |
| | | app.component("ImagePreview", ImagePreview); |
| | | app.component("RightToolbar", RightToolbar); |
| | | app.component("Editor", Editor); |
| | | app.component("PIMTable", PIMTable); |
| | | app.component("PageHeader", PageHeader); |
| | | |
| | | app.use(router); |
| | | app.use(store); |
| | | app.use(plugins); |
| | | app.use(elementIcons); |
| | | app.component("svg-icon", SvgIcon); |
| | | |
| | | directive(app); |
| | | |
| | | // 使ç¨element-plus å¹¶ä¸è®¾ç½®å
¨å±çå¤§å° |
| | | app.use(ElementPlus, { |
| | | locale: locale, |
| | | // æ¯æ largeãdefaultãsmall |
| | | size: Cookies.get("size") || "default", |
| | | }); |
| | | app._context.components.ElDialog.props.closeOnClickModal.default = false; |
| | | |
| | | app.mount("#app"); |
| | |
| | |
|
| | | NProgress.configure({ showSpinner: false })
|
| | |
|
| | | const whiteList = ['/login', '/register', '/callbacklccpn']
|
| | | const whiteList = ['/login', '/register', '/callbacklccpn','/device-info']
|
| | |
|
| | | const isWhiteList = (path) => {
|
| | | return whiteList.some(pattern => isPathMatch(pattern, path))
|
| | |
| | | import { createWebHistory, createRouter } from 'vue-router'
|
| | | import { createWebHistory, createRouter } from "vue-router";
|
| | | /* Layout */
|
| | | import Layout from '@/layout'
|
| | | import Layout from "@/layout";
|
| | |
|
| | | /**
|
| | | * Note: è·¯ç±é
置项
|
| | |
| | | * 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' // å½è·¯ç±è®¾ç½®äºè¯¥å±æ§ï¼åä¼é«äº®ç¸å¯¹åºçä¾§è¾¹æ ã
|
| | | }
|
| | | 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',
|
| | | path: "/redirect",
|
| | | component: Layout,
|
| | | hidden: true,
|
| | | children: [
|
| | | {
|
| | | path: '/redirect/:path(.*)',
|
| | | component: () => import('@/views/redirect/index.vue')
|
| | | }
|
| | | ]
|
| | | path: "/redirect/:path(.*)",
|
| | | component: () => import("@/views/redirect/index.vue"),
|
| | | },
|
| | | ],
|
| | | },
|
| | | {
|
| | | path: '/login',
|
| | | component: () => import('@/views/login'),
|
| | | hidden: true
|
| | | },
|
| | | {
|
| | | path: "/callbacklccpn",
|
| | | component: () => import("@/views/tideLogin.vue"),
|
| | | path: "/login",
|
| | | component: () => import("@/views/login"),
|
| | | hidden: true,
|
| | | },
|
| | | {
|
| | | path: '/register',
|
| | | component: () => import('@/views/register'),
|
| | | hidden: true
|
| | | path: "/register",
|
| | | component: () => import("@/views/register"),
|
| | | hidden: true,
|
| | | },
|
| | | {
|
| | | path: "/:pathMatch(.*)*",
|
| | | component: () => import('@/views/error/404'),
|
| | | hidden: true
|
| | | component: () => import("@/views/error/404"),
|
| | | hidden: true,
|
| | | },
|
| | | {
|
| | | path: '/401',
|
| | | component: () => import('@/views/error/401'),
|
| | | hidden: true
|
| | | path: "/401",
|
| | | component: () => import("@/views/error/401"),
|
| | | hidden: true,
|
| | | },
|
| | |
|
| | | {
|
| | | path: '',
|
| | | path: "",
|
| | | component: Layout,
|
| | | redirect: '/index',
|
| | | redirect: "/index",
|
| | | children: [
|
| | | {
|
| | | path: '/index',
|
| | | component: () => import('@/views/index'),
|
| | | name: 'Index',
|
| | | meta: { title: 'é¦é¡µ', icon: 'dashboard', affix: true }
|
| | | }
|
| | | ]
|
| | | path: "/index",
|
| | | component: () => import("@/views/index"),
|
| | | name: "Index",
|
| | | meta: { title: "é¦é¡µ", icon: "dashboard", affix: true },
|
| | | },
|
| | | ],
|
| | | },
|
| | | {
|
| | | path: '/user',
|
| | | path: "/user",
|
| | | component: Layout,
|
| | | hidden: true,
|
| | | redirect: 'noredirect',
|
| | | redirect: "noredirect",
|
| | | children: [
|
| | | {
|
| | | path: 'profile',
|
| | | component: () => import('@/views/system/user/profile/index'),
|
| | | name: 'Profile',
|
| | | meta: { title: '个人ä¸å¿', icon: 'user' }
|
| | | }
|
| | | ]
|
| | | }
|
| | | ]
|
| | | path: "profile",
|
| | | component: () => import("@/views/system/user/profile/index"),
|
| | | name: "Profile",
|
| | | meta: { title: "个人ä¸å¿", icon: "user" },
|
| | | },
|
| | | ],
|
| | | },
|
| | | {
|
| | | path: "/device-info",
|
| | | component: () => import("@/views/equipmentManagement/deviceInfo/index.vue"),
|
| | | hidden: true,
|
| | | name: "DeviceInfo",
|
| | | meta: { title: "设å¤ä¿¡æ¯", icon: "monitor" },
|
| | | },
|
| | | // æ·»å 项ç®è¯¦æ
页é¢è·¯ç±é
ç½®
|
| | | {
|
| | | path: "/oaSystem/projectManagement/projectDetail",
|
| | | component: Layout,
|
| | | hidden: true,
|
| | | children: [
|
| | | {
|
| | | path: ":projectId",
|
| | | component: () => import("@/views/oaSystem/projectManagement/projectDetail.vue"),
|
| | | name: "ProjectDetail",
|
| | | meta: { title: "项ç®è¯¦æ
", activeMenu: "/oaSystem/projectManagement" },
|
| | | },
|
| | | ],
|
| | | },
|
| | | ];
|
| | |
|
| | | // å¨æè·¯ç±ï¼åºäºç¨æ·æé卿å»å è½½
|
| | | export const dynamicRoutes = [
|
| | | {
|
| | | path: '/system/user-auth',
|
| | | path: "/system/user-auth",
|
| | | component: Layout,
|
| | | hidden: true,
|
| | | permissions: ['system:user:edit'],
|
| | | permissions: ["system:user:edit"],
|
| | | children: [
|
| | | {
|
| | | path: 'role/:userId(\\d+)',
|
| | | component: () => import('@/views/system/user/authRole'),
|
| | | name: 'AuthRole',
|
| | | meta: { title: 'åé
è§è²', activeMenu: '/system/user' }
|
| | | }
|
| | | ]
|
| | | path: "role/:userId(\\d+)",
|
| | | component: () => import("@/views/system/user/authRole"),
|
| | | name: "AuthRole",
|
| | | meta: { title: "åé
è§è²", activeMenu: "/system/user" },
|
| | | },
|
| | | ],
|
| | | },
|
| | | {
|
| | | path: '/main/MobileChat',
|
| | | path: "/system/role-auth",
|
| | | component: Layout,
|
| | | redirect: '',
|
| | | hidden: true,
|
| | | permissions: ['MobileChat:edit'],
|
| | | permissions: ["system:role:edit"],
|
| | | children: [
|
| | | {
|
| | | path: '',
|
| | | component: () => import('@/views/chatHome/chatHomeIndex/MobileChat'),
|
| | | name: 'MobileChat',
|
| | | meta: { title: 'AI对è¯', activeMenu: '/chatHome/chatHomeIndex'}
|
| | | }
|
| | | ]
|
| | | path: "user/:roleId(\\d+)",
|
| | | component: () => import("@/views/system/role/authUser"),
|
| | | name: "AuthUser",
|
| | | meta: { title: "åé
ç¨æ·", activeMenu: "/system/role" },
|
| | | },
|
| | | ],
|
| | | },
|
| | | {
|
| | | path: '/system/role-auth',
|
| | | path: "/system/dict-data",
|
| | | component: Layout,
|
| | | hidden: true,
|
| | | permissions: ['system:role:edit'],
|
| | | permissions: ["system:dict:list"],
|
| | | children: [
|
| | | {
|
| | | path: 'user/:roleId(\\d+)',
|
| | | component: () => import('@/views/system/role/authUser'),
|
| | | name: 'AuthUser',
|
| | | meta: { title: 'åé
ç¨æ·', activeMenu: '/system/role' }
|
| | | }
|
| | | ]
|
| | | path: "index/:dictId(\\d+)",
|
| | | component: () => import("@/views/system/dict/data"),
|
| | | name: "Data",
|
| | | meta: { title: "åå
¸æ°æ®", activeMenu: "/system/dict" },
|
| | | },
|
| | | ],
|
| | | },
|
| | | {
|
| | | path: '/system/dict-data',
|
| | | path: "/monitor/job-log",
|
| | | component: Layout,
|
| | | hidden: true,
|
| | | permissions: ['system:dict:list'],
|
| | | permissions: ["monitor:job:list"],
|
| | | children: [
|
| | | {
|
| | | path: 'index/:dictId(\\d+)',
|
| | | component: () => import('@/views/system/dict/data'),
|
| | | name: 'Data',
|
| | | meta: { title: 'åå
¸æ°æ®', activeMenu: '/system/dict' }
|
| | | }
|
| | | ]
|
| | | path: "index/:jobId(\\d+)",
|
| | | component: () => import("@/views/monitor/job/log"),
|
| | | name: "JobLog",
|
| | | meta: { title: "è°åº¦æ¥å¿", activeMenu: "/monitor/job" },
|
| | | },
|
| | | ],
|
| | | },
|
| | | {
|
| | | path: '/monitor/job-log',
|
| | | path: "/tool/gen-edit",
|
| | | component: Layout,
|
| | | hidden: true,
|
| | | permissions: ['monitor:job:list'],
|
| | | permissions: ["tool:gen:edit"],
|
| | | children: [
|
| | | {
|
| | | path: 'index/:jobId(\\d+)',
|
| | | component: () => import('@/views/monitor/job/log'),
|
| | | name: 'JobLog',
|
| | | meta: { title: 'è°åº¦æ¥å¿', activeMenu: '/monitor/job' }
|
| | | }
|
| | | ]
|
| | | path: "index/:tableId(\\d+)",
|
| | | component: () => import("@/views/tool/gen/editTable"),
|
| | | name: "GenEdit",
|
| | | meta: { title: "ä¿®æ¹çæé
ç½®", activeMenu: "/tool/gen" },
|
| | | },
|
| | | ],
|
| | | },
|
| | | {
|
| | | 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 savedPosition;
|
| | | }
|
| | | return { top: 0 }
|
| | | return { top: 0 };
|
| | | },
|
| | | })
|
| | | });
|
| | |
|
| | | export default router
|
| | | export default router;
|
| | |
| | | // axiosä¸è¯·æ±é
ç½®æbaseURLé项ï¼è¡¨ç¤ºè¯·æ±URLå
Œ
±é¨å
|
| | | baseURL: import.meta.env.VITE_APP_BASE_API,
|
| | | // è¶
æ¶
|
| | | timeout: 60000
|
| | | timeout: 160000
|
| | | })
|
| | |
|
| | | // requestæ¦æªå¨
|
| | |
| | | //鲿 |
| | | import dayjs from "dayjs"; |
| | | |
| | | export function debounce(fn) { |
| | | console.log(1) |
| | | let t = null //åªä¼æ§è¡ä¸æ¬¡ |
| | |
| | | 'aplication/zip': 'zpi', |
| | | } |
| | | } |
| | | |
| | | export const deepCopySameProperties = (source, target) =>{ |
| | | for (const key in source) { |
| | | if (target.hasOwnProperty(key)) { |
| | | if (typeof source[key] === 'object' && source[key] !== null && |
| | | typeof target[key] === 'object' && target[key] !== null) { |
| | | // éå½å¤ç对象 |
| | | deepCopySameProperties(source[key], target[key]); |
| | | } else { |
| | | // åºæ¬ç±»åç´æ¥èµå¼ |
| | | target[key] = source[key]; |
| | | } |
| | | } |
| | | } |
| | | return target; |
| | | } |
| | | export function filterArr(arr) { |
| | | return arr.filter(item => item.flag !== false); |
| | | } |
| | | } |
| | | |
| | | export function getCurrentMonth () { |
| | | let month = dayjs().month() + 1 |
| | | if (month <= 3) { |
| | | return '1'; |
| | | } else if (month <= 6) { |
| | | return '2'; |
| | | } else if (month <= 9) { |
| | | return '3'; |
| | | } else if (month <= 12) { |
| | | return '4'; |
| | | } |
| | | } |
| | |
| | | <span class="search_title">客æ·åç§°ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.customerName" |
| | | style="width: 240px" |
| | | style="width: 240px;margin-right: 10px" |
| | | placeholder="请è¾å
¥" |
| | | @change="handleQuery" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | /> |
| | | <span class="search_title">客æ·åç±»ï¼</span> |
| | | <el-select |
| | | v-model="searchForm.customerType" |
| | | placeholder="è¯·éæ©" |
| | | style="width: 240px" |
| | | clearable |
| | | @change="handleQuery" |
| | | > |
| | | <el-option label="é¶å®å®¢æ·" value="é¶å®å®¢æ·" /> |
| | | <el-option label="è¿éå客æ·" value="è¿éå客æ·" /> |
| | | </el-select> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="客æ·åç±»ï¼" prop="customerType"> |
| | | <el-select v-model="form.customerType" placeholder="è¯·éæ©" clearable> |
| | | <el-option label="é¶å®å®¢æ·" value="é¶å®å®¢æ·" /> |
| | | <el-option label="è¿éå客æ·" value="è¿éå客æ·" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30" v-for="(contact, index) in formYYs.contactList" :key="index"> |
| | | <el-col :span="12"> |
| | |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | <template #tip> |
| | | <div class="el-upload__tip text-center"> |
| | | <span>ä»
å
许导å
¥xlsãxlsxæ ¼å¼æä»¶ã</span> |
| | | <!-- <el-link--> |
| | | <!-- type="primary"--> |
| | | <!-- :underline="false"--> |
| | | <!-- style="font-size: 12px; vertical-align: baseline"--> |
| | | <!-- @click="importTemplate"--> |
| | | <!-- >ä¸è½½æ¨¡æ¿</el-link--> |
| | | <!-- >--> |
| | | <el-link |
| | | type="primary" |
| | | :underline="false" |
| | | style="font-size: 12px; vertical-align: baseline" |
| | | @click="importTemplate" |
| | | >ä¸è½½æ¨¡æ¿</el-link |
| | | > |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | |
| | | const userStore = useUserStore(); |
| | | |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "客æ·åç±»", |
| | | prop: "customerType", |
| | | width: 120, |
| | | }, |
| | | { |
| | | label: "客æ·åç§°", |
| | | prop: "customerName", |
| | |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.maintainer !== userStore.nickName |
| | | } |
| | | }, |
| | | ], |
| | | }, |
| | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | customerName: "", |
| | | customerType: "", |
| | | }, |
| | | form: { |
| | | customerName: "", |
| | |
| | | basicBankAccount: "", |
| | | bankAccount: "", |
| | | bankCode: "", |
| | | customerType: "", |
| | | }, |
| | | rules: { |
| | | customerName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | |
| | | basicBankAccount: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | bankAccount: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | bankCode: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | customerType: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | }, |
| | | }); |
| | | const upload = reactive({ |
| | |
| | | // æä»¶ä¸ä¼ æåæ¶çåè° |
| | | onSuccess: (response, file, fileList) => { |
| | | console.log('ä¸ä¼ æå', response, file, fileList); |
| | | upload.isUploading = false; |
| | | if(response.code === 200){ |
| | | proxy.$modal.msgSuccess("æä»¶ä¸ä¼ æå"); |
| | | upload.open = false; |
| | | proxy.$refs["uploadRef"].clearFiles(); |
| | | getList(); |
| | | }else if(response.code === 500){ |
| | | proxy.$modal.msgError(response.msg); |
| | | }else{ |
| | |
| | | // æä»¶ä¸ä¼ 失败æ¶çåè° |
| | | onError: (error, file, fileList) => { |
| | | console.error('ä¸ä¼ 失败', error, file, fileList); |
| | | upload.isUploading = false; |
| | | proxy.$modal.msgError("æä»¶ä¸ä¼ 失败"); |
| | | }, |
| | | // æä»¶ä¸ä¼ è¿åº¦åè° |
| | |
| | | }; |
| | | /** æäº¤ä¸ä¼ æä»¶ */ |
| | | function submitFileForm() { |
| | | upload.isUploading = true; |
| | | proxy.$refs["uploadRef"].submit(); |
| | | } |
| | | /** 导å
¥æé®æä½ */ |
| | |
| | | upload.title = "客æ·å¯¼å
¥"; |
| | | upload.open = true; |
| | | } |
| | | /** ä¸è½½æ¨¡æ¿ */ |
| | | function importTemplate() { |
| | | proxy.download("/basic/customer/downloadTemplate", {}, "客æ·å¯¼å
¥æ¨¡æ¿.xlsx"); |
| | | } |
| | | // æå¼å¼¹æ¡ |
| | | const openForm = (type, row) => { |
| | | operationType.value = type; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog v-model="visible" title="éæ©äº§å" width="900px" destroy-on-close :close-on-click-modal="false"> |
| | | <el-form :inline="true" :model="query" class="mb-2"> |
| | | <el-form-item label="产å大类"> |
| | | <el-input v-model="query.productName" placeholder="è¾å
¥äº§å大类" clearable @keyup.enter="onSearch" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="åå·åç§°"> |
| | | <el-input v-model="query.model" placeholder="è¾å
¥åå·åç§°" clearable @keyup.enter="onSearch" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-button type="primary" @click="onSearch">æç´¢</el-button> |
| | | <el-button @click="onReset">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <!-- å表 --> |
| | | <el-table ref="tableRef" v-loading="loading" :data="tableData" height="420" highlight-current-row row-key="id" |
| | | @selection-change="handleSelectionChange" @select="handleSelect"> |
| | | <el-table-column type="selection" width="55" /> |
| | | <el-table-column type="index" label="åºå·" width="60" /> |
| | | <el-table-column prop="productName" label="产å大类" min-width="160" /> |
| | | <el-table-column prop="model" label="åå·åç§°" min-width="200" /> |
| | | <el-table-column prop="unit" label="åä½" min-width="160" /> |
| | | </el-table> |
| | | |
| | | <div class="mt-3 flex justify-end"> |
| | | <el-pagination background layout="total, sizes, prev, pager, next, jumper" :total="total" |
| | | v-model:page-size="page.pageSize" v-model:current-page="page.pageNum" :page-sizes="[10, 20, 50, 100]" |
| | | @size-change="onPageChange" @current-change="onPageChange" /> |
| | | </div> |
| | | |
| | | <template #footer> |
| | | <el-button @click="close()">åæ¶</el-button> |
| | | <el-button type="primary" :disabled="multipleSelection.length === 0" @click="onConfirm"> |
| | | ç¡®å® |
| | | </el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { computed, onMounted, reactive, ref, watch, nextTick } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { productModelList } from '@/api/basicData/productModel' |
| | | |
| | | export type ProductRow = { |
| | | id: number; |
| | | productName: string; |
| | | model: string; |
| | | unit?: string; |
| | | }; |
| | | |
| | | const props = defineProps<{ |
| | | modelValue: boolean; |
| | | single?: boolean; // æ¯å¦åªè½éæ©ä¸ä¸ªï¼é»è®¤falseï¼å¯éæ©å¤ä¸ªï¼ |
| | | }>(); |
| | | |
| | | const emit = defineEmits(['update:modelValue', 'confirm']); |
| | | |
| | | const visible = computed({ |
| | | get: () => props.modelValue, |
| | | set: (v) => emit("update:modelValue", v), |
| | | }); |
| | | |
| | | const query = reactive({ |
| | | productName: "", |
| | | model: "", |
| | | }); |
| | | |
| | | const page = reactive({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | }); |
| | | |
| | | const loading = ref(false); |
| | | const tableData = ref<ProductRow[]>([]); |
| | | const total = ref(0); |
| | | const multipleSelection = ref<ProductRow[]>([]); |
| | | const tableRef = ref(); |
| | | |
| | | function close() { |
| | | visible.value = false; |
| | | } |
| | | |
| | | const handleSelectionChange = (val: ProductRow[]) => { |
| | | if (props.single && val.length > 1) { |
| | | // 妿éå¶ä¸ºåä¸ªéæ©ï¼åªä¿çæåä¸ä¸ªéä¸ç |
| | | const lastSelected = val[val.length - 1]; |
| | | multipleSelection.value = [lastSelected]; |
| | | // æ¸
ç©ºè¡¨æ ¼éä¸ç¶æï¼ç¶åéæ°é䏿åä¸ä¸ª |
| | | nextTick(() => { |
| | | if (tableRef.value) { |
| | | tableRef.value.clearSelection(); |
| | | tableRef.value.toggleRowSelection(lastSelected, true); |
| | | } |
| | | }); |
| | | } else { |
| | | multipleSelection.value = val; |
| | | } |
| | | } |
| | | |
| | | // å¤çåä¸ªéæ© |
| | | const handleSelect = (selection: ProductRow[], row: ProductRow) => { |
| | | if (props.single) { |
| | | // 妿éå¶ä¸ºåä¸ªï¼æ¸
空å
¶ä»éæ©ï¼åªä¿çå½åè¡ |
| | | if (selection.includes(row)) { |
| | | // éä¸å½åè¡æ¶ï¼æ¸
空å
¶ä»éä¸ |
| | | multipleSelection.value = [row]; |
| | | nextTick(() => { |
| | | if (tableRef.value) { |
| | | tableData.value.forEach((item) => { |
| | | if (item.id !== row.id) { |
| | | tableRef.value.toggleRowSelection(item, false); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | |
| | | function onSearch() { |
| | | page.pageNum = 1; |
| | | loadData(); |
| | | } |
| | | |
| | | function onReset() { |
| | | query.productName = ""; |
| | | query.model = ""; |
| | | page.pageNum = 1; |
| | | loadData(); |
| | | } |
| | | |
| | | function onPageChange() { |
| | | loadData(); |
| | | } |
| | | |
| | | function onConfirm() { |
| | | if (multipleSelection.value.length === 0) { |
| | | ElMessage.warning("è¯·éæ©ä¸æ¡äº§å"); |
| | | return; |
| | | } |
| | | if (props.single && multipleSelection.value.length > 1) { |
| | | ElMessage.warning("åªè½éæ©ä¸ä¸ªäº§å"); |
| | | return; |
| | | } |
| | | emit("confirm", props.single ? [multipleSelection.value[0]] : multipleSelection.value); |
| | | close(); |
| | | } |
| | | |
| | | async function loadData() { |
| | | loading.value = true; |
| | | try { |
| | | multipleSelection.value = []; // 翻页/æç´¢åæ¸
ç©ºéæ©æ´ç¬¦å颿 |
| | | const res: any = await productModelList({ |
| | | productName: query.productName.trim(), |
| | | model: query.model.trim(), |
| | | current: page.pageNum, |
| | | size: page.pageSize, |
| | | }); |
| | | tableData.value = res.records; |
| | | total.value = res.total; |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | } |
| | | |
| | | // çå¬å¼¹çªæå¼ï¼éç½®éæ© |
| | | watch(() => props.modelValue, (visible) => { |
| | | if (visible) { |
| | | multipleSelection.value = []; |
| | | } |
| | | }); |
| | | |
| | | onMounted(() => { |
| | | loadData() |
| | | }) |
| | | </script> |
| | |
| | | :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 |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">ä¾åºåæ¡£æ¡ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.supplierName" |
| | | style="width: 240px" |
| | | placeholder="è¾å
¥ä¾åºååç§°æç´¢" |
| | | @change="handleQuery" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | | </div> |
| | | <div> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | ></PIMTable> |
| | | </div> |
| | | <el-dialog |
| | | v-model="dialogFormVisible" |
| | | :title="operationType === 'add' ? 'æ°å¢ä¾åºåä¿¡æ¯' : 'ç¼è¾ä¾åºåä¿¡æ¯'" |
| | | width="70%" |
| | | @close="closeDia" |
| | | > |
| | | <el-form |
| | | :model="form" |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="rules" |
| | | ref="formRef" |
| | | > |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¾åºååç§°ï¼" prop="supplierName"> |
| | | <el-input |
| | | v-model="form.supplierName" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item |
| | | label="纳ç¨äººè¯å«å·ï¼" |
| | | prop="taxpayerIdentificationNum" |
| | | > |
| | | <el-input |
| | | v-model="form.taxpayerIdentificationNum" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬å¸å°åï¼" prop="companyAddress"> |
| | | <el-input |
| | | v-model="form.companyAddress" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬å¸çµè¯ï¼" prop="companyPhone"> |
| | | <el-input |
| | | v-model="form.companyPhone" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="弿·è¡ï¼" prop="bankAccountName"> |
| | | <el-input |
| | | v-model="form.bankAccountName" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è´¦å·ï¼" prop="bankAccountNum"> |
| | | <el-input |
| | | v-model="form.bankAccountNum" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è系人ï¼" prop="contactUserName"> |
| | | <el-input |
| | | v-model="form.contactUserName" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èç³»çµè¯ï¼" prop="contactUserPhone"> |
| | | <el-input |
| | | v-model="form.contactUserPhone" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»´æ¤äººï¼" prop="maintainUserId"> |
| | | <el-select |
| | | v-model="form.maintainUserId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | disabled |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | | :key="item.nickName" |
| | | :label="item.nickName" |
| | | :value="item.userId" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»´æ¤æ¶é´ï¼" prop="maintainTime"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.maintainTime" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¯å¦ç½ååï¼" prop="isWhite"> |
| | | <el-select v-model="form.isWhite" placeholder="è¯·éæ©" clearable> |
| | | <el-option label="æ¯" :value="0" /> |
| | | <el-option label="å¦" :value="1" /> |
| | | </el-select> |
| | | </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="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- ä¾åºå导å
¥å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | :title="upload.title" |
| | | v-model="upload.open" |
| | | width="400px" |
| | | append-to-body |
| | | > |
| | | <el-upload |
| | | ref="uploadRef" |
| | | :limit="1" |
| | | accept=".xlsx, .xls" |
| | | :headers="upload.headers" |
| | | :action="upload.url + '?updateSupport=' + upload.updateSupport" |
| | | :disabled="upload.isUploading" |
| | | :on-progress="handleFileUploadProgress" |
| | | :on-success="handleFileSuccess" |
| | | :on-error="handleFileError" |
| | | :auto-upload="false" |
| | | drag |
| | | > |
| | | <el-icon class="el-icon--upload"><upload-filled /></el-icon> |
| | | <div class="el-upload__text">å°æä»¶æå°æ¤å¤ï¼æ<em>ç¹å»ä¸ä¼ </em></div> |
| | | <template #tip> |
| | | <div class="el-upload__tip text-center"> |
| | | <span>ä»
å
许导å
¥xlsãxlsxæ ¼å¼æä»¶ã</span> |
| | | <el-link |
| | | type="primary" |
| | | :underline="false" |
| | | style="font-size: 12px; vertical-align: baseline" |
| | | @click="importTemplate" |
| | | >ä¸è½½æ¨¡æ¿</el-link |
| | | > |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitFileForm">ç¡® å®</el-button> |
| | | <el-button @click="upload.open = false">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <files-dia ref="filesDia"></files-dia> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { onMounted, ref } from "vue"; |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import { delSupplier } from "@/api/basicData/supplierManageFile.js"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { userListNoPage } from "@/api/system/user.js"; |
| | | import { |
| | | addSupplier, |
| | | getSupplier, |
| | | listSupplier, |
| | | updateSupplier, |
| | | } from "@/api/basicData/supplierManageFile.js"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { getToken } from "@/utils/auth.js"; |
| | | import FilesDia from "../filesDia.vue"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const userStore = useUserStore(); |
| | | |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "ä¾åºååç§°", |
| | | prop: "supplierName", |
| | | width: 250, |
| | | }, |
| | | { |
| | | label: "纳ç¨äººè¯å«å·", |
| | | prop: "taxpayerIdentificationNum", |
| | | width: 230, |
| | | }, |
| | | { |
| | | label: "å
¬å¸å°å", |
| | | prop: "companyAddress", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "èç³»æ¹å¼", |
| | | prop: "companyPhone", |
| | | width:150 |
| | | }, |
| | | { |
| | | label: "弿·è¡", |
| | | prop: "bankAccountName", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "è´¦å·", |
| | | prop: "bankAccountNum", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "è系人", |
| | | prop: "contactUserName", |
| | | }, |
| | | { |
| | | label: "èç³»çµè¯", |
| | | prop: "contactUserPhone", |
| | | width: 150, |
| | | }, |
| | | { |
| | | label: "ç»´æ¤äºº", |
| | | prop: "maintainUserName", |
| | | }, |
| | | |
| | | { |
| | | label: "ç»´æ¤æ¶é´", |
| | | prop: "maintainTime", |
| | | width:100 |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: 'right', |
| | | width: 150, |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | }, |
| | | { |
| | | //èµè´¨éä»¶ |
| | | name: "èµè´¨æä»¶", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openFilesFormDia(row) |
| | | } |
| | | } |
| | | ], |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const userList = ref([]); |
| | | const tableLoading = ref(false); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0, |
| | | }); |
| | | const filesDia = ref() |
| | | // ç¨æ·ä¿¡æ¯è¡¨åå¼¹æ¡æ°æ® |
| | | const operationType = ref(""); |
| | | const dialogFormVisible = ref(false); |
| | | const data = reactive({ |
| | | searchForm: { |
| | | supplierName: "", |
| | | }, |
| | | form: { |
| | | supplierName: "", |
| | | taxpayerIdentificationNum: "", |
| | | companyAddress: "", |
| | | companyPhone: "", |
| | | bankAccountName: "", |
| | | bankAccountNum: "", |
| | | contactUserName: "", |
| | | contactUserPhone: "", |
| | | maintainUserId: "", |
| | | maintainTime: "", |
| | | isWhite: "", |
| | | }, |
| | | rules: { |
| | | supplierName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | taxpayerIdentificationNum: [ |
| | | { required: true, message: "请è¾å
¥", trigger: "blur" }, |
| | | ], |
| | | companyAddress: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | companyPhone: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | bankAccountName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | bankAccountNum: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | contactUserName: [{ required: false, message: "请è¾å
¥", trigger: "blur" }], |
| | | contactUserPhone: [{ required: false, message: "请è¾å
¥", trigger: "blur" }], |
| | | maintainUserId: [{ required: false, message: "è¯·éæ©", trigger: "change" }], |
| | | maintainTime: [{ required: false, message: "è¯·éæ©", trigger: "change" }], |
| | | }, |
| | | }); |
| | | const { searchForm, form, rules } = toRefs(data); |
| | | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | /** æäº¤ä¸ä¼ æä»¶ */ |
| | | function submitFileForm() { |
| | | upload.isUploading = true; |
| | | proxy.$refs["uploadRef"].submit(); |
| | | } |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | listSupplier({ ...searchForm.value, ...page, isWhite: 1 }).then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records; |
| | | page.total = res.data.total; |
| | | }); |
| | | }; |
| | | const upload = reactive({ |
| | | // æ¯å¦æ¾ç¤ºå¼¹åºå±ï¼ä¾åºå导å
¥ï¼ |
| | | open: false, |
| | | // å¼¹åºå±æ é¢ï¼ä¾åºå导å
¥ï¼ |
| | | title: "", |
| | | // æ¯å¦ç¦ç¨ä¸ä¼ |
| | | isUploading: false, |
| | | // æ¯å¦æ´æ°å·²ç»åå¨çç¨æ·æ°æ® |
| | | updateSupport: 1, |
| | | // 设置ä¸ä¼ ç请æ±å¤´é¨ |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | // ä¸ä¼ çå°å |
| | | url: import.meta.env.VITE_APP_BASE_API + "/system/supplier/import", |
| | | }); |
| | | /** 导å
¥æé®æä½ */ |
| | | function handleImport() { |
| | | upload.title = "ä¾åºå导å
¥"; |
| | | upload.open = true; |
| | | } |
| | | /** ä¸è½½æ¨¡æ¿ */ |
| | | function importTemplate() { |
| | | proxy.download("/system/supplier/downloadTemplate", {}, "ä¾åºå导å
¥æ¨¡æ¿.xlsx"); |
| | | } |
| | | |
| | | /**æä»¶ä¸ä¼ ä¸å¤ç */ |
| | | const handleFileUploadProgress = (event, file, fileList) => { |
| | | upload.isUploading = true; |
| | | }; |
| | | |
| | | /** æä»¶ä¸ä¼ æåå¤ç */ |
| | | const handleFileSuccess = (response, file, fileList) => { |
| | | upload.isUploading = false; |
| | | if(response.code === 200){ |
| | | proxy.$modal.msgSuccess("æä»¶ä¸ä¼ æå"); |
| | | upload.open = false; |
| | | proxy.$refs["uploadRef"].clearFiles(); |
| | | getList(); |
| | | }else if(response.code === 500){ |
| | | proxy.$modal.msgError(response.msg); |
| | | }else{ |
| | | proxy.$modal.msgWarning(response.msg); |
| | | } |
| | | }; |
| | | |
| | | /** æä»¶ä¸ä¼ 失败å¤ç */ |
| | | const handleFileError = (error, file, fileList) => { |
| | | upload.isUploading = false; |
| | | proxy.$modal.msgError("æä»¶ä¸ä¼ 失败"); |
| | | }; |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | // æå¼å¼¹æ¡ |
| | | const openForm = (type, row) => { |
| | | operationType.value = type; |
| | | form.value = {}; |
| | | form.value.maintainUserId = userStore.id; |
| | | form.value.maintainTime = getCurrentDate(); |
| | | userListNoPage().then((res) => { |
| | | userList.value = res.data; |
| | | }); |
| | | if (type === "edit") { |
| | | getSupplier(row.id).then((res) => { |
| | | form.value = { ...res.data }; |
| | | }); |
| | | } |
| | | dialogFormVisible.value = true; |
| | | }; |
| | | // æäº¤è¡¨å |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate((valid) => { |
| | | if (valid) { |
| | | if (operationType.value === "edit") { |
| | | submitEdit(); |
| | | } else { |
| | | submitAdd(); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | // æäº¤æ°å¢ |
| | | const submitAdd = () => { |
| | | addSupplier(form.value).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | getList(); |
| | | }); |
| | | }; |
| | | // æäº¤ä¿®æ¹ |
| | | const submitEdit = () => { |
| | | updateSupplier(form.value).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | getList(); |
| | | }); |
| | | }; |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | | dialogFormVisible.value = false; |
| | | }; |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/system/supplier/export", {}, "ä¾åºåæ¡£æ¡.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | // å é¤ |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | // æ£æ¥æ¯å¦æä»äººç»´æ¤çæ°æ® |
| | | const unauthorizedData = selectedRows.value.filter(item => item.maintainUserName !== userStore.nickName); |
| | | if (unauthorizedData.length > 0) { |
| | | proxy.$modal.msgWarning("ä¸å¯å é¤ä»äººç»´æ¤çæ°æ®"); |
| | | return; |
| | | } |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | | return; |
| | | } |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼", "å é¤æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | tableLoading.value = true; |
| | | delSupplier(ids) |
| | | .then((res) => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getList(); |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // è·åå½åæ¥æå¹¶æ ¼å¼å为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, "0"); // æä»½ä»0å¼å§ |
| | | const day = String(today.getDate()).padStart(2, "0"); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | // æå¼éä»¶å¼¹æ¡ |
| | | const openFilesFormDia = (row) => { |
| | | nextTick(() => { |
| | | filesDia.value?.openDialog(row) |
| | | }) |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | | </script> |
| | | |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">ä¾åºåæ¡£æ¡ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.supplierName" |
| | | style="width: 240px" |
| | | placeholder="è¾å
¥ä¾åºååç§°æç´¢" |
| | | @change="handleQuery" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')" |
| | | >æ°å¢ä¾åºå</el-button |
| | | > |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="info" plain icon="Upload" @click="handleImport" |
| | | >导å
¥</el-button |
| | | > |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | ></PIMTable> |
| | | </div> |
| | | <el-dialog |
| | | v-model="dialogFormVisible" |
| | | :title="operationType === 'add' ? 'æ°å¢ä¾åºåä¿¡æ¯' : 'ç¼è¾ä¾åºåä¿¡æ¯'" |
| | | width="70%" |
| | | @close="closeDia" |
| | | > |
| | | <el-form |
| | | :model="form" |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="rules" |
| | | ref="formRef" |
| | | > |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¾åºååç§°ï¼" prop="supplierName"> |
| | | <el-input |
| | | v-model="form.supplierName" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item |
| | | label="纳ç¨äººè¯å«å·ï¼" |
| | | prop="taxpayerIdentificationNum" |
| | | > |
| | | <el-input |
| | | v-model="form.taxpayerIdentificationNum" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬å¸å°åï¼" prop="companyAddress"> |
| | | <el-input |
| | | v-model="form.companyAddress" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬å¸çµè¯ï¼" prop="companyPhone"> |
| | | <el-input |
| | | v-model="form.companyPhone" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="弿·è¡ï¼" prop="bankAccountName"> |
| | | <el-input |
| | | v-model="form.bankAccountName" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è´¦å·ï¼" prop="bankAccountNum"> |
| | | <el-input |
| | | v-model="form.bankAccountNum" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è系人ï¼" prop="contactUserName"> |
| | | <el-input |
| | | v-model="form.contactUserName" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èç³»çµè¯ï¼" prop="contactUserPhone"> |
| | | <el-input |
| | | v-model="form.contactUserPhone" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»´æ¤äººï¼" prop="maintainUserId"> |
| | | <el-select |
| | | v-model="form.maintainUserId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | disabled |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | | :key="item.nickName" |
| | | :label="item.nickName" |
| | | :value="item.userId" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»´æ¤æ¶é´ï¼" prop="maintainTime"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.maintainTime" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¯å¦ç½ååï¼" prop="isWhite"> |
| | | <el-select v-model="form.isWhite" placeholder="è¯·éæ©" clearable> |
| | | <el-option label="æ¯" :value="0" /> |
| | | <el-option label="å¦" :value="1" /> |
| | | </el-select> |
| | | </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="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- ä¾åºå导å
¥å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | :title="upload.title" |
| | | v-model="upload.open" |
| | | width="400px" |
| | | append-to-body |
| | | > |
| | | <el-upload |
| | | ref="uploadRef" |
| | | :limit="1" |
| | | accept=".xlsx, .xls" |
| | | :headers="upload.headers" |
| | | :action="upload.url + '?updateSupport=' + upload.updateSupport" |
| | | :disabled="upload.isUploading" |
| | | :on-progress="handleFileUploadProgress" |
| | | :on-success="handleFileSuccess" |
| | | :on-error="handleFileError" |
| | | :auto-upload="false" |
| | | drag |
| | | > |
| | | <el-icon class="el-icon--upload"><upload-filled /></el-icon> |
| | | <div class="el-upload__text">å°æä»¶æå°æ¤å¤ï¼æ<em>ç¹å»ä¸ä¼ </em></div> |
| | | <template #tip> |
| | | <div class="el-upload__tip text-center"> |
| | | <span>ä»
å
许导å
¥xlsãxlsxæ ¼å¼æä»¶ã</span> |
| | | <el-link |
| | | type="primary" |
| | | :underline="false" |
| | | style="font-size: 12px; vertical-align: baseline" |
| | | @click="importTemplate" |
| | | >ä¸è½½æ¨¡æ¿</el-link |
| | | > |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitFileForm">ç¡® å®</el-button> |
| | | <el-button @click="upload.open = false">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <files-dia ref="filesDia"></files-dia> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { onMounted, ref } from "vue"; |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import { delSupplier } from "@/api/basicData/supplierManageFile.js"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { userListNoPage } from "@/api/system/user.js"; |
| | | import { |
| | | addSupplier, |
| | | getSupplier, |
| | | listSupplier, |
| | | updateSupplier, |
| | | } from "@/api/basicData/supplierManageFile.js"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { getToken } from "@/utils/auth.js"; |
| | | import FilesDia from "../filesDia.vue"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const userStore = useUserStore(); |
| | | |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "ä¾åºååç§°", |
| | | prop: "supplierName", |
| | | width: 250, |
| | | }, |
| | | { |
| | | label: "纳ç¨äººè¯å«å·", |
| | | prop: "taxpayerIdentificationNum", |
| | | width: 230, |
| | | }, |
| | | { |
| | | label: "å
¬å¸å°å", |
| | | prop: "companyAddress", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "èç³»æ¹å¼", |
| | | prop: "companyPhone", |
| | | width:150 |
| | | }, |
| | | { |
| | | label: "弿·è¡", |
| | | prop: "bankAccountName", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "è´¦å·", |
| | | prop: "bankAccountNum", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "è系人", |
| | | prop: "contactUserName", |
| | | }, |
| | | { |
| | | label: "èç³»çµè¯", |
| | | prop: "contactUserPhone", |
| | | width: 150, |
| | | }, |
| | | { |
| | | label: "ç»´æ¤äºº", |
| | | prop: "maintainUserName", |
| | | }, |
| | | |
| | | { |
| | | label: "ç»´æ¤æ¶é´", |
| | | prop: "maintainTime", |
| | | width:100 |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: 'right', |
| | | width: 150, |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | }, |
| | | { |
| | | //èµè´¨éä»¶ |
| | | name: "èµè´¨æä»¶", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openFilesFormDia(row) |
| | | } |
| | | } |
| | | ], |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const userList = ref([]); |
| | | const tableLoading = ref(false); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0, |
| | | }); |
| | | const filesDia = ref() |
| | | // ç¨æ·ä¿¡æ¯è¡¨åå¼¹æ¡æ°æ® |
| | | const operationType = ref(""); |
| | | const dialogFormVisible = ref(false); |
| | | const data = reactive({ |
| | | searchForm: { |
| | | supplierName: "", |
| | | }, |
| | | form: { |
| | | supplierName: "", |
| | | taxpayerIdentificationNum: "", |
| | | companyAddress: "", |
| | | companyPhone: "", |
| | | bankAccountName: "", |
| | | bankAccountNum: "", |
| | | contactUserName: "", |
| | | contactUserPhone: "", |
| | | maintainUserId: "", |
| | | maintainTime: "", |
| | | isWhite: "", |
| | | }, |
| | | rules: { |
| | | supplierName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | taxpayerIdentificationNum: [ |
| | | { required: true, message: "请è¾å
¥", trigger: "blur" }, |
| | | ], |
| | | companyAddress: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | companyPhone: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | bankAccountName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | bankAccountNum: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | contactUserName: [{ required: false, message: "请è¾å
¥", trigger: "blur" }], |
| | | contactUserPhone: [{ required: false, message: "请è¾å
¥", trigger: "blur" }], |
| | | maintainUserId: [{ required: false, message: "è¯·éæ©", trigger: "change" }], |
| | | maintainTime: [{ required: false, message: "è¯·éæ©", trigger: "change" }], |
| | | }, |
| | | }); |
| | | const { searchForm, form, rules } = toRefs(data); |
| | | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | /** æäº¤ä¸ä¼ æä»¶ */ |
| | | function submitFileForm() { |
| | | upload.isUploading = true; |
| | | proxy.$refs["uploadRef"].submit(); |
| | | } |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | listSupplier({ ...searchForm.value, ...page, isWhite: 0 }).then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records; |
| | | page.total = res.data.total; |
| | | }); |
| | | }; |
| | | const upload = reactive({ |
| | | // æ¯å¦æ¾ç¤ºå¼¹åºå±ï¼ä¾åºå导å
¥ï¼ |
| | | open: false, |
| | | // å¼¹åºå±æ é¢ï¼ä¾åºå导å
¥ï¼ |
| | | title: "", |
| | | // æ¯å¦ç¦ç¨ä¸ä¼ |
| | | isUploading: false, |
| | | // æ¯å¦æ´æ°å·²ç»åå¨çç¨æ·æ°æ® |
| | | updateSupport: 1, |
| | | // 设置ä¸ä¼ ç请æ±å¤´é¨ |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | // ä¸ä¼ çå°å |
| | | url: import.meta.env.VITE_APP_BASE_API + "/system/supplier/import", |
| | | }); |
| | | /** 导å
¥æé®æä½ */ |
| | | function handleImport() { |
| | | upload.title = "ä¾åºå导å
¥"; |
| | | upload.open = true; |
| | | } |
| | | /** ä¸è½½æ¨¡æ¿ */ |
| | | function importTemplate() { |
| | | proxy.download("/system/supplier/downloadTemplate", {}, "ä¾åºå导å
¥æ¨¡æ¿.xlsx"); |
| | | } |
| | | |
| | | /**æä»¶ä¸ä¼ ä¸å¤ç */ |
| | | const handleFileUploadProgress = (event, file, fileList) => { |
| | | upload.isUploading = true; |
| | | }; |
| | | |
| | | /** æä»¶ä¸ä¼ æåå¤ç */ |
| | | const handleFileSuccess = (response, file, fileList) => { |
| | | upload.isUploading = false; |
| | | if(response.code === 200){ |
| | | proxy.$modal.msgSuccess("æä»¶ä¸ä¼ æå"); |
| | | upload.open = false; |
| | | proxy.$refs["uploadRef"].clearFiles(); |
| | | getList(); |
| | | }else if(response.code === 500){ |
| | | proxy.$modal.msgError(response.msg); |
| | | }else{ |
| | | proxy.$modal.msgWarning(response.msg); |
| | | } |
| | | }; |
| | | |
| | | /** æä»¶ä¸ä¼ 失败å¤ç */ |
| | | const handleFileError = (error, file, fileList) => { |
| | | upload.isUploading = false; |
| | | proxy.$modal.msgError("æä»¶ä¸ä¼ 失败"); |
| | | }; |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | // æå¼å¼¹æ¡ |
| | | const openForm = (type, row) => { |
| | | operationType.value = type; |
| | | form.value = {}; |
| | | form.value.maintainUserId = userStore.id; |
| | | form.value.maintainTime = getCurrentDate(); |
| | | userListNoPage().then((res) => { |
| | | userList.value = res.data; |
| | | }); |
| | | if (type === "edit") { |
| | | getSupplier(row.id).then((res) => { |
| | | form.value = { ...res.data }; |
| | | }); |
| | | } |
| | | dialogFormVisible.value = true; |
| | | }; |
| | | // æäº¤è¡¨å |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate((valid) => { |
| | | if (valid) { |
| | | if (operationType.value === "edit") { |
| | | submitEdit(); |
| | | } else { |
| | | submitAdd(); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | // æäº¤æ°å¢ |
| | | const submitAdd = () => { |
| | | addSupplier(form.value).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | getList(); |
| | | }); |
| | | }; |
| | | // æäº¤ä¿®æ¹ |
| | | const submitEdit = () => { |
| | | updateSupplier(form.value).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | getList(); |
| | | }); |
| | | }; |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | | dialogFormVisible.value = false; |
| | | }; |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/system/supplier/export", {}, "ä¾åºåæ¡£æ¡.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | // å é¤ |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | // æ£æ¥æ¯å¦æä»äººç»´æ¤çæ°æ® |
| | | const unauthorizedData = selectedRows.value.filter(item => item.maintainUserName !== userStore.nickName); |
| | | if (unauthorizedData.length > 0) { |
| | | proxy.$modal.msgWarning("ä¸å¯å é¤ä»äººç»´æ¤çæ°æ®"); |
| | | return; |
| | | } |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | | return; |
| | | } |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼", "å é¤æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | tableLoading.value = true; |
| | | delSupplier(ids) |
| | | .then((res) => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getList(); |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // è·åå½åæ¥æå¹¶æ ¼å¼å为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, "0"); // æä»½ä»0å¼å§ |
| | | const day = String(today.getDate()).padStart(2, "0"); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | // æå¼éä»¶å¼¹æ¡ |
| | | const openFilesFormDia = (row) => { |
| | | nextTick(() => { |
| | | filesDia.value?.openDialog(row) |
| | | }) |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | | </script> |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <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" |
| | | @pagination-change="paginationSearch" |
| | | :total="total" |
| | | :page="page.current" |
| | | :limit="page.size" |
| | | > |
| | | </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/basicData/supplierManageFile.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 headers = ref({ |
| | | Authorization: "Bearer " + getToken(), |
| | | }); |
| | | const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // ä¸ä¼ çå¾çæå¡å¨å°å |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = (row) => { |
| | | dialogFormVisible.value = true; |
| | | currentId.value = row.id; |
| | | getList() |
| | | } |
| | | const paginationSearch = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | const getList = () => { |
| | | fileListPage({supplierId: currentId.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.supplierId = currentId.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> |
| | |
| | | <!-- å¨ä½ ç主页é¢ä¸ --> |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">ä¾åºåæ¡£æ¡ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.supplierName" |
| | | style="width: 240px" |
| | | placeholder="è¾å
¥ä¾åºååç§°æç´¢" |
| | | @change="handleQuery" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')" |
| | | >æ°å¢ä¾åºå</el-button |
| | | > |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="info" plain icon="Upload" @click="handleImport" |
| | | >导å
¥</el-button |
| | | > |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | ></PIMTable> |
| | | </div> |
| | | <el-dialog |
| | | v-model="dialogFormVisible" |
| | | :title="operationType === 'add' ? 'æ°å¢ä¾åºåä¿¡æ¯' : 'ç¼è¾ä¾åºåä¿¡æ¯'" |
| | | width="70%" |
| | | @close="closeDia" |
| | | > |
| | | <el-form |
| | | :model="form" |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="rules" |
| | | ref="formRef" |
| | | > |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¾åºååç§°ï¼" prop="supplierName"> |
| | | <el-input |
| | | v-model="form.supplierName" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item |
| | | label="纳ç¨äººè¯å«å·ï¼" |
| | | prop="taxpayerIdentificationNum" |
| | | > |
| | | <el-input |
| | | v-model="form.taxpayerIdentificationNum" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬å¸å°åï¼" prop="companyAddress"> |
| | | <el-input |
| | | v-model="form.companyAddress" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬å¸çµè¯ï¼" prop="companyPhone"> |
| | | <el-input |
| | | v-model="form.companyPhone" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="弿·è¡ï¼" prop="bankAccountName"> |
| | | <el-input |
| | | v-model="form.bankAccountName" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è´¦å·ï¼" prop="bankAccountNum"> |
| | | <el-input |
| | | v-model="form.bankAccountNum" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è系人ï¼" prop="contactUserName"> |
| | | <el-input |
| | | v-model="form.contactUserName" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èç³»çµè¯ï¼" prop="contactUserPhone"> |
| | | <el-input |
| | | v-model="form.contactUserPhone" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»´æ¤äººï¼" prop="maintainUserId"> |
| | | <el-select |
| | | v-model="form.maintainUserId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | disabled |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | | :key="item.nickName" |
| | | :label="item.nickName" |
| | | :value="item.userId" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»´æ¤æ¶é´ï¼" prop="maintainTime"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.maintainTime" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | disabled |
| | | /> |
| | | </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="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- ä¾åºå导å
¥å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | :title="upload.title" |
| | | v-model="upload.open" |
| | | width="400px" |
| | | append-to-body |
| | | > |
| | | <el-upload |
| | | ref="uploadRef" |
| | | :limit="1" |
| | | accept=".xlsx, .xls" |
| | | :headers="upload.headers" |
| | | :action="upload.url + '?updateSupport=' + upload.updateSupport" |
| | | :disabled="upload.isUploading" |
| | | :on-progress="handleFileUploadProgress" |
| | | :on-success="handleFileSuccess" |
| | | :auto-upload="false" |
| | | drag |
| | | > |
| | | <el-icon class="el-icon--upload"><upload-filled /></el-icon> |
| | | <div class="el-upload__text">å°æä»¶æå°æ¤å¤ï¼æ<em>ç¹å»ä¸ä¼ </em></div> |
| | | <template #tip> |
| | | <div class="el-upload__tip text-center"> |
| | | <span>ä»
å
许导å
¥xlsãxlsxæ ¼å¼æä»¶ã</span> |
| | | <!-- <el-link |
| | | type="primary" |
| | | :underline="false" |
| | | style="font-size: 12px; vertical-align: baseline" |
| | | @click="importTemplate" |
| | | >ä¸è½½æ¨¡æ¿</el-link |
| | | > --> |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitFileForm">ç¡® å®</el-button> |
| | | <el-button @click="upload.open = false">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <el-tabs v-model="activeTab" type="card"> |
| | | <el-tab-pane label="æ£å¸¸ä¾åºå" name="home"> |
| | | <HomeTab /> |
| | | </el-tab-pane> |
| | | <el-tab-pane label="é»åå" name="blacklist"> |
| | | <BlacklistTab /> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { onMounted, ref } from "vue"; |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import { delSupplier } from "@/api/basicData/supplierManageFile.js"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { userListNoPage } from "@/api/system/user.js"; |
| | | import { |
| | | addSupplier, |
| | | getSupplier, |
| | | listSupplier, |
| | | updateSupplier, |
| | | } from "@/api/basicData/supplierManageFile.js"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { getToken } from "@/utils/auth.js"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const userStore = useUserStore(); |
| | | <script> |
| | | import HomeTab from './components/HomeTab.vue' |
| | | import BlacklistTab from './components/BlacklistTab.vue' |
| | | |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "ä¾åºååç§°", |
| | | prop: "supplierName", |
| | | width: 250, |
| | | export default { |
| | | name: 'MainPage', |
| | | components: { |
| | | HomeTab, |
| | | BlacklistTab |
| | | }, |
| | | { |
| | | label: "纳ç¨äººè¯å«å·", |
| | | prop: "taxpayerIdentificationNum", |
| | | width: 230, |
| | | data() { |
| | | return { |
| | | activeTab: 'home' |
| | | } |
| | | }, |
| | | { |
| | | label: "å
¬å¸å°å", |
| | | prop: "companyAddress", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "èç³»æ¹å¼", |
| | | prop: "companyPhone", |
| | | width:150 |
| | | }, |
| | | { |
| | | label: "弿·è¡", |
| | | prop: "bankAccountName", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "è´¦å·", |
| | | prop: "bankAccountNum", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "è系人", |
| | | prop: "contactUserName", |
| | | }, |
| | | { |
| | | label: "èç³»çµè¯", |
| | | prop: "contactUserPhone", |
| | | width: 150, |
| | | }, |
| | | { |
| | | label: "ç»´æ¤äºº", |
| | | prop: "maintainUserName", |
| | | }, |
| | | |
| | | { |
| | | label: "ç»´æ¤æ¶é´", |
| | | prop: "maintainTime", |
| | | width:100 |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: 'right', |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.maintainUserName !== userStore.nickName |
| | | } |
| | | }, |
| | | ], |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const userList = ref([]); |
| | | const tableLoading = ref(false); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0, |
| | | }); |
| | | |
| | | // ç¨æ·ä¿¡æ¯è¡¨åå¼¹æ¡æ°æ® |
| | | const operationType = ref(""); |
| | | const dialogFormVisible = ref(false); |
| | | const data = reactive({ |
| | | searchForm: { |
| | | supplierName: "", |
| | | }, |
| | | form: { |
| | | supplierName: "", |
| | | taxpayerIdentificationNum: "", |
| | | companyAddress: "", |
| | | companyPhone: "", |
| | | bankAccountName: "", |
| | | bankAccountNum: "", |
| | | contactUserName: "", |
| | | contactUserPhone: "", |
| | | maintainUserId: "", |
| | | maintainTime: "", |
| | | }, |
| | | rules: { |
| | | supplierName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | taxpayerIdentificationNum: [ |
| | | { required: true, message: "请è¾å
¥", trigger: "blur" }, |
| | | ], |
| | | companyAddress: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | companyPhone: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | bankAccountName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | bankAccountNum: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | contactUserName: [{ required: false, message: "请è¾å
¥", trigger: "blur" }], |
| | | contactUserPhone: [{ required: false, message: "请è¾å
¥", trigger: "blur" }], |
| | | maintainUserId: [{ required: false, message: "è¯·éæ©", trigger: "change" }], |
| | | maintainTime: [{ required: false, message: "è¯·éæ©", trigger: "change" }], |
| | | }, |
| | | }); |
| | | const { searchForm, form, rules } = toRefs(data); |
| | | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | /** æäº¤ä¸ä¼ æä»¶ */ |
| | | function submitFileForm() { |
| | | console.log(upload.url + '?updateSupport=' + upload.updateSupport) |
| | | proxy.$refs["uploadRef"].submit(); |
| | | } |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | listSupplier({ ...searchForm.value, ...page }).then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records; |
| | | page.total = res.data.total; |
| | | }); |
| | | }; |
| | | const upload = reactive({ |
| | | // æ¯å¦æ¾ç¤ºå¼¹åºå±ï¼ä¾åºå导å
¥ï¼ |
| | | open: false, |
| | | // å¼¹åºå±æ é¢ï¼ä¾åºå导å
¥ï¼ |
| | | title: "", |
| | | // æ¯å¦ç¦ç¨ä¸ä¼ |
| | | isUploading: false, |
| | | // æ¯å¦æ´æ°å·²ç»åå¨çç¨æ·æ°æ® |
| | | updateSupport: 1, |
| | | // 设置ä¸ä¼ ç请æ±å¤´é¨ |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | // ä¸ä¼ çå°å |
| | | url: import.meta.env.VITE_APP_BASE_API + "/system/supplier/import", |
| | | }); |
| | | /** 导å
¥æé®æä½ */ |
| | | function handleImport() { |
| | | upload.title = "ä¾åºå导å
¥"; |
| | | upload.open = true; |
| | | } |
| | | |
| | | /**æä»¶ä¸ä¼ ä¸å¤ç */ |
| | | const handleFileUploadProgress = (event, file, fileList) => { |
| | | upload.isUploading = true; |
| | | }; |
| | | |
| | | /** æä»¶ä¸ä¼ æåå¤ç */ |
| | | const handleFileSuccess = (response, file, fileList) => { |
| | | upload.open = false; |
| | | upload.isUploading = false; |
| | | proxy.$refs["uploadRef"].handleRemove(file); |
| | | getList(); |
| | | }; |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | // æå¼å¼¹æ¡ |
| | | const openForm = (type, row) => { |
| | | operationType.value = type; |
| | | form.value = {}; |
| | | form.value.maintainUserId = userStore.id; |
| | | form.value.maintainTime = getCurrentDate(); |
| | | userListNoPage().then((res) => { |
| | | userList.value = res.data; |
| | | }); |
| | | if (type === "edit") { |
| | | getSupplier(row.id).then((res) => { |
| | | form.value = { ...res.data }; |
| | | }); |
| | | } |
| | | dialogFormVisible.value = true; |
| | | }; |
| | | // æäº¤è¡¨å |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate((valid) => { |
| | | if (valid) { |
| | | if (operationType.value === "edit") { |
| | | submitEdit(); |
| | | } else { |
| | | submitAdd(); |
| | | watch: { |
| | | activeTab(newVal) { |
| | | if (newVal === 'home') { |
| | | this.$refs.homeTab && this.$refs.homeTab.getList() |
| | | } else if (newVal === 'blacklist') { |
| | | this.$refs.blacklistTab && this.$refs.blacklistTab.getList() |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | // æäº¤æ°å¢ |
| | | const submitAdd = () => { |
| | | addSupplier(form.value).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | getList(); |
| | | }); |
| | | }; |
| | | // æäº¤ä¿®æ¹ |
| | | const submitEdit = () => { |
| | | updateSupplier(form.value).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | getList(); |
| | | }); |
| | | }; |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | | dialogFormVisible.value = false; |
| | | }; |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/system/supplier/export", {}, "ä¾åºåæ¡£æ¡.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | // å é¤ |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | // æ£æ¥æ¯å¦æä»äººç»´æ¤çæ°æ® |
| | | const unauthorizedData = selectedRows.value.filter(item => item.maintainUserName !== userStore.nickName); |
| | | if (unauthorizedData.length > 0) { |
| | | proxy.$modal.msgWarning("ä¸å¯å é¤ä»äººç»´æ¤çæ°æ®"); |
| | | return; |
| | | } |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | | return; |
| | | } |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼", "å é¤æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | tableLoading.value = true; |
| | | delSupplier(ids) |
| | | .then((res) => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getList(); |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // è·åå½åæ¥æå¹¶æ ¼å¼å为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, "0"); // æä»½ä»0å¼å§ |
| | | const day = String(today.getDate()).padStart(2, "0"); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | </script> |
| | | <style> |
| | | .main-container :deep(.el-tabs__item.is-active) { |
| | | color: #1883f6 !important; |
| | | border-bottom: 2px solid #409EFF; |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| | | </style> |
| | |
| | | <span class="flash_cursor"></span> |
| | | </template> |
| | | <template v-else> |
| | | <pre>{{ item.msg }}</pre> |
| | | <pre style="font-family: none;">{{ item.msg }}</pre> |
| | | </template> |
| | | </div> |
| | | <div class="chat-img" v-if="item.chatType == 1"> |
| | |
| | | } |
| | | chatList.value.push(chatMsg) |
| | | let chatGPT = { |
| | | headImg: headPortrait, |
| | | headImg: chatGPTHeadImg, |
| | | name: 'å°æº', |
| | | time: new Date().toLocaleTimeString(), |
| | | msg: "", |
| | |
| | | uid: '1002' |
| | | }) |
| | | chatList.value.push({ |
| | | headImg: chatGPTHeadImg, |
| | | headImg: headPortrait, |
| | | name: 'å§é¾', |
| | | time: new Date().toLocaleTimeString(), |
| | | msg: route.query.keyWord, |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, getCurrentInstance, reactive, ref, toRefs } from "vue"; |
| | | import { computed, getCurrentInstance, nextTick, reactive, ref, toRefs } from "vue"; |
| | | import { |
| | | approveProcessDetails, |
| | | getDept, |
| | |
| | | userList.value = res.data; |
| | | }); |
| | | form.value = {...row} |
| | | getProductOptions() |
| | | // ç«å³æ¸
é¤è¡¨åéªè¯ç¶æï¼å ä¸ºåæ®µæ¯disabledçï¼ä¸éè¦éªè¯ï¼ |
| | | nextTick(() => { |
| | | if (formRef.value) { |
| | | formRef.value.clearValidate(); |
| | | } |
| | | }); |
| | | // ç¡®ä¿é项å è½½å®æååå¹é
å¼ç±»å |
| | | getProductOptions().then(() => { |
| | | // ç¡®ä¿å¼ç±»åå¹é
ï¼å¦æé项已å è½½ï¼ |
| | | if (productOptions.value.length > 0 && form.value.approveDeptId) { |
| | | const matchedOption = productOptions.value.find(opt => |
| | | opt.deptId == form.value.approveDeptId || |
| | | String(opt.deptId) === String(form.value.approveDeptId) |
| | | ); |
| | | if (matchedOption) { |
| | | form.value.approveDeptId = matchedOption.deptId; |
| | | } |
| | | } |
| | | // 忬¡æ¸
é¤éªè¯ï¼ç¡®ä¿é项å è½½åå¼å¹é
æ£ç¡® |
| | | nextTick(() => { |
| | | if (formRef.value) { |
| | | formRef.value.clearValidate(); |
| | | } |
| | | }); |
| | | }); |
| | | |
| | | // æ¥ä»·å®¡æ¹ï¼ç¨å®¡æ¹äºç±å段æ¿è½½çâæ¥ä»·åå·â廿¥æ¥ä»·å表 |
| | | if (isQuotationApproval.value) { |
| | |
| | | }) |
| | | } |
| | | const getProductOptions = () => { |
| | | getDept().then((res) => { |
| | | return getDept().then((res) => { |
| | | productOptions.value = res.data; |
| | | }); |
| | | }; |
| | | // æäº¤å®¡æ¹ |
| | | const submitForm = (status) => { |
| | | const filteredActivities = activities.value.filter(activity => activity.isShen); |
| | | filteredActivities[0].approveNodeStatus = status; |
| | | if (!filteredActivities || filteredActivities.length === 0) { |
| | | proxy.$modal.msgError("æªæ¾å°å¾
审æ¹çèç¹"); |
| | | return; |
| | | } |
| | | const currentActivity = filteredActivities[0]; |
| | | if (!currentActivity) { |
| | | proxy.$modal.msgError("æªæ¾å°å¾
审æ¹çèç¹"); |
| | | return; |
| | | } |
| | | currentActivity.approveNodeStatus = status; |
| | | // 夿æ¯å¦ä¸ºæå䏿¥ |
| | | const isLast = activities.value.findIndex(a => a.isShen) === activities.value.length-1; |
| | | updateApproveNode({ ...filteredActivities[0], isLast }).then(() => { |
| | | updateApproveNode({ ...currentActivity, isLast }).then(() => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | }); |
| | |
| | | width: 200px; |
| | | height: 60px; |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <!-- ç³è¯·é¨é¨ï¼æ ¡éªä½¿ç¨é¨é¨IDï¼ä¾¿äºä¸æéæ©åç«å³éè¿æ ¡éª --> |
| | | <el-form-item label="ç³è¯·é¨é¨ï¼" prop="approveDeptId"> |
| | | <el-form-item label="ç³è¯·é¨é¨ï¼" prop="approveDeptName"> |
| | | <!-- <el-input v-model="form.approveDeptName" placeholder="请è¾å
¥" clearable/>--> |
| | | <el-select |
| | | v-model="form.approveDeptId" |
| | |
| | | <!-- åºå·®å°ç¹ï¼ä»
å½ approveType 为 3 æ¶æ¾ç¤ºï¼ --> |
| | | <el-row v-if="props.approveType == 3"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="夿³¨ï¼" prop="location"> |
| | | <el-form-item label="åºå·®å°ç¹ï¼" prop="location"> |
| | | <el-input |
| | | v-model="form.location" |
| | | placeholder="请è¾å
¥å¤æ³¨" |
| | | placeholder="请è¾å
¥åºå·®å°ç¹" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | |
| | | approveTime: "", |
| | | approveId: "", |
| | | approveUser: "", |
| | | approveDeptId: "", |
| | | approveDeptId: "", |
| | | approveDeptName: "", |
| | | approveReason: "", |
| | | checkResult: "", |
| | |
| | | location: "" // åºå·®å°ç¹ |
| | | }, |
| | | rules: { |
| | | approveTime: [{ required: false, message: "请è¾å
¥", trigger: "change" }], |
| | | approveTime: [{ required: false, message: "请è¾å
¥", trigger: "change" },], |
| | | approveId: [{ required: false, message: "请è¾å
¥", trigger: "blur" }], |
| | | approveUser: [{ required: false, message: "请è¾å
¥", trigger: "blur" }], |
| | | // 使ç¨é¨é¨IDåå¿
å¡«æ ¡éªï¼é¿å
åç§°æªåæ¥å¯¼è´è¯¯æ¥ |
| | | approveDeptId: [{ required: true, message: "è¯·éæ©ç³è¯·é¨é¨", trigger: "change" }], |
| | | approveDeptName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | approveReason: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | checkResult: [{ required: false, message: "请è¾å
¥", trigger: "blur" }], |
| | | startDate: [{ required: true, message: "è¯·éæ©è¯·åå¼å§æ¶é´", trigger: "change" }], |
| | |
| | | userListNoPageByTenantId().then((res) => { |
| | | userList.value = res.data; |
| | | }); |
| | | getProductOptions(); |
| | | form.value = {} |
| | | approverNodes.value = [ |
| | | { id: 1, userId: null } |
| | |
| | | |
| | | // è·åå½åç¨æ·ä¿¡æ¯å¹¶è®¾ç½®é¨é¨ID |
| | | form.value.approveDeptId = userStore.currentDeptId |
| | | |
| | | // å è½½é¨é¨é项ï¼å¹¶å¨å è½½å®æå设置é¨é¨åç§° |
| | | getProductOptions(); |
| | | if (operationType.value === 'edit') { |
| | | fileList.value = row.commonFileList |
| | | form.value.tempFileIds = fileList.value.map(file => file.id) |
| | |
| | | } |
| | | } |
| | | const getProductOptions = () => { |
| | | getDept().then((res) => { |
| | | return getDept().then((res) => { |
| | | productOptions.value = res.data; |
| | | // 妿已æé¨é¨IDï¼èªå¨è®¾ç½®é¨é¨åç§°ï¼ç¨äºéªè¯ï¼ |
| | | if (form.value.approveDeptId && productOptions.value.length > 0) { |
| | | const matchedDept = productOptions.value.find(dept => |
| | | dept.deptId == form.value.approveDeptId || |
| | | String(dept.deptId) === String(form.value.approveDeptId) |
| | | ); |
| | | if (matchedDept) { |
| | | form.value.approveDeptName = matchedDept.deptName; |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | function convertIdToValue(data) { |
| | |
| | | <div class="app-container"> |
| | | <!-- æ ç¾é¡µåæ¢ä¸åç审æ¹ç±»å --> |
| | | <el-tabs v-model="activeTab" @tab-change="handleTabChange" class="approval-tabs"> |
| | | <el-tab-pane label="åå审æ¹" name="1"></el-tab-pane> |
| | | <el-tab-pane label="å
¬åºç®¡ç" name="1"></el-tab-pane> |
| | | <el-tab-pane label="请å管ç" name="2"></el-tab-pane> |
| | | <el-tab-pane label="éå®å®¡æ¹" name="3"></el-tab-pane> |
| | | <el-tab-pane label="æ¥é审æ¹" name="4"></el-tab-pane> |
| | | <el-tab-pane label="åºå·®ç®¡ç" name="3"></el-tab-pane> |
| | | <el-tab-pane label="æ¥é管ç" name="4"></el-tab-pane> |
| | | <el-tab-pane label="éè´å®¡æ¹" name="5"></el-tab-pane> |
| | | <el-tab-pane label="æ¥ä»·å®¡æ¹" name="6"></el-tab-pane> |
| | | <el-tab-pane label="åºåºå®¡æ¹" name="7"></el-tab-pane> |
| | | <el-tab-pane label="å货审æ¹" name="7"></el-tab-pane> |
| | | </el-tabs> |
| | | |
| | | <div class="search_form"> |
| | |
| | | > |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')" v-if="currentApproveType !== 6">æ°å¢</el-button> |
| | | <el-button |
| | | type="primary" |
| | | @click="openForm('add')" |
| | | v-if="currentApproveType !== 6 && currentApproveType !== 7" |
| | | >æ°å¢</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | @click="handleDelete" |
| | | v-if="currentApproveType !== 7" |
| | | >å é¤</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | disabled: (row) => currentApproveType.value === 6 || row.approveStatus == 2 || row.approveStatus == 1 || row.approveStatus == 4 |
| | | disabled: (row) => |
| | | currentApproveType.value === 6 || |
| | | currentApproveType.value === 7 || |
| | | row.approveStatus == 2 || |
| | | row.approveStatus == 1 || |
| | | row.approveStatus == 4 |
| | | }, |
| | | { |
| | | name: "å®¡æ ¸", |
| | |
| | | 4: "æ¥é管ç审æ¹è¡¨", |
| | | 5: "éè´ç³è¯·å®¡æ¹è¡¨", |
| | | 6: "æ¥ä»·å®¡æ¹è¡¨", |
| | | 7: "åºåºå®¡æ¹è¡¨", |
| | | 7: "å货审æ¹è¡¨", |
| | | } |
| | | const fileName = nameMap[type] || nameMap[0] |
| | | proxy.download(url, {}, `${fileName}.xlsx`) |
| | |
| | | getEmployeeDetail |
| | | } from '@/api/collaborativeApproval/enterpriseBook.js' |
| | | import { getUserProfile } from '@/api/system/user.js' |
| | | import {staffJoinListPage} from "@/api/personnelManagement/onboarding.js"; |
| | | import { |
| | | changeUserStatus, |
| | | listUser, |
| | |
| | | addUser, |
| | | deptTreeSelect, |
| | | } from "@/api/system/user"; |
| | | import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js"; |
| | | |
| | | // æ ç¾é¡µç¶æ |
| | | const activeTab = ref('personal') |
| | |
| | | } |
| | | //è·ååå·¥å表 |
| | | const getEmployeeList = async () => { |
| | | staffJoinListPage(publicSearch.value).then(res => { |
| | | staffOnJobListPage(Object.assign({current: -1, size: -1},publicSearch.value)).then(res => { |
| | | console.log(res.data.records) |
| | | EmployeeList.value = res.data.records |
| | | }).catch(err => {}) |
| | |
| | | // è·ååä½é讯å½å表 |
| | | const getCompanyContactsList = async () => { |
| | | loading.value = true |
| | | staffJoinListPage(companySearch.value).then(res => { |
| | | staffOnJobListPage(Object.assign({current: -1, size: -1},companySearch.value)).then(res => { |
| | | // console.log(res.data.records) |
| | | companyContacts.value = res.data.records |
| | | }).catch(err => {}) |
| | |
| | | }; |
| | | |
| | | if (row.id) { |
| | | // ç¼è¾æ¨¡å¼ - å
å é¤åæ·»å ï¼å ä¸ºåªæ add å del æ¥å£ï¼ |
| | | delNoticeType(row.id).then(res => { |
| | | if (res.code === 200) { |
| | | addNoticeType(data).then(addRes => { |
| | | if (addRes.code === 200) { |
| | | ElMessage.success('ç¼è¾æå'); |
| | | row.editing = false; |
| | | delete row.originalNoticeType; |
| | | fetchNoticeTypeList().then(() => { |
| | | // 妿å½åéä¸çç±»å被ç¼è¾ï¼éè¦éæ°è·åæ°æ® |
| | | if (activeNoticeTypeTab.value === String(row.id)) { |
| | | fetchNoticesByType(addRes.data?.id || row.id); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | } else { |
| | | // æ°å¢æ¨¡å¼ |
| | | addNoticeType(data).then(res => { |
| | | if (res.code === 200) { |
| | | ElMessage.success('æ°å¢æå'); |
| | | row.editing = false; |
| | | fetchNoticeTypeList(); |
| | | } |
| | | }); |
| | | // ç¼è¾æ¨¡å¼ - ä¼ å
¥id |
| | | data.id = row.id; |
| | | } |
| | | |
| | | addNoticeType(data).then(res => { |
| | | if (res.code === 200) { |
| | | ElMessage.success(row.id ? 'ç¼è¾æå' : 'æ°å¢æå'); |
| | | row.editing = false; |
| | | delete row.originalNoticeType; |
| | | fetchNoticeTypeList().then(() => { |
| | | // 妿å½åéä¸çç±»å被ç¼è¾ï¼éè¦éæ°è·åæ°æ® |
| | | if (row.id && activeNoticeTypeTab.value === String(row.id)) { |
| | | fetchNoticesByType(res.data?.id || row.id); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const handleDeleteNoticeType = (row) => { |
| | |
| | | <el-option |
| | | v-for="person in employees" |
| | | :key="person.id" |
| | | :label="`${person.staffName} (${person.postJob})`" |
| | | :label="`${person.staffName} (${person.postName})`" |
| | | :value="person.id" |
| | | /> |
| | | </el-select> |
| | |
| | | import {ElMessage} from 'element-plus' |
| | | import {Plus, Document, Promotion, Bell} from '@element-plus/icons-vue' |
| | | import {getRoomEnum, saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js' |
| | | import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js"; |
| | | import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js"; |
| | | |
| | | // å½åç³è¯·ç±»å |
| | | const currentType = ref('department') // approval: å®¡æ¹æµç¨, department: é¨é¨çº§, notification: éç¥åå¸ |
| | |
| | | getRoomEnum().then(res => { |
| | | meetingRooms.value = res.data |
| | | }) |
| | | getStaffOnJob().then(res => { |
| | | employees.value = res.data.sort((a, b) => a.postJob.localeCompare(b.postJob)) |
| | | staffOnJobListPage({ |
| | | current: -1, |
| | | size: -1, |
| | | staffState: 1 |
| | | }).then(res => { |
| | | employees.value = res.data.records.sort((a, b) => a.postName.localeCompare(b.postName)) |
| | | }) |
| | | }) |
| | | </script> |
| | |
| | | import {ElMessage, ElMessageBox} from 'element-plus' |
| | | import Pagination from '@/components/Pagination/index.vue' |
| | | import {getRoomEnum, getExamineList,saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js' |
| | | import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js"; |
| | | import dayjs from "dayjs"; |
| | | import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js"; |
| | | |
| | | // æ°æ®å表å è½½ç¶æ |
| | | const loading = ref(false) |
| | |
| | | it.participants = staffList.value.filter(staff => staffs.some(id=>id === staff.id)).map(staff => { |
| | | return { |
| | | id: staff.id, |
| | | name: `${staff.staffName}(${staff.postJob})` |
| | | name: `${staff.staffName}(${staff.postName})` |
| | | } |
| | | }) |
| | | |
| | |
| | | |
| | | // 页é¢å è½½æ¶è·åæ°æ® |
| | | onMounted(async () => { |
| | | const [resp1, resp2]= await Promise.all([getRoomEnum(), getStaffOnJob()]) |
| | | const [resp1, resp2]= await Promise.all([getRoomEnum(), staffOnJobListPage({current: -1, size: -1, staffState: 1})]) |
| | | roomEnum.value = resp1.data |
| | | staffList.value = resp2.data |
| | | staffList.value = resp2.data.records |
| | | |
| | | await getList() |
| | | }) |
| | |
| | | import {ElMessage, ElMessageBox} from 'element-plus' |
| | | import Pagination from '@/components/Pagination/index.vue' |
| | | import {getRoomEnum, getMeetingPublish,saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js' |
| | | import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js"; |
| | | import dayjs from "dayjs"; |
| | | import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js"; |
| | | |
| | | // æ°æ®å表å è½½ç¶æ |
| | | const loading = ref(false) |
| | |
| | | it.participants = staffList.value.filter(staff => staffs.some(id=>id === staff.id)).map(staff => { |
| | | return { |
| | | id: staff.id, |
| | | name: `${staff.staffName}(${staff.postJob})` |
| | | name: `${staff.staffName}(${staff.postName})` |
| | | } |
| | | }) |
| | | |
| | |
| | | |
| | | // 页é¢å è½½æ¶è·åæ°æ® |
| | | onMounted(async () => { |
| | | const [resp1, resp2]= await Promise.all([getRoomEnum(), getStaffOnJob()]) |
| | | const [resp1, resp2]= await Promise.all([getRoomEnum(), staffOnJobListPage({current: -1, size: -1, staffState: 1})]) |
| | | roomEnum.value = resp1.data |
| | | staffList.value = resp2.data |
| | | staffList.value = resp2.data.records |
| | | |
| | | await getList() |
| | | }) |
| | |
| | | import Pagination from '@/components/Pagination/index.vue' |
| | | import Editor from '@/components/Editor/index.vue' |
| | | import { getRoomEnum, getMeetingPublish ,getMeetingMinutesByMeetingId,saveMeetingMinutes} from '@/api/collaborativeApproval/meeting.js' |
| | | import { getStaffOnJob } from "@/api/personnelManagement/onboarding.js" |
| | | import dayjs from "dayjs" |
| | | import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js"; |
| | | |
| | | // æ°æ®å表å è½½ç¶æ |
| | | const loading = ref(false) |
| | |
| | | it.participants = staffList.value.filter(staff => staffs.some(id => id === staff.id)).map(staff => { |
| | | return { |
| | | id: staff.id, |
| | | name: `${staff.staffName}(${staff.postJob})` |
| | | name: `${staff.staffName}(${staff.postName})` |
| | | } |
| | | }) |
| | | |
| | |
| | | |
| | | // 页é¢å è½½æ¶è·åæ°æ® |
| | | onMounted(async () => { |
| | | const [resp1, resp2] = await Promise.all([getRoomEnum(), getStaffOnJob()]) |
| | | const [resp1, resp2] = await Promise.all([getRoomEnum(), staffOnJobListPage({current: -1, size: -1, staffState: 1})]) |
| | | roomEnum.value = resp1.data |
| | | staffList.value = resp2.data |
| | | staffList.value = resp2.data.records |
| | | |
| | | await getList() |
| | | }) |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | |
| | | <!-- è§ç« å¶åº¦ç®¡ç--> |
| | | <el-card class="box-card"> |
| | | <template #header> |
| | | <div class="card-header"> |
| | | <span>è§ç« å¶åº¦åå¸</span> |
| | | </div> |
| | | <!-- è§ç« å¶åº¦ç®¡ç--> |
| | | <el-card class="box-card"> |
| | | <template #header> |
| | | <div class="card-header"> |
| | | <span>è§ç« å¶åº¦åå¸</span> |
| | | </div> |
| | | </template> |
| | | <div class="tab-content"> |
| | | <el-row :gutter="20" |
| | | class="mb-20"> |
| | | <span class="ml-10">å¶åº¦æ é¢ï¼</span> |
| | | <el-col :span="6"> |
| | | <el-input v-model="regulationSearchForm.title" |
| | | placeholder="请è¾å
¥å¶åº¦æ é¢" |
| | | clearable /> |
| | | </el-col> |
| | | <span class="search_title">å¶åº¦åç±»ï¼</span> |
| | | <el-col :span="4"> |
| | | <el-select v-model="regulationSearchForm.category" |
| | | placeholder="å¶åº¦åç±»" |
| | | clearable> |
| | | <el-option label="人äºå¶åº¦" |
| | | value="hr" /> |
| | | <el-option label="è´¢å¡å¶åº¦" |
| | | value="finance" /> |
| | | <el-option label="å®å
¨å¶åº¦" |
| | | value="safety" /> |
| | | <el-option label="ææ¯å¶åº¦" |
| | | value="tech" /> |
| | | </el-select> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-button type="primary" |
| | | @click="searchRegulations">æç´¢</el-button> |
| | | <el-button @click="resetRegulationSearch">éç½®</el-button> |
| | | <el-button @click="handleExport">导åº</el-button> |
| | | <el-button type="success" |
| | | @click="handleAdd"> |
| | | åå¸å¶åº¦ |
| | | </el-button> |
| | | </el-col> |
| | | </el-row> |
| | | <el-table :data="regulations" |
| | | border |
| | | v-loading="tableLoading" |
| | | style="width: 100%"> |
| | | <el-table-column prop="regulationNum" |
| | | label="å¶åº¦ç¼å·" |
| | | width="120" /> |
| | | <el-table-column prop="title" |
| | | label="å¶åº¦æ é¢" |
| | | min-width="150" /> |
| | | <el-table-column prop="category" |
| | | label="åç±»" |
| | | width="120"> |
| | | <template #default="scope"> |
| | | <el-tag>{{ getCategoryText(scope.row.category) }}</el-tag> |
| | | </template> |
| | | <div class="tab-content"> |
| | | <el-row :gutter="20" class="mb-20"> |
| | | <span class="ml-10">å¶åº¦æ é¢ï¼</span> |
| | | <el-col :span="6"> |
| | | <el-input v-model="regulationSearchForm.title" placeholder="请è¾å
¥å¶åº¦æ é¢" clearable /> |
| | | </el-col> |
| | | <span class="search_title">å¶åº¦åç±»ï¼</span> |
| | | <el-col :span="4"> |
| | | <el-select v-model="regulationSearchForm.category" placeholder="å¶åº¦åç±»" clearable> |
| | | <el-option label="人äºå¶åº¦" value="hr" /> |
| | | <el-option label="è´¢å¡å¶åº¦" value="finance" /> |
| | | <el-option label="å®å
¨å¶åº¦" value="safety" /> |
| | | <el-option label="ææ¯å¶åº¦" value="tech" /> |
| | | </el-select> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-button type="primary" @click="searchRegulations">æç´¢</el-button> |
| | | <el-button @click="resetRegulationSearch">éç½®</el-button> |
| | | <el-button @click="handleExport">导åº</el-button> |
| | | <el-button type="success" @click="handleAdd"> |
| | | åå¸å¶åº¦ |
| | | </el-button> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-table :data="regulations" border v-loading="tableLoading" style="width: 100%"> |
| | | <el-table-column prop="regulationNum" label="å¶åº¦ç¼å·" width="120" /> |
| | | <el-table-column prop="title" label="å¶åº¦æ é¢" min-width="150" /> |
| | | <el-table-column prop="category" label="åç±»" width="120"> |
| | | <template #default="scope"> |
| | | <el-tag>{{ getCategoryText(scope.row.category) }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="version" label="çæ¬" width="120" /> |
| | | <el-table-column prop="createUserName" label="åå¸äºº" width="120" /> |
| | | <el-table-column prop="createTime" label="å叿¶é´" width="180" /> |
| | | <el-table-column prop="status" label="ç¶æ" width="100"> |
| | | <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="readCount" label="已读人æ°" width="100" /> |
| | | <el-table-column label="æä½" width="320" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button link @click="viewRegulation(scope.row)">æ¥ç</el-button> |
| | | <el-button link type="primary" @click="handleEdit(scope.row)">ç¼è¾</el-button> |
| | | <el-button link type="danger" @click="repealEdit(scope.row)">åºå¼</el-button> |
| | | <el-button link type="success" @click="viewVersionHistory(scope.row)">çæ¬åå²</el-button> |
| | | <el-button link type="warning" @click="viewReadStatus(scope.row)">é
è¯»ç¶æ</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </el-card> |
| | | |
| | | </el-table-column> |
| | | <el-table-column prop="version" |
| | | label="çæ¬" |
| | | width="120" /> |
| | | <el-table-column prop="createUserName" |
| | | label="åå¸äºº" |
| | | width="120" /> |
| | | <el-table-column prop="createTime" |
| | | label="å叿¶é´" |
| | | width="180" /> |
| | | <el-table-column prop="status" |
| | | label="ç¶æ" |
| | | width="100"> |
| | | <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="readCount" |
| | | label="已读人æ°" |
| | | width="100" /> |
| | | <el-table-column label="æä½" |
| | | width="320" |
| | | fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button link |
| | | @click="viewRegulation(scope.row)">æ¥ç</el-button> |
| | | <el-button link |
| | | type="primary" |
| | | @click="handleEdit(scope.row)">ç¼è¾</el-button> |
| | | <el-button link |
| | | type="danger" |
| | | @click="repealEdit(scope.row)">åºå¼</el-button> |
| | | <el-button link |
| | | type="success" |
| | | @click="viewVersionHistory(scope.row)">çæ¬åå²</el-button> |
| | | <!-- <el-button link type="warning" @click="viewReadStatus(scope.row)">é
è¯»ç¶æ</el-button> --> |
| | | <el-button link |
| | | type="primary" |
| | | @click="openFileDialog(scope.row)">éä»¶</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </el-card> |
| | | <!-- ç¨å°ç³è¯·å¯¹è¯æ¡ï¼å·²ç§»é¤ï¼ --> |
| | | |
| | | <!-- è§ç« å¶åº¦åå¸å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="showRegulationDialog" :title="operationType === 'add' ? 'åå¸å¶åº¦' : 'ç¼è¾å¶åº¦'" width="800px"> |
| | | <el-form :model="regulationForm" :rules="regulationRules" ref="regulationFormRef" label-width="100px"> |
| | | <el-form-item label="å¶åº¦ç¼å·" prop="regulationNum"> |
| | | <el-input v-model="regulationForm.regulationNum" placeholder="请è¾å
¥å¶åº¦ç¼å·" /> |
| | | <el-dialog v-model="showRegulationDialog" |
| | | :title="operationType === 'add' ? 'åå¸å¶åº¦' : 'ç¼è¾å¶åº¦'" |
| | | width="800px"> |
| | | <el-form :model="regulationForm" |
| | | :rules="regulationRules" |
| | | ref="regulationFormRef" |
| | | label-width="100px"> |
| | | <el-form-item label="å¶åº¦ç¼å·" |
| | | prop="regulationNum"> |
| | | <el-input v-model="regulationForm.regulationNum" |
| | | placeholder="请è¾å
¥å¶åº¦ç¼å·" /> |
| | | </el-form-item> |
| | | <el-form-item label="å¶åº¦æ é¢" prop="title"> |
| | | <el-input v-model="regulationForm.title" placeholder="请è¾å
¥å¶åº¦æ é¢" /> |
| | | <el-form-item label="å¶åº¦æ é¢" |
| | | prop="title"> |
| | | <el-input v-model="regulationForm.title" |
| | | placeholder="请è¾å
¥å¶åº¦æ é¢" /> |
| | | </el-form-item> |
| | | <el-form-item label="å¶åº¦åç±»" prop="category"> |
| | | <el-select v-model="regulationForm.category" placeholder="è¯·éæ©å¶åº¦åç±»" style="width: 100%"> |
| | | <el-option label="人äºå¶åº¦" value="hr" /> |
| | | <el-option label="è´¢å¡å¶åº¦" value="finance" /> |
| | | <el-option label="å®å
¨å¶åº¦" value="safety" /> |
| | | <el-option label="ææ¯å¶åº¦" value="tech" /> |
| | | <el-form-item label="å¶åº¦åç±»" |
| | | prop="category"> |
| | | <el-select v-model="regulationForm.category" |
| | | placeholder="è¯·éæ©å¶åº¦åç±»" |
| | | style="width: 100%"> |
| | | <el-option label="人äºå¶åº¦" |
| | | value="hr" /> |
| | | <el-option label="è´¢å¡å¶åº¦" |
| | | value="finance" /> |
| | | <el-option label="å®å
¨å¶åº¦" |
| | | value="safety" /> |
| | | <el-option label="ææ¯å¶åº¦" |
| | | value="tech" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å¶åº¦å
容" prop="content"> |
| | | <el-input v-model="regulationForm.content" type="textarea" :rows="10" placeholder="请è¾å
¥å¶åº¦è¯¦ç»å
容" /> |
| | | <el-form-item label="å¶åº¦å
容" |
| | | prop="content"> |
| | | <el-input v-model="regulationForm.content" |
| | | type="textarea" |
| | | :rows="10" |
| | | placeholder="请è¾å
¥å¶åº¦è¯¦ç»å
容" /> |
| | | </el-form-item> |
| | | <el-form-item label="å¶åº¦çæ¬" prop="version"> |
| | | <el-input v-model="regulationForm.version" placeholder="请è¾å
¥å¶åº¦çæ¬" /> |
| | | <el-form-item label="å¶åº¦çæ¬" |
| | | prop="version"> |
| | | <el-input v-model="regulationForm.version" |
| | | placeholder="请è¾å
¥å¶åº¦çæ¬" /> |
| | | </el-form-item> |
| | | <el-form-item label="çææ¶é´" prop="effectiveTime"> |
| | | <el-date-picker v-model="regulationForm.effectiveTime" type="datetime" format="YYYY-MM-DD HH:mm:ss" |
| | | value-format="YYYY-MM-DD HH:mm:ss" placeholder="éæ©çææ¶é´" style="width: 100%" /> |
| | | <el-form-item label="çææ¶é´" |
| | | prop="effectiveTime"> |
| | | <el-date-picker v-model="regulationForm.effectiveTime" |
| | | type="datetime" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | placeholder="éæ©çææ¶é´" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | <el-form-item label="éç¨èå´" prop="scope"> |
| | | <el-form-item label="éç¨èå´" |
| | | prop="scope"> |
| | | <el-checkbox-group v-model="regulationForm.scope"> |
| | | <el-checkbox label="all">å
¨ä½åå·¥</el-checkbox> |
| | | <el-checkbox label="manager">管çå±</el-checkbox> |
| | |
| | | <el-checkbox label="tech">ææ¯é¨é¨</el-checkbox> |
| | | </el-checkbox-group> |
| | | </el-form-item> |
| | | <el-form-item label="æ¯å¦éè¦ç¡®è®¤" prop="requireConfirm"> |
| | | <el-form-item label="æ¯å¦éè¦ç¡®è®¤" |
| | | prop="requireConfirm"> |
| | | <el-switch v-model="regulationForm.requireConfirm" /> |
| | | <span class="ml-10">å¼å¯ååå·¥éè¦é
读确认</span> |
| | | </el-form-item> |
| | |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="showRegulationDialog = false">åæ¶</el-button> |
| | | <el-button type="primary" @click="submitRegulation">åå¸å¶åº¦</el-button> |
| | | <el-button type="primary" |
| | | @click="submitRegulation">åå¸å¶åº¦</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- ç¨å°è¯¦æ
å¯¹è¯æ¡ï¼å·²ç§»é¤ï¼ --> |
| | | |
| | | <!-- è§ç« å¶åº¦è¯¦æ
å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="showRegulationDetailDialog" title="è§ç« å¶åº¦è¯¦æ
" width="800px"> |
| | | <el-dialog v-model="showRegulationDetailDialog" |
| | | title="è§ç« å¶åº¦è¯¦æ
" |
| | | width="800px"> |
| | | <div v-if="currentRegulationDetail"> |
| | | <el-descriptions :column="2" border> |
| | | <el-descriptions :column="2" |
| | | border> |
| | | <el-descriptions-item label="å¶åº¦ç¼å·">{{ currentRegulationDetail.id }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¶åº¦æ é¢">{{ currentRegulationDetail.title }}</el-descriptions-item> |
| | | <el-descriptions-item label="åç±»">{{ getCategoryText(currentRegulationDetail.category) }}</el-descriptions-item> |
| | |
| | | <div class="regulation-content">{{ currentRegulationDetail.content }}</div> |
| | | </div> |
| | | <!-- 妿tableData>0 æ¾ç¤º --> |
| | | <div style="margin: 10px 0;" v-if="tableData && tableData.length > 0" > |
| | | <el-button type="success" @click="resetForm(currentRegulationDetail)">确认æ¥ç</el-button> |
| | | <div style="margin: 10px 0;" |
| | | v-if="tableData && tableData.length > 0"> |
| | | <el-button type="success" |
| | | @click="resetForm(currentRegulationDetail)">确认æ¥ç</el-button> |
| | | </div> |
| | | </div> |
| | | </el-dialog> |
| | | |
| | | <!-- çæ¬åå²å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="showVersionHistoryDialog" title="çæ¬åå²" width="800px"> |
| | | <el-table :data="versionHistory" style="width: 100%;margin-bottom: 10px"> |
| | | <el-table-column prop="version" label="çæ¬å·" width="100" /> |
| | | <el-table-column prop="updateTime" label="æ´æ°æ¶é´" width="180" /> |
| | | <el-table-column prop="createUserName" label="æ´æ°äºº" width="120" /> |
| | | <el-table-column prop="changeLog" label="åæ´è¯´æ"> |
| | | <el-dialog v-model="showVersionHistoryDialog" |
| | | title="çæ¬åå²" |
| | | width="800px"> |
| | | <el-table :data="versionHistory" |
| | | style="width: 100%;margin-bottom: 10px"> |
| | | <el-table-column prop="version" |
| | | label="çæ¬å·" |
| | | width="100" /> |
| | | <el-table-column prop="updateTime" |
| | | label="æ´æ°æ¶é´" |
| | | width="180" /> |
| | | <el-table-column prop="createUserName" |
| | | label="æ´æ°äºº" |
| | | width="120" /> |
| | | <el-table-column prop="changeLog" |
| | | label="åæ´è¯´æ"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'"> |
| | | {{ scope.row.status === 'active' ? 'çæä¸' : 'å·²åºæ¢' }} |
| | |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-dialog> |
| | | |
| | | <!-- é
è¯»ç¶æå¯¹è¯æ¡ --> |
| | | <el-dialog v-model="showReadStatusDialog" title="é
è¯»ç¶æ" width="800px"> |
| | | <el-table :data="readStatusList" style="width: 100%;margin-bottom: 10px"> |
| | | <el-table-column prop="employee" label="åå·¥å§å" width="120" /> |
| | | <el-table-column prop="department" label="æå±é¨é¨" width="150" /> |
| | | <el-table-column prop="createTime" label="é
读æ¶é´" width="180" /> |
| | | <el-table-column prop="confirmTime" label="确认æ¶é´" width="180" /> |
| | | <el-table-column prop="status" label="ç¶æ" width="100"> |
| | | <el-dialog v-model="showReadStatusDialog" |
| | | title="é
è¯»ç¶æ" |
| | | width="800px"> |
| | | <el-table :data="readStatusList" |
| | | style="width: 100%;margin-bottom: 10px"> |
| | | <el-table-column prop="employee" |
| | | label="åå·¥å§å" |
| | | width="120" /> |
| | | <el-table-column prop="department" |
| | | label="æå±é¨é¨" |
| | | width="150" /> |
| | | <el-table-column prop="createTime" |
| | | label="é
读æ¶é´" |
| | | width="180" /> |
| | | <el-table-column prop="confirmTime" |
| | | label="确认æ¶é´" |
| | | width="180" /> |
| | | <el-table-column prop="status" |
| | | label="ç¶æ" |
| | | width="100"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.status === 'confirmed' ? 'success' : 'warning'"> |
| | | {{ scope.row.status === 'confirmed' ? '已确认' : 'æªç¡®è®¤' }} |
| | |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-dialog> |
| | | |
| | | <FileListDialog ref="fileListDialogRef" |
| | | v-model="fileDialogVisible" |
| | | :show-upload-button="true" |
| | | :show-delete-button="true" |
| | | :delete-method="handleAttachmentDelete" |
| | | :rules-regulations-management-id="currentFileRuleId" |
| | | :name-column-label="'éä»¶åç§°'" |
| | | @upload="handleAttachmentUpload" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, getCurrentInstance } from 'vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | import { listRuleManagement,addRuleManagement,updateRuleManagement,delRuleManagement,getReadingStatusByRuleId,addReadingStatus,updateReadingStatus } from '@/api/collaborativeApproval/sealManagement.js' |
| | | import { ref, reactive, onMounted, getCurrentInstance } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import { |
| | | listRuleManagement, |
| | | addRuleManagement, |
| | | updateRuleManagement, |
| | | delRuleManagement, |
| | | getReadingStatusByRuleId, |
| | | addReadingStatus, |
| | | updateReadingStatus, |
| | | } from "@/api/collaborativeApproval/sealManagement.js"; |
| | | import FileListDialog from "@/components/Dialog/FileListDialog.vue"; |
| | | import { |
| | | listRuleFiles, |
| | | delRuleFile, |
| | | addRuleFile, |
| | | } from "@/api/collaborativeApproval/rulesRegulationsManagementFile.js"; |
| | | |
| | | // ååºå¼æ°æ® |
| | | const operationType = ref('add') |
| | | const tableData = ref([]) |
| | | const tableLoading = ref(false) |
| | | // å页忰 |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0 |
| | | }) |
| | | // è§ç« å¶åº¦ç¸å
³ |
| | | const showRegulationDialog = ref(false) |
| | | const showRegulationDetailDialog = ref(false) |
| | | const showVersionHistoryDialog = ref(false) |
| | | const showReadStatusDialog = ref(false) |
| | | const currentRegulationDetail = ref(null) |
| | | const regulationFormRef = ref() |
| | | const regulationForm = reactive({ |
| | | id: '', |
| | | regulationNum: '', |
| | | title: '', |
| | | category: '', |
| | | content: '', |
| | | version: '', |
| | | status: 'active', |
| | | readCount: 0, |
| | | effectiveTime: '', |
| | | scope: [], |
| | | requireConfirm: false |
| | | }) |
| | | // ååºå¼æ°æ® |
| | | const operationType = ref("add"); |
| | | const tableData = ref([]); |
| | | const tableLoading = ref(false); |
| | | // å页忰 |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }); |
| | | // éä»¶å¼¹çª |
| | | const fileDialogVisible = ref(false); |
| | | const fileListDialogRef = ref(null); |
| | | const currentFileRuleId = ref(null); |
| | | const filePage = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }); |
| | | // è§ç« å¶åº¦ç¸å
³ |
| | | const showRegulationDialog = ref(false); |
| | | const showRegulationDetailDialog = ref(false); |
| | | const showVersionHistoryDialog = ref(false); |
| | | const showReadStatusDialog = ref(false); |
| | | const currentRegulationDetail = ref(null); |
| | | const regulationFormRef = ref(); |
| | | const regulationForm = reactive({ |
| | | id: "", |
| | | regulationNum: "", |
| | | title: "", |
| | | category: "", |
| | | content: "", |
| | | version: "", |
| | | status: "active", |
| | | readCount: 0, |
| | | effectiveTime: "", |
| | | scope: [], |
| | | requireConfirm: false, |
| | | }); |
| | | |
| | | const readStatus = ref({ |
| | | id: '', |
| | | ruleId: '', |
| | | employee: '', |
| | | department: '', |
| | | createTime: '', |
| | | confirmTime: '', |
| | | status: 'unconfirmed' |
| | | }) |
| | | const readStatus = ref({ |
| | | id: "", |
| | | ruleId: "", |
| | | employee: "", |
| | | department: "", |
| | | createTime: "", |
| | | confirmTime: "", |
| | | status: "unconfirmed", |
| | | }); |
| | | |
| | | const regulationRules = { |
| | | title: [{ required: true, message: '请è¾å
¥å¶åº¦æ é¢', trigger: 'blur' }], |
| | | category: [{ required: true, message: 'è¯·éæ©å¶åº¦åç±»', trigger: 'change' }], |
| | | content: [{ required: true, message: '请è¾å
¥å¶åº¦å
容', trigger: 'blur' }], |
| | | effectiveTime: [{ required: true, message: 'è¯·éæ©çææ¶é´', trigger: 'change' }], |
| | | scope: [{ required: true, message: 'è¯·éæ©éç¨èå´', trigger: 'change' }] |
| | | } |
| | | const regulationRules = { |
| | | title: [{ required: true, message: "请è¾å
¥å¶åº¦æ é¢", trigger: "blur" }], |
| | | category: [{ required: true, message: "è¯·éæ©å¶åº¦åç±»", trigger: "change" }], |
| | | content: [{ required: true, message: "请è¾å
¥å¶åº¦å
容", trigger: "blur" }], |
| | | effectiveTime: [ |
| | | { required: true, message: "è¯·éæ©çææ¶é´", trigger: "change" }, |
| | | ], |
| | | scope: [{ required: true, message: "è¯·éæ©éç¨èå´", trigger: "change" }], |
| | | }; |
| | | |
| | | const regulationSearchForm = reactive({ |
| | | title: '', |
| | | category: '' |
| | | }) |
| | | const regulationSearchForm = reactive({ |
| | | title: "", |
| | | category: "", |
| | | }); |
| | | |
| | | const regulations = ref([]) |
| | | const regulations = ref([]); |
| | | |
| | | const versionHistory = ref([]) |
| | | const versionHistory = ref([]); |
| | | |
| | | const readStatusList = ref([]) |
| | | const readStatusList = ref([]); |
| | | // { employee: 'éå¿å¼º', department: 'éå®é¨', readTime: '2025-01-11 10:30:00', confirmTime: '2025-01-11 10:35:00', status: 'confirmed' }, |
| | | // { employee: 'åé
å©·', department: 'ææ¯é¨', readTime: '2025-01-11 14:20:00', confirmTime: '', status: 'unconfirmed' }, |
| | | // { employee: 'ç建å½', department: 'è´¢å¡é¨', readTime: '2025-01-12 09:15:00', confirmTime: '2025-01-12 09:20:00', status: 'confirmed' } |
| | | |
| | | // å¶åº¦åç±» |
| | | const getCategoryText = (category) => { |
| | | const categoryMap = { |
| | | hr: '人äºå¶åº¦', |
| | | finance: 'è´¢å¡å¶åº¦', |
| | | safety: 'å®å
¨å¶åº¦', |
| | | tech: 'ææ¯å¶åº¦' |
| | | } |
| | | return categoryMap[category] || 'æªç¥' |
| | | } |
| | | // æç´¢å¶åº¦ |
| | | const searchRegulations = () => { |
| | | page.current=1 |
| | | getRegulationList() |
| | | } |
| | | // éç½®å¶åº¦æç´¢ |
| | | const resetRegulationSearch = () => { |
| | | regulationSearchForm.title = '' |
| | | regulationSearchForm.category = '' |
| | | searchRegulations() |
| | | } |
| | | // æ°å¢ |
| | | const handleAdd = () => { |
| | | operationType.value = 'add' |
| | | resetRegulationForm() |
| | | showRegulationDialog.value = true |
| | | } |
| | | // å¶åº¦åç±» |
| | | const getCategoryText = category => { |
| | | const categoryMap = { |
| | | hr: "人äºå¶åº¦", |
| | | finance: "è´¢å¡å¶åº¦", |
| | | safety: "å®å
¨å¶åº¦", |
| | | tech: "ææ¯å¶åº¦", |
| | | }; |
| | | return categoryMap[category] || "æªç¥"; |
| | | }; |
| | | // æç´¢å¶åº¦ |
| | | const searchRegulations = () => { |
| | | page.current = 1; |
| | | getRegulationList(); |
| | | }; |
| | | // éç½®å¶åº¦æç´¢ |
| | | const resetRegulationSearch = () => { |
| | | regulationSearchForm.title = ""; |
| | | regulationSearchForm.category = ""; |
| | | searchRegulations(); |
| | | }; |
| | | // æ°å¢ |
| | | const handleAdd = () => { |
| | | operationType.value = "add"; |
| | | resetRegulationForm(); |
| | | showRegulationDialog.value = true; |
| | | }; |
| | | |
| | | // ç¼è¾ |
| | | const handleEdit = (row) => { |
| | | operationType.value = 'edit' |
| | | Object.assign(regulationForm, row) |
| | | showRegulationDialog.value = true |
| | | } |
| | | // åºå¼ |
| | | const repealEdit = (row) => { |
| | | operationType.value = 'edit' |
| | | Object.assign(regulationForm, row) |
| | | regulationForm.status = 'repealed' |
| | | ElMessageBox.confirm('确认åºå¼è¯¥å¶åº¦ï¼', 'æç¤º', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | updateRuleManagement(regulationForm).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success('å¶åº¦åºå¼æå') |
| | | // showRegulationDialog.value = false |
| | | getRegulationList() |
| | | resetRegulationForm() |
| | | } |
| | | // ç¼è¾ |
| | | const handleEdit = row => { |
| | | operationType.value = "edit"; |
| | | Object.assign(regulationForm, row); |
| | | showRegulationDialog.value = true; |
| | | }; |
| | | // åºå¼ |
| | | const repealEdit = row => { |
| | | operationType.value = "edit"; |
| | | Object.assign(regulationForm, row); |
| | | regulationForm.status = "repealed"; |
| | | ElMessageBox.confirm("确认åºå¼è¯¥å¶åº¦ï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | }).catch(() => { |
| | | ElMessage({ |
| | | type: 'info', |
| | | message: '已忶åºå¼' |
| | | }) |
| | | }) |
| | | } |
| | | // åå¸å¶åº¦ |
| | | const submitRegulation = async () => { |
| | | try { |
| | | await regulationFormRef.value.validate() |
| | | if(operationType.value == 'add'){ |
| | | addRuleManagement(regulationForm).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success('å¶åº¦å叿å') |
| | | showRegulationDialog.value = false |
| | | getRegulationList() |
| | | resetRegulationForm() |
| | | } |
| | | .then(() => { |
| | | updateRuleManagement(regulationForm).then(res => { |
| | | if (res.code == 200) { |
| | | ElMessage.success("å¶åº¦åºå¼æå"); |
| | | // showRegulationDialog.value = false |
| | | getRegulationList(); |
| | | resetRegulationForm(); |
| | | } |
| | | }); |
| | | }) |
| | | }else{ |
| | | updateRuleManagement(regulationForm).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success('å¶åº¦ç¼è¾æå') |
| | | showRegulationDialog.value = false |
| | | resetRegulationForm() |
| | | getRegulationList() |
| | | }})} |
| | | }catch(err){ |
| | | ElMessage.error(err.msg) |
| | | } |
| | | } |
| | | //éç½®å¶åº¦è¡¨å |
| | | const resetRegulationForm = () => { |
| | | Object.assign(regulationForm, { |
| | | id: '', |
| | | regulationNum: '', |
| | | title: '', |
| | | category: '', |
| | | content: '', |
| | | version: '', |
| | | status: 'active', |
| | | readCount: 0, |
| | | effectiveTime: '', |
| | | scope: [], |
| | | requireConfirm: false |
| | | }) |
| | | } |
| | | |
| | | |
| | | // æ¥çå¶åº¦çæ¬åå² |
| | | const viewVersionHistory = (row) => { |
| | | showVersionHistoryDialog.value = true |
| | | const params = { |
| | | |
| | | category: row.category |
| | | } |
| | | listRuleManagement(page,params).then(res => { |
| | | if(res.code == 200){ |
| | | versionHistory.value = res.data.records |
| | | .catch(() => { |
| | | ElMessage({ |
| | | type: "info", |
| | | message: "已忶åºå¼", |
| | | }); |
| | | }); |
| | | }; |
| | | // åå¸å¶åº¦ |
| | | const submitRegulation = async () => { |
| | | try { |
| | | await regulationFormRef.value.validate(); |
| | | if (operationType.value == "add") { |
| | | addRuleManagement(regulationForm).then(res => { |
| | | if (res.code == 200) { |
| | | ElMessage.success("å¶åº¦å叿å"); |
| | | showRegulationDialog.value = false; |
| | | getRegulationList(); |
| | | resetRegulationForm(); |
| | | } |
| | | }); |
| | | } else { |
| | | updateRuleManagement(regulationForm).then(res => { |
| | | if (res.code == 200) { |
| | | ElMessage.success("å¶åº¦ç¼è¾æå"); |
| | | showRegulationDialog.value = false; |
| | | resetRegulationForm(); |
| | | getRegulationList(); |
| | | } |
| | | }); |
| | | } |
| | | } catch (err) { |
| | | ElMessage.error(err.msg); |
| | | } |
| | | }) |
| | | } |
| | | // æ¥çå¶åº¦è¯¦æ
|
| | | const viewRegulation = (row) => { |
| | | currentRegulationDetail.value = row |
| | | showRegulationDetailDialog.value = true |
| | | getReadingStatusByRuleId(row.id).then(res => { |
| | | if(res.code == 200){ |
| | | readStatusList.value = res.data |
| | | if(readStatusList.value.length==0 && tableData.value.length>0){ |
| | | }; |
| | | //éç½®å¶åº¦è¡¨å |
| | | const resetRegulationForm = () => { |
| | | Object.assign(regulationForm, { |
| | | id: "", |
| | | regulationNum: "", |
| | | title: "", |
| | | category: "", |
| | | content: "", |
| | | version: "", |
| | | status: "active", |
| | | readCount: 0, |
| | | effectiveTime: "", |
| | | scope: [], |
| | | requireConfirm: false, |
| | | }); |
| | | }; |
| | | |
| | | // æ¥çå¶åº¦çæ¬åå² |
| | | const viewVersionHistory = row => { |
| | | showVersionHistoryDialog.value = true; |
| | | const params = { |
| | | category: row.category, |
| | | }; |
| | | listRuleManagement(page, params).then(res => { |
| | | if (res.code == 200) { |
| | | versionHistory.value = res.data.records; |
| | | } |
| | | }); |
| | | }; |
| | | // æ¥çå¶åº¦è¯¦æ
|
| | | const viewRegulation = row => { |
| | | currentRegulationDetail.value = row; |
| | | showRegulationDetailDialog.value = true; |
| | | getReadingStatusByRuleId(row.id).then(res => { |
| | | if (res.code == 200) { |
| | | readStatusList.value = res.data; |
| | | if (readStatusList.value.length == 0 && tableData.value.length > 0) { |
| | | const params = { |
| | | ruleId: row.id, |
| | | employee: tableData.value[0].staffName, |
| | | department: tableData.value[0].postJob, |
| | | status: 'unconfirmed' |
| | | ruleId: row.id, |
| | | employee: tableData.value[0].staffName, |
| | | department: tableData.value[0].postJob, |
| | | status: "unconfirmed", |
| | | }; |
| | | addReadingStatus(params).then(res => { |
| | | if (res.code == 200) { |
| | | ElMessage.success("å¶åº¦é
读æå"); |
| | | } |
| | | }); |
| | | } |
| | | addReadingStatus(params).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success('å¶åº¦é
读æå') |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | |
| | | } |
| | | // æ¥çå¶åº¦é
è¯»ç¶æ |
| | | const viewReadStatus = (row) => { |
| | | showReadStatusDialog.value = true |
| | | //æ¥çé
è¯»ç¶æå表 |
| | | getReadingStatusByRuleId(row.id).then(res => { |
| | | if(res.code == 200){ |
| | | readStatusList.value = res.data |
| | | } |
| | | }) |
| | | } |
| | | |
| | | //确认æ¥ç |
| | | const resetForm = (row) => { |
| | | console.log("row",row) |
| | | row.readCount = row.readCount + 1 |
| | | |
| | | updateRuleManagement(row).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success('æ¥çæ°éä¿®æ¹æå') |
| | | //ä¿®æ¹é
è¯»ç¶æ |
| | | //æ ¹æ®å¶åº¦idåå½åç»å½çåå·¥å¾å°é
è¯»ç¶æ |
| | | // let item = readStatusList.value.filter(item => item.employee == tableData.value[0].staffName ) |
| | | // if(item.length>0){ |
| | | // item[0].status = 'confirmed', |
| | | // item[0].confirmTime = new Date().toISOString().replace('T', ' ').split('.')[0]; |
| | | // } |
| | | // çéå½åå工对åºè¯¥å¶åº¦çé
è¯»ç¶æè®°å½ |
| | | let statusItem = readStatusList.value.find(item => item.employee === tableData.value[0].staffName && item.ruleId === row.id); |
| | | |
| | | if (statusItem) { |
| | | // 妿æ¾å°è®°å½ï¼æ´æ°ç¶æå确认æ¶é´ |
| | | statusItem.status = 'confirmed'; |
| | | // æ ¼å¼åæ¶é´ä¸º"YYYY-MM-DD HH:mm:ss"æ ¼å¼ |
| | | const now = new Date(); |
| | | statusItem.confirmTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`; |
| | | // statusItem.confirmTime = new Date().toISOString().replace('T', ' ').split('.')[0]; |
| | | |
| | | updateReadingStatus(statusItem).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success('å¶åº¦é
è¯»ç¶æä¿®æ¹æå') |
| | | } |
| | | }) |
| | | }); |
| | | }; |
| | | // æ¥çå¶åº¦é
è¯»ç¶æ |
| | | const viewReadStatus = row => { |
| | | showReadStatusDialog.value = true; |
| | | //æ¥çé
è¯»ç¶æå表 |
| | | getReadingStatusByRuleId(row.id).then(res => { |
| | | if (res.code == 200) { |
| | | readStatusList.value = res.data; |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | //确认æ¥ç |
| | | const resetForm = row => { |
| | | console.log("row", row); |
| | | row.readCount = row.readCount + 1; |
| | | |
| | | updateRuleManagement(row).then(res => { |
| | | if (res.code == 200) { |
| | | ElMessage.success("æ¥çæ°éä¿®æ¹æå"); |
| | | //ä¿®æ¹é
è¯»ç¶æ |
| | | //æ ¹æ®å¶åº¦idåå½åç»å½çåå·¥å¾å°é
è¯»ç¶æ |
| | | // let item = readStatusList.value.filter(item => item.employee == tableData.value[0].staffName ) |
| | | // if(item.length>0){ |
| | | // item[0].status = 'confirmed', |
| | | // item[0].confirmTime = new Date().toISOString().replace('T', ' ').split('.')[0]; |
| | | // } |
| | | // çéå½åå工对åºè¯¥å¶åº¦çé
è¯»ç¶æè®°å½ |
| | | let statusItem = readStatusList.value.find( |
| | | item => |
| | | item.employee === tableData.value[0].staffName && |
| | | item.ruleId === row.id |
| | | ); |
| | | |
| | | if (statusItem) { |
| | | // 妿æ¾å°è®°å½ï¼æ´æ°ç¶æå确认æ¶é´ |
| | | statusItem.status = "confirmed"; |
| | | // æ ¼å¼åæ¶é´ä¸º"YYYY-MM-DD HH:mm:ss"æ ¼å¼ |
| | | const now = new Date(); |
| | | statusItem.confirmTime = `${now.getFullYear()}-${String( |
| | | now.getMonth() + 1 |
| | | ).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")} ${String( |
| | | now.getHours() |
| | | ).padStart(2, "0")}:${String(now.getMinutes()).padStart( |
| | | 2, |
| | | "0" |
| | | )}:${String(now.getSeconds()).padStart(2, "0")}`; |
| | | // statusItem.confirmTime = new Date().toISOString().replace('T', ' ').split('.')[0]; |
| | | |
| | | updateReadingStatus(statusItem).then(res => { |
| | | if (res.code == 200) { |
| | | ElMessage.success("å¶åº¦é
è¯»ç¶æä¿®æ¹æå"); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 导åºè§ç« å¶åº¦ |
| | | const { proxy } = getCurrentInstance(); |
| | | const handleExport = () => { |
| | | proxy.download( |
| | | "/rulesRegulationsManagement/export", |
| | | { ...regulationSearchForm }, |
| | | "è§ç« å¶åº¦.xlsx" |
| | | ); |
| | | }; |
| | | |
| | | // éä»¶ï¼æ¥è¯¢ |
| | | const fetchRuleFiles = async rulesRegulationsManagementId => { |
| | | const params = { |
| | | current: filePage.current, |
| | | size: filePage.size, |
| | | rulesRegulationsManagementId, |
| | | }; |
| | | const res = await listRuleFiles(params); |
| | | const records = res?.data?.records || []; |
| | | filePage.total = res?.data?.total || records.length; |
| | | const mapped = records.map(item => ({ |
| | | id: item.id, |
| | | name: item.fileName || item.name, |
| | | url: item.fileUrl || item.url, |
| | | raw: item, |
| | | })); |
| | | fileListDialogRef.value?.setList(mapped); |
| | | }; |
| | | |
| | | // æå¼éä»¶å¼¹çª |
| | | const openFileDialog = async row => { |
| | | currentFileRuleId.value = row.id; |
| | | fileDialogVisible.value = true; |
| | | await fetchRuleFiles(row.id); |
| | | }; |
| | | |
| | | // å·æ°éä»¶å表 |
| | | const refreshFileList = async () => { |
| | | if (!currentFileRuleId.value) return; |
| | | await fetchRuleFiles(currentFileRuleId.value); |
| | | }; |
| | | |
| | | // ä¸ä¼ éä»¶ï¼ç±åç»ä»¶è§¦åï¼ |
| | | const handleAttachmentUpload = async filePayload => { |
| | | if (!currentFileRuleId.value) return; |
| | | const payload = { |
| | | name: filePayload?.fileName || filePayload?.name, |
| | | url: filePayload?.fileUrl || filePayload?.url, |
| | | rulesRegulationsManagementId: currentFileRuleId.value, |
| | | }; |
| | | await addRuleFile(payload); |
| | | ElMessage.success("æä»¶ä¸ä¼ æå"); |
| | | await refreshFileList(); |
| | | }; |
| | | |
| | | // å é¤éä»¶ |
| | | const handleAttachmentDelete = async row => { |
| | | if (!row?.id) return false; |
| | | try { |
| | | await ElMessageBox.confirm("确认å é¤è¯¥éä»¶ï¼", "æç¤º", { type: "warning" }); |
| | | } catch { |
| | | return false; |
| | | } |
| | | }) |
| | | } |
| | | await delRuleFile([row.id]); |
| | | ElMessage.success("å 餿å"); |
| | | await refreshFileList(); |
| | | }; |
| | | |
| | | // 导åºè§ç« å¶åº¦ |
| | | const { proxy } = getCurrentInstance() |
| | | const handleExport = () => { |
| | | proxy.download('/rulesRegulationsManagement/export', { ...regulationSearchForm }, 'è§ç« å¶åº¦.xlsx') |
| | | } |
| | | // è·åè§ç« å¶åº¦åè¡¨æ°æ® |
| | | const getRegulationList = async () => { |
| | | tableLoading.value = true; |
| | | listRuleManagement(page, regulationSearchForm) |
| | | .then(res => { |
| | | regulations.value = res.data.records; |
| | | // è¿æ»¤æå·²åºå¼çå¶åº¦ |
| | | // regulations.value = res.data.records.filter(item => item.status !== 'repealed') |
| | | page.value.total = res.data.total; |
| | | tableLoading.value = false; |
| | | }) |
| | | .catch(err => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // è·åè§ç« å¶åº¦åè¡¨æ°æ® |
| | | const getRegulationList = async () => { |
| | | tableLoading.value = true |
| | | listRuleManagement(page,regulationSearchForm) |
| | | .then(res => { |
| | | |
| | | regulations.value = res.data.records |
| | | // è¿æ»¤æå·²åºå¼çå¶åº¦ |
| | | // regulations.value = res.data.records.filter(item => item.status !== 'repealed') |
| | | page.value.total = res.data.total; |
| | | tableLoading.value = false; |
| | | |
| | | }).catch(err => { |
| | | tableLoading.value = false; |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | // åå§å |
| | | getRegulationList() |
| | | }) |
| | | onMounted(() => { |
| | | // åå§å |
| | | getRegulationList(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .app-container { |
| | | padding: 20px; |
| | | } |
| | | .app-container { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .card-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | .card-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .tab-content { |
| | | padding: 20px 0; |
| | | } |
| | | .tab-content { |
| | | padding: 20px 0; |
| | | } |
| | | |
| | | .mb-20 { |
| | | margin-bottom: 20px; |
| | | } |
| | | .mb-20 { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .mt-20 { |
| | | margin-top: 20px; |
| | | } |
| | | .mt-20 { |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | .ml-10 { |
| | | margin-left: 10px; |
| | | } |
| | | .ml-10 { |
| | | margin-left: 10px; |
| | | } |
| | | |
| | | .regulation-content { |
| | | background-color: #f5f5f5; |
| | | padding: 15px; |
| | | border-radius: 4px; |
| | | line-height: 1.6; |
| | | white-space: pre-wrap; |
| | | height: 200px; |
| | | } |
| | | .regulation-content { |
| | | background-color: #f5f5f5; |
| | | padding: 15px; |
| | | border-radius: 4px; |
| | | line-height: 1.6; |
| | | white-space: pre-wrap; |
| | | height: 200px; |
| | | } |
| | | |
| | | .dialog-footer { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | gap: 10px; |
| | | } |
| | | .dialog-footer { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | gap: 10px; |
| | | } |
| | | </style> |
| | |
| | | <el-option label="å·²æç»" value="rejected" /> |
| | | </el-select> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-col :span="6"> |
| | | <el-button type="primary" @click="searchSealApplications">æç´¢</el-button> |
| | | <el-button @click="resetSealSearch">éç½®</el-button> |
| | | <el-button @click="handleExport">导åº</el-button> |
| | |
| | | import { listSealApplication, addSealApplication, updateSealApplication,listRuleManagement,addRuleManagement,updateRuleManagement,delRuleManagement,getReadingStatusByRuleId,getReadingStatusList,addReadingStatus,updateReadingStatus } from '@/api/collaborativeApproval/sealManagement.js' |
| | | import { el } from 'element-plus/es/locales.mjs' |
| | | import { getUserProfile, userListNoPageByTenantId } from '@/api/system/user.js' |
| | | import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js"; |
| | | import useUserStore from '@/store/modules/user' |
| | | import { userLoginFacotryList } from "@/api/system/user.js" |
| | | import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js"; |
| | | |
| | | // ååºå¼æ°æ® |
| | | const currentUser = ref(null) |
| | |
| | | currentUser.value = res.data.userName |
| | | } |
| | | }) |
| | | staffJoinListPage({staffState: 1, ...page}).then(res => { |
| | | staffOnJobListPage({staffState: 1, ...page}).then(res => { |
| | | tableLoading.value = false; |
| | | // tableData.value = res.data.records |
| | | // //çéåºåcurrentUserååç人å |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog v-model="dialogVisible" title="éä»¶" width="40%" :before-close="handleClose"> |
| | | <el-table :data="tableData" border height="40vh"> |
| | | <el-table-column label="éä»¶åç§°" prop="name" min-width="400" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" width="100" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">ä¸è½½</el-button> |
| | | <el-button link type="primary" size="small" @click="lookFile(scope.row)">é¢è§</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-dialog> |
| | | <filePreview ref="filePreviewRef" /> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue' |
| | | import filePreview from '@/components/filePreview/index.vue' |
| | | |
| | | const dialogVisible = ref(false) |
| | | const tableData = ref([]) |
| | | const { proxy } = getCurrentInstance(); |
| | | const filePreviewRef = ref() |
| | | const handleClose = () => { |
| | | dialogVisible.value = false |
| | | } |
| | | const open = (list) => { |
| | | dialogVisible.value = true |
| | | tableData.value = list |
| | | } |
| | | const downLoadFile = (row) => { |
| | | proxy.$download.name(row.url); |
| | | |
| | | } |
| | | const lookFile = (row) => { |
| | | filePreviewRef.value.open(row.url) |
| | | } |
| | | defineExpose({ |
| | | open |
| | | }) |
| | | </script> |
| | | |
| | | <style></style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">éå®ååå·ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.salesContractNo" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥éå®ååå·æç´¢" |
| | | @change="handleQuery" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | /> |
| | | <span class="search_title ml10">审æ¹ç¶æï¼</span> |
| | | <el-select v-model="searchForm.approveStatus" clearable @change="handleQuery" style="width: 240px"> |
| | | <el-option label="å¾
å®¡æ ¸" :value="2" /> |
| | | <el-option label="å®¡æ ¸æå" :value="3" /> |
| | | <el-option label="å®¡æ ¸å¤±è´¥" :value="4" /> |
| | | </el-select> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | | </div> |
| | | <div> |
| | | <!-- <el-button type="primary" @click="openForm('add')">æ°å¢</el-button>--> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <!-- <el-button type="danger" plain @click="handleDelete">å é¤</el-button>--> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | :total="page.total" |
| | | ></PIMTable> |
| | | </div> |
| | | <info-form-dia ref="infoFormDia" @close="handleQuery" :approveType="approveType"></info-form-dia> |
| | | <approval-dia ref="approvalDia" @close="handleQuery"></approval-dia> |
| | | <FileList ref="fileListRef" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import FileList from "./fileList.vue"; |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import {onMounted, ref} from "vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import InfoFormDia from "@/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue"; |
| | | import ApprovalDia from "@/views/collaborativeApproval/approvalProcess/components/approvalDia.vue"; |
| | | import {getShipmentApprovalList, approveShipment} from "@/api/collaborativeApproval/shipmentReview.js"; |
| | | // import {approveProcessDelete, approveProcessListPage} from "@/api/collaborativeApproval/approvalProcess.js"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { userListNoPage } from "@/api/system/user.js"; |
| | | |
| | | // å®ä¹ç»ä»¶æ¥æ¶çprops |
| | | const props = defineProps({ |
| | | approveType: { |
| | | type: [Number, String], |
| | | default: 6 |
| | | } |
| | | }); |
| | | |
| | | const userList = ref([]); |
| | | |
| | | const userStore = useUserStore(); |
| | | |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | approveId: "", |
| | | approveStatus: "", |
| | | }, |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "审æ¹ç¶æ", |
| | | prop: "approveStatus", |
| | | dataType: "tag", |
| | | width: 100, |
| | | formatData: (params) => { |
| | | if (params === 2) { |
| | | return "å¾
å®¡æ ¸"; |
| | | } else if (params === 3) { |
| | | return "å®¡æ ¸å®æ"; |
| | | } else if (params === 4) { |
| | | return "å®¡æ ¸é©³å"; |
| | | } else { |
| | | return 'æªç¥ç¶æ'; |
| | | } |
| | | }, |
| | | formatType: (params) => { |
| | | if (params === 0) { |
| | | return "warning"; |
| | | } else if (params === 2) { |
| | | return "info"; |
| | | } else if (params === 3) { |
| | | return "success"; |
| | | } else if (params === 4) { |
| | | return "danger"; |
| | | } else { |
| | | return 'danger'; |
| | | } |
| | | }, |
| | | }, |
| | | { |
| | | label: "éå®ååå·", |
| | | prop: "salesContractNo", |
| | | width: 170 |
| | | }, |
| | | { |
| | | label: "客æ·åç§°", |
| | | prop: "customerName", |
| | | width: 200 |
| | | }, |
| | | { |
| | | label: "产å大类", |
| | | prop: "productCategory", |
| | | width: 200 |
| | | }, |
| | | { |
| | | label: "è§æ ¼åå·", |
| | | prop: "specificationModel", |
| | | width: 220 |
| | | }, |
| | | { |
| | | label: "ç³è¯·äºº", |
| | | prop: "approveUserId", |
| | | width: 120, |
| | | align: "center", |
| | | formatData:(params)=>{ |
| | | const user = userList.value.find(item => item.userId === params) |
| | | return user ? user.nickName : '--' |
| | | } |
| | | }, |
| | | { |
| | | label: "车çå·", |
| | | prop: "shippingCarNumber", |
| | | width: 120, |
| | | }, |
| | | { |
| | | label: "ç³è¯·äºº", |
| | | prop: "approveUserId", |
| | | width: 120, |
| | | }, |
| | | { |
| | | label: "ç³è¯·æ¥æ", |
| | | prop: "executionDate", |
| | | width: 200 |
| | | }, |
| | | { |
| | | label: "å½å审æ¹äºº", |
| | | prop: "salesman", |
| | | width: 120 |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 120, |
| | | operation: [ |
| | | { |
| | | name: "éè¿", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | handleApproval("éè¿", row); |
| | | }, |
| | | disabled: (row) => row.approveStatus !== 2 |
| | | }, |
| | | { |
| | | name: "驳å", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | handleApproval("驳å", row); |
| | | }, |
| | | disabled: (row) => row.approveStatus !== 2 |
| | | }, |
| | | // { |
| | | // name: "ç¼è¾", |
| | | // type: "text", |
| | | // clickFun: (row) => { |
| | | // openForm("edit", row); |
| | | // }, |
| | | // disabled: (row) => row.approveStatus == 2 || row.approveStatus == 1 || row.approveStatus == 4 |
| | | // }, |
| | | // { |
| | | // name: "å®¡æ ¸", |
| | | // type: "text", |
| | | // clickFun: (row) => { |
| | | // openApprovalDia("approval", row); |
| | | // }, |
| | | // disabled: (row) => row.approveUserCurrentId == null || row.approveStatus == 2 || row.approveStatus == 3 || row.approveStatus == 4 || row.approveUserCurrentId !== userStore.id |
| | | // }, |
| | | // { |
| | | // name: "详æ
", |
| | | // type: "text", |
| | | // clickFun: (row) => { |
| | | // openApprovalDia('view', row); |
| | | // }, |
| | | // }, |
| | | // { |
| | | // name: "éä»¶", |
| | | // type: "text", |
| | | // clickFun: (row) => { |
| | | // downLoadFile(row); |
| | | // }, |
| | | // }, |
| | | ], |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0 |
| | | }); |
| | | const infoFormDia = ref() |
| | | const approvalDia = ref() |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | const fileListRef = ref(null) |
| | | const downLoadFile = (row) => { |
| | | fileListRef.value.open(row.commonFileList) |
| | | |
| | | } |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | const getList =async () => { |
| | | let userLists = await userListNoPage(); |
| | | userList.value = userLists.data; |
| | | tableLoading.value = true; |
| | | getShipmentApprovalList({...page, ...searchForm.value,approveType:props.approveType}).then(res => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records |
| | | page.total = res.data.total; |
| | | }).catch(err => { |
| | | tableLoading.value = false; |
| | | }) |
| | | }; |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | const type = Number(props.approveType || 6) |
| | | const urlMap = { |
| | | 0: "/shipmentApproval/export", |
| | | } |
| | | const url = urlMap[type] || urlMap[0] |
| | | const nameMap = { |
| | | 0: "åè´§å®¡æ ¸è¡¨", |
| | | } |
| | | const fileName = nameMap[type] || nameMap[0] |
| | | proxy.download(url, {}, `${fileName}.xlsx`) |
| | | } |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | // æå¼æ°å¢ãç¼è¾å¼¹æ¡ |
| | | const openForm = (type, row) => { |
| | | nextTick(() => { |
| | | infoFormDia.value?.openDialog(type, row) |
| | | }) |
| | | }; |
| | | // æå¼æ°å¢æ£éªå¼¹æ¡ |
| | | const openApprovalDia = (type, row) => { |
| | | nextTick(() => { |
| | | approvalDia.value?.openDialog(type, row) |
| | | }) |
| | | }; |
| | | |
| | | // å®¡æ ¸éè¿/驳å |
| | | const handleApproval = (name = "å®¡æ ¸",row) => { |
| | | ElMessageBox.confirm(`éä¸çå
容å°è¢«${name}ï¼æ¯å¦ç¡®è®¤${name}ï¼`, "æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(async()=>{ |
| | | let res = await approveShipment({ |
| | | id: row.id, |
| | | approveStatus: name === "éè¿" ? 3 : 4 |
| | | }); |
| | | if(res.code === 200){ |
| | | proxy.$modal.msgSuccess(`${name}æå`); |
| | | }else{ |
| | | proxy.$modal.msgError(`${name}失败`); |
| | | } |
| | | await getList() |
| | | }).catch(err=>{ |
| | | proxy.$modal.msgError(`æªç¥é误,请è系管çå`); |
| | | }) |
| | | }; |
| | | |
| | | // å é¤ |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | ids = selectedRows.value.map((item) => item.approveId); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | | return; |
| | | } |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | approveProcessDelete(ids).then((res) => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getList(); |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped></style> |
| | |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import {userListNoPageByTenantId} from "@/api/system/user.js"; |
| | | import {afterSalesServiceAdd, afterSalesServiceDispose, afterSalesServiceUpdate} from "@/api/customerService/index.js"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | const dialogFormVisible = ref(false); |
| | |
| | | dialogFormVisible.value = false; |
| | | emit('close') |
| | | }; |
| | | // è·åå½åæ¥æå¹¶æ ¼å¼å为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, "0"); // æä»½ä»0å¼å§ |
| | | const day = String(today.getDate()).padStart(2, "0"); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | defineExpose({ |
| | | openDialog, |
| | | }); |
| | |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | | <el-button @click="handleOut" style="margin-left: 10px">导åº</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | |
| | | |
| | | <script setup> |
| | | import {Search} from "@element-plus/icons-vue"; |
| | | import {onMounted, ref} from "vue"; |
| | | import {onMounted, ref, getCurrentInstance, nextTick} from "vue"; |
| | | import FormDia from "@/views/customerService/afterSalesHandling/components/formDia.vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {afterSalesServiceDelete, afterSalesServiceListPage} from "@/api/customerService/index.js"; |
| | |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/afterSalesService/exportTwo", {}, "å®åå¤ç.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog |
| | | v-model="dialogFormVisible" |
| | | :title="dialogTitle" |
| | | width="70%" |
| | | @close="closeDia" |
| | | > |
| | | <el-form |
| | | :model="form" |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="rules" |
| | | ref="formRef" |
| | | > |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="临æäº§ååç§°ï¼" prop="productName"> |
| | | <el-input |
| | | v-model="form.productName" |
| | | placeholder="请è¾å
¥äº§ååç§°" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="äº§åæ¹å·ï¼" prop="batchNumber"> |
| | | <el-input |
| | | v-model="form.batchNumber" |
| | | placeholder="请è¾å
¥äº§åæ¹å·" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¸´ææ¥æï¼" prop="expiryDate"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.expiryDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©ä¸´ææ¥æ" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåæ°éï¼" prop="stockQuantity"> |
| | | <el-input-number |
| | | v-model="form.stockQuantity" |
| | | :min="0" |
| | | placeholder="请è¾å
¥åºåæ°é" |
| | | style="width: 100%" |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="客æ·åç§°ï¼" prop="customerName"> |
| | | <el-input |
| | | v-model="form.customerName" |
| | | placeholder="请è¾å
¥å®¢æ·åç§°" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èç³»çµè¯ï¼" prop="contactPhone"> |
| | | <el-input |
| | | v-model="form.contactPhone" |
| | | placeholder="请è¾å
¥èç³»çµè¯" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="é®é¢æè¿°ï¼" prop="problemDesc"> |
| | | <el-input |
| | | v-model="form.problemDesc" |
| | | placeholder="请è¾å
¥é®é¢æè¿°" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | type="textarea" |
| | | :rows="3" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30" v-if="operationType !== 'add'"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¤ç人ï¼" prop="handlerId"> |
| | | <el-select |
| | | v-model="form.handlerId" |
| | | placeholder="è¯·éæ©å¤ç人" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | | :key="item.userId" |
| | | :label="item.nickName" |
| | | :value="item.userId" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¤çæ¥æï¼" prop="handleDate"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.handleDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©å¤çæ¥æ" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30" v-if="operationType !== 'add'"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å¤çç»æï¼" prop="handleResult"> |
| | | <el-input |
| | | v-model="form.handleResult" |
| | | placeholder="请è¾å
¥å¤çç»æ" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | type="textarea" |
| | | :rows="3" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm" v-if="operationType !== 'view'">确认</el-button> |
| | | <el-button @click="closeDia">{{ operationType === 'view' ? 'å
³é' : 'åæ¶' }}</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref, computed} from "vue"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | // import {userListNoPageByTenantId} from "@/api/system/user.js"; // ææ¶æ³¨éæï¼ä½¿ç¨åæ°æ® |
| | | // import {expiryAfterSalesAdd, expiryAfterSalesUpdate} from "@/api/customerService/index.js"; // ææ¶æ³¨éæï¼ä½¿ç¨åæ°æ® |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | const dialogFormVisible = ref(false); |
| | | const operationType = ref('') |
| | | const userStore = useUserStore(); |
| | | |
| | | const dialogTitle = computed(() => { |
| | | switch (operationType.value) { |
| | | case 'add': |
| | | return 'æ°å¢ä¸´æå®å'; |
| | | case 'edit': |
| | | return 'ç¼è¾ä¸´æå®å'; |
| | | case 'view': |
| | | return 'æ¥ç临æå®å'; |
| | | default: |
| | | return '临æå®å管ç'; |
| | | } |
| | | }); |
| | | |
| | | const data = reactive({ |
| | | form: { |
| | | id: "", |
| | | productName: "", |
| | | batchNumber: "", |
| | | expiryDate: "", |
| | | stockQuantity: 0, |
| | | customerName: "", |
| | | contactPhone: "", |
| | | problemDesc: "", |
| | | handlerId: "", |
| | | handleDate: "", |
| | | handleResult: "", |
| | | status: 1 |
| | | }, |
| | | rules: { |
| | | productName: [{required: true, message: "请è¾å
¥äº§ååç§°", trigger: "blur"}], |
| | | batchNumber: [{required: true, message: "请è¾å
¥äº§åæ¹å·", trigger: "blur"}], |
| | | expiryDate: [{required: true, message: "è¯·éæ©ä¸´ææ¥æ", trigger: "change"}], |
| | | stockQuantity: [{required: true, message: "请è¾å
¥åºåæ°é", trigger: "blur"}], |
| | | customerName: [{required: true, message: "请è¾å
¥å®¢æ·åç§°", trigger: "blur"}], |
| | | contactPhone: [ |
| | | {required: true, message: "请è¾å
¥èç³»çµè¯", trigger: "blur"}, |
| | | {pattern: /^1[3-9]\d{9}$/, message: "请è¾å
¥æ£ç¡®çææºå·ç ", trigger: "blur"} |
| | | ], |
| | | problemDesc: [{required: true, message: "请è¾å
¥é®é¢æè¿°", trigger: "blur"}], |
| | | } |
| | | }) |
| | | const { form, rules } = toRefs(data); |
| | | const userList = ref([]) |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = (type, row) => { |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | |
| | | // 模æè·åç¨æ·å表 |
| | | userList.value = [ |
| | | { userId: 1, nickName: "å¼ ä¸" }, |
| | | { userId: 2, nickName: "æå" }, |
| | | { userId: 3, nickName: "çäº" }, |
| | | { userId: 4, nickName: "èµµå
" }, |
| | | { userId: 5, nickName: "åå
«" } |
| | | ]; |
| | | |
| | | if (type === 'add') { |
| | | // æ°å¢æ¶é置表å |
| | | form.value = { |
| | | id: "", |
| | | productName: "", |
| | | batchNumber: "", |
| | | expiryDate: "", |
| | | stockQuantity: 0, |
| | | customerName: "", |
| | | contactPhone: "", |
| | | problemDesc: "", |
| | | handlerId: "", |
| | | handleDate: "", |
| | | handleResult: "", |
| | | status: 1 |
| | | }; |
| | | } else { |
| | | // ç¼è¾ææ¥çæ¶å¡«å
æ°æ® |
| | | form.value = { ...row }; |
| | | if (type === 'edit' && !form.value.handlerId) { |
| | | form.value.handlerId = userStore.id; |
| | | form.value.handleDate = getCurrentDate(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // 模ææäº¤æä½ |
| | | setTimeout(() => { |
| | | console.log("模ææäº¤çæ°æ®:", form.value); |
| | | proxy.$modal.msgSuccess(operationType.value === 'add' ? "æ°å¢æå" : "æ´æ°æå"); |
| | | closeDia(); |
| | | }, 300); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | | dialogFormVisible.value = false; |
| | | emit('close') |
| | | }; |
| | | |
| | | defineExpose({ |
| | | openDialog, |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">ä¸´ææ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.expiryDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <span class="search_title ml10">å¤çæ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.handleDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <span style = "margin-left: 10px;" class="search_title">å¤çç¶æï¼</span> |
| | | <el-select v-model="searchForm.status" placeholder="è¯·éæ©ç¶æ" @change="handleQuery" style="width: 140px" clearable> |
| | | <el-option label="å¾
å¤ç" :value="1"></el-option> |
| | | <el-option label="å·²å¤ç" :value="2"></el-option> |
| | | </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> |
| | | <div class="table_actions" style="margin-bottom: 10px;"> |
| | | <el-button type="primary" @click="openForm('add')">æ°å¢</el-button> |
| | | <el-button type="danger" @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | <div class="table_list"> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | > |
| | | <!-- è¡¨æ ¼ææ§½ --> |
| | | <template #status="{ row }"> |
| | | <el-tag :type="row.status === 1 ? 'warning' : 'success'"> |
| | | {{ row.status === 1 ? 'å¾
å¤ç' : 'å·²å¤ç' }} |
| | | </el-tag> |
| | | </template> |
| | | |
| | | <template #operation="{ row }"> |
| | | <el-button type="primary" link @click="openForm('view', row)">æ¥ç</el-button> |
| | | <el-button type="primary" link @click="openForm('edit', row)" v-if="row.status === 1">ç¼è¾</el-button> |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | <form-dia ref="formDia" @close="handleQuery"></form-dia> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {Search} from "@element-plus/icons-vue"; |
| | | import {onMounted, ref} from "vue"; |
| | | import FormDia from "@/views/customerService/expiryAfterSales/components/formDia.vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | // import {expiryAfterSalesDelete, expiryAfterSalesListPage} from "@/api/customerService/index.js"; // ææ¶æ³¨éæï¼ä½¿ç¨åæ°æ® |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const userStore = useUserStore() |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | expiryDate: "", |
| | | handleDate: "", |
| | | status: "" |
| | | }, |
| | | tableData: [], |
| | | page: { |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }, |
| | | selectedRows: [], |
| | | tableLoading: false, |
| | | formDia: null, |
| | | tableColumn: [ |
| | | { |
| | | label: "临æäº§ååç§°", |
| | | prop: "productName", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "äº§åæ¹å·", |
| | | prop: "batchNumber", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "ä¸´ææ¥æ", |
| | | prop: "expiryDate", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "åºåæ°é", |
| | | prop: "stockQuantity", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "客æ·åç§°", |
| | | prop: "customerName", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "é®é¢æè¿°", |
| | | prop: "problemDesc", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "å¤çç¶æ", |
| | | prop: "status", |
| | | width: "", |
| | | slot: true, |
| | | }, |
| | | { |
| | | label: "å¤ç人", |
| | | prop: "handlerName", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "å¤çæ¥æ", |
| | | prop: "handleDate", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "æä½", |
| | | prop: "operation", |
| | | slot: true, |
| | | width: "200", |
| | | }, |
| | | ], |
| | | }); |
| | | |
| | | const { |
| | | searchForm, |
| | | tableData, |
| | | page, |
| | | selectedRows, |
| | | tableLoading, |
| | | formDia, |
| | | tableColumn, |
| | | } = toRefs(data); |
| | | |
| | | // æ¥è¯¢ |
| | | const handleQuery = () => { |
| | | page.value.current = 1; |
| | | getList(); |
| | | }; |
| | | |
| | | // éæ© |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | // éç½® |
| | | const resetQuery = () => { |
| | | proxy.resetForm("queryRef"); |
| | | searchForm.value = { |
| | | expiryDate: "", |
| | | handleDate: "", |
| | | status: "" |
| | | }; |
| | | handleQuery(); |
| | | }; |
| | | |
| | | // å页 |
| | | const pagination = (obj) => { |
| | | page.value.current = obj.page; |
| | | page.value.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | |
| | | // è·ååè¡¨æ°æ® |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | // åæ¶æ³¨é并使ç¨çå®API |
| | | // expiryAfterSalesListPage({ |
| | | // ...searchForm.value, |
| | | // current: page.value.current, |
| | | // size: page.value.size |
| | | // }).then(res => { |
| | | // tableData.value = res.data.records; |
| | | // page.value.total = res.data.total; |
| | | // tableLoading.value = false; |
| | | // }); |
| | | |
| | | // ææ¶è¿åç©ºæ°æ® |
| | | tableData.value = []; |
| | | page.value.total = 0; |
| | | tableLoading.value = false; |
| | | }; |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openForm = (type, row) => { |
| | | nextTick(() => { |
| | | formDia.value?.openDialog(type, row) |
| | | }) |
| | | }; |
| | | |
| | | // å é¤ |
| | | 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(() => { |
| | | tableLoading.value = true; |
| | | // åæ¶æ³¨é并使ç¨çå®API |
| | | // expiryAfterSalesDelete(ids).then(() => { |
| | | // proxy.$modal.msgSuccess("å 餿å"); |
| | | // getList(); |
| | | // }).finally(() => { |
| | | // tableLoading.value = false; |
| | | // }); |
| | | |
| | | // ææ¶æ¨¡æå 餿å |
| | | tableLoading.value = false; |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getList(); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
| | |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import {userListNoPageByTenantId} from "@/api/system/user.js"; |
| | | import {afterSalesServiceAdd, afterSalesServiceUpdate} from "@/api/customerService/index.js"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | const dialogFormVisible = ref(false); |
| | |
| | | dialogFormVisible.value = false; |
| | | emit('close') |
| | | }; |
| | | // è·åå½åæ¥æå¹¶æ ¼å¼å为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, "0"); // æä»½ä»0å¼å§ |
| | | const day = String(today.getDate()).padStart(2, "0"); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | defineExpose({ |
| | | openDialog, |
| | | }); |
| | |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')">æ°å¢</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | |
| | | |
| | | <script setup> |
| | | import {Search} from "@element-plus/icons-vue"; |
| | | import {onMounted, ref} from "vue"; |
| | | import {onMounted, ref, getCurrentInstance, nextTick} from "vue"; |
| | | import FormDia from "@/views/customerService/feedbackRegistration/components/formDia.vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {afterSalesServiceDelete, afterSalesServiceListPage} from "@/api/customerService/index.js"; |
| | |
| | | openForm("edit", row); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.checkUserId !== userStore.id || row.status !== 1 |
| | | return row.status !== 1 |
| | | } |
| | | }, |
| | | ], |
| | |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/afterSalesService/export", {}, "åé¦ç»è®°.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="carbon-management"> |
| | | <!-- 页é¢å¤´é¨ --> |
| | | <div class="page-header"> |
| | | <div class="header-content"> |
| | | <h1 class="page-title">ç¢³ææ¾ç®¡çç³»ç»</h1> |
| | | <p class="page-subtitle">åºäºISO 14064æ å · GHG Protocolæ ¸ç®æ å</p> |
| | | </div> |
| | | <div class="header-stats"> |
| | | <div class="stat-item"> |
| | | <span class="stat-label">æ»ç¢³ææ¾é</span> |
| | | <span class="stat-value">{{totalEmissions}} tCOâe</span> |
| | | </div> |
| | | <div class="stat-item"> |
| | | <span class="stat-label">æ¬æåæ</span> |
| | | <span class="stat-value reduction">-{{monthlyReduction}}%</span> |
| | | </div> |
| | | <div class="stat-item"> |
| | | <span class="stat-label">碳ä¸åè¿åº¦</span> |
| | | <span class="stat-value">{{neutralProgress}}%</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 主è¦å
容åºå --> |
| | | <div class="dashboard-content"> |
| | | <!-- 顶鍿°æ®é¢æ¿ --> |
| | | <div class="top-panels"> |
| | | <div class="data-panel top-left"> |
| | | <div class="panel-title">å½åç¢³ææ¾</div> |
| | | <div class="panel-value">{{carbonData.scope1}} <span class="unit">tCOâe</span></div> |
| | | <div class="panel-subtitle">èå´1ç´æ¥ææ¾</div> |
| | | </div> |
| | | <div class="data-panel top-center"> |
| | | <div class="panel-title">è½èçæµ</div> |
| | | <div class="panel-value">{{carbonData.scope2}} <span class="unit">tCOâe</span></div> |
| | | <div class="panel-subtitle">èå´2é´æ¥ææ¾</div> |
| | | </div> |
| | | <div class="data-panel top-right"> |
| | | <div class="panel-title">ä¾åºé¾ææ¾</div> |
| | | <div class="panel-value">{{carbonData.scope3}} <span class="unit">tCOâe</span></div> |
| | | <div class="panel-subtitle">èå´3ä¾åºé¾ææ¾</div> |
| | | </div> |
| | | <div class="data-panel top-far-right"> |
| | | <div class="panel-title">åæè¿åº¦</div> |
| | | <div class="panel-value">{{neutralProgress}} <span class="unit">%</span></div> |
| | | <div class="panel-subtitle">碳ä¸åç®æ </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- ä¸å¿ä¸»è§å¾åºå --> |
| | | <div class="center-main-view"> |
| | | <!-- 左侧æ§å¶é¢æ¿ --> |
| | | <div class="left-control-panel"> |
| | | <div class="control-section"> |
| | | <div class="section-title">ç¢³ææ¾èå´</div> |
| | | <el-radio-group v-model="selectedScope" @change="updateScopeData" class="vertical-radio"> |
| | | <el-radio-button :value="'all'">å
¨é¨èå´</el-radio-button> |
| | | <el-radio-button :value="'scope1'">èå´1</el-radio-button> |
| | | <el-radio-button :value="'scope2'">èå´2</el-radio-button> |
| | | <el-radio-button :value="'scope3'">èå´3</el-radio-button> |
| | | </el-radio-group> |
| | | </div> |
| | | <div class="control-section"> |
| | | <div class="section-title">çæµå±çº§</div> |
| | | <el-radio-group v-model="heatmapLevel" @change="updateHeatmapLevel" class="vertical-radio"> |
| | | <el-radio-button :value="'device'">设å¤çº§</el-radio-button> |
| | | <el-radio-button :value="'line'">产线级</el-radio-button> |
| | | <el-radio-button :value="'enterprise'">ä¼ä¸çº§</el-radio-button> |
| | | </el-radio-group> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- ä¸å¿çåå¾ --> |
| | | <div class="main-heatmap"> |
| | | <div class="heatmap-header"> |
| | | <h2 class="main-title">碳足迹çåå¾åæ</h2> |
| | | <div class="date-selector"> |
| | | <el-date-picker |
| | | v-model="selectedDate" |
| | | type="date" |
| | | placeholder="éæ©æ¥æ" |
| | | size="small" |
| | | @change="updateHeatmapData" |
| | | /> |
| | | </div> |
| | | </div> |
| | | <div class="heatmap-view"> |
| | | <Echarts ref="heatmapChart" |
| | | :series="heatmapSeries" |
| | | :xAxis="heatmapXAxis" |
| | | :yAxis="heatmapYAxis" |
| | | :tooltip="heatmapTooltip" |
| | | :visualMap="heatmapVisualMap" |
| | | :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}" |
| | | style="height: 450px"></Echarts> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- å³ä¾§æ°æ®é¢æ¿ --> |
| | | <div class="right-data-panel"> |
| | | <div class="data-section"> |
| | | <div class="section-title">宿¶çæ§</div> |
| | | <div class="mini-chart"> |
| | | <Echarts ref="realtimeChart" |
| | | :series="realtimeSeries" |
| | | :xAxis="realtimeXAxis" |
| | | :chartStyle="chartStyle" |
| | | :yAxis="realtimeYAxis" |
| | | :tooltip="realtimeTooltip" |
| | | :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}" |
| | | style="height: 300px"></Echarts> |
| | | </div> |
| | | </div> |
| | | <div class="data-section"> |
| | | <div class="section-title">è¶å¿åæ</div> |
| | | <div class="trend-controls"> |
| | | <el-radio-group v-model="trendPeriod" size="small" @change="updateTrendData"> |
| | | <el-radio-button :value="'week'">å¨</el-radio-button> |
| | | <el-radio-button :value="'month'">æ</el-radio-button> |
| | | <el-radio-button :value="'year'">å¹´</el-radio-button> |
| | | </el-radio-group> |
| | | </div> |
| | | <div class="mini-chart"> |
| | | <Echarts ref="trendChart" |
| | | :series="trendSeries" |
| | | :xAxis="trendXAxis" |
| | | :yAxis="trendYAxis" |
| | | :tooltip="trendTooltip" |
| | | :chartStyle="chartStyle" |
| | | :legend="trendLegend" |
| | | :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}" |
| | | style="height: 200px"></Echarts> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- åºé¨è¿åº¦é¢æ¿ --> |
| | | <div class="bottom-progress-panel"> |
| | | <div class="progress-section"> |
| | | <div class="progress-title">2024å¹´åæç®æ </div> |
| | | <div class="progress-data"> |
| | | <span class="current">{{reductionTarget.current}}</span> |
| | | <span class="separator">/</span> |
| | | <span class="target">{{reductionTarget.target}} tCOâe</span> |
| | | </div> |
| | | <el-progress :percentage="reductionTarget.percentage" :stroke-width="6" color="#00E676"/> |
| | | </div> |
| | | <div class="progress-section"> |
| | | <div class="progress-title">碳ä¸åè¿åº¦</div> |
| | | <div class="progress-data"> |
| | | <span class="current">{{neutralTarget.current}}</span> |
| | | <span class="separator">/</span> |
| | | <span class="target">{{neutralTarget.target}} tCOâe</span> |
| | | </div> |
| | | <el-progress :percentage="neutralTarget.percentage" :stroke-width="6" color="#00D4FF"/> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- åºé¨æ°æ®è¡¨æ ¼ --> |
| | | <div class="bottom-data-table"> |
| | | <div class="table-panel"> |
| | | <div class="table-header"> |
| | | <h3 class="table-title">ç¢³ææ¾è¯¦ç»æ°æ®</h3> |
| | | <div class="table-controls"> |
| | | <el-input |
| | | v-model="searchKeyword" |
| | | placeholder="æç´¢è®¾å¤æäº§çº¿" |
| | | size="small" |
| | | style="width: 200px; margin-right: 10px;" |
| | | /> |
| | | <el-button type="primary" size="small" @click="exportData">å¯¼åºæ°æ®</el-button> |
| | | </div> |
| | | </div> |
| | | <el-table :data="filteredTableData" style="width: 100%" height="180"> |
| | | <el-table-column prop="name" label="设å¤/产线" width="150"/> |
| | | <el-table-column prop="type" label="ç±»å" width="100"/> |
| | | <el-table-column prop="scope1" label="èå´1ææ¾" width="120"/> |
| | | <el-table-column prop="scope2" label="èå´2ææ¾" width="120"/> |
| | | <el-table-column prop="scope3" label="èå´3ææ¾" width="120"/> |
| | | <el-table-column prop="total" label="æ»ææ¾é" width="120"/> |
| | | <el-table-column prop="efficiency" label="碳æç" width="100"/> |
| | | <el-table-column prop="status" label="ç¶æ" width="100"> |
| | | <template #default="scope"> |
| | | <el-tag :type="getStatusType(scope.row.status)">{{scope.row.status}}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, onBeforeUnmount, computed } from 'vue' |
| | | import * as echarts from 'echarts' |
| | | import Echarts from '@/components/Echarts/echarts.vue' |
| | | |
| | | // ååºå¼æ°æ® |
| | | const selectedScope = ref('all') |
| | | const heatmapLevel = ref('device') |
| | | const selectedDate = ref(new Date()) |
| | | const trendPeriod = ref('week') |
| | | const searchKeyword = ref('') |
| | | |
| | | // ç¢³ææ¾æ°æ® |
| | | const carbonData = ref({ |
| | | scope1: 125.6, |
| | | scope2: 89.3, |
| | | scope3: 234.7 |
| | | }) |
| | | const chartStyle = { |
| | | width: '96%', |
| | | height: '110%' // 设置å¾è¡¨å®¹å¨çé«åº¦ |
| | | } |
| | | // 计ç®å±æ§ |
| | | const totalEmissions = computed(() => { |
| | | return (carbonData.value.scope1 + carbonData.value.scope2 + carbonData.value.scope3).toFixed(1) |
| | | }) |
| | | |
| | | const monthlyReduction = ref(8.5) |
| | | |
| | | // 计ç®ç¢³ä¸åè¿åº¦ç¾åæ¯ |
| | | const neutralProgress = computed(() => { |
| | | return Math.round(neutralTarget.value.percentage) |
| | | }) |
| | | |
| | | // åæç®æ æ°æ® |
| | | const reductionTarget = ref({ |
| | | current: 320.5, |
| | | target: 500, |
| | | percentage: 64.1 |
| | | }) |
| | | |
| | | const neutralTarget = ref({ |
| | | current: 1250, |
| | | target: 3800, |
| | | percentage: 32.9 |
| | | }) |
| | | |
| | | // 宿¶çæ§å¾è¡¨é
ç½® |
| | | const realtimeSeries = ref([ |
| | | { |
| | | name: '宿¶ç¢³ææ¾', |
| | | type: 'line', |
| | | smooth: true, |
| | | data: generateRealtimeData(), |
| | | itemStyle: { |
| | | color: '#FF6B6B' |
| | | }, |
| | | areaStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: 'rgba(255, 107, 107, 0.3)' }, |
| | | { offset: 1, color: 'rgba(255, 107, 107, 0.1)' } |
| | | ]) |
| | | } |
| | | } |
| | | ]) |
| | | |
| | | const realtimeXAxis = [{ |
| | | type: 'category', |
| | | data: Array.from({length: 24}, (_, i) => `${i.toString().padStart(2, '0')}:00`), |
| | | axisLabel: { color: '#B8C8E0' } |
| | | }] |
| | | |
| | | const realtimeYAxis = [{ |
| | | type: 'value', |
| | | name: 'tCOâe/h', |
| | | axisLabel: { color: '#B8C8E0' }, |
| | | nameTextStyle: { color: '#B8C8E0' } |
| | | }] |
| | | |
| | | const realtimeTooltip = { |
| | | trigger: 'axis', |
| | | formatter: '{b}: {c} tCOâe/h' |
| | | } |
| | | |
| | | // çåå¾é
ç½® |
| | | const heatmapSeries = ref([ |
| | | { |
| | | name: 'ç¢³ææ¾é', |
| | | type: 'heatmap', |
| | | data: generateHeatmapData(), |
| | | label: { |
| | | show: false |
| | | }, |
| | | emphasis: { |
| | | itemStyle: { |
| | | shadowBlur: 10, |
| | | shadowColor: 'rgba(0, 0, 0, 0.5)' |
| | | } |
| | | } |
| | | } |
| | | ]) |
| | | |
| | | const heatmapXAxis = [{ |
| | | type: 'category', |
| | | data: Array.from({length: 24}, (_, i) => `${i}:00`), |
| | | splitArea: { show: true }, |
| | | axisLabel: { color: '#B8C8E0' } |
| | | }] |
| | | |
| | | const heatmapYAxis = [{ |
| | | type: 'category', |
| | | data: ['设å¤A', '设å¤B', '设å¤C', '设å¤D', '设å¤E', '设å¤F', '设å¤G'], |
| | | splitArea: { show: true }, |
| | | axisLabel: { color: '#B8C8E0' } |
| | | }] |
| | | |
| | | const heatmapTooltip = { |
| | | trigger: 'item', |
| | | formatter: function (params) { |
| | | const [hour, device] = params.data |
| | | const value = params.value[2] |
| | | return `设å¤: ${heatmapYAxis[0].data[device]}<br/>æ¶é´: ${hour}:00<br/>ç¢³ææ¾é: ${value} tCOâe` |
| | | } |
| | | } |
| | | |
| | | const heatmapVisualMap = ref({ |
| | | min: 0, |
| | | max: 50, |
| | | calculable: true, |
| | | orient: 'horizontal', |
| | | left: 'center', |
| | | bottom: '5%', |
| | | inRange: { |
| | | color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026'] |
| | | }, |
| | | textStyle: { color: '#B8C8E0' } |
| | | }) |
| | | |
| | | // è¶å¿åæå¾è¡¨é
ç½® |
| | | const trendSeries = ref([ |
| | | { |
| | | name: 'èå´1', |
| | | type: 'line', |
| | | data: [120, 132, 101, 134, 90, 230, 210], |
| | | itemStyle: { color: '#FF6B6B' } |
| | | }, |
| | | { |
| | | name: 'èå´2', |
| | | type: 'line', |
| | | data: [220, 182, 191, 234, 290, 330, 310], |
| | | itemStyle: { color: '#4ECDC4' } |
| | | }, |
| | | { |
| | | name: 'èå´3', |
| | | type: 'line', |
| | | data: [150, 232, 201, 154, 190, 330, 410], |
| | | itemStyle: { color: '#45B7D1' } |
| | | } |
| | | ]) |
| | | |
| | | const trendXAxis = [{ |
| | | type: 'category', |
| | | data: ['å¨ä¸', 'å¨äº', 'å¨ä¸', 'å¨å', 'å¨äº', 'å¨å
', '卿¥'], |
| | | axisLabel: { color: '#B8C8E0' } |
| | | }] |
| | | |
| | | const trendYAxis = [{ |
| | | type: 'value', |
| | | name: 'tCOâe', |
| | | axisLabel: { color: '#B8C8E0' }, |
| | | nameTextStyle: { color: '#B8C8E0' } |
| | | }] |
| | | |
| | | const trendTooltip = { |
| | | trigger: 'axis' |
| | | } |
| | | |
| | | const trendLegend = { |
| | | data: ['èå´1', 'èå´2', 'èå´3'], |
| | | textStyle: { color: '#B8C8E0' } |
| | | } |
| | | |
| | | // è¡¨æ ¼æ°æ® |
| | | const carbonTableData = ref([ |
| | | { name: 'ç产线A', type: '产线', scope1: 45.2, scope2: 32.1, scope3: 18.7, total: 96.0, efficiency: 'è¯å¥½', status: 'æ£å¸¸' }, |
| | | { name: '设å¤B-01', type: '设å¤', scope1: 12.5, scope2: 8.3, scope3: 5.2, total: 26.0, efficiency: 'ä¼ç§', status: 'æ£å¸¸' }, |
| | | { name: 'ç产线C', type: '产线', scope1: 38.7, scope2: 28.9, scope3: 15.4, total: 83.0, efficiency: 'è¯å¥½', status: 'åè¦' }, |
| | | { name: '设å¤D-02', type: '设å¤', scope1: 15.8, scope2: 11.2, scope3: 7.1, total: 34.1, efficiency: 'ä¸è¬', status: 'æ£å¸¸' }, |
| | | { name: 'ç产线E', type: '产线', scope1: 52.3, scope2: 39.6, scope3: 22.8, total: 114.7, efficiency: 'å¾
ä¼å', status: 'åè¦' } |
| | | ]) |
| | | |
| | | // çæå®æ¶æ°æ® |
| | | function generateRealtimeData() { |
| | | return Array.from({length: 24}, () => (Math.random() * 20 + 10).toFixed(1)) |
| | | } |
| | | |
| | | // çæçå徿°æ® |
| | | function generateHeatmapData() { |
| | | const data = [] |
| | | let yAxisLength = 7 // é»è®¤è®¾å¤çº§ |
| | | let baseMultiplier = 1 // åºç¡åæ° |
| | | |
| | | // æ ¹æ®å±çº§ç¡®å®Yè½´é¿åº¦åæ°æ®èå´ |
| | | if (heatmapLevel.value === 'line') { |
| | | yAxisLength = 5 |
| | | baseMultiplier = 2 // äº§çº¿çº§æ°æ®æ´å¤§ |
| | | } else if (heatmapLevel.value === 'enterprise') { |
| | | yAxisLength = 3 |
| | | baseMultiplier = 4 // ä¼ä¸çº§æ°æ®æå¤§ |
| | | } |
| | | |
| | | for (let i = 0; i < yAxisLength; i++) { |
| | | for (let j = 0; j < 24; j++) { |
| | | let value |
| | | // ç®åçæ¶é´æ®µé»è¾ |
| | | if (j >= 8 && j <= 18) { |
| | | // 工使¶é´ææ¾éè¾é« |
| | | value = Math.random() * 30 + 20 |
| | | } else if (j >= 19 && j <= 22) { |
| | | // æé´ææ¾éä¸ç |
| | | value = Math.random() * 20 + 10 |
| | | } else { |
| | | // æ·±å¤ååæ¨ææ¾éè¾ä½ |
| | | value = Math.random() * 10 + 2 |
| | | } |
| | | |
| | | // æ·»å 设å¤å·®å¼åå±çº§åæ° |
| | | value *= (0.8 + i * 0.1) * baseMultiplier |
| | | |
| | | data.push([j, i, Math.round(value * 10) / 10]) |
| | | } |
| | | } |
| | | return data |
| | | } |
| | | |
| | | // æ´æ°èå´æ°æ® |
| | | function updateScopeData() { |
| | | // æ ¹æ®éæ©çèå´æ´æ°ææç¸å
³å¾è¡¨æ°æ® |
| | | const scopeMultiplier = { |
| | | 'all': 1, |
| | | 'scope1': 0.3, |
| | | 'scope2': 0.4, |
| | | 'scope3': 0.3 |
| | | } |
| | | |
| | | const multiplier = scopeMultiplier[selectedScope.value] || 1 |
| | | |
| | | // æ´æ°ç¢³ææ¾æ°æ®æ¾ç¤º |
| | | if (selectedScope.value === 'all') { |
| | | carbonData.value = { |
| | | scope1: 125.6, |
| | | scope2: 89.3, |
| | | scope3: 234.7 |
| | | } |
| | | } else { |
| | | const baseTotal = 125.6 + 89.3 + 234.7 |
| | | carbonData.value = { |
| | | scope1: selectedScope.value === 'scope1' ? 125.6 : 0, |
| | | scope2: selectedScope.value === 'scope2' ? 89.3 : 0, |
| | | scope3: selectedScope.value === 'scope3' ? 234.7 : 0 |
| | | } |
| | | } |
| | | |
| | | // æ´æ°çå徿°æ® |
| | | heatmapSeries.value[0].data = generateHeatmapData().map(item => [ |
| | | item[0], item[1], Math.round(item[2] * multiplier * 10) / 10 |
| | | ]) |
| | | |
| | | // æ´æ°å®æ¶çæ§æ°æ® |
| | | realtimeSeries.value[0].data = generateRealtimeData().map(val => |
| | | Math.round(parseFloat(val) * multiplier * 10) / 10 |
| | | ) |
| | | } |
| | | |
| | | // æ´æ°çåå¾å±çº§ |
| | | function updateHeatmapLevel() { |
| | | // æ ¹æ®å±çº§æ´æ°Yè½´æ°æ®åvisualMapèå´ |
| | | if (heatmapLevel.value === 'device') { |
| | | heatmapYAxis[0].data = ['é
çA', 'å缩æºB', 'å·å´å¡C', '飿ºD', 'æ³µE', 'ååå¨F', 'çµæºG'] |
| | | heatmapVisualMap.value.max = 50 |
| | | } else if (heatmapLevel.value === 'line') { |
| | | heatmapYAxis[0].data = ['ç产线1', 'ç产线2', 'ç产线3', 'ç产线4', 'ç产线5'] |
| | | heatmapVisualMap.value.max = 100 |
| | | } else { |
| | | heatmapYAxis[0].data = ['ååºA', 'ååºB', 'ååºC'] |
| | | heatmapVisualMap.value.max = 200 |
| | | } |
| | | |
| | | // æ´æ°çå徿°æ® |
| | | heatmapSeries.value[0].data = generateHeatmapData() |
| | | |
| | | // æ´æ°è¡¨æ ¼æ°æ®ä»¥å¹é
å½åå±çº§ |
| | | updateTableDataForLevel() |
| | | } |
| | | |
| | | // æ ¹æ®å±çº§æ´æ°è¡¨æ ¼æ°æ® |
| | | function updateTableDataForLevel() { |
| | | const levelConfigs = { |
| | | device: [ |
| | | { name: 'é
çA', type: '设å¤', scope1: 45.2, scope2: 32.1, scope3: 18.7, total: 96.0, efficiency: 'è¯å¥½', status: 'æ£å¸¸' }, |
| | | { name: 'å缩æºB', type: '设å¤', scope1: 38.5, scope2: 28.3, scope3: 15.2, total: 82.0, efficiency: 'ä¼ç§', status: 'æ£å¸¸' }, |
| | | { name: 'å·å´å¡C', type: '设å¤', scope1: 22.8, scope2: 18.9, scope3: 12.3, total: 54.0, efficiency: 'è¯å¥½', status: 'åè¦' }, |
| | | { name: '飿ºD', type: '设å¤', scope1: 15.6, scope2: 12.4, scope3: 8.1, total: 36.1, efficiency: 'ä¸è¬', status: 'æ£å¸¸' }, |
| | | { name: 'æ³µE', type: '设å¤', scope1: 12.3, scope2: 9.8, scope3: 6.4, total: 28.5, efficiency: 'ä¼ç§', status: 'æ£å¸¸' } |
| | | ], |
| | | line: [ |
| | | { name: 'ç产线1', type: '产线', scope1: 125.6, scope2: 89.3, scope3: 56.8, total: 271.7, efficiency: 'è¯å¥½', status: 'æ£å¸¸' }, |
| | | { name: 'ç产线2', type: '产线', scope1: 98.4, scope2: 72.1, scope3: 45.2, total: 215.7, efficiency: 'ä¼ç§', status: 'æ£å¸¸' }, |
| | | { name: 'ç产线3', type: '产线', scope1: 87.2, scope2: 65.8, scope3: 41.6, total: 194.6, efficiency: 'è¯å¥½', status: 'åè¦' }, |
| | | { name: 'ç产线4', type: '产线', scope1: 76.9, scope2: 58.3, scope3: 37.1, total: 172.3, efficiency: 'ä¸è¬', status: 'æ£å¸¸' }, |
| | | { name: 'ç产线5', type: '产线', scope1: 65.7, scope2: 49.2, scope3: 31.8, total: 146.7, efficiency: 'å¾
ä¼å', status: 'åè¦' } |
| | | ], |
| | | enterprise: [ |
| | | { name: 'ååºA', type: 'ååº', scope1: 456.8, scope2: 334.7, scope3: 212.5, total: 1004.0, efficiency: 'è¯å¥½', status: 'æ£å¸¸' }, |
| | | { name: 'ååºB', type: 'ååº', scope1: 387.2, scope2: 289.6, scope3: 184.3, total: 861.1, efficiency: 'ä¼ç§', status: 'æ£å¸¸' }, |
| | | { name: 'ååºC', type: 'ååº', scope1: 298.5, scope2: 223.8, scope3: 142.7, total: 665.0, efficiency: 'è¯å¥½', status: 'åè¦' } |
| | | ] |
| | | } |
| | | |
| | | carbonTableData.value = levelConfigs[heatmapLevel.value] || levelConfigs.device |
| | | } |
| | | |
| | | // æ´æ°çå徿°æ®ï¼æ¥æååæ¶ï¼ |
| | | function updateHeatmapData() { |
| | | heatmapSeries.value[0].data = generateHeatmapData() |
| | | |
| | | // åæ¶æ´æ°å
¶ä»ç¸å
³æ°æ® |
| | | updateScopeData() |
| | | } |
| | | |
| | | // æ´æ°è¶å¿æ°æ® |
| | | function updateTrendData() { |
| | | const trendDataConfigs = { |
| | | week: { |
| | | xAxisData: ['å¨ä¸', 'å¨äº', 'å¨ä¸', 'å¨å', 'å¨äº', 'å¨å
', '卿¥'], |
| | | scope1Data: [120, 132, 101, 134, 90, 80, 75], |
| | | scope2Data: [220, 182, 191, 234, 190, 150, 140], |
| | | scope3Data: [150, 232, 201, 154, 190, 120, 110] |
| | | }, |
| | | month: { |
| | | xAxisData: ['1æ', '2æ', '3æ', '4æ', '5æ', '6æ', '7æ', '8æ', '9æ', '10æ', '11æ', '12æ'], |
| | | scope1Data: [1200, 1150, 1300, 1250, 1180, 1320, 1280, 1350, 1220, 1290, 1160, 1100], |
| | | scope2Data: [2200, 2100, 2350, 2280, 2150, 2400, 2320, 2450, 2180, 2380, 2120, 2050], |
| | | scope3Data: [1800, 1750, 1950, 1880, 1820, 2000, 1920, 2100, 1850, 1980, 1780, 1720] |
| | | }, |
| | | year: { |
| | | xAxisData: ['2019', '2020', '2021', '2022', '2023', '2024'], |
| | | scope1Data: [14500, 14200, 13800, 13500, 13100, 12800], |
| | | scope2Data: [26800, 26200, 25600, 25000, 24400, 23800], |
| | | scope3Data: [22400, 21800, 21200, 20600, 20000, 19400] |
| | | } |
| | | } |
| | | |
| | | const config = trendDataConfigs[trendPeriod.value] || trendDataConfigs.week |
| | | |
| | | // æ´æ°Xè½´æ°æ® |
| | | trendXAxis[0].data = config.xAxisData |
| | | |
| | | // æ´æ°ç³»åæ°æ® |
| | | trendSeries.value = [ |
| | | { |
| | | name: 'èå´1', |
| | | type: 'line', |
| | | data: config.scope1Data, |
| | | itemStyle: { color: '#FF6B6B' }, |
| | | smooth: true |
| | | }, |
| | | { |
| | | name: 'èå´2', |
| | | type: 'line', |
| | | data: config.scope2Data, |
| | | itemStyle: { color: '#4ECDC4' }, |
| | | smooth: true |
| | | }, |
| | | { |
| | | name: 'èå´3', |
| | | type: 'line', |
| | | data: config.scope3Data, |
| | | itemStyle: { color: '#45B7D1' }, |
| | | smooth: true |
| | | } |
| | | ] |
| | | } |
| | | |
| | | // è·åç¶æç±»å |
| | | function getStatusType(status) { |
| | | switch (status) { |
| | | case 'æ£å¸¸': return 'success' |
| | | case 'åè¦': return 'warning' |
| | | case 'å¼å¸¸': return 'danger' |
| | | default: return 'info' |
| | | } |
| | | } |
| | | |
| | | // å¯¼åºæ°æ® |
| | | function exportData() { |
| | | // åå¤å¯¼åºæ°æ® |
| | | const exportDataSet = { |
| | | åºæ¬ä¿¡æ¯: { |
| | | å¯¼åºæ¶é´: new Date().toLocaleString('zh-CN'), |
| | | æ°æ®å±çº§: heatmapLevel.value === 'device' ? '设å¤çº§' : heatmapLevel.value === 'line' ? '产线级' : 'ä¼ä¸çº§', |
| | | éæ©èå´: selectedScope.value === 'all' ? 'å
¨é¨èå´' : `èå´${selectedScope.value.slice(-1)}`, |
| | | éæ©æ¥æ: selectedDate.value ? selectedDate.value.toLocaleDateString('zh-CN') : '仿¥' |
| | | }, |
| | | ç¢³ææ¾ç»è®¡: { |
| | | èå´1ç´æ¥ææ¾: carbonData.value.scope1 + ' tCOâe', |
| | | èå´2é´æ¥ææ¾: carbonData.value.scope2 + ' tCOâe', |
| | | èå´3ä¾åºé¾ææ¾: carbonData.value.scope3 + ' tCOâe', |
| | | æ»ææ¾é: totalEmissions.value + ' tCOâe' |
| | | }, |
| | | è¯¦ç»æ°æ®: carbonTableData.value, |
| | | çå徿°æ®: heatmapSeries.value[0].data.map(item => ({ |
| | | æ¶é´: `${item[0]}:00`, |
| | | 设å¤åºå·: item[1], |
| | | 设å¤åç§°: heatmapYAxis.data[item[1]], |
| | | ç¢³ææ¾é: item[2] + ' tCOâe' |
| | | })) |
| | | } |
| | | |
| | | // å建CSVå
容 |
| | | let csvContent = '\uFEFF' // BOM for UTF-8 |
| | | |
| | | // åºæ¬ä¿¡æ¯ |
| | | csvContent += 'åºæ¬ä¿¡æ¯\n' |
| | | Object.entries(exportDataSet.åºæ¬ä¿¡æ¯).forEach(([key, value]) => { |
| | | csvContent += `${key},${value}\n` |
| | | }) |
| | | csvContent += '\n' |
| | | |
| | | // ç¢³ææ¾ç»è®¡ |
| | | csvContent += 'ç¢³ææ¾ç»è®¡\n' |
| | | Object.entries(exportDataSet.ç¢³ææ¾ç»è®¡).forEach(([key, value]) => { |
| | | csvContent += `${key},${value}\n` |
| | | }) |
| | | csvContent += '\n' |
| | | |
| | | // è¯¦ç»æ°æ®è¡¨æ ¼ |
| | | csvContent += 'è¯¦ç»æ°æ®\n' |
| | | csvContent += 'åç§°,ç±»å,èå´1ææ¾,èå´2ææ¾,èå´3ææ¾,æ»ææ¾é,碳æç,ç¶æ\n' |
| | | exportDataSet.è¯¦ç»æ°æ®.forEach(row => { |
| | | csvContent += `${row.name},${row.type},${row.scope1},${row.scope2},${row.scope3},${row.total},${row.efficiency},${row.status}\n` |
| | | }) |
| | | csvContent += '\n' |
| | | |
| | | // çå徿°æ®ï¼å50æ¡ï¼ |
| | | csvContent += 'çå徿°æ®ï¼å50æ¡ï¼\n' |
| | | csvContent += 'æ¶é´,设å¤åç§°,ç¢³ææ¾é\n' |
| | | exportDataSet.çå徿°æ®.slice(0, 50).forEach(row => { |
| | | csvContent += `${row.æ¶é´},${row.设å¤åç§°},${row.ç¢³ææ¾é}\n` |
| | | }) |
| | | |
| | | // å建ä¸è½½é¾æ¥ |
| | | const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }) |
| | | const link = document.createElement('a') |
| | | const url = URL.createObjectURL(blob) |
| | | link.setAttribute('href', url) |
| | | link.setAttribute('download', `ç¢³ææ¾æ°æ®_${new Date().toISOString().slice(0, 10)}.csv`) |
| | | link.style.visibility = 'hidden' |
| | | document.body.appendChild(link) |
| | | link.click() |
| | | document.body.removeChild(link) |
| | | |
| | | // æ¾ç¤ºæåæ¶æ¯ |
| | | console.log('ç¢³ææ¾æ°æ®å¯¼åºæå') |
| | | } |
| | | |
| | | // æç´¢è¿æ»¤åè½ |
| | | const filteredTableData = computed(() => { |
| | | if (!searchKeyword.value) { |
| | | return carbonTableData.value |
| | | } |
| | | return carbonTableData.value.filter(item => |
| | | item.name.toLowerCase().includes(searchKeyword.value.toLowerCase()) || |
| | | item.type.toLowerCase().includes(searchKeyword.value.toLowerCase()) |
| | | ) |
| | | }) |
| | | |
| | | // çåå¾ç¹å»äºä»¶å¤ç |
| | | function handleHeatmapClick(params) { |
| | | if (params.componentType === 'series') { |
| | | const [hour, deviceIndex, value] = params.data |
| | | const deviceName = heatmapYAxis.data[deviceIndex] |
| | | console.log(`ç¹å»äºè®¾å¤: ${deviceName}, æ¶é´: ${hour}:00, ææ¾é: ${value} tCOâe`) |
| | | |
| | | // å¯ä»¥å¨è¿éæ·»å 详ç»ä¿¡æ¯å¼¹çªæè·³è½¬å°è¯¦ç»é¡µé¢ |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | // 页é¢å è½½å®æåçåå§åæä½ |
| | | console.log('碳管ç页é¢å·²å è½½') |
| | | |
| | | // åå§åçå徿°æ® |
| | | updateHeatmapLevel() |
| | | |
| | | // åå§åè¶å¿æ°æ® |
| | | updateTrendData() |
| | | |
| | | // åå§åèå´æ°æ® |
| | | updateScopeData() |
| | | |
| | | // è®¾ç½®å®æ¶å¨ï¼æ¯30ç§æ´æ°ä¸æ¬¡å®æ¶æ°æ® |
| | | const timer = setInterval(() => { |
| | | realtimeSeries.value[0].data = generateRealtimeData() |
| | | }, 30000) |
| | | |
| | | // æ¸
ç宿¶å¨ |
| | | onBeforeUnmount(() => { |
| | | clearInterval(timer) |
| | | }) |
| | | }) |
| | | |
| | | // æ·»å çåå¾ç¹å»äºä»¶ç»å® |
| | | function bindHeatmapEvents() { |
| | | // è¿ä¸ªå½æ°å¯ä»¥ç¨æ¥ç»å®çåå¾çç¹å»äºä»¶ |
| | | // å¨å®é
使ç¨ä¸ï¼å¯ä»¥éè¿EChartsçäºä»¶ç³»ç»æ¥å®ç° |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .carbon-management { |
| | | min-height: 100vh; |
| | | background: |
| | | radial-gradient(ellipse at top, rgba(29, 78, 216, 0.15), transparent 50%), |
| | | radial-gradient(ellipse at bottom, rgba(139, 92, 246, 0.15), transparent 50%), |
| | | linear-gradient(135deg, #0a0f1c 0%, #1e293b 25%, #0f172a 50%, #1e293b 75%, #0a0f1c 100%); |
| | | padding: 20px; |
| | | font-family: 'Inter', 'Microsoft YaHei', sans-serif; |
| | | overflow: hidden; |
| | | position: relative; |
| | | } |
| | | |
| | | .carbon-management::before { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background: |
| | | radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.1) 0%, transparent 50%), |
| | | radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.1) 0%, transparent 50%), |
| | | radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.05) 0%, transparent 50%); |
| | | pointer-events: none; |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | .page-header { |
| | | background: |
| | | linear-gradient(135deg, rgba(15, 27, 46, 0.95) 0%, rgba(30, 41, 59, 0.9) 100%), |
| | | radial-gradient(circle at top right, rgba(59, 130, 246, 0.1), transparent 50%); |
| | | border: 1px solid rgba(148, 163, 184, 0.2); |
| | | border-radius: 20px; |
| | | padding: 40px; |
| | | margin-bottom: 30px; |
| | | box-shadow: |
| | | 0 25px 50px -12px rgba(0, 0, 0, 0.4), |
| | | 0 0 0 1px rgba(255, 255, 255, 0.05), |
| | | inset 0 1px 0 rgba(255, 255, 255, 0.1); |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | position: relative; |
| | | overflow: hidden; |
| | | backdrop-filter: blur(20px); |
| | | |
| | | } |
| | | |
| | | .page-header:hover { |
| | | transform: translateY(-2px); |
| | | box-shadow: |
| | | 0 32px 64px -12px rgba(0, 0, 0, 0.5), |
| | | 0 0 0 1px rgba(255, 255, 255, 0.1), |
| | | inset 0 1px 0 rgba(255, 255, 255, 0.15); |
| | | } |
| | | |
| | | .page-header::before { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background: |
| | | linear-gradient(45deg, rgba(59, 130, 246, 0.08) 0%, rgba(147, 51, 234, 0.08) 50%, rgba(236, 72, 153, 0.08) 100%); |
| | | pointer-events: none; |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | .header-content { |
| | | flex: 1; |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | |
| | | .page-title { |
| | | font-size: 28px; |
| | | font-weight: bold; |
| | | color: #ffffff; |
| | | margin: 0 0 8px 0; |
| | | text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5); |
| | | } |
| | | |
| | | .page-subtitle { |
| | | font-size: 14px; |
| | | color: #B8C8E0; |
| | | margin: 0; |
| | | } |
| | | |
| | | .header-stats { |
| | | display: flex; |
| | | gap: 40px; |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | |
| | | .stat-item { |
| | | text-align: center; |
| | | padding: 20px; |
| | | background: |
| | | linear-gradient(135deg, rgba(59, 130, 246, 0.15) 0%, rgba(147, 51, 234, 0.15) 100%), |
| | | radial-gradient(circle at center, rgba(255, 255, 255, 0.05), transparent 70%); |
| | | border-radius: 12px; |
| | | border: 1px solid rgba(148, 163, 184, 0.2); |
| | | position: relative; |
| | | overflow: hidden; |
| | | |
| | | backdrop-filter: blur(10px); |
| | | } |
| | | |
| | | .stat-item:hover { |
| | | transform: translateY(-2px) scale(1.05); |
| | | box-shadow: |
| | | 0 20px 25px -5px rgba(59, 130, 246, 0.3), |
| | | 0 10px 10px -5px rgba(59, 130, 246, 0.2); |
| | | } |
| | | |
| | | .stat-item::before { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | left: -100%; |
| | | width: 100%; |
| | | height: 100%; |
| | | background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent); |
| | | |
| | | } |
| | | |
| | | .stat-item:hover::before { |
| | | left: 100%; |
| | | } |
| | | |
| | | .stat-label { |
| | | display: block; |
| | | font-size: 12px; |
| | | color: #94A3B8; |
| | | margin-bottom: 8px; |
| | | font-weight: 500; |
| | | letter-spacing: 0.5px; |
| | | text-transform: uppercase; |
| | | } |
| | | |
| | | .stat-value { |
| | | display: block; |
| | | font-size: 28px; |
| | | font-weight: 700; |
| | | color: #00D4FF; |
| | | text-shadow: |
| | | 0 0 20px rgba(0, 212, 255, 0.6), |
| | | 0 0 40px rgba(0, 212, 255, 0.3); |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | |
| | | .stat-value.reduction { |
| | | color: #00E676; |
| | | text-shadow: |
| | | 0 0 20px rgba(0, 230, 118, 0.6), |
| | | 0 0 40px rgba(0, 230, 118, 0.3); |
| | | } |
| | | |
| | | .dashboard-content { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20px; |
| | | min-height: calc(100vh - 200px); |
| | | } |
| | | |
| | | .top-panels { |
| | | display: grid; |
| | | grid-template-columns: 1fr 1fr 1fr 1fr; |
| | | gap: 20px; |
| | | height: 120px; |
| | | } |
| | | |
| | | .data-panel { |
| | | background: |
| | | linear-gradient(135deg, rgba(15, 27, 46, 0.9) 0%, rgba(30, 41, 59, 0.85) 100%), |
| | | radial-gradient(circle at bottom left, rgba(59, 130, 246, 0.08), transparent 50%); |
| | | border: 1px solid rgba(148, 163, 184, 0.15); |
| | | border-radius: 16px; |
| | | padding: 20px; |
| | | box-shadow: |
| | | 0 20px 25px -5px rgba(0, 0, 0, 0.3), |
| | | 0 10px 10px -5px rgba(0, 0, 0, 0.2), |
| | | 0 0 0 1px rgba(255, 255, 255, 0.05); |
| | | backdrop-filter: blur(16px); |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | align-items: center; |
| | | text-align: center; |
| | | } |
| | | |
| | | .panel-title { |
| | | font-size: 12px; |
| | | color: #94A3B8; |
| | | margin-bottom: 8px; |
| | | font-weight: 500; |
| | | letter-spacing: 0.5px; |
| | | text-transform: uppercase; |
| | | } |
| | | |
| | | .panel-value { |
| | | font-size: 24px; |
| | | font-weight: 700; |
| | | color: #00D4FF; |
| | | text-shadow: |
| | | 0 0 20px rgba(0, 212, 255, 0.6), |
| | | 0 0 40px rgba(0, 212, 255, 0.3); |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .panel-subtitle { |
| | | font-size: 11px; |
| | | color: #B8C8E0; |
| | | font-weight: 400; |
| | | } |
| | | |
| | | .unit { |
| | | font-size: 16px; |
| | | color: #94A3B8; |
| | | } |
| | | |
| | | .center-main-view { |
| | | display: grid; |
| | | grid-template-columns: 200px 1fr 300px; |
| | | gap: 20px; |
| | | flex: 1; |
| | | } |
| | | |
| | | .left-control-panel { |
| | | background: |
| | | linear-gradient(135deg, rgba(15, 27, 46, 0.9) 0%, rgba(30, 41, 59, 0.85) 100%); |
| | | border: 1px solid rgba(148, 163, 184, 0.15); |
| | | border-radius: 16px; |
| | | padding: 20px; |
| | | box-shadow: |
| | | 0 20px 25px -5px rgba(0, 0, 0, 0.3), |
| | | 0 0 0 1px rgba(255, 255, 255, 0.05); |
| | | backdrop-filter: blur(16px); |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20px; |
| | | } |
| | | |
| | | .control-section { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 10px; |
| | | } |
| | | |
| | | .section-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #ffffff; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .vertical-radio { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .main-heatmap { |
| | | background: |
| | | linear-gradient(135deg, rgba(15, 27, 46, 0.9) 0%, rgba(30, 41, 59, 0.85) 100%); |
| | | border: 1px solid rgba(148, 163, 184, 0.15); |
| | | border-radius: 16px; |
| | | padding: 20px; |
| | | box-shadow: |
| | | 0 20px 25px -5px rgba(0, 0, 0, 0.3), |
| | | 0 0 0 1px rgba(255, 255, 255, 0.05); |
| | | backdrop-filter: blur(16px); |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .heatmap-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 20px; |
| | | padding-bottom: 15px; |
| | | border-bottom: 1px solid rgba(148, 163, 184, 0.2); |
| | | } |
| | | |
| | | .main-title { |
| | | font-size: 18px; |
| | | font-weight: bold; |
| | | color: #ffffff; |
| | | margin: 0; |
| | | } |
| | | |
| | | .date-selector { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .heatmap-view { |
| | | flex: 1; |
| | | } |
| | | |
| | | .right-data-panel { |
| | | background: |
| | | linear-gradient(135deg, rgba(15, 27, 46, 0.9) 0%, rgba(30, 41, 59, 0.85) 100%); |
| | | border: 1px solid rgba(148, 163, 184, 0.15); |
| | | border-radius: 16px; |
| | | padding: 20px; |
| | | box-shadow: |
| | | 0 20px 25px -5px rgba(0, 0, 0, 0.3), |
| | | 0 0 0 1px rgba(255, 255, 255, 0.05); |
| | | backdrop-filter: blur(16px); |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20px; |
| | | } |
| | | |
| | | .data-section { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 10px; |
| | | } |
| | | |
| | | .mini-chart { |
| | | width: 100%; |
| | | } |
| | | |
| | | .trend-controls { |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .bottom-progress-panel { |
| | | display: grid; |
| | | grid-template-columns: 1fr 1fr; |
| | | gap: 40px; |
| | | height: 100px; |
| | | } |
| | | |
| | | .progress-section { |
| | | background: |
| | | linear-gradient(135deg, rgba(15, 27, 46, 0.9) 0%, rgba(30, 41, 59, 0.85) 100%); |
| | | border: 1px solid rgba(148, 163, 184, 0.15); |
| | | border-radius: 16px; |
| | | padding: 20px; |
| | | box-shadow: |
| | | 0 20px 25px -5px rgba(0, 0, 0, 0.3), |
| | | 0 0 0 1px rgba(255, 255, 255, 0.05); |
| | | backdrop-filter: blur(16px); |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .progress-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #ffffff; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .progress-data { |
| | | display: flex; |
| | | align-items: baseline; |
| | | gap: 4px; |
| | | margin-bottom: 12px; |
| | | } |
| | | |
| | | .progress-data .current { |
| | | font-size: 20px; |
| | | font-weight: 700; |
| | | color: #00D4FF; |
| | | } |
| | | |
| | | .progress-data .separator { |
| | | font-size: 16px; |
| | | color: #94A3B8; |
| | | } |
| | | |
| | | .progress-data .target { |
| | | font-size: 14px; |
| | | color: #B8C8E0; |
| | | } |
| | | |
| | | .bottom-data-table { |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | .table-panel { |
| | | background: |
| | | linear-gradient(135deg, rgba(15, 27, 46, 0.9) 0%, rgba(30, 41, 59, 0.85) 100%), |
| | | radial-gradient(circle at bottom left, rgba(59, 130, 246, 0.08), transparent 50%); |
| | | border: 1px solid rgba(148, 163, 184, 0.15); |
| | | border-radius: 16px; |
| | | padding: 20px; |
| | | box-shadow: |
| | | 0 20px 25px -5px rgba(0, 0, 0, 0.3), |
| | | 0 10px 10px -5px rgba(0, 0, 0, 0.2), |
| | | 0 0 0 1px rgba(255, 255, 255, 0.05), |
| | | inset 0 1px 0 rgba(255, 255, 255, 0.1); |
| | | backdrop-filter: blur(16px); |
| | | } |
| | | |
| | | .table-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 15px; |
| | | padding-bottom: 10px; |
| | | border-bottom: 1px solid rgba(148, 163, 184, 0.2); |
| | | } |
| | | |
| | | .table-title { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #ffffff; |
| | | margin: 0; |
| | | } |
| | | |
| | | .table-controls { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 10px; |
| | | } |
| | | |
| | | .panel-card { |
| | | background: |
| | | linear-gradient(135deg, rgba(15, 27, 46, 0.9) 0%, rgba(30, 41, 59, 0.85) 100%), |
| | | radial-gradient(circle at bottom left, rgba(59, 130, 246, 0.08), transparent 50%); |
| | | border: 1px solid rgba(148, 163, 184, 0.15); |
| | | border-radius: 16px; |
| | | padding: 24px; |
| | | box-shadow: |
| | | 0 20px 25px -5px rgba(0, 0, 0, 0.3), |
| | | 0 10px 10px -5px rgba(0, 0, 0, 0.2), |
| | | 0 0 0 1px rgba(255, 255, 255, 0.05), |
| | | inset 0 1px 0 rgba(255, 255, 255, 0.1); |
| | | position: relative; |
| | | overflow: hidden; |
| | | backdrop-filter: blur(16px); |
| | | transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); |
| | | } |
| | | |
| | | |
| | | |
| | | .heatmap-card { |
| | | height: 500px; |
| | | } |
| | | |
| | | .card-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 20px; |
| | | padding-bottom: 15px; |
| | | border-bottom: 1px solid rgba(81, 129, 219, 0.3); |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | |
| | | .card-title { |
| | | font-size: 18px; |
| | | font-weight: bold; |
| | | color: #ffffff; |
| | | margin: 0; |
| | | text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5); |
| | | } |
| | | |
| | | .heatmap-controls { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .scope-stats { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 15px; |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | |
| | | .scope-item { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 20px; |
| | | border-radius: 12px; |
| | | background: |
| | | linear-gradient(135deg, rgba(59, 130, 246, 0.12) 0%, rgba(147, 51, 234, 0.12) 100%), |
| | | radial-gradient(circle at top, rgba(255, 255, 255, 0.05), transparent 60%); |
| | | border-left: 4px solid #00D4FF; |
| | | border: 1px solid rgba(148, 163, 184, 0.15); |
| | | position: relative; |
| | | overflow: hidden; |
| | | transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); |
| | | backdrop-filter: blur(8px); |
| | | } |
| | | |
| | | .scope-item:hover { |
| | | transform: translateY(-3px); |
| | | box-shadow: |
| | | 0 15px 30px -5px rgba(59, 130, 246, 0.25), |
| | | 0 0 0 1px rgba(255, 255, 255, 0.1); |
| | | } |
| | | |
| | | .scope-item::after { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | height: 2px; |
| | | background: linear-gradient(90deg, #3B82F6, #8B5CF6, #EC4899); |
| | | opacity: 0; |
| | | transition: opacity 0.3s ease; |
| | | } |
| | | |
| | | .scope-item:hover::after { |
| | | opacity: 1; |
| | | } |
| | | |
| | | /* ç¢³ææ¾ç»è®¡æ ·å¼ */ |
| | | .carbon-stats { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-bottom: 20px; |
| | | gap: 15px; |
| | | } |
| | | |
| | | .carbon-stat-item { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | gap: 12px; |
| | | padding: 20px; |
| | | background: |
| | | linear-gradient(135deg, rgba(59, 130, 246, 0.12) 0%, rgba(147, 51, 234, 0.12) 100%), |
| | | radial-gradient(circle at top, rgba(255, 255, 255, 0.05), transparent 60%); |
| | | border-radius: 12px; |
| | | border: 1px solid rgba(148, 163, 184, 0.15); |
| | | flex: 1; |
| | | position: relative; |
| | | overflow: hidden; |
| | | transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); |
| | | backdrop-filter: blur(8px); |
| | | } |
| | | |
| | | .carbon-stat-item:hover { |
| | | transform: translateY(-3px); |
| | | box-shadow: |
| | | 0 15px 30px -5px rgba(59, 130, 246, 0.25), |
| | | 0 0 0 1px rgba(255, 255, 255, 0.1); |
| | | } |
| | | |
| | | .carbon-stat-item::after { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | height: 2px; |
| | | background: linear-gradient(90deg, #3B82F6, #8B5CF6, #EC4899); |
| | | opacity: 0; |
| | | transition: opacity 0.3s ease; |
| | | } |
| | | |
| | | .carbon-stat-item:hover::after { |
| | | opacity: 1; |
| | | } |
| | | |
| | | .carbon-label { |
| | | color: #94A3B8; |
| | | font-size: 11px; |
| | | text-align: center; |
| | | font-weight: 500; |
| | | letter-spacing: 0.5px; |
| | | text-transform: uppercase; |
| | | } |
| | | |
| | | .carbon-value { |
| | | color: #00D4FF; |
| | | font-size: 18px; |
| | | font-weight: 700; |
| | | text-shadow: |
| | | 0 0 15px rgba(0, 212, 255, 0.6), |
| | | 0 0 30px rgba(0, 212, 255, 0.3); |
| | | position: relative; |
| | | } |
| | | |
| | | .scope-item.scope1 { |
| | | border-left-color: #FF6B6B; |
| | | } |
| | | |
| | | .scope-item.scope2 { |
| | | border-left-color: #FFD93D; |
| | | } |
| | | |
| | | .scope-item.scope3 { |
| | | border-left-color: #6BCF7F; |
| | | } |
| | | |
| | | .scope-icon { |
| | | font-size: 24px; |
| | | margin-right: 15px; |
| | | } |
| | | |
| | | .scope-info { |
| | | flex: 1; |
| | | } |
| | | |
| | | .scope-name { |
| | | display: block; |
| | | font-weight: bold; |
| | | color: #ffffff; |
| | | margin-bottom: 5px; |
| | | } |
| | | |
| | | .scope-value { |
| | | display: block; |
| | | font-size: 20px; |
| | | font-weight: bold; |
| | | color: #00D4FF; |
| | | margin-bottom: 3px; |
| | | text-shadow: 0 0 8px rgba(0, 212, 255, 0.5); |
| | | } |
| | | |
| | | .scope-desc { |
| | | display: block; |
| | | font-size: 12px; |
| | | color: #B8C8E0; |
| | | } |
| | | |
| | | .target-progress { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20px; |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | |
| | | .progress-item { |
| | | padding: 15px; |
| | | background: rgba(81, 129, 219, 0.1); |
| | | border-radius: 8px; |
| | | border: 1px solid rgba(81, 129, 219, 0.2); |
| | | } |
| | | |
| | | .progress-info { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .progress-label { |
| | | font-weight: bold; |
| | | color: #ffffff; |
| | | } |
| | | |
| | | .progress-value { |
| | | color: #B8C8E0; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .bottom-panel { |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | .table-controls { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | /* Element Plus ç»ä»¶æ·±è²ä¸»é¢æ ·å¼ */ |
| | | :deep(.el-table) { |
| | | background: transparent !important; |
| | | color: #ffffff !important; |
| | | } |
| | | |
| | | :deep(.el-table th) { |
| | | background: rgba(81, 129, 219, 0.2) !important; |
| | | color: #ffffff !important; |
| | | border-bottom: 1px solid rgba(81, 129, 219, 0.3) !important; |
| | | } |
| | | |
| | | :deep(.el-table td) { |
| | | background: transparent !important; |
| | | color: #B8C8E0 !important; |
| | | border-bottom: 1px solid rgba(81, 129, 219, 0.1) !important; |
| | | } |
| | | |
| | | :deep(.el-table tr:hover > td) { |
| | | background: rgba(81, 129, 219, 0.1) !important; |
| | | } |
| | | |
| | | :deep(.el-input__wrapper) { |
| | | background: rgba(15, 27, 46, 0.8) !important; |
| | | border: 1px solid rgba(81, 129, 219, 0.3) !important; |
| | | color: #ffffff !important; |
| | | } |
| | | |
| | | :deep(.el-input__inner) { |
| | | color: #ffffff !important; |
| | | } |
| | | |
| | | :deep(.el-button--primary) { |
| | | background: linear-gradient(135deg, #5181DB, #D369E0) !important; |
| | | border: none !important; |
| | | box-shadow: 0 0 10px rgba(81, 129, 219, 0.5) !important; |
| | | } |
| | | |
| | | /* åç´åéæé®ç»æ ·å¼ */ |
| | | :deep(.vertical-radio) { |
| | | display: flex !important; |
| | | flex-direction: column !important; |
| | | gap: 6px !important; |
| | | } |
| | | |
| | | :deep(.vertical-radio .el-radio-button) { |
| | | margin: 0 !important; |
| | | width: 100% !important; |
| | | } |
| | | |
| | | :deep(.vertical-radio .el-radio-button__inner) { |
| | | background: rgba(59, 130, 246, 0.1) !important; |
| | | border: 1px solid rgba(148, 163, 184, 0.2) !important; |
| | | color: #B8C8E0 !important; |
| | | border-radius: 8px !important; |
| | | padding: 10px 16px !important; |
| | | width: 100% !important; |
| | | text-align: center !important; |
| | | font-size: 12px !important; |
| | | font-weight: 500 !important; |
| | | } |
| | | |
| | | :deep(.vertical-radio .el-radio-button__inner:hover) { |
| | | background: rgba(59, 130, 246, 0.2) !important; |
| | | border-color: rgba(59, 130, 246, 0.4) !important; |
| | | color: #ffffff !important; |
| | | } |
| | | |
| | | :deep(.vertical-radio .el-radio-button.is-active .el-radio-button__inner) { |
| | | background: linear-gradient(135deg, #3B82F6, #8B5CF6) !important; |
| | | border-color: #3B82F6 !important; |
| | | color: #ffffff !important; |
| | | box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3) !important; |
| | | } |
| | | |
| | | :deep(.vertical-radio .el-radio-button:first-child .el-radio-button__inner) { |
| | | border-left: 1px solid rgba(148, 163, 184, 0.2) !important; |
| | | } |
| | | |
| | | :deep(.el-radio-group .el-radio-button__inner) { |
| | | background: rgba(59, 130, 246, 0.1) !important; |
| | | border: 1px solid rgba(148, 163, 184, 0.2) !important; |
| | | color: #B8C8E0 !important; |
| | | border-radius: 6px !important; |
| | | padding: 6px 12px !important; |
| | | margin: 0 2px !important; |
| | | font-size: 12px !important; |
| | | } |
| | | |
| | | :deep(.el-radio-group .el-radio-button__inner:hover) { |
| | | background: rgba(59, 130, 246, 0.2) !important; |
| | | border-color: rgba(59, 130, 246, 0.4) !important; |
| | | color: #ffffff !important; |
| | | } |
| | | |
| | | :deep(.el-radio-group .el-radio-button.is-active .el-radio-button__inner) { |
| | | background: linear-gradient(135deg, #3B82F6, #8B5CF6) !important; |
| | | border-color: #3B82F6 !important; |
| | | color: #ffffff !important; |
| | | box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3) !important; |
| | | } |
| | | |
| | | :deep(.el-date-editor .el-input__wrapper) { |
| | | background: rgba(15, 27, 46, 0.8) !important; |
| | | border: 1px solid rgba(81, 129, 219, 0.3) !important; |
| | | } |
| | | |
| | | :deep(.el-progress-bar__outer) { |
| | | background: rgba(81, 129, 219, 0.2) !important; |
| | | } |
| | | |
| | | :deep(.el-tag) { |
| | | background: rgba(81, 129, 219, 0.2) !important; |
| | | border: 1px solid rgba(81, 129, 219, 0.3) !important; |
| | | color: #ffffff !important; |
| | | } |
| | | |
| | | :deep(.el-tag.el-tag--success) { |
| | | background: rgba(0, 230, 118, 0.2) !important; |
| | | border-color: rgba(0, 230, 118, 0.3) !important; |
| | | color: #00E676 !important; |
| | | } |
| | | |
| | | :deep(.el-tag.el-tag--warning) { |
| | | background: rgba(255, 193, 7, 0.2) !important; |
| | | border-color: rgba(255, 193, 7, 0.3) !important; |
| | | color: #FFC107 !important; |
| | | } |
| | | |
| | | :deep(.el-tag.el-tag--danger) { |
| | | background: rgba(244, 67, 54, 0.2) !important; |
| | | border-color: rgba(244, 67, 54, 0.3) !important; |
| | | color: #F44336 !important; |
| | | } |
| | | |
| | | /* ååºå¼è®¾è®¡ */ |
| | | @media (max-width: 1200px) { |
| | | .main-content { |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .header-stats { |
| | | gap: 20px; |
| | | } |
| | | } |
| | | |
| | | @media (max-width: 768px) { |
| | | .page-header { |
| | | flex-direction: column; |
| | | text-align: center; |
| | | gap: 20px; |
| | | } |
| | | |
| | | .header-stats { |
| | | justify-content: center; |
| | | } |
| | | |
| | | .carbon-management { |
| | | padding: 10px; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | version: 'v2.1.0', |
| | | status: 'active', |
| | | accuracy: '94.2%', |
| | | lastUpdate: '2024-01-15 14:30:00' |
| | | lastUpdate: '2025-01-15 14:30:00' |
| | | }, |
| | | { |
| | | modelName: 'å°å±åå颿µæ¨¡å', |
| | | version: 'v1.8.5', |
| | | status: 'active', |
| | | accuracy: '91.7%', |
| | | lastUpdate: '2024-01-14 09:15:00' |
| | | lastUpdate: '2025-01-14 09:15:00' |
| | | }, |
| | | { |
| | | modelName: 'è½èåææ¨¡å', |
| | | version: 'v2.0.3', |
| | | status: 'standby', |
| | | accuracy: '89.3%', |
| | | lastUpdate: '2024-01-13 16:45:00' |
| | | lastUpdate: '2025-01-13 16:45:00' |
| | | } |
| | | ]) |
| | | |
| | |
| | | v-model="searchForm.date" |
| | | type="date" |
| | | placeholder="è¯·éæ©æ¥æ" |
| | | :size="size" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | /> |
| | | <!-- <el-time-picker |
| | | v-model="searchForm.timeRange" |
| | |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')">æ°å¢</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | |
| | | </template> |
| | | <script setup> |
| | | import {Search} from "@element-plus/icons-vue"; |
| | | import {onMounted, ref} from "vue"; |
| | | import {onMounted, ref, getCurrentInstance} from "vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {getToken} from "@/utils/auth.js"; |
| | | import {periodListPage,periodDelete,periodAdd,periodUpdate} from "@/api/energyManagement/index.js"; |
| | |
| | | }, |
| | | form: { |
| | | date: "", |
| | | price: "", |
| | | price: "", |
| | | peak: "", |
| | | valley: "", |
| | | flat: "", |
| | |
| | | const { searchForm,form } = toRefs(data); |
| | | const page = ref({ |
| | | current: 1, |
| | | size: 10, |
| | | size: 100, |
| | | total: 0 |
| | | }); |
| | | const dialogFormVisible = ref(false); |
| | |
| | | }; |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | periodListPage({ ...searchForm, ...page.value }).then((res) => { |
| | | periodListPage({ ...searchForm.value, ...page.value }).then((res) => { |
| | | tableLoading.value = false; |
| | | if (res && res.data) { |
| | | tableData.value = res.data.records || []; |
| | | page.total = res.data.total || 0; |
| | | page.value.total = res.data.total || 0; |
| | | } else { |
| | | tableData.value = []; |
| | | page.total = 0; |
| | | page.value.total = 0; |
| | | ElMessageBox.warning('æªè·åå°æ°æ®'); |
| | | } |
| | | }) |
| | |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/energyPeriod/export", {}, "ç¨çµæ¶æ®µç®¡ç.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | |
| | | import {ref} from "vue"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import {deviceList, equipmentEnergyAdd, equipmentEnergyUpdate, areaListTree} from "@/api/energyManagement/index.js"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | const dialogFormVisible = ref(false); |
| | |
| | | dialogFormVisible.value = false; |
| | | emit('close') |
| | | }; |
| | | // è·åå½åæ¥æå¹¶æ ¼å¼å为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, "0"); // æä»½ä»0å¼å§ |
| | | const day = String(today.getDate()).padStart(2, "0"); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | defineExpose({ |
| | | openDialog, |
| | | }); |
| | |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')">æ°å¢</el-button> |
| | | <el-button type="info" plain icon="Upload" @click="handleImport">导å
¥</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | |
| | | |
| | | <script setup> |
| | | import {Search} from "@element-plus/icons-vue"; |
| | | import {onMounted, ref} from "vue"; |
| | | import {onMounted, ref, getCurrentInstance} from "vue"; |
| | | import FormDia from "@/views/energyManagement/energyPower/components/formDia.vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {getToken} from "@/utils/auth.js"; |
| | |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/equipmentEnergyConsumption/export", {}, "è½æºåç.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | | <el-button @click="handleOut" style="margin-left: 10px">导åº</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | |
| | | |
| | | <script setup> |
| | | import {Search} from "@element-plus/icons-vue"; |
| | | import {onMounted, ref} from "vue"; |
| | | import {onMounted, ref, getCurrentInstance} from "vue"; |
| | | import {listPageByTrend} from "@/api/energyManagement/index.js"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | const page = reactive({ |
| | | current: 1, |
| | |
| | | page.total = res.data.total; |
| | | }); |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/equipmentEnergyConsumption/exportTwo", {}, "è½æºè¶å¿.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | |
| | | // æ¨¡ææ°æ®çæ |
| | | const generateMockData = () => { |
| | | // æ´æ°ç»è®¡æ°æ® |
| | | totalDevices.value = Math.floor(Math.random() * 10) + 15 // 15-25å°è®¾å¤ |
| | | totalDevices.value = Math.floor(Math.random() * 8) // 0-7å°è®¾å¤ |
| | | dailyConsumption.value = Math.floor(Math.random() * 100) + 200 // 200-300 m³ |
| | | monthlyConsumption.value = Math.floor(Math.random() * 2000) + 5000 // 5000-7000 m³ |
| | | gasUnitPrice.value = (Math.random() * 2 + 3).toFixed(2) // 3-5å
/m³ |
| | |
| | | power: '75.5', |
| | | powerFactor: '0.85', |
| | | status: 'æ£å¸¸', |
| | | lastUpdateTime: '2024-01-15 10:30:00' |
| | | lastUpdateTime: '2025-01-15 10:30:00' |
| | | }, |
| | | { |
| | | id: 2, |
| | |
| | | power: '45.2', |
| | | powerFactor: '0.92', |
| | | status: 'æ£å¸¸', |
| | | lastUpdateTime: '2024-01-15 10:25:00' |
| | | lastUpdateTime: '2025-01-15 10:25:00' |
| | | } |
| | | ] |
| | | this.pagination.total = this.meterList.length |
| | |
| | | power: '50.0', |
| | | powerFactor: '0.85', |
| | | status: 'æ£å¸¸', |
| | | lastUpdateTime: '2024-01-15 12:00:00' |
| | | lastUpdateTime: '2025-01-15 12:00:00' |
| | | } |
| | | this.detailDialogVisible = true |
| | | }, |
| | |
| | | import {ref, reactive, nextTick} from "vue"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import {waterDeviceList, waterEquipmentAdd, waterEquipmentUpdate} from "@/api/energyManagement/waterManagement.js"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | const dialogFormVisible = ref(false); |
| | |
| | | dialogFormVisible.value = false; |
| | | emit('close') |
| | | }; |
| | | // è·åå½åæ¥æå¹¶æ ¼å¼å为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, "0"); // æä»½ä»0å¼å§ |
| | | const day = String(today.getDate()).padStart(2, "0"); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | defineExpose({ |
| | | openDialog, |
| | | }); |
| | |
| | | import {ref, reactive, nextTick, watch} from "vue"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import {waterDeviceList, waterBillAdd, waterBillUpdate} from "@/api/energyManagement/waterManagement.js"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | const dialogFormVisible = ref(false); |
| | |
| | | dialogFormVisible.value = false; |
| | | emit('close') |
| | | }; |
| | | // è·åå½åæ¥æå¹¶æ ¼å¼å为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, "0"); // æä»½ä»0å¼å§ |
| | | const day = String(today.getDate()).padStart(2, "0"); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | defineExpose({ |
| | | openDialog, |
| | | }); |
| | |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')">æ°å¢</el-button> |
| | | <el-button type="info" plain icon="Upload" @click="handleImport">导å
¥</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | |
| | | |
| | | <script setup> |
| | | import {Search} from "@element-plus/icons-vue"; |
| | | import {onMounted, ref, reactive, nextTick} from "vue"; |
| | | import {onMounted, ref, reactive, nextTick, getCurrentInstance} from "vue"; |
| | | import FormDia from "@/views/energyManagement/waterManagement/components/formDia.vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {getToken} from "@/utils/auth.js"; |
| | |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/waterRecord/export", {}, "ç¨æ°´ç®¡ç.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="filters" :inline="true"> |
| | | <el-form-item label="åçåç§°/å½å®¶"> |
| | | <el-input |
| | | v-model="filters.name" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥å
³é®è¯" |
| | | clearable |
| | | prefix-icon="Search" |
| | | @change="getTableData" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getTableData">æç´¢</el-button> |
| | | <el-button @click="resetFilters">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <div class="table_list"> |
| | | <div class="actions"> |
| | | <div></div> |
| | | <div> |
| | | <el-button type="primary" @click="openAdd" icon="Plus"> æ°å¢ </el-button> |
| | | <el-button |
| | | type="danger" |
| | | icon="Delete" |
| | | :disabled="multipleSelection.length <= 0" |
| | | @click="handleBatchDelete" |
| | | >æ¹éå é¤</el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <PIMTable |
| | | rowKey="id" |
| | | isSelection |
| | | :column="columns" |
| | | :tableData="dataList" |
| | | :page="{ |
| | | current: pagination.currentPage, |
| | | size: pagination.pageSize, |
| | | total: pagination.total, |
| | | }" |
| | | @selection-change="handleSelectionChange" |
| | | @pagination="changePage" |
| | | > |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog v-model="visible" :title="dialogTitle" width="520px" destroy-on-close> |
| | | <el-form :model="form" ref="formRef" :rules="rules" label-width="90px"> |
| | | <el-form-item label="åçåç§°" prop="name"> |
| | | <el-input v-model="form.name" placeholder="请è¾å
¥åçåç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="æå±å½å®¶" prop="country"> |
| | | <el-input v-model="form.country" placeholder="请è¾å
¥å½å®¶/å°åº" /> |
| | | </el-form-item> |
| | | <el-form-item label="æè¿°" prop="description"> |
| | | <el-input v-model="form.description" type="textarea" :rows="3" placeholder="å¯å¡«ååçç®ä»" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="visible = false">åæ¶</el-button> |
| | | <el-button type="primary" @click="handleSubmit">ç¡®å®</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, getCurrentInstance, onMounted } from 'vue' |
| | | import { ElMessageBox, ElMessage } from 'element-plus' |
| | | import { usePaginationApi } from '@/hooks/usePaginationApi' |
| | | import { getBrandPage, addBrand, editBrand, delBrand } from '@/api/equipmentManagement/brand' |
| | | |
| | | defineOptions({ name: '设å¤åç管ç' }) |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | const multipleSelection = ref([]) |
| | | const formRef = ref() |
| | | const visible = ref(false) |
| | | const dialogTitle = ref('æ°å¢åç') |
| | | const form = ref({ id: undefined, name: '', country: '', description: '' }) |
| | | |
| | | const rules = { |
| | | name: [{ required: true, message: '请è¾å
¥åçåç§°', trigger: 'blur' }], |
| | | country: [{ required: true, message: '请è¾å
¥æå±å½å®¶', trigger: 'blur' }] |
| | | } |
| | | |
| | | const { |
| | | filters, |
| | | columns, |
| | | dataList, |
| | | pagination, |
| | | getTableData, |
| | | resetFilters, |
| | | onCurrentChange, |
| | | } = usePaginationApi( |
| | | getBrandPage, |
| | | { name: undefined }, |
| | | [ |
| | | { label: 'åçåç§°', align: 'center', prop: 'name' }, |
| | | { label: 'æå±å½å®¶', align: 'center', prop: 'country' }, |
| | | { label: 'æè¿°', align: 'center', prop: 'description' }, |
| | | { label: 'å建æ¶é´', align: 'center', prop: 'createdAt' }, |
| | | { |
| | | dataType: 'action', |
| | | label: 'æä½', |
| | | align: 'center', |
| | | fixed: 'right', |
| | | width: 140, |
| | | operation: [ |
| | | { |
| | | name: 'ç¼è¾', |
| | | type: 'text', |
| | | clickFun: (row) => openEdit(row), |
| | | }, |
| | | { |
| | | name: 'å é¤', |
| | | type: 'text', |
| | | clickFun: (row) => handleDelete(row.id), |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | ) |
| | | |
| | | const handleSelectionChange = (list) => { |
| | | multipleSelection.value = list |
| | | } |
| | | |
| | | const changePage = ({ page, limit }) => { |
| | | pagination.currentPage = page |
| | | pagination.pageSize = limit |
| | | onCurrentChange(page) |
| | | } |
| | | |
| | | function resetForm() { |
| | | form.value = { id: undefined, name: '', country: '', description: '' } |
| | | } |
| | | |
| | | function openAdd() { |
| | | resetForm() |
| | | dialogTitle.value = 'æ°å¢åç' |
| | | visible.value = true |
| | | } |
| | | |
| | | function openEdit(row) { |
| | | form.value = { id: row.id, name: row.name, country: row.country, description: row.description } |
| | | dialogTitle.value = 'ç¼è¾åç' |
| | | visible.value = true |
| | | } |
| | | |
| | | function handleSubmit() { |
| | | formRef.value.validate(async (valid) => { |
| | | if (!valid) return |
| | | const isEdit = Boolean(form.value.id) |
| | | const api = isEdit ? editBrand : addBrand |
| | | const { code, msg } = await api({ ...form.value }) |
| | | if (code === 200) { |
| | | ElMessage.success(isEdit ? 'ä¿®æ¹æå' : 'æ°å¢æå') |
| | | visible.value = false |
| | | getTableData() |
| | | } else { |
| | | ElMessage.error(msg || 'æä½å¤±è´¥') |
| | | } |
| | | }) |
| | | } |
| | | |
| | | function handleDelete(id) { |
| | | ElMessageBox.confirm('æ¤æä½å°æ°¸ä¹
å é¤è¯¥åç, æ¯å¦ç»§ç»?', 'æç¤º', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning', |
| | | }).then(async () => { |
| | | const { code } = await delBrand(id) |
| | | if (code === 200) { |
| | | ElMessage.success('å 餿å') |
| | | getTableData() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | function handleBatchDelete() { |
| | | if (multipleSelection.value.length === 0) return |
| | | ElMessageBox.confirm('å°å é¤éä¸çåçï¼æ¯å¦ç»§ç»ï¼', 'æç¤º', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning', |
| | | }).then(async () => { |
| | | const ids = multipleSelection.value.map((i) => i.id) |
| | | const { code } = await delBrand(ids) |
| | | if (code === 200) { |
| | | ElMessage.success('å 餿å') |
| | | getTableData() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getTableData() |
| | | }) |
| | | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .table_list { margin-top: unset; } |
| | | .actions { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-bottom: 10px; |
| | | } |
| | | </style> |
| | | |
| | | |
| | |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | | <el-button @click="handleReset" style="margin-left: 10px">éç½®</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {onMounted, ref} from "vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue"; |
| | | import {ElMessageBox, ElMessage} from "element-plus"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import CalibrationDia from "@/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue"; |
| | | import {ledgerRecordListPage} from "@/api/equipmentManagement/calibration.js"; |
| | | import {ledgerRecordListPage, ledgerRecordDelete} from "@/api/equipmentManagement/calibration.js"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const userStore = useUserStore() |
| | | |
| | |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | width: 140, |
| | | align: "center", |
| | | fixed: 'right', |
| | | operation: [ |
| | |
| | | clickFun: (row) => { |
| | | openCalibrationDia("edit", row); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.userId !== userStore.id |
| | | } |
| | | }, |
| | | { |
| | | name: "å é¤", |
| | | type: "text", |
| | | style: { |
| | | color: "#F56C6C" |
| | | }, |
| | | clickFun: (row) => { |
| | | handleDelete(row); |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | |
| | | // éç½®æç´¢æ¡ä»¶ |
| | | const handleReset = () => { |
| | | searchForm.value.recordDate = ""; |
| | | searchForm.value.entryDate = ""; |
| | | searchForm.value.code = ""; |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | |
| | | }) |
| | | } |
| | | |
| | | // å é¤è®°å½ |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤è®¡éå¨å
·ç¼å·ä¸º"${row.code}"çæ£å®è®°å½åï¼`, "å é¤ç¡®è®¤", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | ledgerRecordDelete([row.id]).then(() => { |
| | | ElMessage.success("å 餿å"); |
| | | getList(); |
| | | }).catch(() => { |
| | | ElMessage.error("å é¤å¤±è´¥"); |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶å é¤"); |
| | | }); |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="defect-management"> |
| | | <!-- æä½æé® --> |
| | | <div class="actions"> |
| | | <el-button type="primary" @click="showRegisterDialog = true">ç»è®°ç¼ºé·</el-button> |
| | | </div> |
| | | |
| | | <!-- 缺é·å表 --> |
| | | <el-table :data="defectList" style="width: 100%; margin-top: 10px;" border> |
| | | <el-table-column prop="deviceName" label="设å¤åç§°" width="180"></el-table-column> |
| | | <el-table-column prop="defectDescription" label="ç¼ºé·æè¿°" win-width="300"></el-table-column> |
| | | <el-table-column prop="status" label="ç¶æ" width="220"> |
| | | <template #default="{ row }"> |
| | | <el-tag :type="row.status === '严é缺é·' ? 'danger' : 'success'"> |
| | | {{ row.status }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="220"> |
| | | <template #default="{ row }"> |
| | | <el-button |
| | | v-if="row.status === '严é缺é·' || row.status === 'ä¸è¬ç¼ºé·'" |
| | | type="text" |
| | | @click="eliminateDefect(row)" |
| | | > |
| | | æ¶é¤ç¼ºé· |
| | | </el-button> |
| | | <!-- <el-button |
| | | v-if="row.status === '严é缺é·'" |
| | | type="text" |
| | | @click="transferToRepairOrder(row.id)" |
| | | > |
| | | 转维修å |
| | | </el-button> --> |
| | | <el-button type="text" @click="getLedger(row.deviceLedgerId)"> |
| | | æ¥çå°è´¦ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- 缺é·ç»è®°å¯¹è¯æ¡ --> |
| | | <el-dialog title="ç»è®°è®¾å¤ç¼ºé·" v-model="showRegisterDialog" width="50%"> |
| | | <el-form :model="defectForm" :rules="defectRules" ref="defectFormRef" label-width="100px"> |
| | | <el-form-item label="设å¤åç§°" prop="deviceName"> |
| | | <el-select v-model="defectForm.deviceLedgerId" @change="setDeviceModel"> |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | | :key="index" |
| | | :label="item.deviceName" |
| | | :value="item.id" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç¼ºé·æè¿°" prop="defectDescription"> |
| | | <el-input type="textarea" v-model="defectForm.defectDescription"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="设å¤ç¶æ" prop="status"> |
| | | <el-radio-group v-model="defectForm.status"> |
| | | <el-radio label="æ£å¸¸">æ£å¸¸</el-radio> |
| | | <el-radio label="ä¸è¬ç¼ºé·">ä¸è¬ç¼ºé·</el-radio> |
| | | <el-radio label="严é缺é·">严é缺é·</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="showRegisterDialog = false">åæ¶</el-button> |
| | | <el-button type="primary" @click="submitDefectForm">ç¡®å®</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 缺é·è®¾å¤å°è´¦å¯¹è¯æ¡ --> |
| | | <el-dialog title="缺é·è®¾å¤å°è´¦" v-model="showLedgerDialog" width="80%"> |
| | | <el-table :data="ledgerList" style="width: 100%; margin-top: 10px;" border> |
| | | <el-table-column prop="deviceName" label="设å¤åç§°"></el-table-column> |
| | | <el-table-column prop="defectDescription" label="ç¼ºé·æè¿°"></el-table-column> |
| | | <el-table-column prop="status" label="ç¶æ"></el-table-column> |
| | | <el-table-column prop="eliminateTime" label="æ¶ç¼ºæ¶é´"></el-table-column> |
| | | </el-table> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive } from 'vue'; |
| | | import { ElMessage } from 'element-plus'; |
| | | import { getDeviceLedger } from "@/api/equipmentManagement/ledger"; |
| | | // åè®¾ä»¥ä¸æ¯å端æ¥å£ |
| | | import { |
| | | registerDefect, |
| | | getDefectList, |
| | | eliminateDefect as apiEliminateDefect, |
| | | getDefectLedger, |
| | | deleteDefect |
| | | } from '@/api/equipmentManagement/defectManagement'; |
| | | |
| | | // 缺é·å表 |
| | | const defectList = ref([]); |
| | | // ç»è®°å¯¹è¯æ¡æ¾ç¤ºç¶æ |
| | | const showRegisterDialog = ref(false); |
| | | // å°è´¦å¯¹è¯æ¡æ¾ç¤ºç¶æ |
| | | const showLedgerDialog = ref(false); |
| | | // 缺é·è¡¨å |
| | | const defectForm = reactive({ |
| | | deviceLedgerId: '', |
| | | defectDescription: '', |
| | | status: '', |
| | | }); |
| | | const deviceOptions = ref([]); |
| | | // 表åéªè¯è§å |
| | | const defectRules = reactive({ |
| | | deviceLedgerId: [{ required: true, message: '请è¾å
¥è®¾å¤åç§°', trigger: 'blur' }], |
| | | defectDescription: [{ required: true, message: '请è¾å
¥ç¼ºé·æè¿°', trigger: 'blur' }] |
| | | }); |
| | | // 表åå¼ç¨ |
| | | const defectFormRef = ref(null); |
| | | // å°è´¦å表 |
| | | const ledgerList = ref([]); |
| | | |
| | | const loadDeviceName = async () => { |
| | | const { data } = await getDeviceLedger(); |
| | | // console.log(data); |
| | | deviceOptions.value = data; |
| | | }; |
| | | |
| | | // è·å缺é·å表 |
| | | const fetchDefectList = async () => { |
| | | try { |
| | | const res = await getDefectList(); |
| | | if (res.code === 200) { |
| | | defectList.value = res.data.records; |
| | | } else { |
| | | ElMessage.error(res.message || 'è·å缺é·å表失败'); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·å缺é·å表失败'); |
| | | } |
| | | }; |
| | | |
| | | // æäº¤ç¼ºé·ç»è®°è¡¨å |
| | | const submitDefectForm = async () => { |
| | | if (!defectFormRef.value) return; |
| | | try { |
| | | await defectFormRef.value.validate(); |
| | | const res = await registerDefect(defectForm); |
| | | if (res.code === 200) { |
| | | ElMessage.success('缺é·ç»è®°æå'); |
| | | showRegisterDialog.value = false; |
| | | fetchDefectList(); |
| | | } else { |
| | | ElMessage.error(res.message || '缺é·ç»è®°å¤±è´¥'); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('请填å宿´è¡¨åä¿¡æ¯'); |
| | | } |
| | | }; |
| | | |
| | | // æ¶é¤ç¼ºé· |
| | | const eliminateDefect = async (row) => { |
| | | |
| | | try { |
| | | const res = await apiEliminateDefect(row); |
| | | if (res.code === 200) { |
| | | ElMessage.success('ç¼ºé·æ¶é¤æå'); |
| | | fetchDefectList(); |
| | | } else { |
| | | ElMessage.error(res.message || 'ç¼ºé·æ¶é¤å¤±è´¥'); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('ç¼ºé·æ¶é¤å¤±è´¥'); |
| | | } |
| | | }; |
| | | |
| | | // // 转维修工å |
| | | // const transferToRepairOrder = async (id) => { |
| | | // try { |
| | | // const res = await transferToRepair(id); |
| | | // if (res.code === 200) { |
| | | // ElMessage.success('转维修工åæå'); |
| | | // } else { |
| | | // ElMessage.error(res.message || '转维修工å失败'); |
| | | // } |
| | | // } catch (error) { |
| | | // ElMessage.error('转维修工å失败'); |
| | | // } |
| | | // }; |
| | | |
| | | // è·å缺é·è®¾å¤å°è´¦ |
| | | const getLedger = async (deviceLedgerId) => { |
| | | try { |
| | | const res = await getDefectLedger(deviceLedgerId); |
| | | if (res.code === 200) { |
| | | ledgerList.value = res.data.records; |
| | | showLedgerDialog.value = true; |
| | | } else { |
| | | ElMessage.error(res.message || 'è·å缺é·è®¾å¤å°è´¦å¤±è´¥'); |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·å缺é·è®¾å¤å°è´¦å¤±è´¥'); |
| | | } |
| | | }; |
| | | |
| | | // ç»ä»¶æè½½æ¶è·å缺é·å表 |
| | | const onMounted = () => { |
| | | fetchDefectList(); |
| | | loadDeviceName(); |
| | | }; |
| | | onMounted(); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .defect-management { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .actions { |
| | | margin-bottom: 10px; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="device-info-container"> |
| | | <div class="page-header"> |
| | | <h1>设å¤ä¿¡æ¯</h1> |
| | | <div class="device-status" :class="deviceStatusClass"> |
| | | {{ deviceStatusText }} |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="info-card"> |
| | | <div class="card-header">åºæ¬ä¿¡æ¯</div> |
| | | <div class="card-content"> |
| | | <div class="info-row"> |
| | | <span class="label">设å¤åç§°ï¼</span> |
| | | <span class="value">{{ deviceInfo.deviceName }}</span> |
| | | </div> |
| | | <div class="info-row"> |
| | | <span class="label">è§æ ¼åå·ï¼</span> |
| | | <span class="value">{{ deviceInfo.deviceModel }}</span> |
| | | </div> |
| | | <div class="info-row"> |
| | | <span class="label">ç产åå®¶ï¼</span> |
| | | <span class="value">{{ deviceInfo.supplierName }}</span> |
| | | </div> |
| | | <div class="info-row"> |
| | | <span class="label">åä½ï¼</span> |
| | | <span class="value">{{ deviceInfo.unit }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="info-card"> |
| | | <div class="card-header">ç»´æ¤ä¿¡æ¯</div> |
| | | <div class="card-content"> |
| | | <div class="maintenance-info"> |
| | | <div class="maintenance-item"> |
| | | <span class="label">æåç»´æ¤ï¼</span> |
| | | <span class="value">{{ deviceInfo.updateTime }}</span> |
| | | </div> |
| | | <div class="maintenance-item"> |
| | | <span class="label">䏿¬¡ç»´æ¤ï¼</span> |
| | | <span class="value">{{ deviceInfo.createTime }}</span> |
| | | </div> |
| | | <div class="maintenance-item"> |
| | | <span class="label">ç»´æ¤ç¶æï¼</span> |
| | | <span class="value status-normal">{{ deviceInfo.statusText }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, computed } from 'vue' |
| | | import { useRoute } from 'vue-router' |
| | | import { ElMessage } from 'element-plus' |
| | | import { |
| | | getDeviceInfo, |
| | | } from '@/api/equipmentManagement/deviceInfo' |
| | | |
| | | const route = useRoute() |
| | | |
| | | const deviceInfo = reactive({ |
| | | deviceName: '', |
| | | deviceModel: '', |
| | | supplierName: '', |
| | | unit: '', |
| | | statusText:'æ£å¸¸', |
| | | updateTime:'', |
| | | createTime:'' |
| | | }) |
| | | |
| | | const deviceStatusClass = computed(() => { |
| | | return 'status-normal' |
| | | }) |
| | | |
| | | const deviceStatusText = computed(() => { |
| | | return 'æ£å¸¸' |
| | | }) |
| | | |
| | | const fetchDeviceInfo = async (deviceId) => { |
| | | try { |
| | | // è·å设å¤ä¿¡æ¯ |
| | | const deviceResponse = await getDeviceInfo({id:deviceId}) |
| | | if (deviceResponse.code === 200) { |
| | | Object.assign(deviceInfo, deviceResponse.data) |
| | | } |
| | | |
| | | |
| | | } catch (error) { |
| | | |
| | | ElMessage.warning('ä½¿ç¨æ¨¡ææ°æ®ï¼å®é
APIè°ç¨å¤±è´¥') |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | const deviceId = route.query.deviceId || route.params.deviceId || '' |
| | | fetchDeviceInfo(deviceId) |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .device-info-container { |
| | | min-height: 100vh; |
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| | | padding: 20px; |
| | | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; |
| | | } |
| | | |
| | | .page-header { |
| | | background: rgba(255, 255, 255, 0.95); |
| | | border-radius: 16px; |
| | | padding: 20px; |
| | | margin-bottom: 20px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .page-header h1 { |
| | | margin: 0; |
| | | color: #2c3e50; |
| | | font-size: 24px; |
| | | } |
| | | |
| | | .device-status { |
| | | padding: 8px 16px; |
| | | border-radius: 20px; |
| | | font-size: 14px; |
| | | color: white; |
| | | background: #52c41a; |
| | | } |
| | | |
| | | .info-card { |
| | | background: rgba(255, 255, 255, 0.95); |
| | | border-radius: 16px; |
| | | margin-bottom: 20px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .card-header { |
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| | | color: white; |
| | | padding: 16px 20px; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .card-content { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .info-row, .maintenance-item { |
| | | display: flex; |
| | | margin-bottom: 12px; |
| | | align-items: center; |
| | | } |
| | | |
| | | .label { |
| | | width: 100px; |
| | | color: #666; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .value { |
| | | flex: 1; |
| | | color: #2c3e50; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .status-normal { |
| | | color: #52c41a; |
| | | } |
| | | |
| | | |
| | | |
| | | @media (max-width: 768px) { |
| | | .device-info-container { |
| | | padding: 16px; |
| | | } |
| | | |
| | | .page-header h1 { |
| | | font-size: 20px; |
| | | } |
| | | |
| | | .label { |
| | | width: 80px; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | const maintenanceRecords = ref([ |
| | | { |
| | | id: 1, |
| | | date: '2024-01-15', |
| | | date: '2025-01-15', |
| | | type: 'inspection', |
| | | title: '年度æ£éª', |
| | | description: 'æç
§TSG 21-2016æ åè¿è¡å¹´åº¦æ£éªï¼è®¾å¤ç¶æè¯å¥½', |
| | |
| | | }, |
| | | { |
| | | id: 2, |
| | | date: '2024-02-20', |
| | | date: '2025-02-20', |
| | | type: 'maintenance', |
| | | title: 'å®å
¨éç»´æ¤', |
| | | description: 'æ´æ¢å®å
¨éå¯å°åï¼æ ¡ååå设å®å¼', |
| | |
| | | }, |
| | | { |
| | | id: 3, |
| | | date: '2024-03-10', |
| | | date: '2025-03-10', |
| | | type: 'inspection', |
| | | title: 'ååæµè¯', |
| | | description: 'è¿è¡åå容卿°´åè¯éªï¼ç¬¦åè®¾è®¡è¦æ±', |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog :title="operationType === 'add' ? 'æ°å¢å·¡æ£ä»»å¡' : 'ç¼è¾å·¡æ£ä»»å¡'" |
| | | v-model="dialogVisitable" width="800px" @close="cancel"> |
| | | <el-form ref="formRef" :model="form" :rules="rules" label-width="120px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设å¤åç§°" prop="taskId"> |
| | | <el-select v-model="form.taskId" @change="setDeviceModel" filterable> |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | | :key="index" |
| | | :label="item.deviceName" |
| | | :value="item.id" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å·¡æ£äºº" prop="inspector"> |
| | | <el-select v-model="form.inspector" filterable |
| | | default-first-option |
| | | :reserve-keyword="false" placeholder="è¯·éæ©" multiple clearable> |
| | | <el-option v-for="item in userList" :label="item.nickName" :value="item.userId" :key="item.userId"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="夿³¨" prop="remarks"> |
| | | <el-input v-model="form.remarks" placeholder="请è¾å
¥å¤æ³¨" type="textarea" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»è®°æ¶é´" prop="dateStr"> |
| | | <el-date-picker |
| | | v-model="form.dateStr" |
| | | type="date" |
| | | placeholder="éæ©ç»è®°æ¥æ" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä»»å¡é¢ç" prop="frequencyType"> |
| | | <el-select v-model="form.frequencyType" placeholder="è¯·éæ©" clearable> |
| | | <el-option label="æ¯æ¥" value="DAILY"/> |
| | | <el-option label="æ¯å¨" value="WEEKLY"/> |
| | | <el-option label="æ¯æ" value="MONTHLY"/> |
| | | <!-- <el-option label="å£åº¦" value="QUARTERLY"/> --> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType"> |
| | | <el-form-item label="æ¥æ" prop="frequencyDetail"> |
| | | <el-time-picker v-model="form.frequencyDetail" placeholder="éæ©æ¶é´" format="HH:mm" |
| | | value-format="HH:mm" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType"> |
| | | <el-form-item label="æ¥æ" prop="frequencyDetail"> |
| | | <el-select v-model="form.week" placeholder="è¯·éæ©" clearable style="width: 50%"> |
| | | <el-option label="å¨ä¸" value="MON"/> |
| | | <el-option label="å¨äº" value="TUE"/> |
| | | <el-option label="å¨ä¸" value="WED"/> |
| | | <el-option label="å¨å" value="THU"/> |
| | | <el-option label="å¨äº" value="FRI"/> |
| | | <el-option label="å¨å
" value="SAT"/> |
| | | <el-option label="卿¥" value="SUN"/> |
| | | </el-select> |
| | | <el-time-picker v-model="form.time" placeholder="éæ©æ¶é´" format="HH:mm" |
| | | value-format="HH:mm" style="width: 50%"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType"> |
| | | <el-form-item label="æ¥æ" prop="frequencyDetail"> |
| | | <el-date-picker |
| | | v-model="form.frequencyDetail" |
| | | type="datetime" |
| | | clearable |
| | | placeholder="éæ©å¼å§æ¥æ" |
| | | format="DD,HH:mm" |
| | | value-format="DD,HH:mm" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType"> |
| | | <el-form-item label="æ¥æ" prop="frequencyDetail"> |
| | | <el-date-picker |
| | | v-model="form.frequencyDetail" |
| | | type="datetime" |
| | | clearable |
| | | placeholder="éæ©å¼å§æ¥æ" |
| | | format="MM,DD,HH:mm" |
| | | value-format="MM,DD,HH:mm" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="cancel">åæ¶</el-button> |
| | | <el-button type="primary" @click="submitForm">ä¿å</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {reactive, ref, getCurrentInstance, toRefs} from "vue"; |
| | | import useUserStore from '@/store/modules/user' |
| | | import {addOrEditTimingTask} from "@/api/inspectionManagement/index.js"; |
| | | import {userListNoPageByTenantId} from "@/api/system/user.js"; |
| | | import { getDeviceLedger } from "@/api/equipmentManagement/ledger"; |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits() |
| | | const userStore = useUserStore() |
| | | const dialogVisitable = ref(false); |
| | | const operationType = ref('add'); |
| | | const deviceOptions = ref([]); |
| | | const data = reactive({ |
| | | form: { |
| | | taskId: undefined, |
| | | taskName: undefined, |
| | | inspector: '', |
| | | inspectorIds: '', |
| | | remarks: '', |
| | | frequencyType: '', |
| | | frequencyDetail: '', |
| | | week: '', |
| | | time: '', |
| | | dateStr: '' |
| | | }, |
| | | rules: { |
| | | taskId: [{ required: true, message: "è¯·éæ©è®¾å¤", trigger: "change" },], |
| | | inspector: [{ required: true, message: "请è¾å
¥å·¡æ£äºº", trigger: "blur" },], |
| | | dateStr: [{ required: true, message: "è¯·éæ©ç»è®°æ¶é´", trigger: "change" }], |
| | | frequencyType: [{ required: true, message: "è¯·éæ©ä»»å¡é¢ç", trigger: "change" }], |
| | | frequencyDetail: [ |
| | | { |
| | | required: true, |
| | | message: "è¯·éæ©æ¥æ", |
| | | trigger: "change", |
| | | validator: (rule, value, callback) => { |
| | | if (!form.value.frequencyType) { |
| | | callback() |
| | | return |
| | | } |
| | | if (form.value.frequencyType === 'WEEKLY') { |
| | | if (!form.value.week || !form.value.time) { |
| | | callback(new Error("è¯·éæ©æ¥æåæ¶é´")) |
| | | } else { |
| | | callback() |
| | | } |
| | | } else { |
| | | if (!value) { |
| | | callback(new Error("è¯·éæ©æ¥æ")) |
| | | } else { |
| | | callback() |
| | | } |
| | | } |
| | | } |
| | | } |
| | | ], |
| | | week: [ |
| | | { |
| | | required: true, |
| | | message: "è¯·éæ©ææ", |
| | | trigger: "change", |
| | | validator: (rule, value, callback) => { |
| | | if (form.value.frequencyType === 'WEEKLY' && !value) { |
| | | callback(new Error("è¯·éæ©ææ")) |
| | | } else { |
| | | callback() |
| | | } |
| | | } |
| | | } |
| | | ], |
| | | time: [ |
| | | { |
| | | required: true, |
| | | message: "è¯·éæ©æ¶é´", |
| | | trigger: "change", |
| | | validator: (rule, value, callback) => { |
| | | if (form.value.frequencyType === 'WEEKLY' && !value) { |
| | | callback(new Error("è¯·éæ©æ¶é´")) |
| | | } else { |
| | | callback() |
| | | } |
| | | } |
| | | } |
| | | ] |
| | | } |
| | | }) |
| | | const { form, rules } = toRefs(data) |
| | | const userList = ref([]) |
| | | |
| | | const loadDeviceName = async () => { |
| | | const { data } = await getDeviceLedger(); |
| | | deviceOptions.value = data; |
| | | }; |
| | | |
| | | const setDeviceModel = (id) => { |
| | | const option = deviceOptions.value.find((item) => item.id === id); |
| | | if (option) { |
| | | form.value.taskName = option.deviceName; |
| | | } |
| | | } |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = async (type, row) => { |
| | | dialogVisitable.value = true |
| | | operationType.value = type |
| | | |
| | | // é置表å |
| | | resetForm(); |
| | | |
| | | // å è½½ç¨æ·å表 |
| | | userListNoPageByTenantId().then((res) => { |
| | | userList.value = res.data; |
| | | }); |
| | | |
| | | // å 载设å¤å表 |
| | | await loadDeviceName(); |
| | | |
| | | if (type === 'edit' && row) { |
| | | form.value = {...row} |
| | | form.value.inspector = form.value.inspectorIds.split(',').map(Number) |
| | | |
| | | // 妿æè®¾å¤IDï¼èªå¨è®¾ç½®è®¾å¤ä¿¡æ¯ |
| | | if (form.value.taskId) { |
| | | setDeviceModel(form.value.taskId); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // å
³éå¯¹è¯æ¡ |
| | | const cancel = () => { |
| | | resetForm() |
| | | dialogVisitable.value = false |
| | | emit('closeDia') |
| | | } |
| | | |
| | | // é置表å彿° |
| | | const resetForm = () => { |
| | | if (proxy.$refs.formRef) { |
| | | proxy.$refs.formRef.resetFields() |
| | | } |
| | | // éç½®è¡¨åæ°æ®ç¡®ä¿è®¾å¤ä¿¡æ¯æ£ç¡®éç½® |
| | | form.value = { |
| | | taskId: undefined, |
| | | taskName: undefined, |
| | | inspector: '', |
| | | inspectorIds: '', |
| | | remarks: '', |
| | | frequencyType: '', |
| | | frequencyDetail: '', |
| | | week: '', |
| | | time: '' |
| | | } |
| | | } |
| | | |
| | | // æäº¤è¡¨å |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate(async valid => { |
| | | if (valid) { |
| | | try { |
| | | form.value.inspectorIds = form.value.inspector.join(',') |
| | | delete form.value.inspector |
| | | |
| | | if (form.value.frequencyType === 'WEEKLY') { |
| | | let frequencyDetail = '' |
| | | frequencyDetail = form.value.week + ',' + form.value.time |
| | | form.value.frequencyDetail = frequencyDetail |
| | | } |
| | | |
| | | let res = await userStore.getInfo() |
| | | form.value.registrantId = res.user.userId |
| | | |
| | | await addOrEditTimingTask(form.value) |
| | | cancel() |
| | | proxy.$modal.msgSuccess('æäº¤æå') |
| | | } catch (error) { |
| | | proxy.$modal.msgError('æäº¤å¤±è´¥ï¼è¯·éè¯') |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | defineExpose({ openDialog }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog :title="operationType === 'add' ? 'æ°å¢äºç»´ç ' : 'ç¼è¾äºç»´ç '" |
| | | v-model="dialogVisitable" width="500px" @close="cancel"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="120px"> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="设å¤åç§°" prop="deviceName"> |
| | | <el-input v-model="form.deviceName" placeholder="请è¾å
¥è®¾å¤åç§°" maxlength="30" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="æå¨ä½ç½®æè¿°" prop="location"> |
| | | <el-input v-model="form.location" placeholder="请è¾å
¥æå¨ä½ç½®æè¿°" maxlength="30"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div> |
| | | <el-button type="primary" @click="submitForm">çæå¹¶æå°äºç»´ç </el-button> |
| | | </div> |
| | | <div v-if="isShowQrCode" class="print-section" ref="qrCodeContainer" id="qrCodeContainer"> |
| | | <vue-qrcode :value="qrCodeValue" :width="qrCodeSize"></vue-qrcode> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import {reactive, ref} from "vue"; |
| | | import printJS from 'print-js'; |
| | | import {addOrEditQrCode} from "@/api/inspectionUpload/index.js"; |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits() |
| | | const userStore = useUserStore() |
| | | const dialogVisitable = ref(false); |
| | | const isShowQrCode = ref(false); |
| | | const operationType = ref('add'); |
| | | |
| | | const qrCodeValue = ref(''); |
| | | const qrCodeSize = ref(100); |
| | | const data = reactive({ |
| | | form: { |
| | | deviceName: '', |
| | | location: '', |
| | | qrCodeId: '', |
| | | id: '' |
| | | }, |
| | | rules: { |
| | | deviceName: [{ required: true, message: '请è¾å
¥è®¾å¤åç§°', trigger: 'blur' }], |
| | | location: [{ required: true, message: '请è¾å
¥å°ç¹', trigger: 'blur' }] |
| | | } |
| | | }) |
| | | const { form, rules } = toRefs(data) |
| | | |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = async (type, row) => { |
| | | dialogVisitable.value = true |
| | | qrCodeValue.value = '' |
| | | isShowQrCode.value = false; |
| | | if (type === 'edit') { |
| | | form.value.id = row.id |
| | | form.value.qrCodeId = row.id |
| | | form.value.deviceName = row.deviceName |
| | | form.value.location = row.location |
| | | // å°è¡¨åæ°æ®è½¬ä¸º JSON å符串ä½ä¸ºäºç»´ç å
容 |
| | | qrCodeValue.value = JSON.stringify(form.value); |
| | | isShowQrCode.value = true; |
| | | } |
| | | } |
| | | // æäº¤å并表å |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | addOrEditQrCode(form.value).then((res) => { |
| | | form.value.qrCodeId = res.data |
| | | }) |
| | | // å°è¡¨åæ°æ®è½¬ä¸º JSON å符串ä½ä¸ºäºç»´ç å
容 |
| | | qrCodeValue.value = JSON.stringify(form.value); |
| | | isShowQrCode.value = true; |
| | | showQrCode() |
| | | } |
| | | }) |
| | | } |
| | | const showQrCode = () => { |
| | | // å»¶è¿æ§è¡æå°ï¼é¿å
DOM æ´æ°åå°±è°ç¨æå° |
| | | setTimeout(() => { |
| | | printJS({ |
| | | printable: 'qrCodeContainer',//é¡µé¢ |
| | | type: "html",//ææ¡£ç±»å |
| | | maxWidth: 360, |
| | | style: `@page { |
| | | margin:0; |
| | | size: 400px 75px collapse; |
| | | margin-top:3px; |
| | | &:first-of-type{ |
| | | margin-top:0 !important; |
| | | } |
| | | } |
| | | html{ |
| | | zoom:100%; |
| | | } |
| | | @media print{ |
| | | width: 400px; |
| | | height: 75px; |
| | | margin:0; |
| | | }`, |
| | | targetStyles: ["*"], // 使ç¨domçæææ ·å¼ï¼å¾éè¦ |
| | | font_size: '0.20cm', |
| | | }); |
| | | }, 300); |
| | | } |
| | | // å
³éå并表å |
| | | const cancel = () => { |
| | | proxy.resetForm("formRef") |
| | | dialogVisitable.value = false |
| | | emit('closeDia') |
| | | } |
| | | defineExpose({ openDialog }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .print-section { |
| | | text-align: center; |
| | | margin-top: 30px; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog title="æ¥çéä»¶" |
| | | v-model="dialogVisitable" width="800px" @close="cancel"> |
| | | <div class="upload-container"> |
| | | <!-- ç产å --> |
| | | <div class="form-container"> |
| | | <div class="title">ç产å</div> |
| | | |
| | | <!-- å¾çå表 --> |
| | | <div style="display: flex; flex-wrap: wrap;"> |
| | | <img v-for="(item, index) in beforeProductionImgs" :key="index" |
| | | @click="showMedia(beforeProductionImgs, index, 'image')" |
| | | :src="item" style="max-width: 100px; height: 100px; margin: 5px;" alt=""> |
| | | </div> |
| | | |
| | | <!-- è§é¢å表 --> |
| | | <div style="display: flex; flex-wrap: wrap;"> |
| | | <div |
| | | v-for="(videoUrl, index) in beforeProductionVideos" |
| | | :key="index" |
| | | @click="showMedia(beforeProductionVideos, index, 'video')" |
| | | style="position: relative; margin: 10px; cursor: pointer;" |
| | | > |
| | | <div style="width: 160px; height: 90px; background-color: #333; display: flex; align-items: center; justify-content: center;"> |
| | | <img src="@/assets/images/video.png" alt="ææ¾" style="width: 30px; height: 30px; opacity: 0.8;" /> |
| | | </div> |
| | | <div style="text-align: center; font-size: 12px; color: #666;">ç¹å»ææ¾</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- ç产å --> |
| | | <div class="form-container"> |
| | | <div class="title">ç产ä¸</div> |
| | | |
| | | <!-- å¾çå表 --> |
| | | <div style="display: flex; flex-wrap: wrap;"> |
| | | <img v-for="(item, index) in afterProductionImgs" :key="index" |
| | | @click="showMedia(afterProductionImgs, index, 'image')" |
| | | :src="item" style="max-width: 100px; height: 100px; margin: 5px;" alt=""> |
| | | </div> |
| | | |
| | | <!-- è§é¢å表 --> |
| | | <div style="display: flex; flex-wrap: wrap;"> |
| | | <div |
| | | v-for="(videoUrl, index) in afterProductionVideos" |
| | | :key="index" |
| | | @click="showMedia(afterProductionVideos, index, 'video')" |
| | | style="position: relative; margin: 10px; cursor: pointer;" |
| | | > |
| | | <div style="width: 160px; height: 90px; background-color: #333; display: flex; align-items: center; justify-content: center;"> |
| | | <img src="@/assets/images/video.png" alt="ææ¾" style="width: 30px; height: 30px; opacity: 0.8;" /> |
| | | </div> |
| | | <div style="text-align: center; font-size: 12px; color: #666;">ç¹å»ææ¾</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- ç产é®é¢ --> |
| | | <div class="form-container"> |
| | | <div class="title">ç产å</div> |
| | | |
| | | <!-- å¾çå表 --> |
| | | <div style="display: flex; flex-wrap: wrap;"> |
| | | <img v-for="(item, index) in productionIssuesImgs" :key="index" |
| | | @click="showMedia(productionIssuesImgs, index, 'image')" |
| | | :src="item" style="max-width: 100px; height: 100px; margin: 5px;" alt=""> |
| | | </div> |
| | | |
| | | <!-- è§é¢å表 --> |
| | | <div style="display: flex; flex-wrap: wrap;"> |
| | | <div |
| | | v-for="(videoUrl, index) in productionIssuesVideos" |
| | | :key="index" |
| | | @click="showMedia(productionIssuesVideos, index, 'video')" |
| | | style="position: relative; margin: 10px; cursor: pointer;" |
| | | > |
| | | <div style="width: 160px; height: 90px; background-color: #333; display: flex; align-items: center; justify-content: center;"> |
| | | <img src="@/assets/images/video.png" alt="ææ¾" style="width: 30px; height: 30px; opacity: 0.8;" /> |
| | | </div> |
| | | <div style="text-align: center; font-size: 12px; color: #666;">ç¹å»ææ¾</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-dialog> |
| | | |
| | | <!-- ç»ä¸åªä½æ¥çå¨ --> |
| | | <div v-if="isMediaViewerVisible" class="media-viewer-overlay" @click.self="closeMediaViewer"> |
| | | <div class="media-viewer-content" @click.stop> |
| | | <!-- å¾ç --> |
| | | <vue-easy-lightbox |
| | | v-if="mediaType === 'image'" |
| | | :visible="isMediaViewerVisible" |
| | | :imgs="mediaList" |
| | | :index="currentMediaIndex" |
| | | @hide="closeMediaViewer" |
| | | ></vue-easy-lightbox> |
| | | |
| | | <!-- è§é¢ --> |
| | | <div v-else-if="mediaType === 'video'" style="position: relative;"> |
| | | <Video |
| | | :src="mediaList[currentMediaIndex]" |
| | | autoplay |
| | | controls |
| | | style="max-width: 90vw; max-height: 80vh;" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <script setup> |
| | | import { ref } from 'vue'; |
| | | import VueEasyLightbox from 'vue-easy-lightbox'; |
| | | |
| | | // æ§å¶å¼¹çªæ¾ç¤º |
| | | const dialogVisitable = ref(false); |
| | | |
| | | // å¾çæ°ç» |
| | | const beforeProductionImgs = ref([]); |
| | | const afterProductionImgs = ref([]); |
| | | const productionIssuesImgs = ref([]); |
| | | |
| | | // è§é¢æ°ç» |
| | | const beforeProductionVideos = ref([]); |
| | | const afterProductionVideos = ref([]); |
| | | const productionIssuesVideos = ref([]); |
| | | |
| | | // åªä½æ¥çå¨ç¶æ |
| | | const isMediaViewerVisible = ref(false); |
| | | const currentMediaIndex = ref(0); |
| | | const mediaList = ref([]); // åå¨å½åè¦æ¥ççåªä½å表ï¼å«å¾çåè§é¢å¯¹è±¡ï¼ |
| | | const mediaType = ref('image'); // image | video |
| | | |
| | | // å¤çæ¯ä¸ç±»æ°æ®ï¼å离å¾çåè§é¢ |
| | | function processItems(items) { |
| | | const images = []; |
| | | const videos = []; |
| | | items.forEach(item => { |
| | | if (item.contentType?.startsWith('image/')) { |
| | | images.push(item.url); |
| | | } else if (item.contentType?.startsWith('video/')) { |
| | | videos.push(item.url); |
| | | } |
| | | }); |
| | | return { images, videos }; |
| | | } |
| | | |
| | | // æå¼å¼¹çªå¹¶å è½½æ°æ® |
| | | const openDialog = async (row) => { |
| | | const { images: beforeImgs, videos: beforeVids } = processItems(row.beforeProduction); |
| | | const { images: afterImgs, videos: afterVids } = processItems(row.afterProduction); |
| | | const { images: issueImgs, videos: issueVids } = processItems(row.productionIssues); |
| | | |
| | | beforeProductionImgs.value = beforeImgs; |
| | | beforeProductionVideos.value = beforeVids; |
| | | |
| | | afterProductionImgs.value = afterImgs; |
| | | afterProductionVideos.value = afterVids; |
| | | |
| | | productionIssuesImgs.value = issueImgs; |
| | | productionIssuesVideos.value = issueVids; |
| | | |
| | | dialogVisitable.value = true; |
| | | }; |
| | | |
| | | // æ¾ç¤ºåªä½ï¼å¾ç or è§é¢ï¼ |
| | | function showMedia(mediaArray, index, type) { |
| | | mediaList.value = mediaArray; |
| | | currentMediaIndex.value = index; |
| | | mediaType.value = type; |
| | | isMediaViewerVisible.value = true; |
| | | } |
| | | |
| | | // å
³éåªä½æ¥çå¨ |
| | | function closeMediaViewer() { |
| | | isMediaViewerVisible.value = false; |
| | | mediaList.value = []; |
| | | mediaType.value = 'image'; |
| | | } |
| | | |
| | | // 表åå
³éæ¹æ³ |
| | | const cancel = () => { |
| | | dialogVisitable.value = false; |
| | | }; |
| | | |
| | | defineExpose({ openDialog }); |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | .upload-container { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | padding: 20px; |
| | | border: 1px solid #dcdfe6; |
| | | box-sizing: border-box; |
| | | |
| | | .form-container { |
| | | flex: 1; |
| | | width: 100%; |
| | | margin-bottom: 20px; |
| | | } |
| | | } |
| | | |
| | | .title { |
| | | font-size: 14px; |
| | | color: #165dff; |
| | | line-height: 20px; |
| | | font-weight: 600; |
| | | padding-left: 10px; |
| | | position: relative; |
| | | margin: 6px 0; |
| | | |
| | | &::before { |
| | | content: ""; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 3px; |
| | | width: 4px; |
| | | height: 14px; |
| | | background-color: #165dff; |
| | | } |
| | | } |
| | | |
| | | .media-viewer-overlay { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background-color: rgba(0, 0, 0, 0.8); |
| | | z-index: 9999; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .media-viewer-content { |
| | | position: relative; |
| | | max-width: 90vw; |
| | | max-height: 90vh; |
| | | overflow: hidden; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog title="æ¥çéä»¶" |
| | | v-model="dialogVisitable" width="800px" @close="cancel"> |
| | | <div class="upload-container"> |
| | | <div class="form-container"> |
| | | <div class="title">å·¡æ£éä»¶</div> |
| | | <!-- å¾çå表 --> |
| | | <div style="display: flex; flex-wrap: wrap;"> |
| | | <img v-for="(item, index) in beforeProductionImgs" :key="index" |
| | | @click="showMedia(beforeProductionImgs, index, 'image')" |
| | | :src="item" style="max-width: 100px; height: 100px; margin: 5px;" alt=""> |
| | | </div> |
| | | |
| | | <!-- è§é¢å表 --> |
| | | <div style="display: flex; flex-wrap: wrap;"> |
| | | <div |
| | | v-for="(videoUrl, index) in beforeProductionVideos" |
| | | :key="index" |
| | | @click="showMedia(beforeProductionVideos, index, 'video')" |
| | | style="position: relative; margin: 10px; cursor: pointer;" |
| | | > |
| | | <div style="width: 160px; height: 90px; background-color: #333; display: flex; align-items: center; justify-content: center;"> |
| | | <img src="@/assets/images/video.png" alt="ææ¾" style="width: 30px; height: 30px; opacity: 0.8;" /> |
| | | </div> |
| | | <div style="text-align: center; font-size: 12px; color: #666;">ç¹å»ææ¾</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-dialog> |
| | | <!-- ç»ä¸åªä½æ¥çå¨ --> |
| | | <div v-if="isMediaViewerVisible" class="media-viewer-overlay" @click.self="closeMediaViewer"> |
| | | <div class="media-viewer-content" @click.stop> |
| | | <!-- å¾ç --> |
| | | <vue-easy-lightbox |
| | | v-if="mediaType === 'image'" |
| | | :visible="isMediaViewerVisible" |
| | | :imgs="mediaList" |
| | | :index="currentMediaIndex" |
| | | @hide="closeMediaViewer" |
| | | ></vue-easy-lightbox> |
| | | |
| | | <!-- è§é¢ --> |
| | | <div v-else-if="mediaType === 'video'" style="position: relative;"> |
| | | <Video |
| | | :src="mediaList[currentMediaIndex]" |
| | | autoplay |
| | | controls |
| | | style="max-width: 90vw; max-height: 80vh;" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | // æ§å¶å¼¹çªæ¾ç¤º |
| | | import VueEasyLightbox from "vue-easy-lightbox"; |
| | | |
| | | const dialogVisitable = ref(false); |
| | | // å¾çæ°ç» |
| | | const beforeProductionImgs = ref([]); |
| | | // è§é¢æ°ç» |
| | | const beforeProductionVideos = ref([]); |
| | | // åªä½æ¥çå¨ç¶æ |
| | | const isMediaViewerVisible = ref(false); |
| | | const currentMediaIndex = ref(0); |
| | | const mediaList = ref([]); // åå¨å½åè¦æ¥ççåªä½å表ï¼å«å¾çåè§é¢å¯¹è±¡ï¼ |
| | | const mediaType = ref('image'); // image | video |
| | | |
| | | // æå¼å¼¹çªå¹¶å è½½æ°æ® |
| | | const openDialog = async (row) => { |
| | | const { images: beforeImgs, videos: beforeVids } = processItems(row.storageBlobDTO); |
| | | |
| | | beforeProductionImgs.value = beforeImgs; |
| | | beforeProductionVideos.value = beforeVids; |
| | | dialogVisitable.value = true; |
| | | }; |
| | | // æ¾ç¤ºåªä½ï¼å¾ç or è§é¢ï¼ |
| | | function showMedia(mediaArray, index, type) { |
| | | mediaList.value = mediaArray; |
| | | currentMediaIndex.value = index; |
| | | mediaType.value = type; |
| | | isMediaViewerVisible.value = true; |
| | | } |
| | | // å
³éåªä½æ¥çå¨ |
| | | function closeMediaViewer() { |
| | | isMediaViewerVisible.value = false; |
| | | mediaList.value = []; |
| | | mediaType.value = 'image'; |
| | | } |
| | | // 表åå
³éæ¹æ³ |
| | | const cancel = () => { |
| | | dialogVisitable.value = false; |
| | | }; |
| | | // å¤çæ¯ä¸ç±»æ°æ®ï¼å离å¾çåè§é¢ |
| | | function processItems(items) { |
| | | const images = []; |
| | | const videos = []; |
| | | items.forEach(item => { |
| | | if (item.contentType?.startsWith('image/')) { |
| | | images.push(item.url); |
| | | } else if (item.contentType?.startsWith('video/')) { |
| | | videos.push(item.url); |
| | | } |
| | | }); |
| | | return { images, videos }; |
| | | } |
| | | defineExpose({ openDialog }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .upload-container { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | padding: 20px; |
| | | border: 1px solid #dcdfe6; |
| | | box-sizing: border-box; |
| | | |
| | | .form-container { |
| | | flex: 1; |
| | | width: 100%; |
| | | margin-bottom: 20px; |
| | | } |
| | | } |
| | | |
| | | .title { |
| | | font-size: 14px; |
| | | color: #165dff; |
| | | line-height: 20px; |
| | | font-weight: 600; |
| | | padding-left: 10px; |
| | | position: relative; |
| | | margin: 6px 0; |
| | | |
| | | &::before { |
| | | content: ""; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 3px; |
| | | width: 4px; |
| | | height: 14px; |
| | | background-color: #165dff; |
| | | } |
| | | } |
| | | |
| | | .media-viewer-overlay { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background-color: rgba(0, 0, 0, 0.8); |
| | | z-index: 9999; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .media-viewer-content { |
| | | position: relative; |
| | | max-width: 90vw; |
| | | max-height: 90vh; |
| | | overflow: hidden; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :inline="true" :model="queryParams" class="search-form"> |
| | | <el-form-item label="å·¡æ£ä»»å¡åç§°"> |
| | | <el-input |
| | | v-model="queryParams.taskName" |
| | | placeholder="请è¾å
¥å·¡æ£ä»»å¡åç§°" |
| | | clearable |
| | | :style="{ width: '100%' }" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="handleQuery">æ¥è¯¢</el-button> |
| | | <el-button @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-card> |
| | | <div style="display: flex;flex-direction: row;justify-content: space-between;margin-bottom: 10px;"> |
| | | <el-radio-group v-model="activeRadio" @change="radioChange"> |
| | | <el-radio-button v-for="tab in radios" |
| | | :key="tab.name" |
| | | :label="tab.label" |
| | | :value="tab.name"/> |
| | | </el-radio-group> |
| | | <!-- æä½æé®åº --> |
| | | <el-space v-if="activeRadio !== 'task'"> |
| | | <el-button type="primary" :icon="Plus" @click="handleAdd(undefined)">æ°å»º</el-button> |
| | | <el-button type="danger" :icon="Delete" @click="handleDelete">å é¤</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | </el-space> |
| | | <el-space v-else> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | </el-space> |
| | | </div> |
| | | <div> |
| | | <div> |
| | | <PIMTable :table-loading="tableLoading" |
| | | :table-data="tableData" |
| | | :column="tableColumns" |
| | | @selection-change="handleSelectionChange" |
| | | :is-selection="true" |
| | | :border="true" |
| | | :table-style="{ width: '100%', height: 'calc(100vh - 23em)' }" |
| | | :page="{ |
| | | current: pageNum, |
| | | size: pageSize, |
| | | total: total, |
| | | }" |
| | | @pagination="pagination" |
| | | > |
| | | <template #inspector="{ row }"> |
| | | <div class="person-tags"> |
| | | <!-- è°è¯ä¿¡æ¯ï¼ä¸çº¿æ¶å é¤ --> |
| | | <!-- {{ console.log('inspector data:', row.inspector) }} --> |
| | | <template v-if="row.inspector && row.inspector.length > 0"> |
| | | <el-tag |
| | | v-for="(person, index) in row.inspector" |
| | | :key="index" |
| | | size="small" |
| | | type="primary" |
| | | class="person-tag" |
| | | > |
| | | {{ person }} |
| | | </el-tag> |
| | | </template> |
| | | <span v-else class="no-data">--</span> |
| | | </div> |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | <form-dia ref="formDia" @closeDia="handleQuery"></form-dia> |
| | | <view-files ref="viewFiles"></view-files> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { Delete, Plus } from "@element-plus/icons-vue"; |
| | | import { onMounted, ref, reactive, getCurrentInstance, nextTick } from "vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | |
| | | // ç»ä»¶å¼å
¥ |
| | | import Pagination from "@/components/Pagination/index.vue"; |
| | | import PIMTable from "@/components/PIMTable/PIMTable.vue"; |
| | | import FormDia from "@/views/equipmentManagement/inspectionManagement/components/formDia.vue"; |
| | | import ViewFiles from "@/views/equipmentManagement/inspectionManagement/components/viewFiles.vue"; |
| | | |
| | | // æ¥å£å¼å
¥ |
| | | import { |
| | | delTimingTask, |
| | | inspectionTaskList, |
| | | timingTaskList |
| | | } from "@/api/inspectionManagement/index.js"; |
| | | |
| | | // å
¨å±åé |
| | | const { proxy } = getCurrentInstance(); |
| | | const formDia = ref(); |
| | | const viewFiles = ref(); |
| | | |
| | | // æ¥è¯¢åæ° |
| | | const queryParams = reactive({ |
| | | taskName: "", |
| | | }); |
| | | |
| | | // åéæ¡é
ç½® |
| | | const activeRadio = ref("taskManage"); |
| | | const radios = reactive([ |
| | | { name: "taskManage", label: "宿¶ä»»å¡ç®¡ç" }, |
| | | { name: "task", label: "宿¶ä»»å¡è®°å½" }, |
| | | ]); |
| | | |
| | | // è¡¨æ ¼æ°æ® |
| | | const selectedRows = ref([]); |
| | | const tableData = ref([]); |
| | | const operationsArr = ref([]); |
| | | const tableColumns = ref([]); |
| | | const tableLoading = ref(false); |
| | | const total = ref(0); |
| | | const pageNum = ref(1); |
| | | const pageSize = ref(10); |
| | | |
| | | // åé
ç½® |
| | | const columns = ref([ |
| | | { prop: "taskName", label: "å·¡æ£ä»»å¡åç§°", minWidth: 160 }, |
| | | { prop: "remarks", label: "夿³¨", minWidth: 150 }, |
| | | { prop: "inspector", label: "æ§è¡å·¡æ£äºº", minWidth: 150, slot: "inspector" }, |
| | | { |
| | | prop: "frequencyType", |
| | | label: "颿¬¡", |
| | | minWidth: 150, |
| | | formatData: (cell) => ({ |
| | | DAILY: "æ¯æ¥", |
| | | WEEKLY: "æ¯å¨", |
| | | MONTHLY: "æ¯æ", |
| | | QUARTERLY: "å£åº¦" |
| | | }[cell] || "") |
| | | }, |
| | | { |
| | | prop: "frequencyDetail", |
| | | label: "å¼å§æ¥æä¸æ¶é´", |
| | | minWidth: 150, |
| | | formatter: (row, column, cellValue) => { |
| | | // å
夿æ¯å¦æ¯å符串 |
| | | if (typeof cellValue !== 'string') return ''; |
| | | let val = cellValue; |
| | | const replacements = { |
| | | MON: 'å¨ä¸', |
| | | TUE: 'å¨äº', |
| | | WED: 'å¨ä¸', |
| | | THU: 'å¨å', |
| | | FRI: 'å¨äº', |
| | | SAT: 'å¨å
', |
| | | SUN: '卿¥' |
| | | }; |
| | | // ä½¿ç¨æ£å䏿¬¡æ§æ¿æ¢ææå¹é
项 |
| | | return val.replace(/MON|TUE|WED|THU|FRI|SAT|SUN/g, match => replacements[match]); |
| | | } |
| | | }, |
| | | { prop: "registrant", label: "ç»è®°äºº", minWidth: 100 }, |
| | | { prop: "dateStr", label: "ç»è®°æ¥æ", minWidth: 100 }, |
| | | ]); |
| | | |
| | | // æä½åé
ç½® |
| | | const getOperationColumn = (operations) => { |
| | | if (!operations || operations.length === 0) return null; |
| | | |
| | | const operationConfig = { |
| | | label: "æä½", |
| | | width: 130, |
| | | fixed: "right", |
| | | dataType: "action", |
| | | operation: operations.map(op => { |
| | | switch (op) { |
| | | case 'edit': |
| | | return { |
| | | name: "ç¼è¾", |
| | | clickFun: handleAdd, |
| | | color: "#409EFF" |
| | | }; |
| | | case 'viewFile': |
| | | return { |
| | | name: "æ¥çéä»¶", |
| | | clickFun: viewFile, |
| | | color: "#67C23A" |
| | | }; |
| | | default: |
| | | return null; |
| | | } |
| | | }).filter(Boolean) |
| | | }; |
| | | |
| | | return operationConfig; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | radioChange('taskManage'); |
| | | }); |
| | | |
| | | // åéåå |
| | | const radioChange = (value) => { |
| | | if (value === "taskManage") { |
| | | const operationColumn = getOperationColumn(['edit']); |
| | | tableColumns.value = [...columns.value, ...(operationColumn ? [operationColumn] : [])]; |
| | | operationsArr.value = ['edit']; |
| | | } else if (value === "task") { |
| | | const operationColumn = getOperationColumn(['viewFile']); |
| | | tableColumns.value = [...columns.value, ...(operationColumn ? [operationColumn] : [])]; |
| | | operationsArr.value = ['viewFile']; |
| | | } |
| | | pageNum.value = 1; |
| | | pageSize.value = 10; |
| | | getList(); |
| | | }; |
| | | |
| | | // æ¥è¯¢æä½ |
| | | const handleQuery = () => { |
| | | pageNum.value = 1; |
| | | pageSize.value = 10; |
| | | getList(); |
| | | }; |
| | | const pagination = (obj) => { |
| | | pageNum.value = obj.page; |
| | | pageSize.value = obj.limit; |
| | | getList(); |
| | | }; |
| | | // è·ååè¡¨æ°æ® |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | |
| | | const params = { ...queryParams, size: pageSize.value, current: pageNum.value }; |
| | | |
| | | let apiCall; |
| | | if (activeRadio.value === "task") { |
| | | apiCall = inspectionTaskList(params); |
| | | } else { |
| | | apiCall = timingTaskList(params); |
| | | } |
| | | |
| | | apiCall.then(res => { |
| | | const rawData = res.data.records || []; |
| | | // å¤ç inspector åæ®µï¼å°å符串转æ¢ä¸ºæ°ç»ï¼éç¨äºæææ
åµï¼ |
| | | tableData.value = rawData.map(item => { |
| | | const processedItem = { ...item }; |
| | | |
| | | // å¤ç inspector åæ®µ |
| | | if (processedItem.inspector) { |
| | | if (typeof processedItem.inspector === 'string') { |
| | | // å符串æéå·åå² |
| | | processedItem.inspector = processedItem.inspector.split(',').map(s => s.trim()).filter(s => s); |
| | | } else if (!Array.isArray(processedItem.inspector)) { |
| | | // éæ°ç»è½¬ä¸ºæ°ç» |
| | | processedItem.inspector = [processedItem.inspector]; |
| | | } |
| | | } else { |
| | | // 空å¼è®¾ä¸ºç©ºæ°ç» |
| | | processedItem.inspector = []; |
| | | } |
| | | |
| | | return processedItem; |
| | | }); |
| | | total.value = res.data.total || 0; |
| | | }).finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // éç½®æ¥è¯¢ |
| | | const resetQuery = () => { |
| | | for (const key in queryParams) { |
| | | if (!["pageNum", "pageSize"].includes(key)) { |
| | | queryParams[key] = ""; |
| | | } |
| | | } |
| | | handleQuery(); |
| | | }; |
| | | |
| | | // æ°å¢ / ç¼è¾ |
| | | const handleAdd = (row) => { |
| | | const type = row ? 'edit' : 'add'; |
| | | nextTick(() => { |
| | | formDia.value?.openDialog(type, row); |
| | | }); |
| | | }; |
| | | |
| | | // æ¥çéä»¶ |
| | | const viewFile = (row) => { |
| | | nextTick(() => { |
| | | viewFiles.value?.openDialog(row); |
| | | }); |
| | | }; |
| | | |
| | | // å é¤æä½ |
| | | const handleDelete = () => { |
| | | if (!selectedRows.value.length) { |
| | | proxy.$modal.msgWarning("è¯·éæ©è¦å é¤çæ°æ®"); |
| | | return; |
| | | } |
| | | |
| | | const deleteIds = selectedRows.value.map(item => item.id); |
| | | |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å 餿鿰æ®é¡¹ï¼').then(() => { |
| | | return delTimingTask(deleteIds); |
| | | }).then(() => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | handleQuery(); |
| | | }).catch(() => {}); |
| | | }; |
| | | |
| | | // å¤éåæ´ |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | // æ ¹æ®å½åéä¸çæ ç¾é¡µè°ç¨ä¸åçå¯¼åºæ¥å£ |
| | | if (activeRadio.value === "taskManage") { |
| | | // 宿¶ä»»å¡ç®¡ç |
| | | proxy.download("/timingTask/export", {}, "宿¶ä»»å¡ç®¡ç.xlsx"); |
| | | } else if (activeRadio.value === "task") { |
| | | // 宿¶ä»»å¡è®°å½ |
| | | proxy.download("/inspectionTask/export", {}, "宿¶ä»»å¡è®°å½.xlsx"); |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .person-tags { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 4px; |
| | | } |
| | | |
| | | .person-tag { |
| | | margin-right: 4px; |
| | | margin-bottom: 2px; |
| | | } |
| | | |
| | | .no-data { |
| | | color: #909399; |
| | | font-size: 14px; |
| | | } |
| | | </style> |
| | |
| | | const devices = reactive([ |
| | | { |
| | | id: 'water-pump', |
| | | name: '注水泵1', |
| | | name: '设å¤1', |
| | | type: 'ç§»å¨è£
å¤', |
| | | baseline: { vibration: 9 }, |
| | | initial: { temperature: 40, pressure: 0.70 }, |
| | |
| | | }, |
| | | { |
| | | id: 'fluid-supply-truck', |
| | | name: '注水泵2', |
| | | name: '设å¤2', |
| | | type: 'ç§»å¨è£
å¤', |
| | | baseline: { vibration: 7 }, |
| | | initial: { temperature: 30, pressure: 0.60 }, |
| | |
| | | }, |
| | | { |
| | | id: 'fracturing-truck', |
| | | name: '注水泵3', |
| | | name: '设å¤3', |
| | | type: 'ç§»å¨è£
å¤', |
| | | baseline: { vibration: 12 }, |
| | | initial: { temperature: 65, pressure: 1.40 }, |
| | |
| | | }, |
| | | { |
| | | id: 'oil-tank-truck', |
| | | name: '注水泵4', |
| | | name: '设å¤4', |
| | | type: 'ç§»å¨è£
å¤', |
| | | baseline: { vibration: 6 }, |
| | | initial: { temperature: 28, pressure: 0.50 }, |
| | |
| | | const devices = reactive([ |
| | | { |
| | | id: 'hydrocyclone-desander', |
| | | name: 'ææµé¤ç å¨', |
| | | name: '设å¤1', |
| | | type: 'å离设å¤', |
| | | baseline: { vibration: 8 }, |
| | | initial: { temperature: 35, pressure: 0.85 }, |
| | |
| | | }, |
| | | { |
| | | id: 'high-pressure-separator', |
| | | name: 'é«ååç¦»å¨æ¬', |
| | | name: '设å¤2', |
| | | type: 'å离设å¤', |
| | | baseline: { vibration: 6 }, |
| | | initial: { temperature: 45, pressure: 1.20 }, |
| | |
| | | }, |
| | | { |
| | | id: 'heating-throttle-pressure', |
| | | name: 'ç»åå¼å çèæµè°å', |
| | | name: '设å¤3', |
| | | type: 'è°å设å¤', |
| | | baseline: { vibration: 10 }, |
| | | initial: { temperature: 75, pressure: 1.80 }, |
| | |
| | | }, |
| | | { |
| | | id: 'three-phase-separator', |
| | | name: 'ä¸ç¸å离å¨', |
| | | name: '设å¤4', |
| | | type: 'å离设å¤', |
| | | baseline: { vibration: 7 }, |
| | | initial: { temperature: 38, pressure: 0.95 }, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="kpl-monitor-container"> |
| | | <!-- 页é¢å¤´é¨ --> |
| | | <div class="page-header"> |
| | | <div class="header-content"> |
| | | <h1>KPLçæ§åæ</h1> |
| | | <p>设å¤å
³é®æ§è½ææ çæ§ä¸ç»´ä¿çç¥ä¼å</p> |
| | | </div> |
| | | <div class="time-range"> |
| | | <el-date-picker |
| | | v-model="timeRange" |
| | | type="daterange" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | | @change="fetchKPLData" |
| | | /> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- å
³é®ææ æ¦è§ --> |
| | | <div class="metrics-overview"> |
| | | <div class="metric-card mtbf-card"> |
| | | <div class="metric-icon">â±ï¸</div> |
| | | <div class="metric-content"> |
| | | <div class="metric-title">MTBF</div> |
| | | <div class="metric-subtitle">å¹³åæ æ
éæ¶é´</div> |
| | | <div class="metric-value">{{ currentMTBF }}<span class="unit">å°æ¶</span></div> |
| | | <div class="metric-trend" :class="mtbfTrendClass"> |
| | | <span class="trend-icon">{{ mtbfTrendText }}</span> |
| | | <span class="trend-text">{{ Math.abs(mtbfChange) }}%</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="metric-card mttr-card"> |
| | | <div class="metric-icon">ð§</div> |
| | | <div class="metric-content"> |
| | | <div class="metric-title">MTTR</div> |
| | | <div class="metric-subtitle">å¹³åä¿®å¤æ¶é´</div> |
| | | <div class="metric-value">{{ currentMTTR }}<span class="unit">å°æ¶</span></div> |
| | | <div class="metric-trend" :class="mttrTrendClass"> |
| | | <span class="trend-icon">{{ mttrTrendText }}</span> |
| | | <span class="trend-text">{{ Math.abs(mttrChange) }}%</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="metric-card availability-card"> |
| | | <div class="metric-icon">ð</div> |
| | | <div class="metric-content"> |
| | | <div class="metric-title">设å¤å¯ç¨ç</div> |
| | | <div class="metric-subtitle">è¿è¡æçææ </div> |
| | | <div class="metric-value">{{ currentAvailability }}<span class="unit">%</span></div> |
| | | <div class="metric-trend" :class="availabilityTrendClass"> |
| | | <span class="trend-icon">{{ availabilityTrendText }}</span> |
| | | <span class="trend-text">{{ Math.abs(availabilityChange) }}%</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- è¶å¿åæå¾è¡¨ --> |
| | | <div class="charts-section"> |
| | | <div class="chart-container"> |
| | | <div class="chart-header"> |
| | | <h3>MTBF & MTTR è¶å¿åæ</h3> |
| | | <div class="chart-legend"> |
| | | <span class="legend-item mtbf-legend"> |
| | | <span class="legend-color"></span> |
| | | MTBF (å¹³åæ æ
éæ¶é´) |
| | | </span> |
| | | <span class="legend-item mttr-legend"> |
| | | <span class="legend-color"></span> |
| | | MTTR (å¹³åä¿®å¤æ¶é´) |
| | | </span> |
| | | </div> |
| | | </div> |
| | | <div class="chart-wrapper"> |
| | | <div ref="trendChart" class="chart"></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- ç»´ä¿çç¥å»ºè®® --> |
| | | <div class="recommendations-section"> |
| | | <div class="section-header"> |
| | | <h3>ç»´ä¿çç¥ä¼å建议</h3> |
| | | <p>åºäºå½åææ åæï¼ä¸ºæ¨æä¾é对æ§çä¼å建议</p> |
| | | </div> |
| | | <div class="recommendations-grid"> |
| | | <div |
| | | v-for="(recommendation, index) in recommendations" |
| | | :key="index" |
| | | class="recommendation-card" |
| | | > |
| | | <div class="recommendation-icon">{{ recommendation.icon }}</div> |
| | | <div class="recommendation-content"> |
| | | <h4>{{ recommendation.title }}</h4> |
| | | <p>{{ recommendation.description }}</p> |
| | | <div class="recommendation-priority" :class="recommendation.priority"> |
| | | {{ recommendation.priorityText }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, computed, nextTick } from 'vue' |
| | | import * as echarts from 'echarts' |
| | | |
| | | // çææ¨¡ææ°æ® |
| | | const generateMockData = () => { |
| | | const months = ['1æ', '2æ', '3æ', '4æ', '5æ', '6æ', '7æ', '8æ', '9æ', '10æ', '11æ', '12æ'] |
| | | const mtbfData = months.map(() => Math.floor(Math.random() * 200 + 300)) // 300-500å°æ¶ |
| | | const mttrData = months.map(() => Math.floor(Math.random() * 8 + 4)) // 4-12å°æ¶ |
| | | |
| | | return { |
| | | months, |
| | | mtbfData, |
| | | mttrData |
| | | } |
| | | } |
| | | |
| | | const timeRange = ref([ |
| | | new Date(new Date().getFullYear(), 0, 1).toISOString().split('T')[0], |
| | | new Date().toISOString().split('T')[0] |
| | | ]) |
| | | |
| | | const mockData = reactive(generateMockData()) |
| | | |
| | | // 计ç®å½åææ å¼ |
| | | const currentMTBF = computed(() => mockData.mtbfData[mockData.mtbfData.length - 1]) |
| | | const currentMTTR = computed(() => mockData.mttrData[mockData.mttrData.length - 1]) |
| | | const currentAvailability = computed(() => |
| | | Math.round((currentMTBF.value / (currentMTBF.value + currentMTTR.value)) * 100) |
| | | ) |
| | | |
| | | // 计ç®ååè¶å¿ |
| | | const mtbfChange = computed(() => { |
| | | const current = currentMTBF.value |
| | | const previous = mockData.mtbfData[mockData.mtbfData.length - 2] || current |
| | | return Math.round(((current - previous) / previous) * 100) |
| | | }) |
| | | |
| | | const mttrChange = computed(() => { |
| | | const current = currentMTTR.value |
| | | const previous = mockData.mttrData[mockData.mttrData.length - 2] || current |
| | | return Math.round(((current - previous) / previous) * 100) |
| | | }) |
| | | |
| | | const availabilityChange = computed(() => { |
| | | const current = currentAvailability.value |
| | | const previous = Math.round( |
| | | (mockData.mtbfData[mockData.mtbfData.length - 2] / |
| | | (mockData.mtbfData[mockData.mtbfData.length - 2] + mockData.mttrData[mockData.mttrData.length - 2])) * 100 |
| | | ) || current |
| | | return Math.round(((current - previous) / previous) * 100) |
| | | }) |
| | | |
| | | // è¶å¿æ ·å¼åææ¬ |
| | | const mtbfTrendClass = computed(() => mtbfChange.value >= 0 ? 'trend-up' : 'trend-down') |
| | | const mttrTrendClass = computed(() => mttrChange.value <= 0 ? 'trend-up' : 'trend-down') |
| | | const availabilityTrendClass = computed(() => availabilityChange.value >= 0 ? 'trend-up' : 'trend-down') |
| | | |
| | | const mtbfTrendText = computed(() => mtbfChange.value >= 0 ? 'â' : 'â') |
| | | const mttrTrendText = computed(() => mttrChange.value <= 0 ? 'â' : 'â') |
| | | const availabilityTrendText = computed(() => availabilityChange.value >= 0 ? 'â' : 'â') |
| | | |
| | | // æºè½ç»´ä¿å»ºè®® |
| | | const recommendations = computed(() => { |
| | | const suggestions = [] |
| | | |
| | | // MTBFç¸å
³å»ºè®® |
| | | if (currentMTBF.value < 400) { |
| | | suggestions.push({ |
| | | icon: 'ð§', |
| | | title: 'æåMTBF', |
| | | description: 'å½åMTBFè¾ä½ï¼å»ºè®®å 强é¢é²æ§ç»´æ¤ï¼å®ææ£æ¥å
³é®é¨ä»¶ï¼å»¶é¿è®¾å¤æ æ
éè¿è¡æ¶é´', |
| | | priority: 'high', |
| | | priorityText: 'é«ä¼å
级' |
| | | }) |
| | | } |
| | | |
| | | // MTTRç¸å
³å»ºè®® |
| | | if (currentMTTR.value > 8) { |
| | | suggestions.push({ |
| | | icon: 'â¡', |
| | | title: 'ä¼åMTTR', |
| | | description: 'å½åMTTRè¾é«ï¼å»ºè®®ä¼åç»´ä¿®æµç¨ï¼æé«ç»´ä¿®äººåæè½ï¼ç¼©çæ
éä¿®å¤æ¶é´', |
| | | priority: 'high', |
| | | priorityText: 'é«ä¼å
级' |
| | | }) |
| | | } |
| | | |
| | | // å¯ç¨çç¸å
³å»ºè®® |
| | | if (currentAvailability.value < 95) { |
| | | suggestions.push({ |
| | | icon: 'ð', |
| | | title: 'æåå¯ç¨ç', |
| | | description: '设å¤å¯ç¨çæå¾
æåï¼å»ºè®®ä¼åç»´ä¿è®¡å宿ï¼åå°è®¡åå¤åæºæ¶é´', |
| | | priority: 'medium', |
| | | priorityText: 'ä¸ä¼å
级' |
| | | }) |
| | | } |
| | | |
| | | // 综å建议 |
| | | if (currentMTBF.value >= 400 && currentMTTR.value <= 8 && currentAvailability.value >= 95) { |
| | | suggestions.push({ |
| | | icon: 'â
', |
| | | title: 'è¿è¡ç¶åµè¯å¥½', |
| | | description: 'å½å设å¤è¿è¡ç¶åµè¯å¥½ï¼åé¡¹ææ åè¾¾å°é¢æï¼å»ºè®®ç»§ç»ä¿æç°æç»´ä¿çç¥', |
| | | priority: 'low', |
| | | priorityText: 'ä½ä¼å
级' |
| | | }) |
| | | } |
| | | |
| | | // é¢é²æ§å»ºè®® |
| | | suggestions.push({ |
| | | icon: 'ð', |
| | | title: 'é¢é²æ§ç»´æ¤', |
| | | description: '建议建ç«è®¾å¤å¥åº·æ¡£æ¡ï¼å®æåæè®¾å¤è¿è¡æ°æ®ï¼æåè¯å«æ½å¨æ
éé£é©', |
| | | priority: 'medium', |
| | | priorityText: 'ä¸ä¼å
级' |
| | | }) |
| | | |
| | | return suggestions |
| | | }) |
| | | |
| | | // å¾è¡¨å®ä¾ |
| | | let trendChart = null |
| | | |
| | | const initChart = () => { |
| | | nextTick(() => { |
| | | trendChart = echarts.init(document.querySelector('.chart')) |
| | | trendChart.setOption({ |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { |
| | | type: 'cross' |
| | | } |
| | | }, |
| | | legend: { |
| | | data: ['MTBF', 'MTTR'], |
| | | top: 10 |
| | | }, |
| | | grid: { |
| | | left: '3%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | containLabel: true |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | data: mockData.months, |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: '#e0e0e0' |
| | | } |
| | | } |
| | | }, |
| | | yAxis: [ |
| | | { |
| | | type: 'value', |
| | | name: 'MTBF (å°æ¶)', |
| | | position: 'left', |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: '#1890ff' |
| | | } |
| | | }, |
| | | axisLabel: { |
| | | formatter: '{value}h' |
| | | } |
| | | }, |
| | | { |
| | | type: 'value', |
| | | name: 'MTTR (å°æ¶)', |
| | | position: 'right', |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: '#52c41a' |
| | | } |
| | | }, |
| | | axisLabel: { |
| | | formatter: '{value}h' |
| | | } |
| | | } |
| | | ], |
| | | series: [ |
| | | { |
| | | name: 'MTBF', |
| | | type: 'line', |
| | | yAxisIndex: 0, |
| | | data: mockData.mtbfData, |
| | | smooth: true, |
| | | lineStyle: { |
| | | color: '#1890ff', |
| | | width: 3 |
| | | }, |
| | | itemStyle: { |
| | | color: '#1890ff' |
| | | }, |
| | | areaStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: 'rgba(24, 144, 255, 0.3)' }, |
| | | { offset: 1, color: 'rgba(24, 144, 255, 0.1)' } |
| | | ]) |
| | | } |
| | | }, |
| | | { |
| | | name: 'MTTR', |
| | | type: 'line', |
| | | yAxisIndex: 1, |
| | | data: mockData.mttrData, |
| | | smooth: true, |
| | | lineStyle: { |
| | | color: '#52c41a', |
| | | width: 3 |
| | | }, |
| | | itemStyle: { |
| | | color: '#52c41a' |
| | | }, |
| | | areaStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: 'rgba(82, 196, 26, 0.3)' }, |
| | | { offset: 1, color: 'rgba(82, 196, 26, 0.1)' } |
| | | ]) |
| | | } |
| | | } |
| | | ] |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | const fetchKPLData = () => { |
| | | // æ¨¡ææ°æ®å·æ° |
| | | Object.assign(mockData, generateMockData()) |
| | | |
| | | // éæ°æ¸²æå¾è¡¨ |
| | | if (trendChart) { |
| | | trendChart.setOption({ |
| | | xAxis: { |
| | | data: mockData.months |
| | | }, |
| | | series: [ |
| | | { |
| | | data: mockData.mtbfData |
| | | }, |
| | | { |
| | | data: mockData.mttrData |
| | | } |
| | | ] |
| | | }) |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | initChart() |
| | | |
| | | // çå¬çªå£å¤§å°ååï¼éæ°è°æ´å¾è¡¨å¤§å° |
| | | window.addEventListener('resize', () => { |
| | | if (trendChart) trendChart.resize() |
| | | }) |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .kpl-monitor-container { |
| | | min-height: 100vh; |
| | | background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); |
| | | padding: 24px; |
| | | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; |
| | | } |
| | | |
| | | /* 页é¢å¤´é¨ */ |
| | | .page-header { |
| | | background: white; |
| | | border-radius: 12px; |
| | | padding: 24px; |
| | | margin-bottom: 24px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .header-content h1 { |
| | | margin: 0 0 8px 0; |
| | | color: #1f2937; |
| | | font-size: 28px; |
| | | font-weight: 700; |
| | | } |
| | | |
| | | .header-content p { |
| | | margin: 0; |
| | | color: #6b7280; |
| | | font-size: 16px; |
| | | } |
| | | |
| | | .time-range { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 12px; |
| | | } |
| | | |
| | | /* ææ æ¦è§ */ |
| | | .metrics-overview { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); |
| | | gap: 20px; |
| | | margin-bottom: 24px; |
| | | } |
| | | |
| | | .metric-card { |
| | | background: white; |
| | | border-radius: 12px; |
| | | padding: 24px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 16px; |
| | | transition: transform 0.2s ease, box-shadow 0.2s ease; |
| | | } |
| | | |
| | | .metric-card:hover { |
| | | transform: translateY(-2px); |
| | | box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); |
| | | } |
| | | |
| | | .metric-icon { |
| | | font-size: 32px; |
| | | width: 60px; |
| | | height: 60px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border-radius: 12px; |
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| | | } |
| | | |
| | | .mtbf-card .metric-icon { |
| | | background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); |
| | | } |
| | | |
| | | .mttr-card .metric-icon { |
| | | background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); |
| | | } |
| | | |
| | | .availability-card .metric-icon { |
| | | background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); |
| | | } |
| | | |
| | | .metric-content { |
| | | flex: 1; |
| | | } |
| | | |
| | | .metric-title { |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | color: #1f2937; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .metric-subtitle { |
| | | font-size: 14px; |
| | | color: #6b7280; |
| | | margin-bottom: 12px; |
| | | } |
| | | |
| | | .metric-value { |
| | | font-size: 32px; |
| | | font-weight: 700; |
| | | color: #1f2937; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .unit { |
| | | font-size: 16px; |
| | | font-weight: 500; |
| | | color: #6b7280; |
| | | margin-left: 4px; |
| | | } |
| | | |
| | | .metric-trend { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 4px; |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .trend-up { |
| | | color: #10b981; |
| | | } |
| | | |
| | | .trend-down { |
| | | color: #ef4444; |
| | | } |
| | | |
| | | .trend-icon { |
| | | font-size: 16px; |
| | | } |
| | | |
| | | /* å¾è¡¨åºå */ |
| | | .charts-section { |
| | | margin-bottom: 24px; |
| | | } |
| | | |
| | | .chart-container { |
| | | background: white; |
| | | border-radius: 12px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .chart-header { |
| | | padding: 20px 24px; |
| | | border-bottom: 1px solid #e5e7eb; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .chart-header h3 { |
| | | margin: 0; |
| | | color: #1f2937; |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .chart-legend { |
| | | display: flex; |
| | | gap: 20px; |
| | | } |
| | | |
| | | .legend-item { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | font-size: 14px; |
| | | color: #6b7280; |
| | | } |
| | | |
| | | .legend-color { |
| | | width: 12px; |
| | | height: 12px; |
| | | border-radius: 2px; |
| | | } |
| | | |
| | | .mtbf-legend .legend-color { |
| | | background: #1890ff; |
| | | } |
| | | |
| | | .mttr-legend .legend-color { |
| | | background: #52c41a; |
| | | } |
| | | |
| | | .chart-wrapper { |
| | | padding: 20px; |
| | | height: 400px; |
| | | } |
| | | |
| | | .chart { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | /* 建议åºå */ |
| | | .recommendations-section { |
| | | background: white; |
| | | border-radius: 12px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .section-header { |
| | | padding: 24px; |
| | | border-bottom: 1px solid #e5e7eb; |
| | | } |
| | | |
| | | .section-header h3 { |
| | | margin: 0 0 8px 0; |
| | | color: #1f2937; |
| | | font-size: 20px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .section-header p { |
| | | margin: 0; |
| | | color: #6b7280; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .recommendations-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); |
| | | gap: 20px; |
| | | padding: 24px; |
| | | } |
| | | |
| | | .recommendation-card { |
| | | background: #f8fafc; |
| | | border-radius: 8px; |
| | | padding: 20px; |
| | | display: flex; |
| | | gap: 16px; |
| | | transition: transform 0.2s ease, box-shadow 0.2s ease; |
| | | } |
| | | |
| | | .recommendation-card:hover { |
| | | transform: translateY(-1px); |
| | | box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .recommendation-icon { |
| | | font-size: 24px; |
| | | width: 40px; |
| | | height: 40px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border-radius: 8px; |
| | | background: white; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | .recommendation-content { |
| | | flex: 1; |
| | | } |
| | | |
| | | .recommendation-content h4 { |
| | | margin: 0 0 8px 0; |
| | | color: #1f2937; |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .recommendation-content p { |
| | | margin: 0 0 12px 0; |
| | | color: #6b7280; |
| | | font-size: 14px; |
| | | line-height: 1.5; |
| | | } |
| | | |
| | | .recommendation-priority { |
| | | display: inline-block; |
| | | padding: 4px 8px; |
| | | border-radius: 4px; |
| | | font-size: 12px; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .priority.high { |
| | | background: #fef2f2; |
| | | color: #dc2626; |
| | | } |
| | | |
| | | .priority.medium { |
| | | background: #fffbeb; |
| | | color: #d97706; |
| | | } |
| | | |
| | | .priority.low { |
| | | background: #f0fdf4; |
| | | color: #16a34a; |
| | | } |
| | | |
| | | /* ååºå¼è®¾è®¡ */ |
| | | @media (max-width: 768px) { |
| | | .kpl-monitor-container { |
| | | padding: 16px; |
| | | } |
| | | |
| | | .page-header { |
| | | flex-direction: column; |
| | | gap: 16px; |
| | | align-items: stretch; |
| | | } |
| | | |
| | | .metrics-overview { |
| | | grid-template-columns: 1fr; |
| | | } |
| | | |
| | | .recommendations-grid { |
| | | grid-template-columns: 1fr; |
| | | } |
| | | |
| | | .chart-wrapper { |
| | | height: 300px; |
| | | } |
| | | |
| | | .chart-legend { |
| | | flex-direction: column; |
| | | gap: 8px; |
| | | } |
| | | } |
| | | |
| | | @media (max-width: 480px) { |
| | | .metric-card { |
| | | flex-direction: column; |
| | | text-align: center; |
| | | } |
| | | |
| | | .recommendation-card { |
| | | flex-direction: column; |
| | | text-align: center; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef"> |
| | | <el-form :model="form" label-width="120px" :rules="formRules" ref="formRef"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设å¤åç§°" prop="deviceName"> |
| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§æ ¼åå·" prop="deviceModel"> |
| | | <el-input v-model="form.deviceModel" :disabled="(form.deviceModel != null && operationType === 'edit')" placeholder="请è¾å
¥è§æ ¼åå·" /> |
| | | <el-input v-model="form.deviceModel" placeholder="请è¾å
¥è§æ ¼åå·" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设å¤åç" prop="deviceBrand"> |
| | | <el-input v-model="form.deviceBrand" placeholder="请è¾å
¥è®¾å¤åç" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设å¤ç±»å" prop="type"> |
| | | <el-select |
| | | v-model="form.type" |
| | | placeholder="è¯·éæ©æè¾å
¥è®¾å¤ç±»å" |
| | | clearable |
| | | filterable |
| | | allow-create |
| | | default-first-option |
| | | style="width: 100%" |
| | | @change="handleDeviceTypeChange" |
| | | > |
| | | <el-option |
| | | v-for="item in deviceTypeOptions" |
| | | :key="item" |
| | | :label="item" |
| | | :value="item" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åæ¾ä½ç½®" prop="storageLocation"> |
| | | <el-input v-model="form.storageLocation" placeholder="请è¾å
¥åæ¾ä½ç½®" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åä½" prop="unit"> |
| | | <el-input v-model="form.unit" placeholder="请è¾å
¥åä½" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¯ç¨ææ§" prop="isDepr"> |
| | | <el-switch v-model="form.isDepr" :active-value="1" :inactive-value="2" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.isDepr === 1"> |
| | | <el-form-item label="æ¯å¹´ææ§éé¢" prop="annualDepreciationAmount"> |
| | | <el-input-number |
| | | :step="0.01" |
| | | :min="0" |
| | | style="width: 100%" |
| | | v-model="form.annualDepreciationAmount" |
| | | placeholder="请è¾å
¥æ¯å¹´ææ§éé¢" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ°é" prop="number"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" |
| | | <el-input-number :min="1" style="width: 100%" |
| | | v-model="form.number" |
| | | disabled |
| | | placeholder="请è¾å
¥æ°é" |
| | | @change="mathNum" |
| | | /> |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é¢è®¡è¿è¡æ¶é´" prop="planRuntimeTime"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.planRuntimeTime" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©å½å
¥æ¥æ" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </template> |
| | |
| | | }); |
| | | const formRef = ref(null); |
| | | const operationType = ref(''); |
| | | // 设å¤ç±»ååºå®é项 |
| | | const deviceTypeOptions = ref([ |
| | | 'ç产设å¤', |
| | | 'åå
¬è®¾å¤', |
| | | 'æ£æµè®¾å¤', |
| | | 'è¿è¾è®¾å¤', |
| | | 'å
¶ä»è®¾å¤' |
| | | ]); |
| | | const formRules = { |
| | | deviceName: [{ required: true, trigger: "blur", message: "请è¾å
¥" }], |
| | | deviceModel: [{ required: true, trigger: "blur", message: "请è¾å
¥" }], |
| | | type: [{ required: true, trigger: "change", message: "è¯·éæ©æè¾å
¥è®¾å¤ç±»å" }], |
| | | supplierName: [{ required: true, trigger: "blur", message: "请è¾å
¥" }], |
| | | unit: [{ required: true, trigger: "blur", message: "请è¾å
¥" }], |
| | | number: [{ required: true, trigger: "blur", message: "请è¾å
¥" }], |
| | | taxIncludingPriceUnit: [{ required: true, trigger: "blur", message: "请è¾å
¥" }], |
| | | taxRate: [{ required: true, trigger: "change", message: "请è¾å
¥" }], |
| | | planRuntimeTime: [{ required: true, trigger: "change", message: "è¯·éæ©" }], |
| | | annualDepreciationAmount: [ |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (form.isDepr === 1 && (value === undefined || value === null || value === '')) { |
| | | callback(new Error('å¯ç¨ææ§æ¶ï¼è¯·è¾å
¥æ¯å¹´ææ§éé¢')); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }, |
| | | trigger: "blur" |
| | | } |
| | | ], |
| | | } |
| | | |
| | | const { form, resetForm } = useFormData({ |
| | | deviceName: undefined, // 设å¤åç§° |
| | | deviceModel: undefined, // è§æ ¼åå· |
| | | deviceBrand: undefined, // 设å¤åç |
| | | type: undefined, // 设å¤ç±»å |
| | | supplierName: undefined, // ä¾åºå |
| | | storageLocation: undefined, // åæ¾ä½ç½® |
| | | isDepr: 2, // æ¯å¦å¯ç¨ææ§ 1-æ¯ 2-å¦ |
| | | annualDepreciationAmount: undefined, // æ¯å¹´ææ§éé¢ |
| | | unit: undefined, // åä½ |
| | | number: undefined, // æ°é |
| | | number: 1, // æ°é |
| | | taxIncludingPriceUnit: undefined, // å«ç¨åä»· |
| | | taxIncludingPriceTotal: undefined, // å«ç¨æ»ä»· |
| | | taxRate: undefined, // ç¨ç |
| | | unTaxIncludingPriceTotal: undefined, // ä¸å«ç¨æ»ä»· |
| | | // createUser: useUserStore().nickName, // å½å
¥äºº |
| | | createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), // å½å
¥æ¥æ |
| | | planRuntimeTime: dayjs().format("YYYY-MM-DD"), // å½å
¥æ¥æ |
| | | }); |
| | | |
| | | const loadForm = async (id) => { |
| | |
| | | if (code == 200) { |
| | | form.deviceName = data.deviceName; |
| | | form.deviceModel = data.deviceModel; |
| | | form.deviceBrand = data.deviceBrand; |
| | | form.type = data.type; |
| | | form.supplierName = data.supplierName; |
| | | form.storageLocation = data.storageLocation; |
| | | form.isDepr = data.isDepr; |
| | | form.annualDepreciationAmount = data.annualDepreciationAmount; |
| | | form.unit = data.unit; |
| | | form.number = data.number; |
| | | form.number = 1; |
| | | form.taxIncludingPriceUnit = data.taxIncludingPriceUnit; |
| | | form.taxIncludingPriceTotal = data.taxIncludingPriceTotal; |
| | | form.taxRate = data.taxRate; |
| | |
| | | } |
| | | }; |
| | | |
| | | const handleDeviceTypeChange = (value) => { |
| | | // 妿è¾å
¥çæ°å¼ä¸å¨åºå®é项ä¸ï¼åæ·»å å°é项å表 |
| | | if (value && !deviceTypeOptions.value.includes(value)) { |
| | | deviceTypeOptions.value.push(value); |
| | | } |
| | | }; |
| | | |
| | | const mathNum = () => { |
| | | if (!form.taxIncludingPriceUnit) { |
| | | ElMessage.error("请è¾å
¥åä»·"); |
| | | return; |
| | | } |
| | | if (!form.number) { |
| | | ElMessage.error("请è¾å
¥æ°é"); |
| | | return; |
| | | } |
| | | form.taxIncludingPriceTotal = calculateTaxIncludeTotalPrice( |
| | |
| | | <template> |
| | | <el-dialog :title="modalOptions.title" v-model="visible" @close="close"> |
| | | <el-dialog :title="modalOptions.title" v-model="visible" @close="close" draggable> |
| | | <Form ref="formRef"></Form> |
| | | <template #footer> |
| | | <el-button type="primary" @click="sendForm" :loading="loading"> |
| | |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥è®¾å¤åç§°" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | @change="getTableData" |
| | | /> |
| | | </el-form-item> |
| | |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥è§æ ¼åå·" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | @change="getTableData" |
| | | /> |
| | | </el-form-item> |
| | |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥ä¾åºå" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | @change="getTableData" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="åä½"> |
| | | <el-input |
| | | v-model="filters.unit" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥åä½" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | @change="getTableData" |
| | | /> |
| | | </el-form-item> |
| | |
| | | </PIMTable> |
| | | </div> |
| | | <Modal ref="modalRef" @success="getTableData"></Modal> |
| | | <el-dialog v-model="qrDialogVisible" title="äºç»´ç " width="300px"> |
| | | <el-dialog v-model="qrDialogVisible" title="äºç»´ç " width="300px" draggable> |
| | | <div style="text-align:center;"> |
| | | <img :src="qrCodeUrl" alt="äºç»´ç " style="width:200px;height:200px;" /> |
| | | <div style="margin:10px 0;"> |
| | |
| | | deviceName: undefined, |
| | | deviceModel: undefined, |
| | | supplierName: undefined, |
| | | unit: undefined, |
| | | entryDateStart: undefined, |
| | | entryDateEnd: undefined, |
| | | }, |
| | | [ |
| | | { |
| | | label: "设å¤åç§°", |
| | | align: "center", |
| | | prop: "deviceName", |
| | | }, |
| | | { |
| | | label: "è§æ ¼åå·", |
| | | align: "center", |
| | | prop: "deviceModel", |
| | | }, |
| | | { |
| | | label: "设å¤åç", |
| | | prop: "deviceBrand", |
| | | }, |
| | | { |
| | | label: "设å¤ç±»å", |
| | | prop: "type", |
| | | }, |
| | | { |
| | | label: "ä¾åºå", |
| | | align: "center", |
| | | prop: "supplierName", |
| | | }, |
| | | { |
| | | label: "åä½", |
| | | align: "center", |
| | | prop: "unit", |
| | | label: "åæ¾ä½ç½®", |
| | | prop: "storageLocation", |
| | | }, |
| | | { |
| | | label: "æ°é", |
| | | align: "center", |
| | | prop: "number", |
| | | }, |
| | | { |
| | | label: "å«ç¨åä»·", |
| | | align: "center", |
| | | prop: "taxIncludingPriceUnit", |
| | | }, |
| | | { |
| | | label: "å«ç¨æ»ä»·", |
| | | align: "center", |
| | | prop: "taxIncludingPriceTotal", |
| | | }, |
| | | { |
| | | label: "ç¨ç", |
| | | align: "center", |
| | | prop: "taxRate", |
| | | }, |
| | | { |
| | | label: "ä¸å«ç¨æ»ä»·", |
| | | align: "center", |
| | | prop: "unTaxIncludingPriceTotal", |
| | | }, |
| | | { |
| | | label: "å½å
¥äºº", |
| | | align: "center", |
| | | prop: "createUser", |
| | | }, |
| | | { |
| | | label: "å½å
¥æ¥æ", |
| | | align: "center", |
| | | prop: "createTime", |
| | | formatData: (v) => { |
| | | if (!v) return ''; |
| | | // 妿å
嫿¶åç§ï¼åªåæ¥æé¨å |
| | | if (v.includes(' ')) { |
| | | return v.split(' ')[0]; |
| | | } |
| | | return v; |
| | | }, |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: 'right', |
| | | width: 140, |
| | | width: 150, |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | edit(row.id) |
| | | }, |
| | | }, |
| | | { |
| | | name: "çæäºç»´ç ", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | showQRCode(row) |
| | | }, |
| | |
| | | }; |
| | | |
| | | const showQRCode = async (row) => { |
| | | // ä½ å¯ä»¥èªå®ä¹äºç»´ç å
å®¹ï¼æ¯å¦ row.id æ row.deviceName |
| | | const qrContent = JSON.stringify(row); // æ `${row.id}` |
| | | // ç´æ¥ä½¿ç¨URLï¼ä¸è¦ç¨JSON.stringifyå
è£
|
| | | const qrContent = proxy.javaApi + '/device-info?deviceId=' + row.id; |
| | | qrCodeUrl.value = await QRCode.toDataURL(qrContent); |
| | | qrRowData.value = row; |
| | | qrDialogVisible.value = true; |
| | |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | filters.entryDate = [ |
| | | dayjs().format("YYYY-MM-DD"), |
| | | dayjs().add(1, "day").format("YYYY-MM-DD"), |
| | | ] |
| | | filters.entryDateStart = dayjs().format("YYYY-MM-DD") |
| | | filters.entryDateEnd = dayjs().add(1, "day").format("YYYY-MM-DD") |
| | | getTableData(); |
| | | }); |
| | | </script> |
| | |
| | | v-model="dialogFormVisible" |
| | | title="计éå¨å
·" |
| | | width="50%" |
| | | draggable |
| | | @close="closeDia" |
| | | > |
| | | <el-form |
| | |
| | | <el-select |
| | | v-model="form.userId" |
| | | placeholder="è¯·éæ©" |
| | | disabled |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | clearable |
| | | > |
| | | <el-option |
| | |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | disabled |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref} from "vue"; |
| | | import {ref, reactive, toRefs, getCurrentInstance} from "vue"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import {userListNoPageByTenantId} from "@/api/system/user.js"; |
| | | import {afterSalesServiceAdd, afterSalesServiceUpdate} from "@/api/customerService/index.js"; |
| | | import {getToken} from "@/utils/auth.js"; |
| | | import {ledgerRecordUpdate, ledgerRecordVerifying} from "@/api/equipmentManagement/calibration.js"; |
| | | import {delLedgerFile} from "@/api/salesManagement/salesLedger.js"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | const dialogFormVisible = ref(false); |
| | |
| | | if(type === "add"){ |
| | | fileList.value = row.commonFiles; |
| | | } |
| | | if(type === "verifying"){ |
| | | form.value.valid = row.valid; |
| | | form.value.recordDate = row.mostDate; |
| | | } |
| | | |
| | | form.value.id = row.id; |
| | | form.value.code = row.code; |
| | |
| | | dialogFormVisible.value = false; |
| | | emit('close') |
| | | }; |
| | | // è·åå½åæ¥æå¹¶æ ¼å¼å为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, "0"); // æä»½ä»0å¼å§ |
| | | const day = String(today.getDate()).padStart(2, "0"); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | defineExpose({ |
| | | openDialog, |
| | | }); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | |
| | | </template> |
| | | |
| | | <script setup> |
| | | |
| | | </script> |
| | |
| | | v-model="dialogFormVisible" |
| | | title="计éå¨å
·" |
| | | width="50%" |
| | | draggable |
| | | @close="closeDia" |
| | | > |
| | | <el-form |
| | |
| | | ref="formRef" |
| | | > |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="计éå¨å
·ç¼å·ï¼" prop="code"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="åºåç¼å·ï¼" prop="code"> |
| | | <el-input |
| | | v-model="form.code" |
| | | placeholder="请è¾å
¥" |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="计éå¨å
·åç§°ï¼" prop="name"> |
| | | <el-input |
| | | v-model="form.name" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§æ ¼åå·ï¼" prop="model"> |
| | | <el-form-item label="å®è£
ä½ç½®ï¼" prop="instationLocation"> |
| | | <el-input |
| | | v-model="form.model" |
| | | v-model="form.installationLocation" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é¢è®¡ä¸æ¬¡æ£å®æ¥æï¼" prop="nextDate"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.nextDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | /> |
| | | <el-form-item label="æ£å®åä½ï¼" prop="unit"> |
| | | <el-input |
| | | v-model="form.unit" |
| | | placeholder="请è¾å
¥æ£å®åä½" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è¯ä¹¦ç¼å·ï¼" prop="model"> |
| | | <el-input |
| | | v-model="form.model" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ææ°é´å®æ¥æï¼" prop="mostDate"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.mostDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æææ¥æ(天)ï¼" prop="valid"> |
| | | <el-input |
| | | v-model="form.valid" |
| | | placeholder="请è¾å
¥æææå¤©æ°" |
| | | clearable |
| | | > |
| | | <template #append>æ¥</template> |
| | | </el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ£å®å¨æï¼" prop="cycle"> |
| | | <el-input |
| | | v-model="form.cycle" |
| | | placeholder="请è¾å
¥æ£å®å¨æ" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å½å
¥äººï¼" prop="userId"> |
| | |
| | | v-model="form.userId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | disabled |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | |
| | | style="width: 100%" |
| | | v-model="form.recordDate" |
| | | value-format="YYYY-MM-DD" |
| | | disabled |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | disabled |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | /> |
| | |
| | | import {userListNoPageByTenantId} from "@/api/system/user.js"; |
| | | import {afterSalesServiceAdd, afterSalesServiceUpdate} from "@/api/customerService/index.js"; |
| | | import {getToken} from "@/utils/auth.js"; |
| | | import {measuringInstrumentAdd, measuringInstrumentUpdate} from "@/api/equipmentManagement/measurementEquipment.js"; |
| | | import {addMeasuringInstrumentLedger, updateMeasuringInstrumentLedger} from "@/api/equipmentManagement/measurementEquipment.js"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | const dialogFormVisible = ref(false); |
| | |
| | | const data = reactive({ |
| | | form: { |
| | | code: "", |
| | | name: "", |
| | | installationLocation: "", |
| | | mostDate:"", |
| | | model: "", |
| | | cycle:"", |
| | | validDate: "", |
| | | nextDate: "", |
| | | userId: "", |
| | |
| | | }, |
| | | rules: { |
| | | code: [{required: true, message: "请è¾å
¥", trigger: "blur"}], |
| | | name: [{required: true, message: "请è¾å
¥", trigger: "blur"}], |
| | | model: [{required: true, message: "请è¾å
¥", trigger: "blur"}], |
| | | validDate: [{required: true, message: "请è¾å
¥", trigger: "blur"}], |
| | | nextDate: [{required: true, message: "è¯·éæ©", trigger: "change"}], |
| | | userId: [{required: true, message: "è¯·éæ©", trigger: "change"}], |
| | | recordDate: [{required: true, message: "è¯·éæ©", trigger: "change"}], |
| | | installationLocation: [{required: true, message: "请è¾å
¥", trigger: "blur"}], |
| | | mostDate: [{required: true, message: "è¯·éæ©", trigger: "change"}], |
| | | cycle: [{required: true, message: "è¯·éæ©", trigger: "blur"}], |
| | | valid: [{required: true, message: "请è¾å
¥", trigger: "blur"}], |
| | | unit: [{required: true, message: "请è¾å
¥", trigger: "blur"}], |
| | | } |
| | | }) |
| | | const { form, rules } = toRefs(data); |
| | |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | if (operationType.value === "add") { |
| | | measuringInstrumentAdd(form.value).then(response => { |
| | | addMeasuringInstrumentLedger(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå") |
| | | form.value.tempFileIds = [] |
| | | closeDia() |
| | | }) |
| | | } else { |
| | | measuringInstrumentUpdate(form.value).then(response => { |
| | | updateMeasuringInstrumentLedger(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå") |
| | | form.value.tempFileIds = [] |
| | | closeDia() |
| | |
| | | dialogFormVisible.value = false; |
| | | emit('close') |
| | | }; |
| | | // è·åå½åæ¥æå¹¶æ ¼å¼å为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, "0"); // æä»½ä»0å¼å§ |
| | | const day = String(today.getDate()).padStart(2, "0"); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | defineExpose({ |
| | | openDialog, |
| | | }); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog |
| | | v-model="dialogFormVisible" |
| | | title="æ£å®æ ¡åè®°å½" |
| | | width="50%" |
| | | @close="closeDia" |
| | | > |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :tableLoading="tableLoading" |
| | | @selection-change="handleSelectionChange" |
| | | height="500" |
| | | :isPagination="false" |
| | | > |
| | | </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 filePreview from '@/components/filePreview/index.vue' |
| | | import {ledgerRecordListPage} from "@/api/equipmentManagement/calibration.js"; |
| | | import Pagination from "@/components/PIMTable/Pagination.vue"; |
| | | const emit = defineEmits(['close']) |
| | | |
| | | const dialogFormVisible = ref(false); |
| | | const currentId = ref('') |
| | | const selectedRows = ref([]); |
| | | const filePreviewRef = ref() |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "æ£å®æ¥æ", |
| | | prop: "recordDate", |
| | | width: 130, |
| | | }, |
| | | { |
| | | label: "计éå¨å
·ç¼å·", |
| | | prop: "code", |
| | | width: 150, |
| | | }, |
| | | { |
| | | label: "计éå¨å
·åç§°", |
| | | prop: "name", |
| | | width: 200, |
| | | }, |
| | | { |
| | | label: "è§æ ¼åå·", |
| | | prop: "model", |
| | | width:200 |
| | | }, |
| | | { |
| | | label: "æææ", |
| | | prop: "valid", |
| | | width: 100, |
| | | }, |
| | | { |
| | | label: "å½å
¥äºº", |
| | | prop: "userName", |
| | | }, |
| | | { |
| | | label: "å½å
¥æ¥æ", |
| | | prop: "entryDate", |
| | | width: 130, |
| | | }, |
| | | ]); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | }); |
| | | const total = ref(0); |
| | | const tableData = ref([]); |
| | | const tableLoading = ref(false); |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = (row,type) => { |
| | | dialogFormVisible.value = true; |
| | | currentId.value = row.id; |
| | | getList() |
| | | } |
| | | const paginationSearch = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | const getList = () => { |
| | | let query = { |
| | | measuringInstrumentLedgerId:currentId.value, |
| | | current : page.current, |
| | | size : page.size |
| | | } |
| | | ledgerRecordListPage(query).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') |
| | | }; |
| | | |
| | | defineExpose({ |
| | | openDialog, |
| | | }); |
| | | </script> |
| | |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :tableLoading="tableLoading" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | @pagination="paginationSearch" |
| | | 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> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref} from "vue"; |
| | | import {ref, reactive, getCurrentInstance} from "vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {getToken} from "@/utils/auth.js"; |
| | | import filePreview from '@/components/filePreview/index.vue' |
| | | import PIMTable from "@/components/PIMTable/PIMTable.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 page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0, |
| | | }); |
| | | const total = ref(0); |
| | | const tableData = ref([]); |
| | | const fileList = ref([]); |
| | | const tableLoading = ref(false); |
| | |
| | | const getList = () => { |
| | | fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => { |
| | | tableData.value = res.data.records; |
| | | total.value = res.data.total; |
| | | page.total = res.data.total; |
| | | }) |
| | | } |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | | <el-button @click="handleReset" style="margin-left: 10px">éç½®</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')">æ°å¢è®¡éå¨å
·</el-button> |
| | |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | :dbRowClick="dbRowClick" |
| | | ></PIMTable> |
| | | </div> |
| | | <form-dia ref="formDia" @close="handleQuery"></form-dia> |
| | | <calibration-dia ref="calibrationDia" @close="handleQuery"></calibration-dia> |
| | | <files-dia ref="filesDia"></files-dia> |
| | | <rowClickDataForm ref="rowClickData"></rowClickDataForm> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {onMounted, ref} from "vue"; |
| | | import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue"; |
| | | import FormDia from "@/views/equipmentManagement/measurementEquipment/components/formDia.vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import CalibrationDia from "@/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue"; |
| | | import { |
| | | measuringInstrumentDelete, |
| | | measuringInstrumentListPage |
| | | measuringInstrumentDelete, |
| | | measuringInstrumentListPage, |
| | | } from "@/api/equipmentManagement/measurementEquipment.js"; |
| | | import FilesDia from "./filesDia.vue"; |
| | | import rowClickDataForm from "./components/rowClickData.vue" |
| | | const { proxy } = getCurrentInstance(); |
| | | const userStore = useUserStore() |
| | | |
| | |
| | | |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "ç¶æ", |
| | | prop: "status", |
| | | dataType: "tag", |
| | | formatData: (params) => { |
| | | if (params == 1) { |
| | | return "ææ"; |
| | | } else if (params == 2) { |
| | | return "龿"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | formatType: (params) => { |
| | | if (params == 1) { |
| | | return "success"; |
| | | } else if (params == 2) { |
| | | return "danger"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | label: "åºåç¼å·", |
| | | prop: "code", |
| | | minWidth:150, |
| | | align:"center" |
| | | }, |
| | | { |
| | | label: "æè¿ä¸æ¬¡æ£å®æ¥æ", |
| | | label: "å®è£
ä½ç½®", |
| | | prop: "instationLocation", |
| | | width: 150, |
| | | align:"center" |
| | | }, |
| | | { |
| | | label: "æ£å®åä½", |
| | | prop: "unit", |
| | | width: 200, |
| | | align:"center" |
| | | }, |
| | | { |
| | | label: "è¯ä¹¦ç¼å·", |
| | | prop: "model", |
| | | width:200, |
| | | align:"center" |
| | | }, |
| | | { |
| | | label: "ææ°é´å®æ¥æ", |
| | | prop: "mostDate", |
| | | width: 130, |
| | | }, |
| | | { |
| | | label: "计éå¨å
·ç¼å·", |
| | | prop: "code", |
| | | width: 150, |
| | | }, |
| | | { |
| | | label: "计éå¨å
·åç§°", |
| | | prop: "name", |
| | | width: 200, |
| | | }, |
| | | { |
| | | label: "è§æ ¼åå·", |
| | | prop: "model", |
| | | width:200 |
| | | }, |
| | | { |
| | | label: "æææ", |
| | | prop: "valid", |
| | | width: 130, |
| | | }, |
| | | { |
| | | label: "é¢è®¡ä¸æ¬¡æ£å®æ¥æ", |
| | | prop: "nextDate", |
| | | width: 130, |
| | | align:"center" |
| | | }, |
| | | { |
| | | label: "å½å
¥äºº", |
| | | prop: "userName", |
| | | width: 130, |
| | | align:"center" |
| | | }, |
| | | { |
| | | label: "å½å
¥æ¥æ", |
| | | prop: "recordDate", |
| | | width: 130, |
| | | align:"center", |
| | | minWidth: 130 |
| | | }, |
| | | { |
| | | label: "æææ¥æ", |
| | | prop: "valid", |
| | | width: 130, |
| | | align:"center" |
| | | }, |
| | | { |
| | | label: "æ£å®å¨æ(天)", |
| | | prop: "cycle", |
| | | width: 130, |
| | | align:"center" |
| | | }, |
| | | { |
| | | label: "ç¶æ", |
| | | prop: "status", |
| | | width: 130, |
| | | align: "center", |
| | | formatData: (params) => { |
| | | if (params === 1) { |
| | | return "ææ"; |
| | | } else if (params === 2) { |
| | | return "龿"; |
| | | } else { |
| | | return null; |
| | | } |
| | | } |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | |
| | | width: '130', |
| | | fixed: 'right', |
| | | operation: [ |
| | | { |
| | | name: "éä»¶", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openFilesFormDia(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "æ£å®æ ¡å", |
| | | name: "æ¥ç", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openCalibrationDia("verifying", row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "éä»¶", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openFilesFormDia(row); |
| | | }, |
| | | }, |
| | | ], |
| | |
| | | ]); |
| | | const tableData = ref([]); |
| | | const tableLoading = ref(false); |
| | | const rowClickData = ref([]) |
| | | const filesDia = ref() |
| | | const page = reactive({ |
| | | current: 1, |
| | |
| | | |
| | | // æå¼éä»¶å¼¹æ¡ |
| | | const openFilesFormDia = (row) => { |
| | | console.log(row) |
| | | nextTick(() => { |
| | | filesDia.value?.openDialog( row,'计éå¨å
·å°è´¦') |
| | | }) |
| | | filesDia.value?.openDialog(row,'计éå¨å
·å°è´¦') |
| | | }; |
| | | |
| | | const dbRowClick = (row)=>{ |
| | | rowClickData.value?.openDialog(row) |
| | | } |
| | | |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | |
| | | // éç½®æç´¢æ¡ä»¶ |
| | | const handleReset = () => { |
| | | searchForm.value.recordDate = ""; |
| | | searchForm.value.code = ""; |
| | | searchForm.value.status = ""; |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | // æ£æ¥æ¯å¦æä»äººç»´æ¤çæ°æ® |
| | | const unauthorizedData = selectedRows.value.filter(item => item.userId !== userStore.id); |
| | | if (unauthorizedData.length > 0) { |
| | | proxy.$modal.msgWarning("ä¸å¯å é¤ä»äººç»´æ¤çæ°æ®"); |
| | | return; |
| | | } |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | |
| | | <!-- ç鿡件 --> |
| | | <div class="filter-section"> |
| | | <el-select v-model="deviceFilter" placeholder="设å¤ç¶æçé" clearable style="width: 200px; margin-right: 10px;"> |
| | | <el-option label="å
¨é¨" value="all" /> |
| | | <el-option label="è¿è¡ä¸" value="start" /> |
| | | <el-option label="忢è¿è¡" value="stop" /> |
| | | </el-select> |
| | | </div> |
| | | |
| | | <!-- 设å¤å¯åè®°å½è¡¨æ ¼ --> |
| | | <el-card class="table-card"> |
| | | <template #header> |
| | | <span>设å¤è¿è¡è®°å½</span> |
| | | </template> |
| | | <el-table |
| | | :data="filteredDeviceRecords" |
| | | style="width: 100%" |
| | | :header-cell-style="{ background: '#F0F1F5', color: '#333333' }" |
| | | :row-class-name="getRowClassName" |
| | | v-loading="loading" |
| | | > |
| | | <el-table-column |
| | | align="center" |
| | | label="åºå·" |
| | | type="index" |
| | | width="60" |
| | | /> |
| | | <el-table-column |
| | | label="设å¤åç§°" |
| | | prop="deviceName" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="è§æ ¼åå·" |
| | | prop="deviceModel" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="设å¤ç¶æ" |
| | | prop="status" |
| | | width="150" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | <!-- è¶
æ¶æªå¯å¨æ¶æ¾ç¤ºè¦å --> |
| | | <el-tag |
| | | v-if="isOverdue(scope.row)" |
| | | type="warning" |
| | | size="small" |
| | | effect="dark" |
| | | > |
| | | <el-icon><Warning /></el-icon> |
| | | è¶
æ¶æªå¯å¨ |
| | | </el-tag> |
| | | <!-- æ£å¸¸ç¶ææ¶æ¾ç¤ºè®¾å¤ç¶æ --> |
| | | <el-tag |
| | | v-else |
| | | :type="getDeviceStatusType(scope.row.status)" |
| | | size="small" |
| | | > |
| | | <el-icon v-if="scope.row.status === 'è¿è¡ä¸'"><VideoPlay /></el-icon> |
| | | <el-icon v-else><VideoPause /></el-icon> |
| | | {{ scope.row.status || 'æªç¥' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="计åè¿è¡æ¶é´" |
| | | prop="planRuntimeTime" |
| | | width="150" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | {{ scope.row.planRuntimeTime || '-' }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="å¼å§è¿è¡æ¶é´" |
| | | prop="startRuntimeTime" |
| | | width="180" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | {{ scope.row.startRuntimeTime || '-' }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="ç»æè¿è¡æ¶é´" |
| | | prop="endRuntimeTime" |
| | | width="180" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | {{ scope.row.endRuntimeTime || '-' }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="è¿è¡æ¶é¿" |
| | | prop="runtimeDuration" |
| | | width="120" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | {{ scope.row.runtimeDuration || '-' }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æä½" |
| | | width="120" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | <!-- è¶
æ¶æªå¯å¨æ¶æ¾ç¤ºå¯å¨æé® --> |
| | | <el-button |
| | | v-if="isOverdue(scope.row)" |
| | | type="warning" |
| | | size="small" |
| | | @click="changeDeviceStatus(scope.row, 'å¯å¨è¿è¡')" |
| | | > |
| | | <el-icon><VideoPlay /></el-icon> |
| | | ç«å³å¯å¨ |
| | | </el-button> |
| | | <!-- æ£å¸¸ç¶ææ¶æ¾ç¤ºå¯¹åºçæä½æé® --> |
| | | <template v-else> |
| | | <el-button |
| | | v-if="scope.row.status === 'è¿è¡ä¸'" |
| | | type="danger" |
| | | size="small" |
| | | @click="changeDeviceStatus(scope.row, '忢è¿è¡')" |
| | | > |
| | | <el-icon><VideoPause /></el-icon> |
| | | 忢è¿è¡ |
| | | </el-button> |
| | | <el-button |
| | | v-else |
| | | type="success" |
| | | size="small" |
| | | @click="changeDeviceStatus(scope.row, 'å¯å¨è¿è¡')" |
| | | > |
| | | <el-icon><VideoPlay /></el-icon> |
| | | å¯å¨è¿è¡ |
| | | </el-button> |
| | | </template> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted, computed } from 'vue' |
| | | import { ElMessage } from 'element-plus' |
| | | import { |
| | | VideoPlay, |
| | | VideoPause, |
| | | Warning |
| | | } from '@element-plus/icons-vue' |
| | | import {editLedger, getLedgerPage} from "@/api/equipmentManagement/ledger.js"; |
| | | |
| | | // ååºå¼æ°æ® |
| | | const deviceFilter = ref('all') |
| | | const loading = ref(false) |
| | | const total = ref(0) |
| | | const queryParams = ref({ |
| | | current: -1, |
| | | size: -1 |
| | | }) |
| | | |
| | | // ç§»é¤æ¦è§æ°æ®ï¼å 为ç°å¨ä½¿ç¨è¡¨æ ¼å±ç¤º |
| | | |
| | | // 设å¤å¯åè®°å½æ°æ® |
| | | const deviceRecords = ref([]) |
| | | const allDeviceRecords = ref([]) // å卿æåå§æ°æ® |
| | | |
| | | // æ ¹æ®çéæ¡ä»¶è¿æ»¤æ°æ® |
| | | const filteredDeviceRecords = computed(() => { |
| | | let filtered = allDeviceRecords.value |
| | | |
| | | // æ ¹æ®è®¾å¤ç¶æçé |
| | | if (deviceFilter.value !== 'all') { |
| | | if (deviceFilter.value === 'start') { |
| | | filtered = filtered.filter(device => device.status === 'è¿è¡ä¸') |
| | | } else if (deviceFilter.value === 'stop') { |
| | | filtered = filtered.filter(device => device.status === '忢è¿è¡') |
| | | } |
| | | } |
| | | |
| | | return filtered |
| | | }) |
| | | |
| | | // æ£æ¥è®¾å¤æ¯å¦è¶
æ¶æªå¯å¨ |
| | | const isOverdue = (device) => { |
| | | if (!device.planRuntimeTime || device.status === 'è¿è¡ä¸' || device.startRuntimeTime) { |
| | | return false |
| | | } |
| | | |
| | | const planTime = new Date(device.planRuntimeTime) |
| | | const currentTime = new Date() |
| | | |
| | | return currentTime > planTime |
| | | } |
| | | |
| | | // æ¹æ³ |
| | | const getList = async () => { |
| | | loading.value = true |
| | | try { |
| | | const response = await getLedgerPage(queryParams.value) |
| | | if (response.code === 200) { |
| | | allDeviceRecords.value = response.data.records || [] |
| | | total.value = response.data.total || 0 |
| | | } |
| | | } catch (error) { |
| | | console.error('è·å设å¤å表失败:', error) |
| | | ElMessage.error('è·å设å¤å表失败') |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | | } |
| | | |
| | | const changeDeviceStatus = async (device, status) => { |
| | | try { |
| | | const currentTime = new Date().toLocaleString('zh-CN', { |
| | | year: 'numeric', |
| | | month: '2-digit', |
| | | day: '2-digit', |
| | | hour: '2-digit', |
| | | minute: '2-digit', |
| | | second: '2-digit', |
| | | hour12: false |
| | | }).replace(/\//g, '-') |
| | | |
| | | // æ´æ°è®¾å¤ç¶æåç¸å
³æ¶é´å段 |
| | | if (status === 'å¯å¨è¿è¡') { |
| | | device.status = 'è¿è¡ä¸' |
| | | device.startRuntimeTime = currentTime |
| | | device.endRuntimeTime = null // æ¸
ç©ºç»ææ¶é´ |
| | | device.runtimeDuration = null // æ¸
空è¿è¡æ¶é¿ |
| | | } else { |
| | | device.status = '忢è¿è¡' |
| | | device.endRuntimeTime = currentTime |
| | | // 计ç®è¿è¡æ¶é¿ |
| | | if (device.startRuntimeTime) { |
| | | const startTime = new Date(device.startRuntimeTime) |
| | | const endTime = new Date(currentTime) |
| | | const duration = endTime - startTime |
| | | const hours = Math.floor(duration / (1000 * 60 * 60)) |
| | | const minutes = Math.floor((duration % (1000 * 60 * 60)) / (1000 * 60)) |
| | | device.runtimeDuration = `${hours}å°æ¶${minutes}åé` |
| | | } |
| | | } |
| | | const params = { |
| | | id: device.id, |
| | | status: device.status, |
| | | planRuntimeTime: device.planRuntimeTime, |
| | | startRuntimeTime: device.startRuntimeTime, |
| | | endRuntimeTime: device.endRuntimeTime, |
| | | runtimeDuration: device.runtimeDuration, |
| | | } |
| | | // è°ç¨APIæ´æ°è®¾å¤ç¶æ |
| | | const response = await editLedger(params) |
| | | if (response.code === 200) { |
| | | ElMessage.success(`${device.deviceName} ${status}æå`) |
| | | // å·æ°å表 |
| | | await getList() |
| | | } else { |
| | | ElMessage.error(response.msg || 'æä½å¤±è´¥') |
| | | } |
| | | } catch (error) { |
| | | console.error('æ´æ°è®¾å¤ç¶æå¤±è´¥:', error) |
| | | ElMessage.error('æä½å¤±è´¥') |
| | | } |
| | | } |
| | | |
| | | const getDeviceStatusType = (status) => { |
| | | if (status === 'è¿è¡ä¸') { |
| | | return 'success' |
| | | } else if (status === '忢è¿è¡') { |
| | | return 'danger' |
| | | } else { |
| | | return 'info' |
| | | } |
| | | } |
| | | |
| | | // è·åè¡¨æ ¼è¡çç±»å |
| | | const getRowClassName = ({ row }) => { |
| | | if (isOverdue(row)) { |
| | | return 'overdue-row' |
| | | } |
| | | return '' |
| | | } |
| | | |
| | | |
| | | |
| | | // ç»ä»¶æè½½æ¶åå§åæ°æ® |
| | | onMounted(() => { |
| | | getList() |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .app-container { |
| | | padding: 20px; |
| | | background: #f5f7fa; |
| | | min-height: 100vh; |
| | | } |
| | | |
| | | |
| | | .filter-section { |
| | | margin-bottom: 20px; |
| | | padding: 15px; |
| | | background: #fff; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
| | | display: flex; |
| | | justify-content: flex-start; |
| | | } |
| | | |
| | | .table-card { |
| | | margin-bottom: 20px; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | :deep(.el-card__header) { |
| | | background: #f8f9fa; |
| | | border-bottom: 1px solid #e9ecef; |
| | | font-weight: 500; |
| | | font-size: 16px; |
| | | } |
| | | |
| | | :deep(.el-table .el-table__header-wrapper th) { |
| | | background-color: #F0F1F5 !important; |
| | | color: #333333; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | :deep(.el-table .el-table__body-wrapper td) { |
| | | padding: 12px 0; |
| | | } |
| | | |
| | | :deep(.el-select) { |
| | | width: 100%; |
| | | } |
| | | |
| | | :deep(.el-tag) { |
| | | display: inline-flex; |
| | | align-items: center; |
| | | gap: 4px; |
| | | } |
| | | |
| | | /* è¶
æ¶æªå¯å¨è¡çæ ·å¼ */ |
| | | :deep(.overdue-row) { |
| | | background-color: #fef0f0 !important; |
| | | border-left: 4px solid #f56c6c; |
| | | } |
| | | |
| | | :deep(.overdue-row:hover) { |
| | | background-color: #fde2e2 !important; |
| | | } |
| | | |
| | | :deep(.overdue-row td) { |
| | | background-color: transparent !important; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr"> |
| | | <MaintainForm ref="maintainFormRef" /> |
| | | <template #footer> |
| | | <el-button type="primary" @click="sendForm" :loading="loading"> |
| | | {{ modalOptions.confirmText }} |
| | | </el-button> |
| | | <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | <FormDialog |
| | | v-model="visible" |
| | | :title="'设å¤ç»´ä¿®'" |
| | | width="500px" |
| | | @confirm="sendForm" |
| | | @cancel="handleCancel" |
| | | @close="handleClose" |
| | | > |
| | | <el-form :model="form" label-width="80px"> |
| | | <el-form-item label="维修人"> |
| | | <el-input v-model="form.maintenanceName" placeholder="请è¾å
¥ç»´ä¿®äºº" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç»´ä¿®ç»æ"> |
| | | <el-input v-model="form.maintenanceResult" placeholder="请è¾å
¥ç»´ä¿®ç»æ" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç»´ä¿®ç¶æ"> |
| | | <el-select v-model="form.status"> |
| | | <el-option label="å¾
æ¥ä¿®" :value="0"></el-option> |
| | | <el-option label="å®ç»" :value="1"></el-option> |
| | | <el-option label="失败" :value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç»´ä¿®æ¥æ"> |
| | | <el-date-picker |
| | | v-model="form.maintenanceTime" |
| | | placeholder="è¯·éæ©ç»´ä¿®æ¥æ" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="datetime" |
| | | clearable |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { useModal } from "@/hooks/useModal"; |
| | | import MaintainForm from "../Form/MaintainForm.vue"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { addMaintain } from "@/api/equipmentManagement/repair"; |
| | | import useFormData from "@/hooks/useFormData"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import dayjs from "dayjs"; |
| | | import { ElMessage } from "element-plus"; |
| | | |
| | | defineOptions({ |
| | | name: "ç»´ä¿®æ¨¡ææ¡", |
| | | }); |
| | | |
| | | const maintainFormRef = ref(); |
| | | const emits = defineEmits(["ok"]); |
| | | |
| | | const { |
| | | id, |
| | | visible, |
| | | loading, |
| | | openModal, |
| | | modalOptions, |
| | | handleConfirm, |
| | | closeModal, |
| | | } = useModal({ title: "设å¤ç»´ä¿®" }); |
| | | // ä¿åæ¥ä¿®è®°å½çid |
| | | const repairId = ref(); |
| | | const visible = ref(false); |
| | | const loading = ref(false); |
| | | |
| | | const userStore = useUserStore(); |
| | | const { form, resetForm } = useFormData({ |
| | | maintenanceName: undefined, // ç»´ä¿®åç§° |
| | | maintenanceResult: undefined, // ç»´ä¿®ç»æ |
| | | maintenanceTime: undefined, // ç»´ä¿®æ¥æ |
| | | status: 0, |
| | | }); |
| | | |
| | | const setForm = (data) => { |
| | | form.maintenanceName = data.maintenanceName ?? userStore.nickName; |
| | | form.maintenanceResult = data.maintenanceResult; |
| | | form.maintenanceTime = |
| | | data.maintenanceTime |
| | | ? dayjs(data.maintenanceTime).format("YYYY-MM-DD HH:mm:ss") |
| | | : dayjs().format("YYYY-MM-DD HH:mm:ss"); |
| | | form.status = 1; // é»è®¤ç¶æä¸ºå®ç» |
| | | }; |
| | | |
| | | const sendForm = async () => { |
| | | loading.value = true; |
| | | const form = await maintainFormRef.value.getForm(); |
| | | const { code } = await addMaintain({ id: id.value, ...form }); |
| | | if (code == 200) { |
| | | emits("ok"); |
| | | maintainFormRef.value.resetForm(); |
| | | closeModal(); |
| | | try { |
| | | const { code } = await addMaintain({ id: repairId.value, ...form }); |
| | | if (code == 200) { |
| | | ElMessage.success("ç»´ä¿®æå"); |
| | | emits("ok"); |
| | | resetForm(); |
| | | visible.value = false; |
| | | } |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | loading.value = false; |
| | | }; |
| | | |
| | | const handleCancel = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const open = async (id, row) => { |
| | | openModal(id); |
| | | repairId.value = id; // ä¿åæ¥ä¿®è®°å½çid |
| | | visible.value = true; |
| | | await nextTick(); |
| | | maintainFormRef.value.setForm(row); |
| | | setForm(row); |
| | | }; |
| | | |
| | | defineExpose({ |
| | |
| | | <template> |
| | | <el-dialog v-model="visible" :title="modalOptions.title" @close="close"> |
| | | <RepairForm ref="repairFormRef" /> |
| | | <template #footer> |
| | | <el-button type="primary" @click="sendForm" :loading="loading"> |
| | | {{ modalOptions.confirmText }} |
| | | </el-button> |
| | | <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | <FormDialog |
| | | v-model="visible" |
| | | :title="id ? 'ç¼è¾è®¾å¤æ¥ä¿®' : 'æ°å¢è®¾å¤æ¥ä¿®'" |
| | | width="800px" |
| | | @confirm="sendForm" |
| | | @cancel="handleCancel" |
| | | @close="handleClose" |
| | | > |
| | | <el-form :model="form" label-width="100px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设å¤åç§°"> |
| | | <el-select v-model="form.deviceLedgerId" @change="setDeviceModel" filterable> |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | | :key="index" |
| | | :label="item.deviceName" |
| | | :value="item.id" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§æ ¼åå·"> |
| | | <el-input |
| | | v-model="form.deviceModel" |
| | | placeholder="请è¾å
¥è§æ ¼åå·" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¥ä¿®æ¥æ"> |
| | | <el-date-picker |
| | | v-model="form.repairTime" |
| | | placeholder="è¯·éæ©æ¥ä¿®æ¥æ" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | type="date" |
| | | clearable |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¥ä¿®äºº"> |
| | | <el-input v-model="form.repairName" placeholder="请è¾å
¥æ¥ä¿®äºº" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row v-if="id"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¥ä¿®ç¶æ"> |
| | | <el-select v-model="form.status"> |
| | | <el-option label="å¾
ç»´ä¿®" :value="0"></el-option> |
| | | <el-option label="å®ç»" :value="1"></el-option> |
| | | <el-option label="失败" :value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="æ
éç°è±¡"> |
| | | <el-input |
| | | v-model="form.remark" |
| | | :rows="2" |
| | | type="textarea" |
| | | placeholder="请è¾å
¥æ
éç°è±¡" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { useModal } from "@/hooks/useModal"; |
| | | import RepairForm from "../Form/RepairForm.vue"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { |
| | | addRepair, |
| | | editRepair, |
| | | getRepairById, |
| | | } from "@/api/equipmentManagement/repair"; |
| | | import { ElMessage } from "element-plus"; |
| | | import dayjs from "dayjs"; |
| | | import useFormData from "@/hooks/useFormData"; |
| | | import { getDeviceLedger } from "@/api/equipmentManagement/ledger"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | |
| | | defineOptions({ |
| | | name: "è®¾å¤æ¥ä¿®å¼¹çª", |
| | |
| | | |
| | | const emits = defineEmits(["ok"]); |
| | | |
| | | const repairFormRef = ref(); |
| | | const { |
| | | id, |
| | | visible, |
| | | loading, |
| | | openModal, |
| | | modalOptions, |
| | | handleConfirm, |
| | | closeModal, |
| | | } = useModal({ title: "è®¾å¤æ¥ä¿®" }); |
| | | const id = ref(); |
| | | const visible = ref(false); |
| | | const loading = ref(false); |
| | | |
| | | const userStore = useUserStore(); |
| | | const deviceOptions = ref([]); |
| | | |
| | | const loadDeviceName = async () => { |
| | | const { data } = await getDeviceLedger(); |
| | | deviceOptions.value = data; |
| | | }; |
| | | |
| | | const { form, resetForm } = useFormData({ |
| | | deviceLedgerId: undefined, // 设å¤Id |
| | | deviceName: undefined, // 设å¤åç§° |
| | | deviceModel: undefined, // è§æ ¼åå· |
| | | repairTime: dayjs().format("YYYY-MM-DD"), // æ¥ä¿®æ¥æï¼é»è®¤å½å¤© |
| | | repairName: userStore.nickName, // æ¥ä¿®äºº |
| | | remark: undefined, // æ
éç°è±¡ |
| | | status: 0, // æ¥ä¿®ç¶æ |
| | | }); |
| | | |
| | | const setDeviceModel = (deviceId) => { |
| | | const option = deviceOptions.value.find((item) => item.id === deviceId); |
| | | form.deviceModel = option.deviceModel; |
| | | }; |
| | | |
| | | const setForm = (data) => { |
| | | form.deviceLedgerId = data.deviceLedgerId; |
| | | form.deviceName = data.deviceName; |
| | | form.deviceModel = data.deviceModel; |
| | | form.repairTime = data.repairTime; |
| | | form.repairName = data.repairName; |
| | | form.remark = data.remark; |
| | | form.status = data.status; |
| | | }; |
| | | |
| | | const sendForm = async () => { |
| | | loading.value = true; |
| | | const form = await repairFormRef.value.getForm(); |
| | | const { code } = id.value |
| | | ? await editRepair({ id: unref(id), ...form }) |
| | | : await addRepair(form); |
| | | if (code == 200) { |
| | | ElMessage.success(`${id ? "ç¼è¾" : "æ°å¢"}æ¥ä¿®æå`); |
| | | closeModal(); |
| | | emits("ok"); |
| | | try { |
| | | const { code } = id.value |
| | | ? await editRepair({ id: unref(id), ...form }) |
| | | : await addRepair(form); |
| | | if (code == 200) { |
| | | ElMessage.success(`${id.value ? "ç¼è¾" : "æ°å¢"}æ¥ä¿®æå`); |
| | | visible.value = false; |
| | | emits("ok"); |
| | | } |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | loading.value = false; |
| | | }; |
| | | |
| | | const handleCancel = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const openAdd = async () => { |
| | | openModal(); |
| | | id.value = undefined; |
| | | visible.value = true; |
| | | await nextTick(); |
| | | await repairFormRef.value.loadDeviceName(); |
| | | await loadDeviceName(); |
| | | }; |
| | | |
| | | const openEdit = async (id) => { |
| | | const { data } = await getRepairById(id); |
| | | openModal(id); |
| | | const openEdit = async (editId) => { |
| | | const { data } = await getRepairById(editId); |
| | | id.value = editId; |
| | | visible.value = true; |
| | | await nextTick(); |
| | | await repairFormRef.value.loadDeviceName(); |
| | | await repairFormRef.value.setForm(data); |
| | | }; |
| | | |
| | | const close = () => { |
| | | repairFormRef.value.resetForm(); |
| | | closeModal(); |
| | | await loadDeviceName(); |
| | | setForm(data); |
| | | }; |
| | | |
| | | defineExpose({ |
| | |
| | | openEdit, |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped></style> |
| | |
| | | <div class="actions"> |
| | | <el-text class="mx-1" size="large">è®¾å¤æ¥ä¿®</el-text> |
| | | <div> |
| | | <el-button |
| | | type="primary" |
| | | icon="Plus" |
| | | :disabled="multipleList.length !== 1" |
| | | @click="addMaintain" |
| | | > |
| | | æ°å¢ç»´ä¿® |
| | | </el-button> |
| | | <el-button type="success" icon="Van" @click="addRepair"> |
| | | æ°å¢æ¥ä¿® |
| | | </el-button> |
| | | <el-button @click="handleOut"> |
| | | å¯¼åº |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | icon="Delete" |
| | | :disabled="multipleList.length <= 0" |
| | | :disabled="multipleList.length <= 0 || hasFinishedStatus" |
| | | @click="delRepairByIds(multipleList.map((item) => item.id))" |
| | | > |
| | | æ¹éå é¤ |
| | |
| | | </div> |
| | | </div> |
| | | <PIMTable |
| | | rowKey="id" |
| | | isSelection |
| | | :column="columns" |
| | | :tableData="dataList" |
| | | :page="{ |
| | | rowKey="id" |
| | | isSelection |
| | | :column="columns" |
| | | :tableData="dataList" |
| | | :page="{ |
| | | current: pagination.currentPage, |
| | | size: pagination.pageSize, |
| | | total: pagination.total, |
| | | }" |
| | | @selection-change="handleSelectionChange" |
| | | @pagination="changePage" |
| | | @selection-change="handleSelectionChange" |
| | | @pagination="changePage" |
| | | > |
| | | <template #statusRef="{ row }"> |
| | | <el-tag v-if="row.status === 2" type="danger">失败</el-tag> |
| | | <el-tag v-if="row.status === 1" type="success">å®ç»</el-tag> |
| | | <el-tag v-if="row.status === 0" type="danger">å¾
ç»´ä¿®</el-tag> |
| | | <el-tag v-if="row.status === 0" type="warning">å¾
ç»´ä¿®</el-tag> |
| | | </template> |
| | | <template #operation="{ row }"> |
| | | <el-button |
| | | type="primary" |
| | | text |
| | | icon="editPen" |
| | | link |
| | | :disabled="row.status === 1" |
| | | @click="editRepair(row.id)" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | type="success" |
| | | link |
| | | :disabled="row.status === 1" |
| | | @click="addMaintain(row)" |
| | | > |
| | | ç»´ä¿® |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | text |
| | | icon="delete" |
| | | link |
| | | :disabled="row.status === 1" |
| | | @click="delRepairByIds(row.id)" |
| | | > |
| | | å é¤ |
| | |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | <RepairModal ref="repairModalRef" @ok="getTableData" /> |
| | | <MaintainModal ref="maintainModalRef" @ok="getTableData" /> |
| | | <RepairModal ref="repairModalRef" @ok="getTableData"/> |
| | | <MaintainModal ref="maintainModalRef" @ok="getTableData"/> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { usePaginationApi } from "@/hooks/usePaginationApi"; |
| | | import { getRepairPage, delRepair } from "@/api/equipmentManagement/repair"; |
| | | import { onMounted } from "vue"; |
| | | import { onMounted, getCurrentInstance, computed } from "vue"; |
| | | import {usePaginationApi} from "@/hooks/usePaginationApi"; |
| | | import {getRepairPage, delRepair} from "@/api/equipmentManagement/repair"; |
| | | import RepairModal from "./Modal/RepairModal.vue"; |
| | | import { ElMessageBox, ElMessage } from "element-plus"; |
| | | import {ElMessageBox, ElMessage} from "element-plus"; |
| | | import dayjs from "dayjs"; |
| | | import MaintainModal from "./Modal/MaintainModal.vue"; |
| | | import {Search} from "@element-plus/icons-vue"; |
| | |
| | | defineOptions({ |
| | | name: "è®¾å¤æ¥ä¿®", |
| | | }); |
| | | |
| | | const {proxy} = getCurrentInstance(); |
| | | |
| | | // æ¨¡ææ¡å®ä¾ |
| | | const repairModalRef = ref(); |
| | |
| | | resetFilters, |
| | | onCurrentChange, |
| | | } = usePaginationApi( |
| | | getRepairPage, |
| | | { |
| | | deviceName: undefined, |
| | | deviceModel: undefined, |
| | | remark: undefined, |
| | | maintenanceName: undefined, |
| | | repairTimeStr: undefined, |
| | | maintenanceTimeStr: undefined, |
| | | }, |
| | | [ |
| | | getRepairPage, |
| | | { |
| | | label: "设å¤åç§°", |
| | | align: "center", |
| | | prop: "deviceName", |
| | | deviceName: undefined, |
| | | deviceModel: undefined, |
| | | remark: undefined, |
| | | maintenanceName: undefined, |
| | | repairTimeStr: undefined, |
| | | maintenanceTimeStr: undefined, |
| | | }, |
| | | { |
| | | label: "è§æ ¼åå·", |
| | | align: "center", |
| | | prop: "deviceModel", |
| | | }, |
| | | { |
| | | label: "æ¥ä¿®æ¥æ", |
| | | align: "center", |
| | | prop: "repairTime", |
| | | formatData: (cell) => dayjs(cell).format("YYYY-MM-DD"), |
| | | }, |
| | | { |
| | | label: "æ¥ä¿®äºº", |
| | | align: "center", |
| | | prop: "repairName", |
| | | }, |
| | | { |
| | | label: "æ
éç°è±¡", |
| | | align: "center", |
| | | prop: "remark", |
| | | }, |
| | | { |
| | | label: "维修人", |
| | | align: "center", |
| | | prop: "maintenanceName", |
| | | }, |
| | | { |
| | | label: "ç»´ä¿®ç»æ", |
| | | align: "center", |
| | | prop: "maintenanceResult", |
| | | }, |
| | | { |
| | | label: "ç»´ä¿®æ¥æ", |
| | | align: "center", |
| | | prop: "maintenanceTime", |
| | | formatData: (cell) => (cell ? dayjs(cell).format("YYYY-MM-DD") : ""), |
| | | }, |
| | | { |
| | | label: "ç¶æ", |
| | | align: "center", |
| | | prop: "status", |
| | | dataType: "slot", |
| | | slot: "statusRef", |
| | | }, |
| | | { |
| | | fixed: "right", |
| | | label: "æä½", |
| | | dataType: "slot", |
| | | slot: "operation", |
| | | align: "center", |
| | | width: "200px", |
| | | }, |
| | | ] |
| | | [ |
| | | { |
| | | label: "设å¤åç§°", |
| | | align: "center", |
| | | prop: "deviceName", |
| | | }, |
| | | { |
| | | label: "è§æ ¼åå·", |
| | | align: "center", |
| | | prop: "deviceModel", |
| | | }, |
| | | { |
| | | label: "æ¥ä¿®æ¥æ", |
| | | align: "center", |
| | | prop: "repairTime", |
| | | formatData: (cell) => dayjs(cell).format("YYYY-MM-DD"), |
| | | }, |
| | | { |
| | | label: "æ¥ä¿®äºº", |
| | | align: "center", |
| | | prop: "repairName", |
| | | }, |
| | | { |
| | | label: "æ
éç°è±¡", |
| | | align: "center", |
| | | prop: "remark", |
| | | }, |
| | | { |
| | | label: "维修人", |
| | | align: "center", |
| | | prop: "maintenanceName", |
| | | }, |
| | | { |
| | | label: "ç»´ä¿®ç»æ", |
| | | align: "center", |
| | | prop: "maintenanceResult", |
| | | }, |
| | | { |
| | | label: "ç»´ä¿®æ¥æ", |
| | | align: "center", |
| | | prop: "maintenanceTime", |
| | | formatData: (cell) => (cell ? dayjs(cell).format("YYYY-MM-DD") : ""), |
| | | }, |
| | | { |
| | | label: "ç¶æ", |
| | | align: "center", |
| | | prop: "status", |
| | | dataType: "slot", |
| | | slot: "statusRef", |
| | | }, |
| | | { |
| | | fixed: "right", |
| | | label: "æä½", |
| | | dataType: "slot", |
| | | slot: "operation", |
| | | align: "center", |
| | | width: "300px", |
| | | }, |
| | | ] |
| | | ); |
| | | |
| | | // type === 1 ç»´ä¿® 2æ¥ä¿®é´ |
| | | const handleDateChange = (value,type) => { |
| | | const handleDateChange = (value, type) => { |
| | | filters.maintenanceTimeStr = null |
| | | filters.c = null |
| | | if(type === 1){ |
| | | if (type === 1) { |
| | | if (value) { |
| | | filters.maintenanceTimeStr = dayjs(value).format("YYYY-MM-DD"); |
| | | } |
| | | }else{ |
| | | } else { |
| | | if (value) { |
| | | filters.repairTimeStr = dayjs(value).format("YYYY-MM-DD"); |
| | | } |
| | |
| | | multipleList.value = selectionList; |
| | | }; |
| | | |
| | | // æ£æ¥éä¸çè®°å½ä¸æ¯å¦æå®ç»ç¶æç |
| | | const hasFinishedStatus = computed(() => { |
| | | return multipleList.value.some(item => item.status === 1) |
| | | }) |
| | | |
| | | // æ°å¢æ¥ä¿® |
| | | const addRepair = () => { |
| | | repairModalRef.value.openAdd(); |
| | |
| | | }; |
| | | |
| | | // æ°å¢ç»´ä¿® |
| | | const addMaintain = () => { |
| | | const row = multipleList.value[0]; |
| | | const addMaintain = (row) => { |
| | | maintainModalRef.value.open(row.id, row); |
| | | }; |
| | | |
| | | const changePage = ({ page, limit }) => { |
| | | pagination.currentPage = page; |
| | | pagination.pageSize = limit; |
| | | onCurrentChange(page); |
| | | const changePage = ({page, limit}) => { |
| | | pagination.currentPage = page; |
| | | pagination.pageSize = limit; |
| | | onCurrentChange(page); |
| | | }; |
| | | |
| | | // åè¡å é¤ |
| | | const delRepairByIds = async (ids) => { |
| | | // æ£æ¥æ¯å¦æå®ç»ç¶æçè®°å½ |
| | | const idsArray = Array.isArray(ids) ? ids : [ids]; |
| | | const hasFinished = idsArray.some(id => { |
| | | const record = dataList.value.find(item => item.id === id); |
| | | return record && record.status === 1; |
| | | }); |
| | | |
| | | if (hasFinished) { |
| | | ElMessage.warning('ä¸è½å é¤ç¶æä¸ºå®ç»çè®°å½'); |
| | | return; |
| | | } |
| | | |
| | | ElMessageBox.confirm("确认å 餿¥ä¿®æ°æ®, æ¤æä½ä¸å¯é?", "è¦å", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(async () => { |
| | | const { code } = await delRepair(ids); |
| | | const {code} = await delRepair(ids); |
| | | if (code === 200) { |
| | | ElMessage.success("å 餿å"); |
| | | getTableData(); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/device/repair/export", {}, "è®¾å¤æ¥ä¿®.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.info("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | |
| | | .table_list { |
| | | margin-top: unset; |
| | | } |
| | | |
| | | .actions { |
| | | display: flex; |
| | | justify-content: space-between; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="spare-part-category"> |
| | | <div class="search_form"> |
| | | <el-form :inline="true" :model="queryParams" class="search-form"> |
| | | <el-form-item label="å¤ä»¶åç§°"> |
| | | <el-input |
| | | v-model="queryParams.name" |
| | | placeholder="请è¾å
¥å¤ä»¶åç§°" |
| | | clearable |
| | | style="width: 240px" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="handleQuery">æ¥è¯¢</el-button> |
| | | <el-button @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div> |
| | | <el-button type="primary" @click="addCategory" >æ°å¢</el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="table_list"> |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="renderTableData" |
| | | style="width: 100%; margin-top: 10px;" |
| | | border |
| | | row-key="id" |
| | | > |
| | | <el-table-column prop="deviceNameStr" label="设å¤åç§°" width="300"></el-table-column> |
| | | <el-table-column prop="name" label="å¤ä»¶åç§°" width="200"></el-table-column> |
| | | <el-table-column prop="sparePartsNo" label="å¤ä»¶ç¼å·" width="200"></el-table-column> |
| | | <el-table-column prop="status" label="ç¶æ" width="100"> |
| | | <template #default="{ row }"> |
| | | <el-tag type="success" size="small">{{ row.status }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="price" label="ä»·æ ¼" width="140"></el-table-column> |
| | | <el-table-column prop="quantity" label="æ°é" width="140"></el-table-column> |
| | | <el-table-column prop="description" label="æè¿°" width="150"></el-table-column> |
| | | <el-table-column label="æä½" width="150" fixed="right" align="center"> |
| | | <template #default="{ row }"> |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | @click="() => editCategory(row)" |
| | | :disabled="loading" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | link |
| | | @click="() => deleteCategory(row.id)" |
| | | style="color: #f56c6c;" |
| | | :disabled="loading" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | <el-dialog title="å类管ç" v-model="dialogVisible" width="60%"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="100px"> |
| | | <el-form-item label="设å¤" prop="deviceLedgerIds"> |
| | | <el-select |
| | | v-model="form.deviceLedgerIds" |
| | | placeholder="è¯·éæ©è®¾å¤" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | multiple |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | | :key="index" |
| | | :label="item.deviceName" |
| | | :value="item.id" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å¤ä»¶åç§°" prop="name"> |
| | | <el-input v-model="form.name"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="å¤ä»¶ç¼å·" prop="sparePartsNo"> |
| | | <el-input v-model="form.sparePartsNo"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="æ°é" prop="quantity"> |
| | | <el-input type="number" v-model="form.quantity"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="form.status" placeholder="è¯·éæ©ç¶æ"> |
| | | <el-option label="æ£å¸¸" value="æ£å¸¸"></el-option> |
| | | <el-option label="ç¦ç¨" value="ç¦ç¨"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æè¿°" prop="description"> |
| | | <el-input v-model="form.description"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="ä»·æ ¼" prop="price"> |
| | | <el-input-number |
| | | v-model="form.price" |
| | | placeholder="请è¾å
¥ä»·æ ¼" |
| | | :min="0" |
| | | :step="0.01" |
| | | :precision="2" |
| | | style="width: 100%" |
| | | ></el-input-number> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="dialogVisible = false" :disabled="formLoading">åæ¶</el-button> |
| | | <el-button type="primary" @click="submitForm" :loading="formLoading">ç¡®å®</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, onMounted, reactive, watch } from 'vue'; |
| | | import { ElMessage, ElMessageBox } from 'element-plus'; |
| | | import { getSparePartsList, addSparePart, editSparePart, delSparePart } from "@/api/equipmentManagement/spareParts"; |
| | | import { getDeviceLedger } from "@/api/equipmentManagement/ledger"; |
| | | |
| | | // å è½½ç¶æ |
| | | const loading = ref(false); |
| | | const formLoading = ref(false); |
| | | // å¯¹è¯æ¡æ¾ç¤ºç¶æ |
| | | const dialogVisible = ref(false); |
| | | // ç¼è¾ ID |
| | | const editId = ref(null); |
| | | // è¡¨æ ¼æ°æ® |
| | | const categories = ref([]); |
| | | // 渲æç¨çè¡¨æ ¼æ°æ® |
| | | // const renderTableData = computed(() => buildTree(categories.value)); |
| | | const renderTableData = ref([]); |
| | | const operationType = ref('add') |
| | | // 设å¤é项 |
| | | const deviceOptions = ref([]); |
| | | // 表åå¼ç¨ |
| | | const formRef = ref(null); |
| | | // æ¥è¯¢åæ° |
| | | const queryParams = reactive({ |
| | | name: '' |
| | | }); |
| | | // è¡¨åæ°æ® |
| | | const form = reactive({ |
| | | id:'', |
| | | name: '', |
| | | sparePartsNo: '', |
| | | status: '', |
| | | description: '', |
| | | deviceLedgerIds: [], |
| | | price: null |
| | | }); |
| | | |
| | | // 表åéªè¯è§å |
| | | const rules = reactive({ |
| | | name: [ |
| | | { required: true, message: '请è¾å
¥å¤ä»¶åç§°', trigger: 'blur' } |
| | | ], |
| | | sparePartsNo: [ |
| | | { required: true, message: '请è¾å
¥å¤ä»¶ç¼å·', trigger: 'blur' } |
| | | ], |
| | | quantity:[ |
| | | { required: true, message: '请è¾å
¥æ°é', trigger: 'blur' } |
| | | ], |
| | | status: [ |
| | | { required: true, message: 'è¯·éæ©ç¶æ', trigger: 'change' } |
| | | ], |
| | | deviceLedgerIds: [ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©è®¾å¤', |
| | | trigger: 'change', |
| | | validator: (rule, value, callback) => { |
| | | if (operationType.value === 'add' && (!value || value.length === 0)) { |
| | | callback(new Error('è¯·éæ©è®¾å¤')); |
| | | } else { |
| | | callback(); |
| | | } |
| | | } |
| | | } |
| | | ] |
| | | }); |
| | | // è·å缩è¿é |
| | | const getIndentation = (row) => { |
| | | // è¿éç®åè¿å 20ï¼å¯æ ¹æ®å®é
éæ±å®ç°å±çº§ç¼©è¿é»è¾ |
| | | return 20; |
| | | }; |
| | | // å®ä¹ buildTree 彿° |
| | | const buildTree = (flatData) => { |
| | | const map = {}; |
| | | const result = []; |
| | | if(flatData){ |
| | | return result; |
| | | } |
| | | flatData.forEach(item => { |
| | | map[item.id] = { ...item, children: [] }; |
| | | }); |
| | | flatData.forEach(item => { |
| | | if (item.parentId === null || !map[item.parentId]) { |
| | | result.push(map[item.id]); |
| | | } else { |
| | | map[item.parentId].children.push(map[item.id]); |
| | | } |
| | | }); |
| | | return result; |
| | | }; |
| | | // è·ååè¡¨æ°æ® |
| | | const fetchListData = async () => { |
| | | loading.value = true; |
| | | try { |
| | | const params = {}; |
| | | if (queryParams.name) { |
| | | params.name = queryParams.name; |
| | | } |
| | | const res = await getSparePartsList(params); |
| | | if (res.code === 200) { |
| | | renderTableData.value = res.data.records || []; |
| | | categories.value = res.data.records || []; |
| | | } |
| | | } catch (error) { |
| | | loading.value = false; |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | } |
| | | |
| | | // æ¥è¯¢ |
| | | const handleQuery = () => { |
| | | fetchListData(); |
| | | } |
| | | |
| | | // éç½®æ¥è¯¢ |
| | | const resetQuery = () => { |
| | | queryParams.name = ''; |
| | | fetchListData(); |
| | | } |
| | | |
| | | // å 载设å¤å表ï¼å¨æå¼å¼¹æ¡æ¶è°ç¨ï¼ |
| | | const loadDeviceName = async () => { |
| | | try { |
| | | const { data } = await getDeviceLedger(); |
| | | deviceOptions.value = data || []; |
| | | } catch (error) { |
| | | ElMessage.error('è·å设å¤å表失败'); |
| | | } |
| | | }; |
| | | |
| | | // æ°å¢åç±» |
| | | const addCategory = async () => { |
| | | await loadDeviceName(); |
| | | form.id = ''; |
| | | form.name = ''; |
| | | form.sparePartsNo = ''; |
| | | form.status = ''; |
| | | form.description = ''; |
| | | form.deviceLedgerIds = []; |
| | | form.price = null; |
| | | operationType.value = 'add' |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // ç¼è¾åç±» |
| | | const editCategory = async (row) => { |
| | | await loadDeviceName(); |
| | | Object.assign(form, row); |
| | | // 妿å端è¿åçæ¯ deviceIds å符串ï¼éè¦è½¬æ¢ä¸ºæ°ç» |
| | | if (row.deviceIds && typeof row.deviceIds === 'string') { |
| | | // ç¡®ä¿IDç±»åä¸è®¾å¤é项ä¸çIDç±»åä¸è´ |
| | | const deviceIdsArray = row.deviceIds.split(',').map(id => id.trim()).filter(id => id); |
| | | // å¦æè®¾å¤é项ä¸çIDæ¯æ°åç±»åï¼å转æ¢ä¸ºæ°å |
| | | if (deviceOptions.value.length > 0 && typeof deviceOptions.value[0].id === 'number') { |
| | | form.deviceLedgerIds = deviceIdsArray.map(id => Number(id)).filter(id => !isNaN(id)); |
| | | } else { |
| | | form.deviceLedgerIds = deviceIdsArray; |
| | | } |
| | | } else if (row.deviceIds && Array.isArray(row.deviceIds)) { |
| | | form.deviceLedgerIds = row.deviceIds; |
| | | } else { |
| | | form.deviceLedgerIds = []; |
| | | } |
| | | operationType.value = 'edit' |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // å é¤åç±» |
| | | const deleteCategory = async (id) => { |
| | | try { |
| | | await ElMessageBox.confirm('æ¤æä½å°æ°¸ä¹
å é¤è¯¥åç±»ï¼æ¯å¦ç»§ç»?', 'æç¤º', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }); |
| | | loading.value = true; |
| | | const res = await delSparePart(id); |
| | | if (res.code === 200) { |
| | | ElMessage.success('å 餿å'); |
| | | fetchListData(); |
| | | } else { |
| | | ElMessage.error(res.message || 'å é¤å¤±è´¥'); |
| | | } |
| | | } catch (error) { |
| | | if (error !== 'cancel') { |
| | | ElMessage.error('å é¤å¤±è´¥'); |
| | | } |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }; |
| | | |
| | | // æäº¤è¡¨å |
| | | const submitForm = async () => { |
| | | if (!formRef.value) return; |
| | | try { |
| | | await formRef.value.validate(); |
| | | formLoading.value = true; |
| | | |
| | | // æå»ºæäº¤æ°æ® |
| | | const submitData = { |
| | | ...form, |
| | | deviceIds: form.deviceLedgerIds && form.deviceLedgerIds.length > 0 |
| | | ? form.deviceLedgerIds.join(',') |
| | | : '' |
| | | }; |
| | | |
| | | // å é¤ä¸éè¦çåæ®µ |
| | | delete submitData.deviceLedgerIds; |
| | | |
| | | if (operationType.value === 'edit') { |
| | | let res = await editSparePart(submitData); |
| | | if (res.code === 200) { |
| | | ElMessage.success('ç¼è¾æå'); |
| | | dialogVisible.value = false; |
| | | fetchListData(); |
| | | } |
| | | } else { |
| | | let res = await addSparePart(submitData); |
| | | if (res.code === 200) { |
| | | ElMessage.success('æ°å¢æå'); |
| | | dialogVisible.value = false; |
| | | fetchListData(); |
| | | } |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('请填å宿´è¡¨åä¿¡æ¯'); |
| | | } finally { |
| | | formLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | // ç»ä»¶æè½½æ¶è·ååè¡¨æ°æ® |
| | | onMounted(() => { |
| | | fetchListData(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .spare-part-category { |
| | | padding: 20px; |
| | | } |
| | | .search_form { |
| | | display: flex; |
| | | align-items: flex-start; |
| | | justify-content: space-between; |
| | | } |
| | | .table_list { |
| | | margin-top: unset; |
| | | } |
| | | |
| | | .el-table__header-wrapper th { |
| | | background-color: #f5f7fa; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .el-table__row:hover > td { |
| | | background-color: #fafafa; |
| | | } |
| | | |
| | | /* æé®ç»æ ·å¼ */ |
| | | .actions > div { |
| | | display: flex; |
| | | gap: 10px; |
| | | } |
| | | |
| | | /* ç¡®ä¿è¡¨æ ¼ä¸çæä½æé®ä¸ä¼è¢«æªæ */ |
| | | .el-table-column--fixed-right .el-button { |
| | | margin: 0 2px; |
| | | } |
| | | |
| | | /* æ å½¢èç¹å
å®¹æ ·å¼ */ |
| | | .nested-tree .el-tree-node__expand-icon { |
| | | font-size: 12px; |
| | | margin-right: 4px; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <FormDialog |
| | | v-model="visible" |
| | | :title="'设å¤ä¿å
»'" |
| | | width="500px" |
| | | @confirm="sendForm" |
| | | @cancel="handleCancel" |
| | | @close="handleClose" |
| | | > |
| | | <el-form :model="form" label-width="100px"> |
| | | <el-form-item label="å®é
ä¿å
»äºº"> |
| | | <el-input |
| | | v-model="form.maintenanceActuallyName" |
| | | placeholder="请è¾å
¥å®é
ä¿å
»äºº" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="å®é
ä¿å
»æ¥æ"> |
| | | <el-date-picker |
| | | v-model="form.maintenanceActuallyTime" |
| | | placeholder="è¯·éæ©å®é
ä¿å
»æ¥æ" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="datetime" |
| | | clearable |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ä¿å
»ç¶æ"> |
| | | <el-select v-model="form.status"> |
| | | <el-option label="å¾
ä¿å
»" :value="0"></el-option> |
| | | <el-option label="å®ç»" :value="1"></el-option> |
| | | <el-option label="失败" :value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ä¿å
ȍȾ"> |
| | | <el-input |
| | | v-model="form.maintenanceResult" |
| | | placeholder="请è¾å
¥ä¿å
ȍȾ" |
| | | type="text" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { addMaintenance } from "@/api/equipmentManagement/upkeep"; |
| | | import useFormData from "@/hooks/useFormData"; |
| | | import dayjs from "dayjs"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { ElMessage } from "element-plus"; |
| | | |
| | | defineOptions({ |
| | | name: "ä¿å
»æ¨¡ææ¡", |
| | | }); |
| | | |
| | | const emits = defineEmits(["ok"]); |
| | | |
| | | // ä¿å计åä¿å
»è®°å½çid |
| | | const planId = ref(); |
| | | const visible = ref(false); |
| | | const loading = ref(false); |
| | | const userStore = useUserStore(); |
| | | |
| | | const { form, resetForm } = useFormData({ |
| | | maintenanceActuallyName: undefined, // å®é
ä¿å
»äºº |
| | | maintenanceActuallyTime: undefined, // å®é
ä¿å
»æ¥æ |
| | | maintenanceResult: undefined, // ä¿å
ȍȾ |
| | | status: 0, // ä¿å
»ç¶æ |
| | | }); |
| | | |
| | | const setForm = (data) => { |
| | | form.maintenanceActuallyName = |
| | | data.maintenanceActuallyName ?? userStore.nickName; |
| | | form.maintenanceActuallyTime = |
| | | data.maintenanceActuallyTime |
| | | ? dayjs(data.maintenanceActuallyTime).format("YYYY-MM-DD HH:mm:ss") |
| | | : dayjs().format("YYYY-MM-DD HH:mm:ss"); |
| | | form.maintenanceResult = data.maintenanceResult; |
| | | form.status = 1; // é»è®¤ç¶æä¸ºå®ç» |
| | | }; |
| | | |
| | | /** |
| | | * @desc ä¿åä¿å
» |
| | | */ |
| | | const sendForm = async () => { |
| | | loading.value = true; |
| | | try { |
| | | const { code } = await addMaintenance({ id: planId.value, ...form }); |
| | | if (code == 200) { |
| | | ElMessage.success("ä¿å
»æå"); |
| | | emits("ok"); |
| | | resetForm(); |
| | | visible.value = false; |
| | | } |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const handleCancel = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const open = async (id, row) => { |
| | | planId.value = id; // ä¿å计åä¿å
»è®°å½çid |
| | | visible.value = true; |
| | | await nextTick(); |
| | | setForm(row); |
| | | }; |
| | | |
| | | defineExpose({ |
| | | open, |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped></style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <FormDialog |
| | | v-model="visible" |
| | | :title="id ? 'ç¼è¾è®¾å¤ä¿å
»è®¡å' : 'æ°å¢è®¾å¤ä¿å
»è®¡å'" |
| | | width="500px" |
| | | @confirm="sendForm" |
| | | @cancel="handleCancel" |
| | | @close="handleClose" |
| | | > |
| | | <el-form :model="form" label-width="100px"> |
| | | <el-form-item label="设å¤åç§°"> |
| | | <el-select |
| | | v-model="form.deviceLedgerId" |
| | | @change="setDeviceModel" |
| | | placeholder="è¯·éæ©è®¾å¤" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | > |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | | :key="index" |
| | | :label="item.deviceName" |
| | | :value="item.id" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="è§æ ¼åå·"> |
| | | <el-input |
| | | v-model="form.deviceModel" |
| | | placeholder="请è¾å
¥è§æ ¼åå·" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="å½å
¥äºº"> |
| | | <el-select |
| | | v-model="form.createUser" |
| | | placeholder="è¯·éæ©" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | | :key="item.userId" |
| | | :label="item.nickName" |
| | | :value="item.userId" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-if="id" label="ä¿ä¿®ç¶æ"> |
| | | <el-select v-model="form.status"> |
| | | <el-option label="å¾
ä¿ä¿®" :value="0"></el-option> |
| | | <el-option label="å®ç»" :value="1"></el-option> |
| | | <el-option label="失败" :value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="计åä¿å
»æ¥æ"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.maintenancePlanTime" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="date" |
| | | placeholder="è¯·éæ©è®¡åä¿å
»æ¥ææ¥æ" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { |
| | | addUpkeep, |
| | | editUpkeep, |
| | | getUpkeepById, |
| | | } from "@/api/equipmentManagement/upkeep"; |
| | | import { ElMessage } from "element-plus"; |
| | | import useFormData from "@/hooks/useFormData"; |
| | | import { getDeviceLedger } from "@/api/equipmentManagement/ledger"; |
| | | import { onMounted } from "vue"; |
| | | import dayjs from "dayjs"; |
| | | import { userListNoPage } from "@/api/system/user.js"; |
| | | |
| | | defineOptions({ |
| | | name: "设å¤ä¿å
»æ°å¢è®¡å", |
| | | }); |
| | | |
| | | const emits = defineEmits(["ok"]); |
| | | |
| | | const id = ref(); |
| | | const visible = ref(false); |
| | | const loading = ref(false); |
| | | |
| | | const deviceOptions = ref([]); |
| | | const loadDeviceName = async () => { |
| | | const { data } = await getDeviceLedger(); |
| | | deviceOptions.value = data; |
| | | }; |
| | | |
| | | const { form, resetForm } = useFormData({ |
| | | deviceLedgerId: undefined, // 设å¤Id |
| | | deviceName: undefined, // 设å¤åç§° |
| | | deviceModel: undefined, // è§æ ¼åå· |
| | | maintenancePlanTime: undefined, // 计åä¿å
»æ¥æ |
| | | createUser: undefined, // å½å
¥äºº |
| | | status: 0, //ä¿ä¿®ç¶æ |
| | | }); |
| | | |
| | | const setDeviceModel = (deviceId) => { |
| | | const option = deviceOptions.value.find((item) => item.id === deviceId); |
| | | form.deviceModel = option.deviceModel; |
| | | }; |
| | | |
| | | /** |
| | | * @desc 设置表åå
容 |
| | | * @param data 设å¤ä¿¡æ¯ |
| | | */ |
| | | const setForm = (data) => { |
| | | form.deviceLedgerId = data.deviceLedgerId; |
| | | form.deviceName = data.deviceName; |
| | | form.deviceModel = data.deviceModel; |
| | | form.createUser = Number(data.createUser); |
| | | form.status = data.status; |
| | | form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format( |
| | | "YYYY-MM-DD HH:mm:ss" |
| | | ); |
| | | }; |
| | | |
| | | // ç¨æ·å表 |
| | | const userList = ref([]); |
| | | |
| | | onMounted(() => { |
| | | loadDeviceName(); |
| | | userListNoPage().then((res) => { |
| | | userList.value = res.data; |
| | | }); |
| | | }); |
| | | |
| | | const openEdit = async (editId) => { |
| | | const { data } = await getUpkeepById(editId); |
| | | id.value = editId; |
| | | visible.value = true; |
| | | await nextTick(); |
| | | setForm(data); |
| | | }; |
| | | |
| | | const sendForm = async () => { |
| | | loading.value = true; |
| | | try { |
| | | const { code } = id.value |
| | | ? await editUpkeep({ id: unref(id), ...form }) |
| | | : await addUpkeep(form); |
| | | if (code == 200) { |
| | | ElMessage.success(`${id.value ? "ç¼è¾" : "æ°å¢"}计åæå`); |
| | | visible.value = false; |
| | | emits("ok"); |
| | | } |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const handleCancel = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | resetForm(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const openModal = () => { |
| | | id.value = undefined; |
| | | visible.value = true; |
| | | }; |
| | | |
| | | defineExpose({ |
| | | openModal, |
| | | openEdit, |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped></style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <FormDialog |
| | | v-model="dialogVisitable" |
| | | :title="operationType === 'add' ? 'æ°å¢ä¿å
»ä»»å¡' : 'ç¼è¾ä¿å
»ä»»å¡'" |
| | | width="800px" |
| | | :operation-type="operationType" |
| | | @confirm="submitForm" |
| | | @cancel="cancel" |
| | | @close="cancel" |
| | | > |
| | | <el-form ref="formRef" :model="form" :rules="rules" label-width="120px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设å¤åç§°" prop="taskId"> |
| | | <el-select v-model="form.taskId" @change="setDeviceModel" filterable> |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | | :key="index" |
| | | :label="item.deviceName" |
| | | :value="item.id" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§æ ¼åå·"> |
| | | <el-input |
| | | v-model="form.deviceModel" |
| | | placeholder="请è¾å
¥è§æ ¼åå·" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å½å
¥äºº" prop="inspector"> |
| | | <el-select |
| | | v-model="form.inspector" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | | :label="item.nickName" |
| | | :value="item.userId" |
| | | :key="item.userId" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»è®°æ¶é´" prop="registrationDate"> |
| | | <el-date-picker |
| | | v-model="form.registrationDate" |
| | | type="date" |
| | | placeholder="éæ©ç»è®°æ¥æ" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä»»å¡é¢ç" prop="frequencyType"> |
| | | <el-select v-model="form.frequencyType" placeholder="è¯·éæ©" clearable> |
| | | <el-option label="æ¯æ¥" value="DAILY"/> |
| | | <el-option label="æ¯å¨" value="WEEKLY"/> |
| | | <el-option label="æ¯æ" value="MONTHLY"/> |
| | | <el-option label="å£åº¦" value="QUARTERLY"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType"> |
| | | <el-form-item label="æ¥æ" prop="frequencyDetail"> |
| | | <el-time-picker v-model="form.frequencyDetail" placeholder="éæ©æ¶é´" format="HH:mm" |
| | | value-format="HH:mm" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType"> |
| | | <el-form-item label="æ¥æ" prop="frequencyDetail"> |
| | | <el-select v-model="form.week" placeholder="è¯·éæ©" clearable style="width: 50%"> |
| | | <el-option label="å¨ä¸" value="MON"/> |
| | | <el-option label="å¨äº" value="TUE"/> |
| | | <el-option label="å¨ä¸" value="WED"/> |
| | | <el-option label="å¨å" value="THU"/> |
| | | <el-option label="å¨äº" value="FRI"/> |
| | | <el-option label="å¨å
" value="SAT"/> |
| | | <el-option label="卿¥" value="SUN"/> |
| | | </el-select> |
| | | <el-time-picker v-model="form.time" placeholder="éæ©æ¶é´" format="HH:mm" |
| | | value-format="HH:mm" style="width: 50%"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType"> |
| | | <el-form-item label="æ¥æ" prop="frequencyDetail"> |
| | | <el-date-picker |
| | | v-model="form.frequencyDetail" |
| | | type="datetime" |
| | | clearable |
| | | placeholder="éæ©å¼å§æ¥æ" |
| | | format="DD,HH:mm" |
| | | value-format="DD,HH:mm" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType"> |
| | | <el-form-item label="æ¥æ" prop="frequencyDetail"> |
| | | <el-date-picker |
| | | v-model="form.frequencyDetail" |
| | | type="datetime" |
| | | clearable |
| | | placeholder="éæ©å¼å§æ¥æ" |
| | | format="MM,DD,HH:mm" |
| | | value-format="MM,DD,HH:mm" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="夿³¨" prop="remarks"> |
| | | <el-input v-model="form.remarks" placeholder="请è¾å
¥å¤æ³¨" type="textarea" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { reactive, ref, getCurrentInstance, toRefs } from "vue"; |
| | | import {userListNoPageByTenantId} from "@/api/system/user.js"; |
| | | import { getDeviceLedger } from "@/api/equipmentManagement/ledger"; |
| | | import { deviceMaintenanceTaskAdd, deviceMaintenanceTaskEdit } from "@/api/equipmentManagement/upkeep"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits() |
| | | const dialogVisitable = ref(false); |
| | | const operationType = ref('add'); |
| | | const deviceOptions = ref([]); |
| | | const userStore = useUserStore(); |
| | | const data = reactive({ |
| | | form: { |
| | | taskId: undefined, |
| | | taskName: undefined, |
| | | // å½å
¥äººï¼åéä¸ä¸ªç¨æ· id |
| | | inspector: undefined, |
| | | remarks: '', |
| | | frequencyType: '', |
| | | frequencyDetail: '', |
| | | week: '', |
| | | time: '', |
| | | deviceModel: undefined, // è§æ ¼åå· |
| | | registrationDate: '' |
| | | }, |
| | | rules: { |
| | | taskId: [{ required: true, message: "è¯·éæ©è®¾å¤", trigger: "change" },], |
| | | inspector: [{ required: true, message: "è¯·éæ©å½å
¥äºº", trigger: "blur" },], |
| | | registrationDate: [{ required: true, message: "è¯·éæ©ç»è®°æ¶é´", trigger: "change" }] |
| | | } |
| | | }) |
| | | const { form, rules } = toRefs(data) |
| | | const userList = ref([]) |
| | | |
| | | const loadDeviceName = async () => { |
| | | const { data } = await getDeviceLedger(); |
| | | deviceOptions.value = data; |
| | | }; |
| | | |
| | | // éæ©è®¾å¤æ¶ï¼å填设å¤åç§°(taskName)åè§æ ¼åå·(deviceModel) |
| | | const setDeviceModel = (id) => { |
| | | const option = deviceOptions.value.find((item) => item.id === id); |
| | | if (option) { |
| | | form.value.taskId = option.id; |
| | | form.value.taskName = option.deviceName; |
| | | form.value.deviceModel = option.deviceModel; |
| | | } |
| | | } |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = async (type, row) => { |
| | | dialogVisitable.value = true |
| | | operationType.value = type |
| | | |
| | | // é置表å |
| | | resetForm(); |
| | | |
| | | // å è½½ç¨æ·å表 |
| | | userListNoPageByTenantId().then((res) => { |
| | | userList.value = res.data; |
| | | }); |
| | | |
| | | // å 载设å¤å表 |
| | | await loadDeviceName(); |
| | | |
| | | if (type === 'edit' && row) { |
| | | form.value = { ...row } |
| | | // ç¼è¾æ¶ç¨æ¥å£è¿åç registrantId åæ¾å½å
¥äºº |
| | | if (row.registrantId) { |
| | | form.value.inspector = row.registrantId |
| | | } |
| | | |
| | | // 妿æè®¾å¤IDï¼èªå¨è®¾ç½®è®¾å¤ä¿¡æ¯ |
| | | if (form.value.taskId) { |
| | | setDeviceModel(form.value.taskId); |
| | | } |
| | | } else if (type === 'add') { |
| | | // æ°å¢æ¶è®¾ç½®ç»è®°æ¥æä¸ºå½å¤© |
| | | form.value.registrationDate = getCurrentDate(); |
| | | // æ°å¢æ¶è®¾ç½®å½å
¥äººä¸ºå½åç»å½è´¦æ· |
| | | form.value.inspector = userStore.id; |
| | | } |
| | | } |
| | | |
| | | // å
³éå¯¹è¯æ¡ |
| | | const cancel = () => { |
| | | resetForm() |
| | | dialogVisitable.value = false |
| | | emit('closeDia') |
| | | } |
| | | |
| | | // é置表å彿° |
| | | const resetForm = () => { |
| | | if (proxy.$refs.formRef) { |
| | | proxy.$refs.formRef.resetFields() |
| | | } |
| | | // éç½®è¡¨åæ°æ®ç¡®ä¿è®¾å¤ä¿¡æ¯æ£ç¡®éç½® |
| | | form.value = { |
| | | taskId: undefined, |
| | | taskName: undefined, |
| | | inspector: undefined, |
| | | inspector: undefined, |
| | | remarks: '', |
| | | frequencyType: '', |
| | | frequencyDetail: '', |
| | | week: '', |
| | | time: '', |
| | | deviceModel: undefined, |
| | | registrationDate: '' |
| | | } |
| | | } |
| | | |
| | | // æäº¤è¡¨å |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate(async valid => { |
| | | if (valid) { |
| | | try { |
| | | const payload = { ...form.value } |
| | | // ä¸åååç«¯ä¼ ä¿å
»äººå段ï¼ä»
ä½¿ç¨æ¥å£è¦æ±ç registrant / registrantId |
| | | // æ ¹æ®éæ©ç"å½å
¥äºº"设置 registrant / registrantId |
| | | if (payload.inspector) { |
| | | const selectedUser = userList.value.find( |
| | | (u) => String(u.userId) === String(payload.inspector) |
| | | ) |
| | | if (selectedUser) { |
| | | payload.registrantId = selectedUser.userId |
| | | payload.registrant = selectedUser.nickName |
| | | } |
| | | } |
| | | delete payload.inspector |
| | | delete payload.inspectorIds |
| | | |
| | | if (payload.frequencyType === 'WEEKLY') { |
| | | let frequencyDetail = '' |
| | | frequencyDetail = payload.week + ',' + payload.time |
| | | payload.frequencyDetail = frequencyDetail |
| | | } |
| | | |
| | | // å½å
¥æ¥æï¼ç´æ¥ä½¿ç¨è¡¨åéç registrationDate åæ®µ |
| | | // ä¸äºé»è®¤ç¶æå段 |
| | | if (payload.status === undefined || payload.status === null || payload.status === '') { |
| | | payload.status = '0' // é»è®¤ç¶æï¼å¯æå®é
æä¸¾è°æ´ |
| | | } |
| | | payload.active = true |
| | | payload.deleted = 0 |
| | | |
| | | if (operationType.value === 'edit') { |
| | | await deviceMaintenanceTaskEdit(payload) |
| | | } else { |
| | | await deviceMaintenanceTaskAdd(payload) |
| | | } |
| | | cancel() |
| | | proxy.$modal.msgSuccess('æäº¤æå') |
| | | } catch (error) { |
| | | proxy.$modal.msgError('æäº¤å¤±è´¥ï¼è¯·éè¯') |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | defineExpose({ openDialog }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="filters" :inline="true"> |
| | | <el-form-item label="设å¤åç§°"> |
| | | <el-input |
| | | v-model="filters.deviceName" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥è®¾å¤åç§°" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | @change="getTableData" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="计åä¿å
»æ¥æ"> |
| | | <el-date-picker |
| | | v-model="filters.maintenancePlanTime" |
| | | type="date" |
| | | placeholder="è¯·éæ©è®¡åä¿å
»æ¥æ" |
| | | size="default" |
| | | @change="(date) => handleDateChange(date,2)" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="å®é
ä¿å
»æ¥æ"> |
| | | <el-date-picker |
| | | v-model="filters.maintenanceActuallyTime" |
| | | type="date" |
| | | placeholder="è¯·éæ©å®é
ä¿å
»æ¥æ" |
| | | size="default" |
| | | @change="(date) => handleDateChange(date,1)" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="å®é
ä¿å
»äºº"> |
| | | <el-input |
| | | v-model="filters.maintenanceActuallyName" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥å®é
ä¿å
»äºº" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | @change="getTableData" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getTableData">æç´¢</el-button> |
| | | <el-button @click="resetFilters">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div class="table_list"> |
| | | <div class="actions"> |
| | | <el-text class="mx-1" size="large">设å¤ä¿å
»</el-text> |
| | | <div> |
| | | <el-button |
| | | type="primary" |
| | | icon="Plus" |
| | | :disabled="multipleList.length !== 1" |
| | | @click="addMaintain" |
| | | > |
| | | æ°å¢ä¿å
» |
| | | </el-button> |
| | | <el-button type="success" icon="Van" @click="addPlan"> |
| | | æ°å¢è®¡å |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | icon="Delete" |
| | | :disabled="multipleList.length <= 0" |
| | | @click="delRepairByIds(multipleList.map((item) => item.id))" |
| | | > |
| | | æ¹éå é¤ |
| | | </el-button> |
| | | <el-tabs v-model="activeTab" @tab-change="handleTabChange"> |
| | | <!-- 宿¶ä»»å¡ç®¡çtab --> |
| | | <el-tab-pane label="宿¶ä»»å¡ç®¡ç" name="scheduled"> |
| | | <div class="search_form"> |
| | | <el-form :model="scheduledFilters" :inline="true"> |
| | | <el-form-item label="ä»»å¡åç§°"> |
| | | <el-input |
| | | v-model="scheduledFilters.taskName" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥ä»»å¡åç§°" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | @change="getScheduledTableData" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ä»»å¡ç¶æ"> |
| | | <el-select v-model="scheduledFilters.status" placeholder="è¯·éæ©ä»»å¡ç¶æ" clearable style="width: 200px"> |
| | | <el-option label="å¯ç¨" value="1" /> |
| | | <el-option label="åç¨" value="0" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getScheduledTableData">æç´¢</el-button> |
| | | <el-button @click="resetScheduledFilters">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </div> |
| | | <PIMTable |
| | | <div class="table_list"> |
| | | <div class="actions"> |
| | | <el-text class="mx-1" size="large">宿¶ä»»å¡ç®¡ç</el-text> |
| | | <div> |
| | | <el-button type="primary" icon="Plus" @click="addScheduledTask"> |
| | | æ°å¢ä»»å¡ |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | icon="Delete" |
| | | :disabled="scheduledMultipleList.length <= 0" |
| | | @click="delScheduledTaskByIds(scheduledMultipleList.map((item) => item.id))" |
| | | > |
| | | æ¹éå é¤ |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | <PIMTable |
| | | rowKey="id" |
| | | isSelection |
| | | :column="scheduledColumns" |
| | | :tableData="scheduledDataList" |
| | | :page="{ |
| | | current: scheduledPagination.currentPage, |
| | | size: scheduledPagination.pageSize, |
| | | total: scheduledPagination.total, |
| | | }" |
| | | @selection-change="handleScheduledSelectionChange" |
| | | @pagination="changeScheduledPage" |
| | | > |
| | | <template #statusRef="{ row }"> |
| | | <el-tag v-if="row.status === 1" type="success">å¯ç¨</el-tag> |
| | | <el-tag v-if="row.status === 0" type="danger">åç¨</el-tag> |
| | | </template> |
| | | <template #operation="{ row }"> |
| | | <el-button |
| | | type="primary" |
| | | link |
| | | @click="editScheduledTask(row)" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | link |
| | | @click="delScheduledTaskByIds(row.id)" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | | <!-- ä»»å¡è®°å½tabï¼å设å¤ä¿å
»é¡µé¢ï¼ --> |
| | | <el-tab-pane label="ä»»å¡è®°å½" name="record"> |
| | | <div class="search_form"> |
| | | <el-form :model="filters" :inline="true"> |
| | | <el-form-item label="设å¤åç§°"> |
| | | <el-input |
| | | v-model="filters.deviceName" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥è®¾å¤åç§°" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | @change="getTableData" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="计åä¿å
»æ¥æ"> |
| | | <el-date-picker |
| | | v-model="filters.maintenancePlanTime" |
| | | type="date" |
| | | placeholder="è¯·éæ©è®¡åä¿å
»æ¥æ" |
| | | size="default" |
| | | @change="(date) => handleDateChange(date,2)" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="å®é
ä¿å
»æ¥æ"> |
| | | <el-date-picker |
| | | v-model="filters.maintenanceActuallyTime" |
| | | type="date" |
| | | placeholder="è¯·éæ©å®é
ä¿å
»æ¥æ" |
| | | size="default" |
| | | @change="(date) => handleDateChange(date,1)" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="å®é
ä¿å
»äºº"> |
| | | <el-input |
| | | v-model="filters.maintenanceActuallyName" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥å®é
ä¿å
»äºº" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | @change="getTableData" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getTableData">æç´¢</el-button> |
| | | <el-button @click="resetFilters">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | <div class="table_list"> |
| | | <div class="actions"> |
| | | <el-text class="mx-1" size="large">ä»»å¡è®°å½</el-text> |
| | | <div> |
| | | <el-button type="success" icon="Van" @click="addPlan"> |
| | | æ°å¢è®¡å |
| | | </el-button> |
| | | <el-button @click="handleOut"> |
| | | å¯¼åº |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | icon="Delete" |
| | | :disabled="multipleList.length <= 0 || hasFinishedStatus" |
| | | @click="delRepairByIds(multipleList.map((item) => item.id))" |
| | | > |
| | | æ¹éå é¤ |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | <PIMTable |
| | | rowKey="id" |
| | | isSelection |
| | | :column="columns" |
| | |
| | | @pagination="changePage" |
| | | > |
| | | <template #maintenanceResultRef="{ row }"> |
| | | <el-tag v-if="row.maintenanceResult === 1" type="success"> |
| | | å®å¥½ |
| | | </el-tag> |
| | | <el-tag v-if="row.maintenanceResult === 0" type="danger"> |
| | | ç»´ä¿® |
| | | </el-tag> |
| | | <div>{{ row.maintenanceResult || '-' }}</div> |
| | | </template> |
| | | <template #statusRef="{ row }"> |
| | | <el-tag v-if="row.status === 2" type="danger">失败</el-tag> |
| | | <el-tag v-if="row.status === 1" type="success">å®ç»</el-tag> |
| | | <el-tag v-if="row.status === 0" type="danger">å¾
ä¿å
»</el-tag> |
| | | <el-tag v-if="row.status === 0" type="warning">å¾
ä¿å
»</el-tag> |
| | | </template> |
| | | <template #operation="{ row }"> |
| | | <!-- è¿ä¸ªåè½è·æ°å¢ä¿å
»åè½ä¸æ¨¡ä¸æ ·ï¼æå¥æä¹ï¼ --> |
| | | <!-- <el-button |
| | | type="primary" |
| | | text |
| | | @click="addMaintain(row)" |
| | | > |
| | | æ°å¢ä¿å
» |
| | | </el-button> --> |
| | | <el-button |
| | | type="primary" |
| | | text |
| | | icon="editPen" |
| | | link |
| | | :disabled="row.status === 1" |
| | | @click="editPlan(row.id)" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | type="success" |
| | | link |
| | | :disabled="row.status === 1" |
| | | @click="addMaintain(row)" |
| | | > |
| | | ä¿å
» |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | text |
| | | icon="delete" |
| | | link |
| | | :disabled="row.status === 1" |
| | | @click="delRepairByIds(row.id)" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | <PlanModal ref="planModalRef" @ok="getTableData" /> |
| | | <MaintenanceModal ref="maintainModalRef" @ok="getTableData" /> |
| | | <MaintenanceModal ref="maintainModalRef" @ok="getTableData" /> |
| | | <FormDia ref="formDiaRef" @closeDia="getScheduledTableData" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { usePaginationApi } from "@/hooks/usePaginationApi"; |
| | | import { getUpkeepPage, delUpkeep } from "@/api/equipmentManagement/upkeep"; |
| | | import { onMounted } from "vue"; |
| | | import PlanModal from "./Modal/PlanModal.vue"; |
| | | import MaintenanceModal from "./Modal/MaintenanceModal.vue"; |
| | | import dayjs from "dayjs"; |
| | | import { ElMessageBox, ElMessage } from "element-plus"; |
| | | import {Search} from "@element-plus/icons-vue"; |
| | | import { ref, onMounted, reactive, getCurrentInstance, nextTick, computed } from 'vue' |
| | | import { Search } from '@element-plus/icons-vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | import PlanModal from './Form/PlanModal.vue' |
| | | import MaintenanceModal from './Form/MaintenanceModal.vue' |
| | | import FormDia from './Form/formDia.vue' |
| | | import { |
| | | getUpkeepPage, |
| | | delUpkeep, |
| | | deviceMaintenanceTaskList, |
| | | deviceMaintenanceTaskDel, |
| | | } from '@/api/equipmentManagement/upkeep' |
| | | import dayjs from 'dayjs' |
| | | |
| | | defineOptions({ |
| | | name: "设å¤ä¿å
»", |
| | | }); |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | // Tabç¸å
³ |
| | | const activeTab = ref('scheduled') |
| | | |
| | | // 计åå¼¹çªæ§å¶å¨ |
| | | const planModalRef = ref(); |
| | | const planModalRef = ref() |
| | | // ä¿å
»å¼¹çªæ§å¶å¨ |
| | | const maintainModalRef = ref(); |
| | | const maintainModalRef = ref() |
| | | // 宿¶ä»»å¡å¼¹çªæ§å¶å¨ |
| | | const formDiaRef = ref() |
| | | |
| | | // è¡¨æ ¼å¤éæ¡éä¸é¡¹ |
| | | const multipleList = ref([]); |
| | | // ä»»å¡è®°å½tabï¼å设å¤ä¿å
»é¡µé¢ï¼ç¸å
³åé |
| | | const filters = reactive({ |
| | | deviceName: '', |
| | | maintenancePlanTime: '', |
| | | maintenanceActuallyTime: '', |
| | | maintenanceActuallyName: '', |
| | | }) |
| | | |
| | | // å¤éååä»ä¹ |
| | | const handleSelectionChange = (selectionList) => { |
| | | multipleList.value = selectionList; |
| | | }; |
| | | const dataList = ref([]) |
| | | const pagination = ref({ |
| | | currentPage: 1, |
| | | pageSize: 10, |
| | | total: 0, |
| | | }) |
| | | const multipleList = ref([]) |
| | | |
| | | // è¡¨æ ¼é©å |
| | | const { |
| | | filters, |
| | | columns, |
| | | dataList, |
| | | pagination, |
| | | getTableData, |
| | | resetFilters, |
| | | onCurrentChange, |
| | | } = usePaginationApi(getUpkeepPage, { |
| | | deviceName: undefined, |
| | | maintenancePlanTime: undefined, |
| | | maintenanceActuallyTime: undefined, |
| | | maintenanceActuallyName: undefined, |
| | | }, [ |
| | | { |
| | | label: "设å¤åç§°", |
| | | align: "center", |
| | | prop: "deviceName", |
| | | }, |
| | | { |
| | | label: "è§æ ¼åå·", |
| | | align: "center", |
| | | prop: "deviceModel", |
| | | }, |
| | | { |
| | | label: "计åä¿å
»æ¥æ", |
| | | align: "center", |
| | | prop: "maintenancePlanTime", |
| | | formatData: (cell) => dayjs(cell).format("YYYY-MM-DD"), |
| | | }, |
| | | { |
| | | label: "å½å
¥äºº", |
| | | align: "center", |
| | | prop: "createUserName", |
| | | }, |
| | | { |
| | | label: "å½å
¥æ¥æ", |
| | | align: "center", |
| | | prop: "createTime", |
| | | formatData: (cell) => dayjs(cell).format("YYYY-MM-DD HH:mm:ss"), |
| | | width: 200, |
| | | }, |
| | | { |
| | | label: "å®é
ä¿å
»äºº", |
| | | align: "center", |
| | | prop: "maintenanceActuallyName", |
| | | }, |
| | | { |
| | | label: "å®é
ä¿å
»æ¥æ", |
| | | align: "center", |
| | | prop: "maintenanceActuallyTime", |
| | | formatData: (cell) => |
| | | cell ? dayjs(cell).format("YYYY-MM-DD HH:mm:ss") : "-", |
| | | }, |
| | | { |
| | | label: "ä¿å
ȍȾ", |
| | | align: "center", |
| | | prop: "maintenanceResult", |
| | | dataType: "slot", |
| | | slot: "maintenanceResultRef", |
| | | }, |
| | | { |
| | | label: "ç¶æ", |
| | | align: "center", |
| | | prop: "status", |
| | | dataType: "slot", |
| | | slot: "statusRef", |
| | | }, |
| | | { |
| | | fixed: "right", |
| | | label: "æä½", |
| | | dataType: "slot", |
| | | slot: "operation", |
| | | align: "center", |
| | | width: "200px", |
| | | }, |
| | | ]); |
| | | // type == 1å®é
ä¿å
»æ¶é´ 2计åä¿å
»æ¶é´ |
| | | const handleDateChange = (value,type) => { |
| | | filters.maintenanceActuallyTimeReq = null |
| | | filters.maintenancePlanTimeReq = null |
| | | if(type === 1){ |
| | | if (value) { |
| | | filters.maintenanceActuallyTimeReq = dayjs(value).format("YYYY-MM-DD"); |
| | | } |
| | | }else{ |
| | | if (value) { |
| | | filters.maintenancePlanTimeReq = dayjs(value).format("YYYY-MM-DD"); |
| | | } |
| | | // 宿¶ä»»å¡ç®¡çtabç¸å
³åé |
| | | const scheduledFilters = reactive({ |
| | | taskName: '', |
| | | status: '', |
| | | }) |
| | | |
| | | const scheduledDataList = ref([]) |
| | | const scheduledPagination = reactive({ |
| | | currentPage: 1, |
| | | pageSize: 10, |
| | | total: 0, |
| | | }) |
| | | const scheduledMultipleList = ref([]) |
| | | |
| | | // 宿¶ä»»å¡ç®¡çè¡¨æ ¼åé
ç½® |
| | | const scheduledColumns = ref([ |
| | | { prop: "taskName", label: "设å¤åç§°"}, |
| | | { |
| | | label: "è§æ ¼åå·", |
| | | prop: "deviceModel", |
| | | }, |
| | | { |
| | | prop: "frequencyType", |
| | | label: "颿¬¡", |
| | | minWidth: 150, |
| | | // PIMTable 使ç¨çæ¯ formatDataï¼è䏿¯ Element-Plus ç formatter |
| | | formatData: (cell) => ({ |
| | | DAILY: "æ¯æ¥", |
| | | WEEKLY: "æ¯å¨", |
| | | MONTHLY: "æ¯æ", |
| | | QUARTERLY: "å£åº¦" |
| | | }[cell] || "") |
| | | }, |
| | | { |
| | | prop: "frequencyDetail", |
| | | label: "å¼å§æ¥æä¸æ¶é´", |
| | | minWidth: 150, |
| | | // åæ ·æ¹ç¨ formatDataï¼PIMTable å
é¨ä¼æåå
æ ¼å¼ä¼ è¿æ¥ |
| | | formatData: (cell) => { |
| | | if (typeof cell !== 'string') return ''; |
| | | let val = cell; |
| | | const replacements = { |
| | | MON: 'å¨ä¸', |
| | | TUE: 'å¨äº', |
| | | WED: 'å¨ä¸', |
| | | THU: 'å¨å', |
| | | FRI: 'å¨äº', |
| | | SAT: 'å¨å
', |
| | | SUN: '卿¥' |
| | | }; |
| | | // ä½¿ç¨æ£å䏿¬¡æ§æ¿æ¢ææå¹é
项 |
| | | return val.replace(/MON|TUE|WED|THU|FRI|SAT|SUN/g, match => replacements[match]); |
| | | } |
| | | }, |
| | | { prop: "registrant", label: "ç»è®°äºº", minWidth: 100 }, |
| | | { prop: "registrationDate", label: "ç»è®°æ¥æ", minWidth: 100 }, |
| | | { |
| | | fixed: "right", |
| | | label: "æä½", |
| | | dataType: "slot", |
| | | slot: "operation", |
| | | align: "center", |
| | | width: "200px", |
| | | }, |
| | | ]) |
| | | |
| | | // ä»»å¡è®°å½è¡¨æ ¼åé
ç½®ï¼å设å¤ä¿å
»è¡¨æ ¼åï¼ |
| | | const columns = ref([ |
| | | { |
| | | label: "设å¤åç§°", |
| | | align: "center", |
| | | prop: "deviceName", |
| | | }, |
| | | { |
| | | label: "è§æ ¼åå·", |
| | | align: "center", |
| | | prop: "deviceModel", |
| | | }, |
| | | { |
| | | label: "计åä¿å
»æ¥æ", |
| | | align: "center", |
| | | prop: "maintenancePlanTime", |
| | | formatData: (cell) => dayjs(cell).format("YYYY-MM-DD"), |
| | | }, |
| | | { |
| | | label: "å½å
¥äºº", |
| | | align: "center", |
| | | prop: "createUserName", |
| | | }, |
| | | // { |
| | | // label: "å½å
¥æ¥æ", |
| | | // align: "center", |
| | | // prop: "createTime", |
| | | // formatData: (cell) => dayjs(cell).format("YYYY-MM-DD HH:mm:ss"), |
| | | // width: 200, |
| | | // }, |
| | | { |
| | | label: "å®é
ä¿å
»äºº", |
| | | align: "center", |
| | | prop: "maintenanceActuallyName", |
| | | }, |
| | | { |
| | | label: "å®é
ä¿å
»æ¥æ", |
| | | align: "center", |
| | | prop: "maintenanceActuallyTime", |
| | | formatData: (cell) => |
| | | cell ? dayjs(cell).format("YYYY-MM-DD HH:mm:ss") : "-", |
| | | }, |
| | | { |
| | | label: "ä¿å
ȍȾ", |
| | | align: "center", |
| | | prop: "maintenanceResult", |
| | | dataType: "slot", |
| | | slot: "maintenanceResultRef", |
| | | }, |
| | | { |
| | | label: "ç¶æ", |
| | | align: "center", |
| | | prop: "status", |
| | | dataType: "slot", |
| | | slot: "statusRef", |
| | | }, |
| | | { |
| | | fixed: "right", |
| | | label: "æä½", |
| | | dataType: "slot", |
| | | slot: "operation", |
| | | align: "center", |
| | | width: "300px", |
| | | }, |
| | | ]) |
| | | |
| | | // Tab忢å¤ç |
| | | const handleTabChange = (tabName) => { |
| | | if (tabName === 'record') { |
| | | getTableData() |
| | | } else if (tabName === 'scheduled') { |
| | | getScheduledTableData() |
| | | } |
| | | getTableData(); |
| | | }; |
| | | } |
| | | |
| | | // æ°å¢ä¿å
» |
| | | const addMaintain = () => { |
| | | const row = multipleList.value[0]; |
| | | maintainModalRef.value.open(row.id, row); |
| | | }; |
| | | |
| | | // æ°å¢è®¡å |
| | | const addPlan = () => { |
| | | planModalRef.value.openModal(); |
| | | }; |
| | | |
| | | // ç¼è¾è®¡å |
| | | const editPlan = (id) => { |
| | | planModalRef.value.openEdit(id); |
| | | }; |
| | | |
| | | const changePage = ({ page, limit }) => { |
| | | pagination.currentPage = page; |
| | | pagination.pageSize = limit; |
| | | onCurrentChange(page); |
| | | }; |
| | | |
| | | // åè¡å é¤ |
| | | const delRepairByIds = async (ids) => { |
| | | ElMessageBox.confirm("确认å 餿¥ä¿®æ°æ®, æ¤æä½ä¸å¯é?", "è¦å", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(async () => { |
| | | const { code } = await delUpkeep(ids); |
| | | if (code === 200) { |
| | | ElMessage.success("å 餿å"); |
| | | getTableData(); |
| | | // 宿¶ä»»å¡ç®¡çç¸å
³æ¹æ³ |
| | | const getScheduledTableData = async () => { |
| | | try { |
| | | const params = { |
| | | current: scheduledPagination.currentPage, |
| | | size: scheduledPagination.pageSize, |
| | | taskName: scheduledFilters.taskName || undefined, |
| | | status: scheduledFilters.status || undefined, |
| | | } |
| | | }); |
| | | }; |
| | | const { code, data } = await deviceMaintenanceTaskList(params) |
| | | if (code === 200) { |
| | | scheduledDataList.value = data?.records || [] |
| | | scheduledPagination.total = data?.total || 0 |
| | | } |
| | | } catch (error) { |
| | | ElMessage.error('è·å宿¶ä»»å¡å表失败') |
| | | } |
| | | } |
| | | |
| | | const resetScheduledFilters = () => { |
| | | scheduledFilters.taskName = '' |
| | | scheduledFilters.status = '' |
| | | getScheduledTableData() |
| | | } |
| | | |
| | | const handleScheduledSelectionChange = (selection) => { |
| | | scheduledMultipleList.value = selection |
| | | } |
| | | |
| | | const changeScheduledPage = (page) => { |
| | | scheduledPagination.currentPage = page.page |
| | | scheduledPagination.pageSize = page.limit |
| | | getScheduledTableData() |
| | | } |
| | | |
| | | const addScheduledTask = () => { |
| | | nextTick(() => { |
| | | formDiaRef.value?.openDialog('add'); |
| | | }); |
| | | } |
| | | |
| | | const editScheduledTask = (row) => { |
| | | if (row) { |
| | | nextTick(() => { |
| | | formDiaRef.value?.openDialog('edit', row); |
| | | }); |
| | | } |
| | | } |
| | | |
| | | const delScheduledTaskByIds = async (ids) => { |
| | | try { |
| | | await ElMessageBox.confirm('ç¡®å®å é¤éä¸ç宿¶ä»»å¡åï¼', 'æç¤º', { |
| | | type: 'warning', |
| | | }) |
| | | const payload = Array.isArray(ids) ? ids : [ids] |
| | | await deviceMaintenanceTaskDel(payload) |
| | | ElMessage.success('å é¤å®æ¶ä»»å¡æå') |
| | | getScheduledTableData() |
| | | } catch (error) { |
| | | // ç¨æ·åæ¶å é¤ |
| | | } |
| | | } |
| | | |
| | | const handleScheduledOut = () => { |
| | | ElMessage.info('导åºå®æ¶ä»»å¡åè½å¾
å®ç°') |
| | | } |
| | | |
| | | // ä»»å¡è®°å½ç¸å
³æ¹æ³ï¼å设å¤ä¿å
»é¡µé¢æ¹æ³ï¼ |
| | | const getTableData = async () => { |
| | | try { |
| | | const params = { |
| | | current: pagination.value.currentPage, |
| | | size: pagination.value.pageSize, |
| | | deviceName: filters.deviceName || undefined, |
| | | maintenancePlanTime: filters.maintenancePlanTime ? dayjs(filters.maintenancePlanTime).format('YYYY-MM-DD') : undefined, |
| | | maintenanceActuallyTime: filters.maintenanceActuallyTime ? dayjs(filters.maintenanceActuallyTime).format('YYYY-MM-DD') : undefined, |
| | | maintenanceActuallyName: filters.maintenanceActuallyName || undefined, |
| | | } |
| | | |
| | | const { code, data } = await getUpkeepPage(params) |
| | | if (code === 200) { |
| | | dataList.value = data.records |
| | | pagination.value.total = data.total |
| | | } |
| | | } catch (error) { |
| | | console.log(error); |
| | | |
| | | } |
| | | } |
| | | |
| | | const resetFilters = () => { |
| | | filters.deviceName = '' |
| | | filters.maintenancePlanTime = '' |
| | | filters.maintenanceActuallyTime = '' |
| | | filters.maintenanceActuallyName = '' |
| | | getTableData() |
| | | } |
| | | |
| | | const handleSelectionChange = (selection) => { |
| | | multipleList.value = selection |
| | | } |
| | | |
| | | // æ£æ¥éä¸çè®°å½ä¸æ¯å¦æå®ç»ç¶æç |
| | | const hasFinishedStatus = computed(() => { |
| | | return multipleList.value.some(item => item.status === 1) |
| | | }) |
| | | |
| | | const changePage = (page) => { |
| | | pagination.value.currentPage = page.page |
| | | pagination.value.pageSize = page.limit |
| | | getTableData() |
| | | } |
| | | |
| | | const addMaintain = (row) => { |
| | | maintainModalRef.value.open(row.id, row) |
| | | } |
| | | |
| | | const addPlan = () => { |
| | | planModalRef.value.openModal() |
| | | } |
| | | |
| | | const editPlan = (id) => { |
| | | planModalRef.value.openEdit(id) |
| | | } |
| | | |
| | | const delRepairByIds = async (ids) => { |
| | | // æ£æ¥æ¯å¦æå®ç»ç¶æçè®°å½ |
| | | const hasFinished = multipleList.value.some(item => item.status === 1) |
| | | if (hasFinished) { |
| | | ElMessage.warning('ä¸è½å é¤ç¶æä¸ºå®ç»çè®°å½') |
| | | return |
| | | } |
| | | |
| | | try { |
| | | await ElMessageBox.confirm('确认å é¤ä¿å
»æ°æ®, æ¤æä½ä¸å¯é?', 'è¦å', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning', |
| | | }) |
| | | |
| | | const { code } = await delUpkeep(ids) |
| | | if (code === 200) { |
| | | ElMessage.success('å 餿å') |
| | | getTableData() |
| | | } |
| | | } catch (error) { |
| | | // ç¨æ·åæ¶å é¤ |
| | | } |
| | | } |
| | | |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm('éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼', '导åº', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | proxy.download('/device/maintenance/export', {}, '设å¤ä¿å
».xlsx') |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.info('已忶') |
| | | }) |
| | | } |
| | | |
| | | const handleDateChange = (date, type) => { |
| | | if (type === 1) { |
| | | filters.maintenanceActuallyTime = date ? dayjs(date).format('YYYY-MM-DD') : '' |
| | | } else { |
| | | filters.maintenancePlanTime = date ? dayjs(date).format('YYYY-MM-DD') : '' |
| | | } |
| | | getTableData() |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getTableData(); |
| | | }); |
| | | // æ ¹æ®é»è®¤æ¿æ´»ç Tab è°ç¨å¯¹åºçæ¥è¯¢æ¥å£ |
| | | if (activeTab.value === 'scheduled') { |
| | | getScheduledTableData() |
| | | } else { |
| | | getTableData() |
| | | } |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | margin-bottom: 10px; |
| | | } |
| | | </style> |
| | | |
| | | |
| | | |
| | | |
| | | |
| src/views/example/DynamicTableExample.vue
src/views/example/SimpleExample.vue
src/views/fileManagement/bookshelf/detail.vue
src/views/fileManagement/bookshelf/index.vue
src/views/fileManagement/borrow/index.vue
src/views/fileManagement/document/attachmentManager.vue
src/views/fileManagement/document/index.vue
src/views/fileManagement/return/index.vue
src/views/fileManagement/statistics/index.vue
src/views/financialManagement/accounting/index.vue
src/views/financialManagement/expenseManagement/Form.vue (已删除)
src/views/financialManagement/expenseManagement/Modal.vue
src/views/financialManagement/expenseManagement/index.vue
src/views/financialManagement/financialStatements/index.vue
src/views/financialManagement/inventoryAccounting/index.vue
src/views/financialManagement/loanManagement/Modal.vue
src/views/financialManagement/loanManagement/index.vue
src/views/financialManagement/revenueManagement/Form.vue (已删除)
src/views/financialManagement/revenueManagement/Modal.vue
src/views/financialManagement/revenueManagement/index.vue
src/views/index.vue
src/views/inventoryManagement/dispatchLog/Record.vue
src/views/inventoryManagement/dispatchLog/index.vue
src/views/inventoryManagement/issueManagement/index.vue
src/views/inventoryManagement/receiptManagement/Record.vue
src/views/inventoryManagement/receiptManagement/index.vue
src/views/inventoryManagement/stockManagement/New.vue
src/views/inventoryManagement/stockManagement/Qualified.vue
src/views/inventoryManagement/stockManagement/Subtract.vue
src/views/inventoryManagement/stockManagement/Unqualified.vue
src/views/inventoryManagement/stockManagement/index.vue
src/views/inventoryManagement/stockReport/index.vue
src/views/lavorissue/ledger/Form.vue
src/views/lavorissue/ledger/Modal.vue
src/views/lavorissue/ledger/filesDia.vue
src/views/lavorissue/ledger/index.vue
src/views/lavorissue/statistics/index.vue
src/views/login.vue
src/views/monitorManagement/areaControl/index.vue
src/views/monitorManagement/videoMonitor/index.vue
src/views/oaSystem/projectManagement/components/milestoneList.vue
src/views/oaSystem/projectManagement/components/phaseGoalList.vue
src/views/oaSystem/projectManagement/components/projectForm.vue
src/views/oaSystem/projectManagement/components/taskTree.vue
src/views/oaSystem/projectManagement/index.vue
src/views/oaSystem/projectManagement/projectDetail.vue
src/views/personnelManagement/analytics/index.vue
src/views/personnelManagement/contractManagement/components/formDia.vue
src/views/personnelManagement/contractManagement/filesDia.vue
src/views/personnelManagement/contractManagement/index.vue
src/views/personnelManagement/dimission/components/formDia.vue
src/views/personnelManagement/dimission/index.vue
src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
src/views/personnelManagement/employeeRecord/components/RenewContract.vue
src/views/personnelManagement/employeeRecord/components/Show.vue
src/views/personnelManagement/employeeRecord/components/formDia.vue (已删除)
src/views/personnelManagement/employeeRecord/index.vue
src/views/personnelManagement/onboarding/components/formDia.vue (已删除)
src/views/personnelManagement/onboarding/index.vue (已删除)
src/views/personnelManagement/payrollManagement/components/formDia.vue
src/views/personnelManagement/payrollManagement/index.vue
src/views/personnelManagement/scheduling/index.vue
src/views/personnelManagement/selfService/index.vue
src/views/procurementManagement/advancedPriceManagement/index.vue
src/views/procurementManagement/arrivalManagement/index.vue
src/views/procurementManagement/index.vue
src/views/procurementManagement/invoiceEntry/components/Modal.vue
src/views/procurementManagement/invoiceEntry/index.vue
src/views/procurementManagement/invoiceEntry/indexOld.vue (已删除)
src/views/procurementManagement/paymentEntry/index.vue
src/views/procurementManagement/paymentHistory/index.vue
src/views/procurementManagement/paymentLedger/index.vue
src/views/procurementManagement/priceManagement/index.vue
src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue
src/views/procurementManagement/procurementInvoiceLedger/Modal/EditModal.vue
src/views/procurementManagement/procurementInvoiceLedger/index.vue
src/views/procurementManagement/procurementLedger/index.vue
src/views/procurementManagement/procurementPlan/index.vue
src/views/procurementManagement/procurementReport/index.vue
src/views/procurementManagement/purchaseOrder/index.vue
src/views/procurementManagement/qualityInspection/index.vue
src/views/procurementManagement/returnManagement/index.vue
src/views/procurementManagement/transferManagement/index.vue
src/views/productManagement/productIdentifier/index.vue
src/views/productionManagement/operationScheduling/components/formDia.vue
src/views/productionManagement/operationScheduling/index.vue
src/views/productionManagement/processRoute/Edit.vue
src/views/productionManagement/processRoute/ItemsForm.vue
src/views/productionManagement/processRoute/New.vue
src/views/productionManagement/processRoute/index.vue
src/views/productionManagement/processRoute/processRouteItem/index.vue
src/views/productionManagement/productStructure/Detail/index.vue
src/views/productionManagement/productStructure/StructureEdit.vue
src/views/productionManagement/productStructure/index.vue
src/views/productionManagement/productionCosting/index.vue
src/views/productionManagement/productionDispatching/components/autoDispatchDia.vue
src/views/productionManagement/productionDispatching/components/formDia.vue
src/views/productionManagement/productionDispatching/index.vue
src/views/productionManagement/productionOrder/index.vue
src/views/productionManagement/productionProcess/Edit.vue
src/views/productionManagement/productionProcess/New.vue
src/views/productionManagement/productionProcess/index.vue
src/views/productionManagement/productionReporting/Input.vue
src/views/productionManagement/productionReporting/Output.vue
src/views/productionManagement/productionReporting/components/formDia.vue
src/views/productionManagement/productionReporting/index.vue
src/views/productionManagement/safetyMonitoring/index.vue
src/views/productionManagement/workOrder/index.vue
src/views/qualityManagement/finalInspection/components/filesDia.vue
src/views/qualityManagement/finalInspection/components/formDia.vue
src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue
src/views/qualityManagement/finalInspection/index.vue
src/views/qualityManagement/metricBinding/index.vue
src/views/qualityManagement/metricMaintenance/ParamFormDialog.vue
src/views/qualityManagement/metricMaintenance/StandardFormDialog.vue
src/views/qualityManagement/metricMaintenance/index.vue
src/views/qualityManagement/metricMaintenance/index0.vue
src/views/qualityManagement/nearExpiryReturn/index.vue
src/views/qualityManagement/nonconformingManagement/components/formDia.vue
src/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue
src/views/qualityManagement/nonconformingManagement/index.vue
src/views/qualityManagement/processInspection/components/formDia.vue
src/views/qualityManagement/processInspection/components/inspectionFormDia.vue
src/views/qualityManagement/processInspection/index.vue
src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue
src/views/qualityManagement/rawMaterialInspection/index.vue
src/views/qualityManagement/visualization/qualityDashboard.vue
src/views/reportAnalysis/dataDashboard/index.vue
src/views/reportAnalysis/projectProfit/index.vue
src/views/reportAnalysis/reportManagement.vue
src/views/reportAnalysis/reportManagement/index.vue
src/views/reportAnalysis/taxComparison/index.vue
src/views/salesManagement/customerManagement/index.vue
src/views/salesManagement/deliveryLedger/index.vue
src/views/salesManagement/indicatorStats/index.vue
src/views/salesManagement/invoiceLedger/index.vue
src/views/salesManagement/invoiceRegistration/index.vue
src/views/salesManagement/orderManagement/index.vue
src/views/salesManagement/paymentShipping/index.vue
src/views/salesManagement/receiptPayment/index.vue
src/views/salesManagement/receiptPaymentHistory/index.vue
src/views/salesManagement/receiptPaymentLedger/index.vue
src/views/salesManagement/salesLedger/index.vue
src/views/salesManagement/salesQuotation/index.vue
src/views/salesManagement/salespersonManagement/index.vue
src/views/salesManagement/strategyControl/index.vue
src/views/system/dept/index.vue
src/views/system/user/index.vue |