添加后台启动脚本和修改域名
This commit is contained in:
457
admin-system/package-lock.json
generated
457
admin-system/package-lock.json
generated
@@ -19,6 +19,7 @@
|
||||
"moment": "^2.29.4",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.1.7",
|
||||
"qrcode": "^1.5.4",
|
||||
"vue": "^3.4.15",
|
||||
"vue-router": "^4.2.5",
|
||||
"xlsx": "^0.18.5"
|
||||
@@ -1464,7 +1465,6 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -1473,7 +1473,6 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
@@ -1672,6 +1671,15 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/cfb": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/cfb/-/cfb-1.2.2.tgz",
|
||||
@@ -1730,6 +1738,51 @@
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cliui/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/wrap-ansi": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/codepage": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmmirror.com/codepage/-/codepage-1.15.0.tgz",
|
||||
@@ -1742,7 +1795,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
@@ -1753,8 +1805,7 @@
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
@@ -1876,6 +1927,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/deep-eql": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/deep-eql/-/deep-eql-4.1.4.tgz",
|
||||
@@ -1957,6 +2017,12 @@
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dijkstrajs": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
|
||||
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dir-glob": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||
@@ -2614,6 +2680,15 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
},
|
||||
"node_modules/get-func-name": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/get-func-name/-/get-func-name-2.0.2.tgz",
|
||||
@@ -2926,7 +3001,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -3548,6 +3622,15 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz",
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/package-json-from-dist": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
|
||||
@@ -3576,7 +3659,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
|
||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -3694,6 +3776,15 @@
|
||||
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/pngjs": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz",
|
||||
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.6",
|
||||
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz",
|
||||
@@ -3783,6 +3874,23 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.4.tgz",
|
||||
"integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dijkstrajs": "^1.0.1",
|
||||
"pngjs": "^5.0.0",
|
||||
"yargs": "^15.3.1"
|
||||
},
|
||||
"bin": {
|
||||
"qrcode": "bin/qrcode"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
@@ -3809,6 +3917,21 @@
|
||||
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/require-main-filename": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/resize-observer-polyfill": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||
@@ -4017,6 +4140,12 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/shallow-equal": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/shallow-equal/-/shallow-equal-1.2.1.tgz",
|
||||
@@ -4193,7 +4322,6 @@
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
@@ -4855,6 +4983,12 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/which-module": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/which-module/-/which-module-2.0.1.tgz",
|
||||
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/why-is-node-running": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
|
||||
@@ -5025,6 +5159,119 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/y18n/-/y18n-4.0.3.tgz",
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^18.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/yargs/node_modules/find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
|
||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-locate": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-try": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/p-locate": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-limit": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
@@ -5987,14 +6234,12 @@
|
||||
"ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
@@ -6147,6 +6392,11 @@
|
||||
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
|
||||
"dev": true
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
|
||||
},
|
||||
"cfb": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/cfb/-/cfb-1.2.2.tgz",
|
||||
@@ -6190,6 +6440,43 @@
|
||||
"get-func-name": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"codepage": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmmirror.com/codepage/-/codepage-1.15.0.tgz",
|
||||
@@ -6199,7 +6486,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
@@ -6207,8 +6493,7 @@
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
@@ -6299,6 +6584,11 @@
|
||||
"ms": "^2.1.3"
|
||||
}
|
||||
},
|
||||
"decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
|
||||
},
|
||||
"deep-eql": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/deep-eql/-/deep-eql-4.1.4.tgz",
|
||||
@@ -6353,6 +6643,11 @@
|
||||
"integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
|
||||
"dev": true
|
||||
},
|
||||
"dijkstrajs": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
|
||||
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
|
||||
},
|
||||
"dir-glob": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||
@@ -6847,6 +7142,11 @@
|
||||
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
|
||||
},
|
||||
"get-func-name": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/get-func-name/-/get-func-name-2.0.2.tgz",
|
||||
@@ -7060,8 +7360,7 @@
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
},
|
||||
"is-glob": {
|
||||
"version": "4.0.3",
|
||||
@@ -7516,6 +7815,11 @@
|
||||
"p-limit": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz",
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
|
||||
},
|
||||
"package-json-from-dist": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
|
||||
@@ -7540,8 +7844,7 @@
|
||||
"path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
|
||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
@@ -7622,6 +7925,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"pngjs": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz",
|
||||
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw=="
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.5.6",
|
||||
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz",
|
||||
@@ -7678,6 +7986,16 @@
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||
"dev": true
|
||||
},
|
||||
"qrcode": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.4.tgz",
|
||||
"integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
|
||||
"requires": {
|
||||
"dijkstrajs": "^1.0.1",
|
||||
"pngjs": "^5.0.0",
|
||||
"yargs": "^15.3.1"
|
||||
}
|
||||
},
|
||||
"queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
@@ -7690,6 +8008,16 @@
|
||||
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
|
||||
"dev": true
|
||||
},
|
||||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
|
||||
},
|
||||
"require-main-filename": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
|
||||
},
|
||||
"resize-observer-polyfill": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||
@@ -7824,6 +8152,11 @@
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"dev": true
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
|
||||
},
|
||||
"shallow-equal": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/shallow-equal/-/shallow-equal-1.2.1.tgz",
|
||||
@@ -7955,7 +8288,6 @@
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
}
|
||||
@@ -8365,6 +8697,11 @@
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"which-module": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/which-module/-/which-module-2.0.1.tgz",
|
||||
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
|
||||
},
|
||||
"why-is-node-running": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
|
||||
@@ -8481,6 +8818,88 @@
|
||||
"integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
|
||||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/y18n/-/y18n-4.0.3.tgz",
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"requires": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^18.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"requires": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
|
||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||
"requires": {
|
||||
"p-locate": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"requires": {
|
||||
"p-try": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"requires": {
|
||||
"p-limit": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
|
||||
@@ -33,37 +33,38 @@
|
||||
"deploy": "npm run build && npm run preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons-vue": "^7.0.1",
|
||||
"ant-design-vue": "^4.0.6",
|
||||
"axios": "^1.6.2",
|
||||
"dayjs": "^1.11.10",
|
||||
"echarts": "^5.4.3",
|
||||
"file-saver": "^2.0.5",
|
||||
"lodash-es": "^4.17.21",
|
||||
"moment": "^2.29.4",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.1.7",
|
||||
"qrcode": "^1.5.4",
|
||||
"vue": "^3.4.15",
|
||||
"vue-router": "^4.2.5",
|
||||
"xlsx": "^0.18.5",
|
||||
"@ant-design/icons-vue": "^7.0.1",
|
||||
"dayjs": "^1.11.10",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nprogress": "^0.2.0"
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^4.6.2",
|
||||
"vite": "^4.5.3",
|
||||
"@types/node": "^16.18.68",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^16.18.68",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
"@typescript-eslint/parser": "^5.62.0",
|
||||
"@vitejs/plugin-vue": "^4.6.2",
|
||||
"@vitest/coverage-v8": "^0.34.6",
|
||||
"@vitest/ui": "^0.34.6",
|
||||
"@vue/eslint-config-typescript": "^11.0.3",
|
||||
"eslint": "^8.55.0",
|
||||
"eslint-plugin-vue": "^9.19.2",
|
||||
"rimraf": "^5.0.5",
|
||||
"typescript": "^4.9.5",
|
||||
"vite": "^4.5.3",
|
||||
"vite-bundle-analyzer": "^0.7.0",
|
||||
"vitest": "^0.34.6",
|
||||
"@vitest/ui": "^0.34.6",
|
||||
"@vitest/coverage-v8": "^0.34.6",
|
||||
"vue-tsc": "^1.8.25"
|
||||
}
|
||||
}
|
||||
|
||||
3426
admin-system/pnpm-lock.yaml
generated
Normal file
3426
admin-system/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -31,7 +31,13 @@ const createHeaders = (headers = {}) => {
|
||||
throw new Error('未认证,请先登录');
|
||||
}
|
||||
|
||||
return { ...defaultHeaders, ...headers };
|
||||
// 如果headers中明确设置了Content-Type为undefined,则移除它
|
||||
const mergedHeaders = { ...defaultHeaders, ...headers };
|
||||
if (mergedHeaders['Content-Type'] === undefined) {
|
||||
delete mergedHeaders['Content-Type'];
|
||||
}
|
||||
|
||||
return mergedHeaders;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -342,16 +348,26 @@ export const api = {
|
||||
/**
|
||||
* POST请求
|
||||
* @param {string} endpoint - API端点
|
||||
* @param {Object} data - 请求数据
|
||||
* @param {Object|FormData} data - 请求数据
|
||||
* @param {Object} options - 请求选项
|
||||
* @returns {Promise} 响应数据
|
||||
*/
|
||||
async post(endpoint, data, options = {}) {
|
||||
const url = `${API_BASE_URL}${endpoint}`;
|
||||
|
||||
// 如果是FormData,不设置Content-Type,让浏览器自动处理
|
||||
const isFormData = data instanceof FormData;
|
||||
const headers = isFormData
|
||||
? createHeaders({ ...options.headers, 'Content-Type': undefined })
|
||||
: createHeaders(options.headers);
|
||||
|
||||
// 如果是FormData,直接使用data;否则使用JSON.stringify
|
||||
const body = isFormData ? data : JSON.stringify(data);
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: createHeaders(options.headers),
|
||||
body: JSON.stringify(data),
|
||||
headers: headers,
|
||||
body: body,
|
||||
...options,
|
||||
});
|
||||
return handleResponse(response);
|
||||
|
||||
@@ -104,11 +104,12 @@ const generateRequestId = () => {
|
||||
* @returns {boolean} 是否为标准格式
|
||||
*/
|
||||
export const isValidApiResponse = (response) => {
|
||||
// 基本格式检查:必须有 success 和 message 字段
|
||||
// timestamp 为可选字段(兼容旧接口)
|
||||
return response &&
|
||||
typeof response === 'object' &&
|
||||
typeof response.success === 'boolean' &&
|
||||
typeof response.message === 'string' &&
|
||||
typeof response.timestamp === 'string';
|
||||
(typeof response.message === 'string' || response.message === undefined);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -128,10 +128,10 @@
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="8">
|
||||
<a-form-item label="品系" name="strain">
|
||||
<a-form-item label="品类" name="strain">
|
||||
<a-select
|
||||
v-model:value="formData.strain"
|
||||
placeholder="请选择品系"
|
||||
placeholder="请选择品类"
|
||||
:loading="cattleUsersLoading"
|
||||
@change="handleFieldChange('strain', $event)"
|
||||
show-search
|
||||
@@ -157,6 +157,7 @@
|
||||
show-search
|
||||
:filter-option="filterOption"
|
||||
>
|
||||
<!-- 动态选项 -->
|
||||
<a-select-option
|
||||
v-for="type in cattleTypes"
|
||||
:key="type.id"
|
||||
@@ -168,10 +169,10 @@
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item label="类别" name="cate">
|
||||
<a-form-item label="生理阶段" name="cate">
|
||||
<a-select
|
||||
v-model:value="formData.cate"
|
||||
placeholder="请选择类别"
|
||||
placeholder="请选择生理阶段"
|
||||
@change="handleFieldChange('cate', $event)"
|
||||
show-search
|
||||
:filter-option="filterCateOption"
|
||||
@@ -240,16 +241,7 @@
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="生理阶段" name="physiologicalStage">
|
||||
<a-input
|
||||
v-model:value="formData.physiologicalStage"
|
||||
placeholder="请输入生理阶段"
|
||||
@input="handleFieldChange('physiologicalStage', $event.target.value)"
|
||||
@change="handleFieldChange('physiologicalStage', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-form-item label="胎次" name="parity">
|
||||
<a-input-number
|
||||
@@ -323,13 +315,19 @@
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="来源" name="source">
|
||||
<a-input-number
|
||||
<a-select
|
||||
v-model:value="formData.source"
|
||||
placeholder="请输入来源"
|
||||
:min="0"
|
||||
style="width: 100%"
|
||||
placeholder="请选择来源"
|
||||
@change="handleFieldChange('source', $event)"
|
||||
/>
|
||||
show-search
|
||||
:filter-option="filterOption"
|
||||
>
|
||||
<a-select-option :value="1">购买</a-select-option>
|
||||
<a-select-option :value="2">自繁</a-select-option>
|
||||
<a-select-option :value="3">放生</a-select-option>
|
||||
<a-select-option :value="4">合作社</a-select-option>
|
||||
<a-select-option :value="5">入股</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
@@ -459,7 +457,7 @@ const formData = reactive({
|
||||
penId: null, // 映射iot_cattle.pen_id
|
||||
intoTime: null,
|
||||
parity: 0,
|
||||
source: 0,
|
||||
source: '', // 映射iot_cattle.source,改为空字符串以便验证
|
||||
sourceDay: 0,
|
||||
sourceWeight: 0,
|
||||
ageInMonths: 0, // 从iot_cattle.birthday计算得出
|
||||
@@ -484,7 +482,8 @@ const rules = {
|
||||
cate: [{ required: true, message: '请输入类别', trigger: 'blur' }], // iot_cattle.cate
|
||||
birthWeight: [{ required: true, message: '请输入出生体重', trigger: 'blur' }], // iot_cattle.birth_weight
|
||||
birthday: [{ required: true, message: '请选择出生日期', trigger: 'change' }], // iot_cattle.birthday
|
||||
orgId: [{ required: true, message: '请选择所属农场', trigger: 'change' }] // iot_cattle.org_id
|
||||
orgId: [{ required: true, message: '请选择所属农场', trigger: 'change' }], // iot_cattle.org_id
|
||||
source: [{ required: true, message: '请选择来源', trigger: 'change' }] // iot_cattle.source
|
||||
}
|
||||
|
||||
// 表格列配置(基于iot_cattle表字段映射)
|
||||
@@ -637,16 +636,34 @@ const fetchFarms = async () => {
|
||||
const fetchPens = async (farmId = null) => {
|
||||
try {
|
||||
pensLoading.value = true
|
||||
const token = localStorage.getItem('token')
|
||||
const params = farmId ? { farmId } : {}
|
||||
const response = await api.get('/iot-cattle/pens/list', {
|
||||
params
|
||||
})
|
||||
if (response.success) {
|
||||
pens.value = response.data
|
||||
console.log('🔍 [牛只档案] 开始获取栏舍列表')
|
||||
|
||||
// 调用 /cattle-pens 接口
|
||||
const params = {
|
||||
page: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
|
||||
// 如果有 farmId,可以添加到参数中(如果后端支持)
|
||||
if (farmId) {
|
||||
params.farmId = farmId
|
||||
}
|
||||
|
||||
console.log('📤 [牛只档案] 栏舍列表请求参数:', params)
|
||||
const response = await api.cattlePens.getList(params)
|
||||
console.log('📥 [牛只档案] 栏舍列表响应:', response)
|
||||
|
||||
if (response.success && response.data) {
|
||||
// 从 response.data.list 中提取栏舍列表
|
||||
const pensList = response.data.list || []
|
||||
pens.value = pensList
|
||||
console.log('✅ [牛只档案] 获取栏舍列表成功,共', pensList.length, '条')
|
||||
return pensList
|
||||
}
|
||||
return []
|
||||
} catch (error) {
|
||||
console.error('获取栏舍列表失败:', error)
|
||||
console.error('❌ [牛只档案] 获取栏舍列表失败:', error)
|
||||
return []
|
||||
} finally {
|
||||
pensLoading.value = false
|
||||
}
|
||||
@@ -656,16 +673,37 @@ const fetchPens = async (farmId = null) => {
|
||||
const fetchBatches = async (farmId = null) => {
|
||||
try {
|
||||
batchesLoading.value = true
|
||||
const token = localStorage.getItem('token')
|
||||
const params = farmId ? { farmId } : {}
|
||||
const response = await api.get('/iot-cattle/batches/list', {
|
||||
params
|
||||
})
|
||||
if (response.success) {
|
||||
batches.value = response.data
|
||||
console.log('🔍 [牛只档案] 开始获取批次列表')
|
||||
|
||||
// 调用 /cattle-batches 接口
|
||||
const params = {
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
search: '',
|
||||
exactMatch: true,
|
||||
strictMatch: true
|
||||
}
|
||||
|
||||
// 如果有 farmId,可以添加到参数中(如果后端支持)
|
||||
if (farmId) {
|
||||
params.farmId = farmId
|
||||
}
|
||||
|
||||
console.log('📤 [牛只档案] 批次列表请求参数:', params)
|
||||
const response = await api.cattleBatches.getList(params)
|
||||
console.log('📥 [牛只档案] 批次列表响应:', response)
|
||||
|
||||
if (response.success && response.data) {
|
||||
// 从 response.data.list 中提取批次列表
|
||||
const batchesList = response.data.list || []
|
||||
batches.value = batchesList
|
||||
console.log('✅ [牛只档案] 获取批次列表成功,共', batchesList.length, '条')
|
||||
return batchesList
|
||||
}
|
||||
return []
|
||||
} catch (error) {
|
||||
console.error('获取批次列表失败:', error)
|
||||
console.error('❌ [牛只档案] 获取批次列表失败:', error)
|
||||
return []
|
||||
} finally {
|
||||
batchesLoading.value = false
|
||||
}
|
||||
@@ -801,12 +839,27 @@ const initializeAddMode = () => {
|
||||
|
||||
// ==================== 编辑牛只档案功能 ====================
|
||||
// 编辑牛只档案
|
||||
const editAnimal = (record) => {
|
||||
console.log('=== 点击编辑按钮 ===')
|
||||
console.log('编辑记录:', record)
|
||||
initializeEditMode(record)
|
||||
openModal()
|
||||
loadRequiredData()
|
||||
// 编辑牛只档案
|
||||
const editAnimal = async (record) => {
|
||||
try {
|
||||
console.log('=== 点击编辑按钮 ===')
|
||||
console.log('编辑记录ID:', record.id)
|
||||
|
||||
// 调用后端接口获取详情
|
||||
const response = await api.get(`/iot-cattle/${record.id}`)
|
||||
|
||||
if (response.success && response.data) {
|
||||
console.log('获取到的详情数据:', response.data)
|
||||
initializeEditMode(response.data)
|
||||
openModal()
|
||||
loadRequiredData()
|
||||
} else {
|
||||
message.error('获取牛只档案详情失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取牛只档案详情失败:', error)
|
||||
message.error(error.message || '获取牛只档案详情失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化编辑模式
|
||||
@@ -842,27 +895,99 @@ const populateFormWithRecord = (record) => {
|
||||
formData.id = record.id
|
||||
formData.earNumber = record.earNumber || '' // iot_cattle.ear_number
|
||||
formData.sex = record.sex || 1 // iot_cattle.sex
|
||||
formData.strain = record.strain || '' // iot_cattle.strain
|
||||
formData.varieties = record.varieties || '' // iot_cattle.varieties
|
||||
formData.cate = record.cate || '' // iot_cattle.cate
|
||||
// 使用原始ID(strainId),如果没有则使用strain(兼容旧数据)
|
||||
formData.strain = record.strainId !== undefined ? record.strainId : (record.strain || '') // iot_cattle.strain
|
||||
// 使用原始ID(varietiesId),如果没有则使用varieties(兼容旧数据)
|
||||
formData.varieties = record.varietiesId !== undefined ? record.varietiesId : (record.varieties || '') // iot_cattle.varieties
|
||||
// 使用原始ID(cateId),如果没有则使用cate(兼容旧数据)
|
||||
formData.cate = record.cateId !== undefined ? record.cateId : (record.cate || '') // iot_cattle.cate
|
||||
formData.birthWeight = record.birthWeight || 0 // iot_cattle.birth_weight
|
||||
formData.birthday = record.birthday ? dayjs(record.birthday) : null // iot_cattle.birthday
|
||||
formData.penId = record.penId || null // iot_cattle.pen_id
|
||||
formData.intoTime = record.intoTime || null
|
||||
// 处理出生日期:如果是时间戳(秒),使用dayjs.unix;如果是日期字符串,使用dayjs
|
||||
if (record.birthday) {
|
||||
if (typeof record.birthday === 'number') {
|
||||
// 时间戳(秒)转换为dayjs对象
|
||||
const birthdayDate = dayjs.unix(record.birthday)
|
||||
formData.birthday = birthdayDate.isValid() ? birthdayDate : null
|
||||
console.log('转换出生日期:', record.birthday, '->', formData.birthday?.format('YYYY-MM-DD'))
|
||||
} else {
|
||||
formData.birthday = dayjs(record.birthday) // 日期字符串转换为dayjs对象
|
||||
}
|
||||
} else {
|
||||
formData.birthday = null
|
||||
}
|
||||
// 处理所属栏舍:如果为0或null,则设为null
|
||||
formData.penId = (record.penId && record.penId !== 0) ? record.penId : null // iot_cattle.pen_id
|
||||
// 处理入场日期:如果是时间戳(秒),使用dayjs.unix;如果是日期字符串,使用dayjs
|
||||
if (record.intoTime) {
|
||||
if (typeof record.intoTime === 'number') {
|
||||
formData.intoTime = dayjs.unix(record.intoTime) // 时间戳(秒)转换为dayjs对象
|
||||
} else {
|
||||
formData.intoTime = dayjs(record.intoTime) // 日期字符串转换为dayjs对象
|
||||
}
|
||||
} else {
|
||||
formData.intoTime = null
|
||||
}
|
||||
formData.parity = record.parity || 0
|
||||
formData.source = record.source || 0
|
||||
// 处理来源:如果是数字(包括0),直接使用;否则设为空字符串
|
||||
if (typeof record.source === 'number') {
|
||||
formData.source = record.source
|
||||
} else if (record.source !== undefined && record.source !== null && record.source !== '') {
|
||||
formData.source = record.source
|
||||
} else {
|
||||
formData.source = ''
|
||||
}
|
||||
formData.sourceDay = record.sourceDay || 0
|
||||
formData.sourceWeight = record.sourceWeight || 0
|
||||
formData.ageInMonths = calculateAgeInMonths(record.birthday) // 从iot_cattle.birthday计算月龄
|
||||
// 优先使用JSON中的ageInMonths,如果没有则计算
|
||||
formData.ageInMonths = record.ageInMonths !== undefined ? record.ageInMonths : calculateAgeInMonths(record.birthday)
|
||||
formData.physiologicalStage = record.physiologicalStage || ''
|
||||
formData.currentWeight = record.currentWeight || 0
|
||||
formData.weightCalculateTime = record.weightCalculateTime ? dayjs(record.weightCalculateTime) : null
|
||||
// 处理体重计算时间:如果是时间戳(秒),使用dayjs.unix;如果是日期字符串,使用dayjs
|
||||
if (record.weightCalculateTime) {
|
||||
if (typeof record.weightCalculateTime === 'number') {
|
||||
formData.weightCalculateTime = dayjs.unix(record.weightCalculateTime) // 时间戳(秒)转换为dayjs对象
|
||||
} else {
|
||||
formData.weightCalculateTime = dayjs(record.weightCalculateTime) // 日期字符串转换为dayjs对象
|
||||
}
|
||||
} else {
|
||||
formData.weightCalculateTime = null
|
||||
}
|
||||
formData.dayOfBirthday = record.dayOfBirthday || 0
|
||||
formData.orgId = record.farmId || record.orgId || null // iot_cattle.org_id
|
||||
formData.penId = record.penId || null // iot_cattle.pen_id
|
||||
formData.batchId = record.batchId || null // iot_cattle.batch_id
|
||||
|
||||
// 保存 penId 和 batchId 的值,等待选项加载完成后再设置
|
||||
const savedPenId = (record.penId && record.penId !== 0) ? record.penId : null
|
||||
const savedBatchId = (record.batchId && record.batchId !== 0) ? record.batchId : null
|
||||
|
||||
console.log('填充后的 formData:', JSON.parse(JSON.stringify(formData)));
|
||||
console.log('保存的 penId:', savedPenId, 'batchId:', savedBatchId);
|
||||
console.log('出生日期转换结果:', formData.birthday);
|
||||
|
||||
// 如果所属农场有值,先加载对应的栏舍和批次选项,然后再设置值
|
||||
if (formData.orgId) {
|
||||
Promise.all([
|
||||
fetchPens(formData.orgId),
|
||||
fetchBatches(formData.orgId)
|
||||
]).then(() => {
|
||||
// 选项加载完成后再设置值,使用 nextTick 确保 DOM 更新
|
||||
setTimeout(() => {
|
||||
if (savedPenId !== null) {
|
||||
formData.penId = savedPenId
|
||||
console.log('设置 penId:', savedPenId, '当前栏舍选项:', pens.value)
|
||||
}
|
||||
if (savedBatchId !== null) {
|
||||
formData.batchId = savedBatchId
|
||||
console.log('设置 batchId:', savedBatchId, '当前批次选项:', batches.value)
|
||||
}
|
||||
}, 100) // 延迟100ms确保选项已加载到DOM
|
||||
}).catch(error => {
|
||||
console.error('加载栏舍或批次选项失败:', error)
|
||||
})
|
||||
} else {
|
||||
// 如果没有农场ID,直接设置值(虽然可能没有对应的选项)
|
||||
formData.penId = savedPenId
|
||||
formData.batchId = savedBatchId
|
||||
}
|
||||
}
|
||||
|
||||
// 配置编辑模式设置
|
||||
@@ -932,7 +1057,7 @@ const handleSubmit = async () => {
|
||||
console.log('原始表单数据:', JSON.parse(JSON.stringify(formData)));
|
||||
|
||||
// 检查必填字段
|
||||
const requiredFields = ['earNumber', 'sex', 'strain', 'varieties', 'cate', 'birthWeight', 'birthday', 'orgId'];
|
||||
const requiredFields = ['earNumber', 'sex', 'strain', 'varieties', 'cate', 'birthWeight', 'birthday', 'orgId', 'source'];
|
||||
const missingFields = requiredFields.filter(field => !formData[field] && formData[field] !== 0);
|
||||
if (missingFields.length > 0) {
|
||||
console.error('缺少必填字段:', missingFields);
|
||||
@@ -1006,7 +1131,7 @@ const resetForm = () => {
|
||||
penId: null,
|
||||
intoTime: null,
|
||||
parity: 0,
|
||||
source: 0,
|
||||
source: '',
|
||||
sourceDay: 0,
|
||||
sourceWeight: 0,
|
||||
ageInMonths: 0,
|
||||
@@ -1268,12 +1393,8 @@ const confirmImport = async () => {
|
||||
const formData = new FormData()
|
||||
formData.append('file', importFile.value)
|
||||
|
||||
// 调用导入API
|
||||
const response = await api.post('/iot-cattle/import', formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
// 调用导入API(FormData会自动处理Content-Type,不需要手动设置)
|
||||
const response = await api.post('/iot-cattle/import', formData)
|
||||
|
||||
if (response.data.success) {
|
||||
message.destroy()
|
||||
@@ -1290,7 +1411,16 @@ const confirmImport = async () => {
|
||||
} catch (error) {
|
||||
message.destroy()
|
||||
console.error('导入失败:', error)
|
||||
message.error('导入失败,请检查文件格式是否正确')
|
||||
// 显示具体的错误信息
|
||||
const errorMessage = error.message || error.response?.data?.message || '导入失败,请检查文件格式是否正确'
|
||||
message.error(errorMessage)
|
||||
|
||||
// 如果是认证错误,提示用户重新登录
|
||||
if (errorMessage.includes('认证') || errorMessage.includes('未授权') || errorMessage.includes('登录')) {
|
||||
setTimeout(() => {
|
||||
window.location.href = '/login'
|
||||
}, 2000)
|
||||
}
|
||||
} finally {
|
||||
importLoading.value = false
|
||||
}
|
||||
|
||||
@@ -110,27 +110,22 @@
|
||||
>
|
||||
<a-form-item label="批次名称" name="name">
|
||||
<a-input
|
||||
v-model="formData.name"
|
||||
v-model:value="formData.name"
|
||||
placeholder="请输入批次名称"
|
||||
@input="handleFieldChange('name', $event.target.value)"
|
||||
@change="handleFieldChange('name', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="批次编号" name="code">
|
||||
<a-input
|
||||
v-model="formData.code"
|
||||
v-model:value="formData.code"
|
||||
placeholder="请输入批次编号"
|
||||
@input="handleFieldChange('code', $event.target.value)"
|
||||
@change="handleFieldChange('code', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="批次类型" name="type">
|
||||
<a-select
|
||||
v-model="formData.type"
|
||||
v-model:value="formData.type"
|
||||
placeholder="请选择批次类型"
|
||||
@change="handleFieldChange('type', $event)"
|
||||
>
|
||||
<a-select-option value="育成批次">育成批次</a-select-option>
|
||||
<a-select-option value="繁殖批次">繁殖批次</a-select-option>
|
||||
@@ -142,66 +137,58 @@
|
||||
|
||||
<a-form-item label="开始日期" name="startDate">
|
||||
<a-date-picker
|
||||
v-model="formData.startDate"
|
||||
v-model:value="formData.startDate"
|
||||
style="width: 100%"
|
||||
placeholder="请选择开始日期"
|
||||
@change="handleFieldChange('startDate', $event)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="预计结束日期" name="expectedEndDate">
|
||||
<a-date-picker
|
||||
v-model="formData.expectedEndDate"
|
||||
v-model:value="formData.expectedEndDate"
|
||||
style="width: 100%"
|
||||
placeholder="请选择预计结束日期"
|
||||
@change="handleFieldChange('expectedEndDate', $event)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="实际结束日期" name="actualEndDate">
|
||||
<a-date-picker
|
||||
v-model="formData.actualEndDate"
|
||||
v-model:value="formData.actualEndDate"
|
||||
style="width: 100%"
|
||||
placeholder="请选择实际结束日期"
|
||||
@change="handleFieldChange('actualEndDate', $event)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="目标牛只数量" name="targetCount">
|
||||
<a-input-number
|
||||
v-model="formData.targetCount"
|
||||
v-model:value="formData.targetCount"
|
||||
:min="1"
|
||||
:max="1000"
|
||||
style="width: 100%"
|
||||
placeholder="请输入目标牛只数量"
|
||||
@change="handleFieldChange('targetCount', $event)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="当前牛只数量" name="currentCount">
|
||||
<a-input-number
|
||||
v-model="formData.currentCount"
|
||||
v-model:value="formData.currentCount"
|
||||
:min="0"
|
||||
:max="formData.targetCount || 1000"
|
||||
style="width: 100%"
|
||||
placeholder="当前牛只数量"
|
||||
@change="handleFieldChange('currentCount', $event)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="负责人" name="manager">
|
||||
<a-input
|
||||
v-model="formData.manager"
|
||||
v-model:value="formData.manager"
|
||||
placeholder="请输入负责人姓名"
|
||||
@input="handleFieldChange('manager', $event.target.value)"
|
||||
@change="handleFieldChange('manager', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="状态" name="status">
|
||||
<a-radio-group
|
||||
v-model="formData.status"
|
||||
@change="handleFieldChange('status', $event.target.value)"
|
||||
v-model:value="formData.status"
|
||||
>
|
||||
<a-radio value="进行中">进行中</a-radio>
|
||||
<a-radio value="已完成">已完成</a-radio>
|
||||
@@ -211,11 +198,9 @@
|
||||
|
||||
<a-form-item label="备注" name="remark">
|
||||
<a-textarea
|
||||
v-model="formData.remark"
|
||||
v-model:value="formData.remark"
|
||||
:rows="3"
|
||||
placeholder="请输入备注信息"
|
||||
@input="handleFieldChange('remark', $event.target.value)"
|
||||
@change="handleFieldChange('remark', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
@@ -646,7 +631,7 @@ const handleAdd = () => {
|
||||
modalVisible.value = true
|
||||
}
|
||||
|
||||
const handleEdit = (record) => {
|
||||
const handleEdit = async (record) => {
|
||||
console.log('🔄 [批次设置] 开始编辑操作')
|
||||
console.log('📋 [批次设置] 原始记录数据:', {
|
||||
id: record.id,
|
||||
@@ -663,15 +648,76 @@ const handleEdit = (record) => {
|
||||
})
|
||||
|
||||
modalTitle.value = '编辑批次'
|
||||
Object.assign(formData, {
|
||||
...record,
|
||||
startDate: record.startDate ? dayjs(record.startDate) : null,
|
||||
expectedEndDate: record.expectedEndDate ? dayjs(record.expectedEndDate) : null,
|
||||
actualEndDate: record.actualEndDate ? dayjs(record.actualEndDate) : null
|
||||
})
|
||||
|
||||
// 处理日期转换
|
||||
let startDateValue = null
|
||||
let expectedEndDateValue = null
|
||||
let actualEndDateValue = null
|
||||
|
||||
if (record.startDate) {
|
||||
if (typeof record.startDate === 'string') {
|
||||
startDateValue = dayjs(record.startDate)
|
||||
} else if (record.startDate instanceof Date) {
|
||||
startDateValue = dayjs(record.startDate)
|
||||
} else if (record.startDate && typeof record.startDate === 'object' && record.startDate.format) {
|
||||
startDateValue = record.startDate
|
||||
} else {
|
||||
startDateValue = dayjs(record.startDate)
|
||||
}
|
||||
}
|
||||
|
||||
if (record.expectedEndDate) {
|
||||
if (typeof record.expectedEndDate === 'string') {
|
||||
expectedEndDateValue = dayjs(record.expectedEndDate)
|
||||
} else if (record.expectedEndDate instanceof Date) {
|
||||
expectedEndDateValue = dayjs(record.expectedEndDate)
|
||||
} else if (record.expectedEndDate && typeof record.expectedEndDate === 'object' && record.expectedEndDate.format) {
|
||||
expectedEndDateValue = record.expectedEndDate
|
||||
} else {
|
||||
expectedEndDateValue = dayjs(record.expectedEndDate)
|
||||
}
|
||||
}
|
||||
|
||||
if (record.actualEndDate) {
|
||||
if (typeof record.actualEndDate === 'string') {
|
||||
actualEndDateValue = dayjs(record.actualEndDate)
|
||||
} else if (record.actualEndDate instanceof Date) {
|
||||
actualEndDateValue = dayjs(record.actualEndDate)
|
||||
} else if (record.actualEndDate && typeof record.actualEndDate === 'object' && record.actualEndDate.format) {
|
||||
actualEndDateValue = record.actualEndDate
|
||||
} else {
|
||||
actualEndDateValue = dayjs(record.actualEndDate)
|
||||
}
|
||||
}
|
||||
|
||||
// 填充表单数据 - 使用直接赋值确保响应式更新
|
||||
formData.id = record.id
|
||||
formData.name = record.name || ''
|
||||
formData.code = record.code || ''
|
||||
formData.type = record.type || ''
|
||||
formData.startDate = startDateValue
|
||||
formData.expectedEndDate = expectedEndDateValue
|
||||
formData.actualEndDate = actualEndDateValue
|
||||
formData.targetCount = record.targetCount || 0
|
||||
formData.currentCount = record.currentCount || 0
|
||||
formData.manager = record.manager || ''
|
||||
formData.status = record.status || '进行中'
|
||||
formData.remark = record.remark || ''
|
||||
formData.farmId = record.farmId || record.farm_id || null
|
||||
|
||||
console.log('📝 [批次设置] 表单数据已填充:', formData)
|
||||
console.log('📝 [批次设置] startDate 是否为 dayjs:', formData.startDate && typeof formData.startDate.format === 'function')
|
||||
console.log('📝 [批次设置] expectedEndDate 是否为 dayjs:', formData.expectedEndDate && typeof formData.expectedEndDate.format === 'function')
|
||||
console.log('📝 [批次设置] actualEndDate 是否为 dayjs:', formData.actualEndDate && typeof formData.actualEndDate.format === 'function')
|
||||
|
||||
// 打开模态框
|
||||
modalVisible.value = true
|
||||
|
||||
// 等待模态框和表单渲染完成
|
||||
await nextTick()
|
||||
await new Promise(resolve => setTimeout(resolve, 200))
|
||||
|
||||
console.log('✅ [批次设置] 模态框已打开,表单应该已填充')
|
||||
}
|
||||
|
||||
const handleDelete = (record) => {
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-button type="link" size="small" @click="handleEdit(record)">
|
||||
<a-button type="link" size="small" @click="() => handleEdit(record)">
|
||||
编辑
|
||||
</a-button>
|
||||
<a-button type="link" size="small" @click="handleViewDetails(record)">
|
||||
@@ -167,27 +167,23 @@
|
||||
>
|
||||
<a-form-item label="牛只耳号" name="earNumber">
|
||||
<a-input
|
||||
v-model="formData.earNumber"
|
||||
v-model:value="formData.earNumber"
|
||||
placeholder="请输入牛只耳号"
|
||||
@input="handleFieldChange('earNumber', $event.target.value)"
|
||||
@change="handleFieldChange('earNumber', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="离栏日期" name="exitDate">
|
||||
<a-date-picker
|
||||
v-model="formData.exitDate"
|
||||
v-model:value="formData.exitDate"
|
||||
style="width: 100%"
|
||||
placeholder="请选择离栏日期"
|
||||
@change="handleFieldChange('exitDate', $event)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="离栏原因" name="exitReason">
|
||||
<a-select
|
||||
v-model="formData.exitReason"
|
||||
v-model:value="formData.exitReason"
|
||||
placeholder="请选择离栏原因"
|
||||
@change="handleFieldChange('exitReason', $event)"
|
||||
>
|
||||
<a-select-option value="出售">出售</a-select-option>
|
||||
<a-select-option value="死亡">死亡</a-select-option>
|
||||
@@ -199,9 +195,8 @@
|
||||
|
||||
<a-form-item label="原栏舍" name="originalPenId">
|
||||
<a-select
|
||||
v-model="formData.originalPenId"
|
||||
v-model:value="formData.originalPenId"
|
||||
placeholder="请选择原栏舍"
|
||||
@change="handleFieldChange('originalPenId', $event)"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="pen in penList"
|
||||
@@ -215,18 +210,15 @@
|
||||
|
||||
<a-form-item label="去向" name="destination">
|
||||
<a-input
|
||||
v-model="formData.destination"
|
||||
v-model:value="formData.destination"
|
||||
placeholder="请输入牛只去向"
|
||||
@input="handleFieldChange('destination', $event.target.value)"
|
||||
@change="handleFieldChange('destination', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="处理方式" name="disposalMethod">
|
||||
<a-select
|
||||
v-model="formData.disposalMethod"
|
||||
v-model:value="formData.disposalMethod"
|
||||
placeholder="请选择处理方式"
|
||||
@change="handleFieldChange('disposalMethod', $event)"
|
||||
>
|
||||
<a-select-option value="屠宰">屠宰</a-select-option>
|
||||
<a-select-option value="转售">转售</a-select-option>
|
||||
@@ -238,17 +230,14 @@
|
||||
|
||||
<a-form-item label="处理人员" name="handler">
|
||||
<a-input
|
||||
v-model="formData.handler"
|
||||
v-model:value="formData.handler"
|
||||
placeholder="请输入处理人员姓名"
|
||||
@input="handleFieldChange('handler', $event.target.value)"
|
||||
@change="handleFieldChange('handler', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="状态" name="status">
|
||||
<a-radio-group
|
||||
v-model="formData.status"
|
||||
@change="handleFieldChange('status', $event.target.value)"
|
||||
v-model:value="formData.status"
|
||||
>
|
||||
<a-radio value="已确认">已确认</a-radio>
|
||||
<a-radio value="待确认">待确认</a-radio>
|
||||
@@ -258,11 +247,9 @@
|
||||
|
||||
<a-form-item label="备注" name="remark">
|
||||
<a-textarea
|
||||
v-model="formData.remark"
|
||||
v-model:value="formData.remark"
|
||||
:rows="3"
|
||||
placeholder="请输入备注信息"
|
||||
@input="handleFieldChange('remark', $event.target.value)"
|
||||
@change="handleFieldChange('remark', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
@@ -579,38 +566,207 @@ const handleAdd = () => {
|
||||
modalVisible.value = true
|
||||
}
|
||||
|
||||
const handleEdit = (record) => {
|
||||
console.log('🔄 [离栏记录] 开始编辑操作')
|
||||
console.log('📋 [离栏记录] 原始记录数据:', {
|
||||
id: record.id,
|
||||
earNumber: record.earNumber,
|
||||
exitDate: record.exitDate,
|
||||
exitReason: record.exitReason,
|
||||
originalPenId: record.originalPenId,
|
||||
originalPenName: record.originalPenName,
|
||||
destination: record.destination,
|
||||
disposalMethod: record.disposalMethod,
|
||||
handler: record.handler,
|
||||
status: record.status,
|
||||
remark: record.remark
|
||||
})
|
||||
// 获取离栏记录详情(用于编辑)
|
||||
const getExitRecordDetail = async (id) => {
|
||||
console.log('🔵 [离栏记录-编辑] ========== 开始获取详情 ==========')
|
||||
console.log('🔵 [离栏记录-编辑] 函数被调用,记录ID:', id)
|
||||
console.log('🔵 [离栏记录-编辑] 调用时间:', new Date().toISOString())
|
||||
|
||||
modalTitle.value = '编辑离栏记录'
|
||||
Object.assign(formData, {
|
||||
id: record.id,
|
||||
earNumber: record.earNumber, // 映射耳号字段
|
||||
exitDate: record.exitDate ? dayjs(record.exitDate) : null,
|
||||
exitReason: record.exitReason,
|
||||
originalPenId: record.originalPenId, // 映射原栏舍ID
|
||||
destination: record.destination,
|
||||
disposalMethod: record.disposalMethod,
|
||||
handler: record.handler,
|
||||
status: record.status,
|
||||
remark: record.remark || ''
|
||||
})
|
||||
try {
|
||||
console.log('🔄 [离栏记录-编辑] 开始获取详情')
|
||||
console.log('📋 [离栏记录-编辑] 记录ID:', id)
|
||||
|
||||
// 调用后端接口获取详情
|
||||
console.log('📡 [离栏记录-编辑] 准备调用 API: /cattle-exit-records/' + id)
|
||||
const response = await api.cattleExitRecords.getById(id)
|
||||
console.log('📡 [离栏记录-编辑] API 调用完成,响应状态:', response.success)
|
||||
|
||||
if (response.success && response.data) {
|
||||
console.log('✅ [离栏记录-编辑] 获取详情成功:', response.data)
|
||||
console.log('🔵 [离栏记录-编辑] ========== 获取详情成功 ==========')
|
||||
return response.data
|
||||
} else {
|
||||
console.error('❌ [离栏记录-编辑] 获取详情失败:', response.message)
|
||||
throw new Error(response.message || '获取离栏记录详情失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ [离栏记录-编辑] 获取详情异常:', error)
|
||||
console.error('🔵 [离栏记录-编辑] ========== 获取详情失败 ==========')
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑离栏记录
|
||||
const handleEdit = async (record) => {
|
||||
// 立即输出日志,确认函数被调用
|
||||
console.log('🟢🟢🟢 [离栏记录-编辑] ========== handleEdit 函数被调用 ==========')
|
||||
console.log('🟢 [离栏记录-编辑] 调用时间:', new Date().toISOString())
|
||||
console.log('🟢 [离栏记录-编辑] 记录数据:', record)
|
||||
console.log('🟢 [离栏记录-编辑] 记录ID:', record?.id)
|
||||
|
||||
console.log('📝 [离栏记录] 表单数据已填充:', formData)
|
||||
modalVisible.value = true
|
||||
// 验证 record 对象
|
||||
if (!record) {
|
||||
console.error('❌ [离栏记录-编辑] record 为空')
|
||||
message.error('记录数据为空')
|
||||
return
|
||||
}
|
||||
|
||||
if (!record.id) {
|
||||
console.error('❌ [离栏记录-编辑] record.id 为空')
|
||||
message.error('记录ID为空')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('🔄 [离栏记录-编辑] 开始编辑操作')
|
||||
console.log('📋 [离栏记录-编辑] 编辑记录ID:', record.id)
|
||||
|
||||
// 调用封装的获取详情接口
|
||||
console.log('📞 [离栏记录-编辑] 准备调用 getExitRecordDetail 函数,ID:', record.id)
|
||||
console.log('📞 [离栏记录-编辑] getExitRecordDetail 函数是否存在:', typeof getExitRecordDetail)
|
||||
|
||||
const detailData = await getExitRecordDetail(record.id)
|
||||
console.log('📞 [离栏记录-编辑] getExitRecordDetail 函数调用完成,返回数据:', detailData)
|
||||
|
||||
if (detailData) {
|
||||
console.log('📋 [离栏记录] 获取到的详情数据:', detailData)
|
||||
|
||||
modalTitle.value = '编辑离栏记录'
|
||||
|
||||
// 确保栏舍列表已加载
|
||||
if (penList.value.length === 0) {
|
||||
await loadPenList()
|
||||
}
|
||||
|
||||
// 填充表单数据 - 直接赋值给 reactive 对象的属性
|
||||
|
||||
// 处理日期转换
|
||||
let exitDateValue = null
|
||||
if (detailData.exitDate) {
|
||||
// 如果是字符串,转换为 dayjs 对象
|
||||
if (typeof detailData.exitDate === 'string') {
|
||||
exitDateValue = dayjs(detailData.exitDate)
|
||||
} else if (detailData.exitDate instanceof Date) {
|
||||
exitDateValue = dayjs(detailData.exitDate)
|
||||
} else if (detailData.exitDate && typeof detailData.exitDate === 'object' && detailData.exitDate.format) {
|
||||
// 如果已经是 dayjs 对象,直接使用
|
||||
exitDateValue = detailData.exitDate
|
||||
} else {
|
||||
exitDateValue = dayjs(detailData.exitDate)
|
||||
}
|
||||
console.log('📅 [离栏记录] 日期转换:', detailData.exitDate, '->', exitDateValue?.format('YYYY-MM-DD'))
|
||||
console.log('📅 [离栏记录] exitDateValue 类型:', typeof exitDateValue, '是否为 dayjs:', exitDateValue && typeof exitDateValue.format === 'function')
|
||||
}
|
||||
|
||||
// 先填充表单数据(在打开模态框之前)
|
||||
console.log('📝 [离栏记录] 开始填充表单数据')
|
||||
|
||||
// 直接赋值给 reactive 对象
|
||||
formData.id = detailData.id || null
|
||||
formData.earNumber = detailData.earNumber || ''
|
||||
formData.exitDate = exitDateValue // 确保是 dayjs 对象
|
||||
formData.exitReason = detailData.exitReason || ''
|
||||
formData.originalPenId = detailData.originalPenId || null
|
||||
formData.destination = detailData.destination || ''
|
||||
formData.disposalMethod = detailData.disposalMethod || ''
|
||||
formData.handler = detailData.handler || ''
|
||||
formData.status = detailData.status || '待确认'
|
||||
formData.remark = detailData.remark || ''
|
||||
|
||||
console.log('📝 [离栏记录] 表单数据已填充到 formData')
|
||||
console.log('📝 [离栏记录] formData.exitDate:', formData.exitDate)
|
||||
console.log('📝 [离栏记录] formData.exitDate 类型:', typeof formData.exitDate)
|
||||
console.log('📝 [离栏记录] formData.exitDate 是否为 dayjs:', formData.exitDate && typeof formData.exitDate.format === 'function')
|
||||
console.log('📝 [离栏记录] formData 完整数据:', {
|
||||
id: formData.id,
|
||||
earNumber: formData.earNumber,
|
||||
exitDate: formData.exitDate ? (formData.exitDate.format ? formData.exitDate.format('YYYY-MM-DD') : formData.exitDate) : null,
|
||||
exitReason: formData.exitReason,
|
||||
originalPenId: formData.originalPenId,
|
||||
destination: formData.destination,
|
||||
disposalMethod: formData.disposalMethod,
|
||||
handler: formData.handler,
|
||||
status: formData.status,
|
||||
remark: formData.remark
|
||||
})
|
||||
|
||||
// 先打开模态框
|
||||
modalVisible.value = true
|
||||
console.log('📝 [离栏记录] 模态框已打开')
|
||||
|
||||
// 等待模态框完全打开和表单渲染
|
||||
await nextTick()
|
||||
await new Promise(resolve => setTimeout(resolve, 300))
|
||||
|
||||
// 确保日期字段是 dayjs 对象(防止被序列化)
|
||||
if (detailData.exitDate && (!formData.exitDate || typeof formData.exitDate.format !== 'function')) {
|
||||
formData.exitDate = exitDateValue
|
||||
console.log('🔄 [离栏记录] 重新设置 exitDate 为 dayjs 对象:', formData.exitDate)
|
||||
}
|
||||
|
||||
console.log('🔍 [离栏记录] 检查 formData.exitDate 是否为 dayjs:',
|
||||
formData.exitDate && typeof formData.exitDate.format === 'function' ? '是' : '否',
|
||||
formData.exitDate ? (formData.exitDate.format ? formData.exitDate.format('YYYY-MM-DD') : formData.exitDate) : 'null'
|
||||
)
|
||||
|
||||
// 由于表单使用 v-model 绑定到 formData,直接修改 formData 即可更新表单
|
||||
// 但为了确保表单组件正确响应,我们尝试使用 setFieldsValue(如果可用)
|
||||
if (formRef.value) {
|
||||
// 检查表单实例是否有 setFieldsValue 方法
|
||||
if (typeof formRef.value.setFieldsValue === 'function') {
|
||||
try {
|
||||
const fieldsValue = {
|
||||
id: formData.id,
|
||||
earNumber: formData.earNumber,
|
||||
exitDate: formData.exitDate, // 确保是 dayjs 对象
|
||||
exitReason: formData.exitReason,
|
||||
originalPenId: formData.originalPenId,
|
||||
destination: formData.destination,
|
||||
disposalMethod: formData.disposalMethod,
|
||||
handler: formData.handler,
|
||||
status: formData.status,
|
||||
remark: formData.remark
|
||||
}
|
||||
console.log('🔧 [离栏记录] 使用 setFieldsValue 设置表单值')
|
||||
console.log('🔧 [离栏记录] exitDate 值:', fieldsValue.exitDate, '类型:', typeof fieldsValue.exitDate)
|
||||
formRef.value.setFieldsValue(fieldsValue)
|
||||
console.log('✅ [离栏记录] setFieldsValue 设置成功')
|
||||
} catch (error) {
|
||||
console.warn('⚠️ [离栏记录] setFieldsValue 失败,但 formData 已更新,表单应该会自动响应:', error)
|
||||
}
|
||||
} else {
|
||||
console.log('ℹ️ [离栏记录] 表单实例没有 setFieldsValue 方法,使用 v-model 绑定(formData 已更新)')
|
||||
}
|
||||
} else {
|
||||
console.warn('⚠️ [离栏记录] formRef.value 为空,但 formData 已更新,表单应该会自动响应')
|
||||
}
|
||||
|
||||
// 再次使用 nextTick 确保值已更新
|
||||
await nextTick()
|
||||
await new Promise(resolve => setTimeout(resolve, 100))
|
||||
|
||||
// 验证表单值
|
||||
console.log('✅ [离栏记录] 模态框已打开')
|
||||
console.log('✅ [离栏记录] formData.exitDate 最终值:', formData.exitDate)
|
||||
console.log('✅ [离栏记录] formData.exitDate 是否为 dayjs:', formData.exitDate && typeof formData.exitDate.format === 'function')
|
||||
|
||||
// 如果表单实例有 getFieldsValue 方法,验证表单值
|
||||
if (formRef.value && typeof formRef.value.getFieldsValue === 'function') {
|
||||
try {
|
||||
const currentFormData = formRef.value.getFieldsValue()
|
||||
console.log('✅ [离栏记录] 表单当前值(通过 getFieldsValue):', currentFormData)
|
||||
console.log('✅ [离栏记录] 表单 exitDate 值:', currentFormData.exitDate)
|
||||
} catch (error) {
|
||||
console.warn('⚠️ [离栏记录] 无法获取表单值:', error)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
message.error('获取离栏记录详情失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ [离栏记录] 编辑操作失败:', error)
|
||||
message.error(error.message || '获取离栏记录详情失败')
|
||||
}
|
||||
}
|
||||
|
||||
const handleDelete = (record) => {
|
||||
|
||||
@@ -97,27 +97,22 @@
|
||||
>
|
||||
<a-form-item label="栏舍名称" name="name">
|
||||
<a-input
|
||||
v-model="formData.name"
|
||||
v-model:value="formData.name"
|
||||
placeholder="请输入栏舍名称"
|
||||
@input="handleFieldChange('name', $event.target.value)"
|
||||
@change="handleFieldChange('name', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="栏舍编号" name="code">
|
||||
<a-input
|
||||
v-model="formData.code"
|
||||
v-model:value="formData.code"
|
||||
placeholder="请输入栏舍编号"
|
||||
@input="handleFieldChange('code', $event.target.value)"
|
||||
@change="handleFieldChange('code', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="栏舍类型" name="type">
|
||||
<a-select
|
||||
v-model="formData.type"
|
||||
v-model:value="formData.type"
|
||||
placeholder="请选择栏舍类型"
|
||||
@change="handleFieldChange('type', $event)"
|
||||
>
|
||||
<a-select-option value="育成栏">育成栏</a-select-option>
|
||||
<a-select-option value="产房">产房</a-select-option>
|
||||
@@ -129,51 +124,45 @@
|
||||
|
||||
<a-form-item label="容量" name="capacity">
|
||||
<a-input-number
|
||||
v-model="formData.capacity"
|
||||
v-model:value="formData.capacity"
|
||||
:min="1"
|
||||
:max="1000"
|
||||
style="width: 100%"
|
||||
placeholder="请输入栏舍容量"
|
||||
@change="handleFieldChange('capacity', $event)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="当前牛只数量" name="currentCount">
|
||||
<a-input-number
|
||||
v-model="formData.currentCount"
|
||||
v-model:value="formData.currentCount"
|
||||
:min="0"
|
||||
:max="formData.capacity || 1000"
|
||||
style="width: 100%"
|
||||
placeholder="当前牛只数量"
|
||||
@change="handleFieldChange('currentCount', $event)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="面积(平方米)" name="area">
|
||||
<a-input-number
|
||||
v-model="formData.area"
|
||||
v-model:value="formData.area"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
style="width: 100%"
|
||||
placeholder="请输入栏舍面积"
|
||||
@change="handleFieldChange('area', $event)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="位置描述" name="location">
|
||||
<a-textarea
|
||||
v-model="formData.location"
|
||||
v-model:value="formData.location"
|
||||
:rows="3"
|
||||
placeholder="请输入栏舍位置描述"
|
||||
@input="handleFieldChange('location', $event.target.value)"
|
||||
@change="handleFieldChange('location', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="状态" name="status">
|
||||
<a-radio-group
|
||||
v-model="formData.status"
|
||||
@change="handleFieldChange('status', $event.target.value)"
|
||||
v-model:value="formData.status"
|
||||
>
|
||||
<a-radio value="启用">启用</a-radio>
|
||||
<a-radio value="停用">停用</a-radio>
|
||||
@@ -182,11 +171,9 @@
|
||||
|
||||
<a-form-item label="备注" name="remark">
|
||||
<a-textarea
|
||||
v-model="formData.remark"
|
||||
v-model:value="formData.remark"
|
||||
:rows="3"
|
||||
placeholder="请输入备注信息"
|
||||
@input="handleFieldChange('remark', $event.target.value)"
|
||||
@change="handleFieldChange('remark', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
@@ -219,7 +206,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, computed } from 'vue'
|
||||
import { ref, reactive, onMounted, computed, nextTick } from 'vue'
|
||||
import { message, Modal } from 'ant-design-vue'
|
||||
import {
|
||||
PlusOutlined,
|
||||
@@ -415,9 +402,9 @@ const loadData = async () => {
|
||||
pageSize: pagination.pageSize
|
||||
}
|
||||
|
||||
// 精确匹配栏舍名称
|
||||
if (searchValue.value) {
|
||||
params.name = searchValue.value
|
||||
// 搜索关键词(后端使用 search 参数)
|
||||
if (searchValue.value && searchValue.value.trim()) {
|
||||
params.search = searchValue.value.trim()
|
||||
}
|
||||
|
||||
console.log('📤 [栏舍设置] 发送请求参数:', params)
|
||||
@@ -454,7 +441,7 @@ const handleAdd = () => {
|
||||
modalVisible.value = true
|
||||
}
|
||||
|
||||
const handleEdit = (record) => {
|
||||
const handleEdit = async (record) => {
|
||||
console.log('🔄 [栏舍设置] 开始编辑操作')
|
||||
console.log('📋 [栏舍设置] 原始记录数据:', {
|
||||
id: record.id,
|
||||
@@ -471,10 +458,30 @@ const handleEdit = (record) => {
|
||||
})
|
||||
|
||||
modalTitle.value = '编辑栏舍'
|
||||
Object.assign(formData, record)
|
||||
|
||||
// 填充表单数据 - 使用直接赋值确保响应式更新
|
||||
formData.id = record.id || null
|
||||
formData.name = record.name || ''
|
||||
formData.code = record.code || ''
|
||||
formData.type = record.type || ''
|
||||
formData.capacity = record.capacity || 0
|
||||
formData.currentCount = record.currentCount || 0
|
||||
formData.area = record.area || null
|
||||
formData.location = record.location || ''
|
||||
formData.status = record.status || '启用'
|
||||
formData.remark = record.remark || ''
|
||||
formData.farmId = record.farmId || record.farm_id || null
|
||||
|
||||
console.log('📝 [栏舍设置] 表单数据已填充:', formData)
|
||||
|
||||
// 打开模态框
|
||||
modalVisible.value = true
|
||||
|
||||
// 等待模态框和表单渲染完成
|
||||
await nextTick()
|
||||
await new Promise(resolve => setTimeout(resolve, 200))
|
||||
|
||||
console.log('✅ [栏舍设置] 模态框已打开,表单应该已填充')
|
||||
}
|
||||
|
||||
const handleDelete = (record) => {
|
||||
|
||||
@@ -168,18 +168,15 @@
|
||||
>
|
||||
<a-form-item label="牛只耳号" name="earNumber">
|
||||
<a-input
|
||||
v-model="formData.earNumber"
|
||||
v-model:value="formData.earNumber"
|
||||
placeholder="请输入牛只耳号"
|
||||
@input="handleFieldChange('earNumber', $event.target.value)"
|
||||
@change="handleFieldChange('earNumber', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="转出栏舍" name="fromPenId">
|
||||
<a-select
|
||||
v-model="formData.fromPenId"
|
||||
v-model:value="formData.fromPenId"
|
||||
placeholder="请选择转出栏舍"
|
||||
@change="handleFieldChange('fromPenId', $event)"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="pen in penList"
|
||||
@@ -193,9 +190,8 @@
|
||||
|
||||
<a-form-item label="转入栏舍" name="toPenId">
|
||||
<a-select
|
||||
v-model="formData.toPenId"
|
||||
v-model:value="formData.toPenId"
|
||||
placeholder="请选择转入栏舍"
|
||||
@change="handleFieldChange('toPenId', $event)"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="pen in penList"
|
||||
@@ -209,18 +205,16 @@
|
||||
|
||||
<a-form-item label="转栏日期" name="transferDate">
|
||||
<a-date-picker
|
||||
v-model="formData.transferDate"
|
||||
v-model:value="formData.transferDate"
|
||||
style="width: 100%"
|
||||
placeholder="请选择转栏日期"
|
||||
@change="handleFieldChange('transferDate', $event)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="转栏原因" name="reason">
|
||||
<a-select
|
||||
v-model="formData.reason"
|
||||
v-model:value="formData.reason"
|
||||
placeholder="请选择转栏原因"
|
||||
@change="handleFieldChange('reason', $event)"
|
||||
>
|
||||
<a-select-option value="正常调栏">正常调栏</a-select-option>
|
||||
<a-select-option value="疾病治疗">疾病治疗</a-select-option>
|
||||
@@ -233,17 +227,14 @@
|
||||
|
||||
<a-form-item label="操作人员" name="operator">
|
||||
<a-input
|
||||
v-model="formData.operator"
|
||||
v-model:value="formData.operator"
|
||||
placeholder="请输入操作人员姓名"
|
||||
@input="handleFieldChange('operator', $event.target.value)"
|
||||
@change="handleFieldChange('operator', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="状态" name="status">
|
||||
<a-radio-group
|
||||
v-model="formData.status"
|
||||
@change="handleFieldChange('status', $event.target.value)"
|
||||
v-model:value="formData.status"
|
||||
>
|
||||
<a-radio value="已完成">已完成</a-radio>
|
||||
<a-radio value="进行中">进行中</a-radio>
|
||||
@@ -252,11 +243,9 @@
|
||||
|
||||
<a-form-item label="备注" name="remark">
|
||||
<a-textarea
|
||||
v-model="formData.remark"
|
||||
v-model:value="formData.remark"
|
||||
:rows="3"
|
||||
placeholder="请输入备注信息"
|
||||
@input="handleFieldChange('remark', $event.target.value)"
|
||||
@change="handleFieldChange('remark', $event.target.value)"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
@@ -567,7 +556,7 @@ const handleAdd = () => {
|
||||
modalVisible.value = true
|
||||
}
|
||||
|
||||
const handleEdit = (record) => {
|
||||
const handleEdit = async (record) => {
|
||||
console.log('🔄 [转栏记录] 开始编辑操作')
|
||||
console.log('📋 [转栏记录] 原始记录数据:', {
|
||||
id: record.id,
|
||||
@@ -584,20 +573,50 @@ const handleEdit = (record) => {
|
||||
})
|
||||
|
||||
modalTitle.value = '编辑转栏记录'
|
||||
Object.assign(formData, {
|
||||
id: record.id,
|
||||
earNumber: record.earNumber,
|
||||
fromPenId: record.fromPenId,
|
||||
toPenId: record.toPenId,
|
||||
transferDate: record.transferDate ? dayjs(record.transferDate) : null,
|
||||
reason: record.reason,
|
||||
operator: record.operator,
|
||||
status: record.status,
|
||||
remark: record.remark || ''
|
||||
})
|
||||
|
||||
// 确保栏舍列表已加载
|
||||
if (penList.value.length === 0) {
|
||||
await loadPenList()
|
||||
}
|
||||
|
||||
// 处理日期转换
|
||||
let transferDateValue = null
|
||||
if (record.transferDate) {
|
||||
if (typeof record.transferDate === 'string') {
|
||||
transferDateValue = dayjs(record.transferDate)
|
||||
} else if (record.transferDate instanceof Date) {
|
||||
transferDateValue = dayjs(record.transferDate)
|
||||
} else if (record.transferDate && typeof record.transferDate === 'object' && record.transferDate.format) {
|
||||
// 如果已经是 dayjs 对象,直接使用
|
||||
transferDateValue = record.transferDate
|
||||
} else {
|
||||
transferDateValue = dayjs(record.transferDate)
|
||||
}
|
||||
console.log('📅 [转栏记录] 日期转换:', record.transferDate, '->', transferDateValue?.format('YYYY-MM-DD'))
|
||||
}
|
||||
|
||||
// 填充表单数据
|
||||
formData.id = record.id
|
||||
formData.earNumber = record.earNumber || ''
|
||||
formData.fromPenId = record.fromPenId || null
|
||||
formData.toPenId = record.toPenId || null
|
||||
formData.transferDate = transferDateValue
|
||||
formData.reason = record.reason || ''
|
||||
formData.operator = record.operator || ''
|
||||
formData.status = record.status || '进行中'
|
||||
formData.remark = record.remark || ''
|
||||
|
||||
console.log('📝 [转栏记录] 表单数据已填充:', formData)
|
||||
console.log('📝 [转栏记录] transferDate 是否为 dayjs:', formData.transferDate && typeof formData.transferDate.format === 'function')
|
||||
|
||||
// 打开模态框
|
||||
modalVisible.value = true
|
||||
|
||||
// 等待模态框和表单渲染完成
|
||||
await nextTick()
|
||||
await new Promise(resolve => setTimeout(resolve, 200))
|
||||
|
||||
console.log('✅ [转栏记录] 模态框已打开,表单应该已填充')
|
||||
}
|
||||
|
||||
const handleDelete = (record) => {
|
||||
|
||||
@@ -95,19 +95,16 @@
|
||||
<a-col :span="12">
|
||||
<a-form-item label="栏舍名" name="name" required>
|
||||
<a-input
|
||||
v-model="formData.name"
|
||||
placeholder="请输入栏舍名"
|
||||
@input="(e) => { console.log('栏舍名输入:', e.target.value); formData.name = e.target.value; }"
|
||||
@change="(e) => { console.log('栏舍名变化:', e.target.value); }"
|
||||
v-model:value="formData.name"
|
||||
placeholder="请输入栏舍名"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="动物类型" name="animal_type" required>
|
||||
<a-select
|
||||
v-model="formData.animal_type"
|
||||
v-model:value="formData.animal_type"
|
||||
placeholder="请选择动物类型"
|
||||
@change="(value) => { console.log('动物类型变化:', value); }"
|
||||
>
|
||||
<a-select-option value="马">马</a-select-option>
|
||||
<a-select-option value="牛">牛</a-select-option>
|
||||
@@ -123,20 +120,16 @@
|
||||
<a-col :span="12">
|
||||
<a-form-item label="栏舍类型" name="pen_type">
|
||||
<a-input
|
||||
v-model="formData.pen_type"
|
||||
v-model:value="formData.pen_type"
|
||||
placeholder="请输入栏舍类型"
|
||||
@input="(e) => { console.log('栏舍类型输入:', e.target.value); formData.pen_type = e.target.value; }"
|
||||
@change="(e) => { console.log('栏舍类型变化:', e.target.value); }"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="负责人" name="responsible" required>
|
||||
<a-input
|
||||
v-model="formData.responsible"
|
||||
v-model:value="formData.responsible"
|
||||
placeholder="请输入负责人"
|
||||
@input="(e) => { console.log('负责人输入:', e.target.value); formData.responsible = e.target.value; }"
|
||||
@change="(e) => { console.log('负责人变化:', e.target.value); }"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
@@ -146,20 +139,18 @@
|
||||
<a-col :span="12">
|
||||
<a-form-item label="容量" name="capacity" required>
|
||||
<a-input-number
|
||||
v-model="formData.capacity"
|
||||
v-model:value="formData.capacity"
|
||||
:min="1"
|
||||
:max="10000"
|
||||
placeholder="请输入容量"
|
||||
style="width: 100%"
|
||||
@change="(value) => { console.log('容量变化:', value); formData.capacity = value; }"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="状态" name="status">
|
||||
<a-switch
|
||||
:checked="formData.status"
|
||||
@change="(checked) => { console.log('状态变化:', checked); formData.status = checked; }"
|
||||
v-model:checked="formData.status"
|
||||
:checked-children="'开启'"
|
||||
:un-checked-children="'关闭'"
|
||||
/>
|
||||
@@ -169,11 +160,9 @@
|
||||
|
||||
<a-form-item label="备注" name="description">
|
||||
<a-textarea
|
||||
v-model="formData.description"
|
||||
v-model:value="formData.description"
|
||||
placeholder="请输入备注信息"
|
||||
:rows="3"
|
||||
@input="(e) => { console.log('备注输入:', e.target.value); formData.description = e.target.value; }"
|
||||
@change="(e) => { console.log('备注变化:', e.target.value); }"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
@@ -182,7 +171,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { ref, reactive, computed, onMounted, nextTick } from 'vue'
|
||||
import { message, Modal } from 'ant-design-vue'
|
||||
import { PlusOutlined, SearchOutlined, ExportOutlined } from '@ant-design/icons-vue'
|
||||
import { api } from '../utils/api'
|
||||
@@ -364,21 +353,21 @@ const showAddModal = () => {
|
||||
modalVisible.value = true
|
||||
}
|
||||
|
||||
const handleEdit = (record) => {
|
||||
const handleEdit = async (record) => {
|
||||
console.log('=== 开始编辑栏舍 ===')
|
||||
console.log('点击编辑按钮,原始记录数据:', record)
|
||||
|
||||
isEdit.value = true
|
||||
Object.assign(formData, {
|
||||
id: record.id,
|
||||
name: record.name,
|
||||
animal_type: record.animal_type,
|
||||
pen_type: record.pen_type,
|
||||
responsible: record.responsible,
|
||||
capacity: record.capacity,
|
||||
status: record.status,
|
||||
description: record.description
|
||||
})
|
||||
|
||||
// 填充表单数据 - 使用直接赋值确保响应式更新
|
||||
formData.id = record.id || null
|
||||
formData.name = record.name || ''
|
||||
formData.animal_type = record.animal_type || ''
|
||||
formData.pen_type = record.pen_type || ''
|
||||
formData.responsible = record.responsible || ''
|
||||
formData.capacity = record.capacity || 0
|
||||
formData.status = record.status || false
|
||||
formData.description = record.description || ''
|
||||
|
||||
console.log('编辑模式:表单数据已填充')
|
||||
console.log('formData对象:', formData)
|
||||
@@ -390,8 +379,14 @@ const handleEdit = (record) => {
|
||||
console.log('formData.status:', formData.status)
|
||||
console.log('formData.description:', formData.description)
|
||||
|
||||
// 打开模态框
|
||||
modalVisible.value = true
|
||||
console.log('编辑模态框已打开')
|
||||
|
||||
// 等待模态框和表单渲染完成
|
||||
await nextTick()
|
||||
await new Promise(resolve => setTimeout(resolve, 200))
|
||||
|
||||
console.log('编辑模态框已打开,表单应该已填充')
|
||||
}
|
||||
|
||||
const handleDelete = (record) => {
|
||||
|
||||
@@ -166,24 +166,24 @@
|
||||
<!-- 操作 -->
|
||||
<template v-else-if="column.dataIndex === 'action'">
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 2px;">
|
||||
<a-button type="link" size="small" style="color: #1890ff; padding: 0 4px;" @click="editDevice(record)">
|
||||
<!-- <a-button type="link" size="small" style="color: #1890ff; padding: 0 4px;" @click="editDevice(record)">
|
||||
修改绑定
|
||||
</a-button>
|
||||
</a-button> -->
|
||||
<a-button type="link" size="small" style="color: #1890ff; padding: 0 4px;" @click="clearData(record)">
|
||||
溯源二维码
|
||||
</a-button>
|
||||
<a-button type="link" size="small" style="color: #1890ff; padding: 0 4px;" @click="bindDevice(record)">
|
||||
绑定信息
|
||||
</a-button>
|
||||
<a-button type="link" size="small" style="color: #1890ff; padding: 0 4px;" @click="setDefault(record)">
|
||||
<!-- <a-button type="link" size="small" style="color: #1890ff; padding: 0 4px;" @click="setDefault(record)">
|
||||
设置频次
|
||||
</a-button>
|
||||
<a-button type="link" size="small" style="color: #1890ff; padding: 0 4px;" @click="viewTrack(record)">
|
||||
</a-button> -->
|
||||
<!-- <a-button type="link" size="small" style="color: #1890ff; padding: 0 4px;" @click="viewTrack(record)">
|
||||
日志
|
||||
</a-button>
|
||||
<a-button type="link" size="small" style="color: #1890ff; padding: 0 4px;" @click="viewTrack(record)">
|
||||
查看轨迹
|
||||
</a-button>
|
||||
</a-button> -->
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
@@ -553,6 +553,24 @@
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<!-- 溯源二维码模态框 -->
|
||||
<a-modal
|
||||
:open="qrcodeVisible"
|
||||
title="溯源二维码"
|
||||
:footer="null"
|
||||
width="450px"
|
||||
@cancel="handleQRCodeCancel"
|
||||
>
|
||||
<div class="qrcode-modal-content">
|
||||
<div class="qrcode-container">
|
||||
<img v-if="qrcodeUrl" :src="qrcodeUrl" alt="溯源二维码" class="qrcode-image" />
|
||||
</div>
|
||||
<div class="device-sn-display">
|
||||
{{ currentDeviceSn }}
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<!-- 添加/编辑模态框 -->
|
||||
<a-modal
|
||||
:open="modalVisible"
|
||||
@@ -613,6 +631,7 @@ import { PlusOutlined, ReloadOutlined, ExportOutlined, EnvironmentOutlined, Crow
|
||||
import { api, directApi } from '../utils/api'
|
||||
import { ExportUtils } from '../utils/exportUtils'
|
||||
import { loadBMapScript, createMap } from '@/utils/mapService'
|
||||
import QRCode from 'qrcode'
|
||||
|
||||
// 响应式数据
|
||||
const collars = ref([])
|
||||
@@ -643,6 +662,11 @@ const currentLocation = ref(null)
|
||||
const baiduMap = ref(null)
|
||||
const locationMarker = ref(null)
|
||||
|
||||
// 二维码相关数据
|
||||
const qrcodeVisible = ref(false)
|
||||
const qrcodeUrl = ref('')
|
||||
const currentDeviceSn = ref('')
|
||||
|
||||
// 标签页配置
|
||||
const tabs = [
|
||||
{ key: 'identity', label: '身份信息' },
|
||||
@@ -1013,8 +1037,30 @@ const editDevice = (record) => {
|
||||
message.info(`修改设备 ${record.deviceId}`)
|
||||
}
|
||||
|
||||
const clearData = (record) => {
|
||||
message.info(`清除设备 ${record.deviceId} 的数据`)
|
||||
// 显示溯源二维码
|
||||
const clearData = async (record) => {
|
||||
try {
|
||||
const deviceSn = record.sn
|
||||
if (!deviceSn) {
|
||||
message.warning('设备编号不存在')
|
||||
return
|
||||
}
|
||||
|
||||
currentDeviceSn.value = deviceSn
|
||||
const traceUrl = `https://farm.aiotagro.com/source/source-index.html?device_sn=${deviceSn}`
|
||||
|
||||
// 生成二维码
|
||||
const qrCodeDataUrl = await QRCode.toDataURL(traceUrl, {
|
||||
width: 250,
|
||||
margin: 2
|
||||
})
|
||||
|
||||
qrcodeUrl.value = qrCodeDataUrl
|
||||
qrcodeVisible.value = true
|
||||
} catch (error) {
|
||||
console.error('生成二维码失败:', error)
|
||||
message.error('生成二维码失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索项圈
|
||||
@@ -1334,6 +1380,13 @@ const handleLocationCancel = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭二维码模态框
|
||||
const handleQRCodeCancel = () => {
|
||||
qrcodeVisible.value = false
|
||||
qrcodeUrl.value = ''
|
||||
currentDeviceSn.value = ''
|
||||
}
|
||||
|
||||
// 初始化百度地图
|
||||
const initBaiduMap = async () => {
|
||||
if (!currentLocation.value) return
|
||||
@@ -1773,4 +1826,37 @@ onUnmounted(() => {
|
||||
border-top: 1px solid #f0f0f0;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/* 二维码模态框样式 */
|
||||
.qrcode-modal-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.qrcode-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.qrcode-image {
|
||||
width: 250px;
|
||||
height: 250px;
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.device-sn-display {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -154,18 +154,18 @@
|
||||
<!-- 操作列 -->
|
||||
<template #action="{ record }">
|
||||
<div class="action-buttons">
|
||||
<a-button type="link" size="small" @click="bindLivestock(record)">
|
||||
<!-- <a-button type="link" size="small" @click="bindLivestock(record)">
|
||||
绑定牲畜
|
||||
</a-button>
|
||||
</a-button> -->
|
||||
<a-button type="link" size="small" @click="showQRCode(record)">
|
||||
溯源二维码
|
||||
</a-button>
|
||||
<a-button type="link" size="small" @click="showBindingInfo(record)">
|
||||
绑定信息
|
||||
</a-button>
|
||||
<a-button type="link" size="small" @click="showLog(record)">
|
||||
<!-- <a-button type="link" size="small" @click="showLog(record)">
|
||||
日志
|
||||
</a-button>
|
||||
</a-button> -->
|
||||
</div>
|
||||
</template>
|
||||
</a-table>
|
||||
@@ -219,6 +219,24 @@
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<!-- 溯源二维码模态框 -->
|
||||
<a-modal
|
||||
:open="qrcodeVisible"
|
||||
title="溯源二维码"
|
||||
:footer="null"
|
||||
width="450px"
|
||||
@cancel="handleQRCodeCancel"
|
||||
>
|
||||
<div class="qrcode-modal-content">
|
||||
<div class="qrcode-container">
|
||||
<img v-if="qrcodeUrl" :src="qrcodeUrl" alt="溯源二维码" class="qrcode-image" />
|
||||
</div>
|
||||
<div class="device-sn-display">
|
||||
{{ currentDeviceSn }}
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<!-- 绑定信息模态框 -->
|
||||
<a-modal
|
||||
:open="bindInfoVisible"
|
||||
@@ -337,6 +355,7 @@ import { EnvironmentOutlined, SearchOutlined, ExportOutlined } from '@ant-design
|
||||
import { api, directApi } from '../utils/api'
|
||||
import { ExportUtils } from '../utils/exportUtils'
|
||||
import { formatBindingInfo } from '../utils/fieldMappings'
|
||||
import QRCode from 'qrcode'
|
||||
|
||||
// 响应式数据
|
||||
const loading = ref(false)
|
||||
@@ -362,6 +381,11 @@ const bindInfoData = ref({
|
||||
const activeTab = ref('basic')
|
||||
const currentEartagNumber = ref('')
|
||||
|
||||
// 二维码相关数据
|
||||
const qrcodeVisible = ref(false)
|
||||
const qrcodeUrl = ref('')
|
||||
const currentDeviceSn = ref('')
|
||||
|
||||
// 分页配置
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
@@ -752,9 +776,30 @@ const bindLivestock = (record) => {
|
||||
message.info('绑定牲畜功能开发中...')
|
||||
}
|
||||
|
||||
// 显示二维码
|
||||
const showQRCode = (record) => {
|
||||
message.info('溯源二维码功能开发中...')
|
||||
// 显示溯源二维码
|
||||
const showQRCode = async (record) => {
|
||||
try {
|
||||
const deviceSn = record.eartagNumber
|
||||
if (!deviceSn) {
|
||||
message.warning('设备编号不存在')
|
||||
return
|
||||
}
|
||||
|
||||
currentDeviceSn.value = deviceSn
|
||||
const traceUrl = `https://farm.aiotagro.com/source/source-index.html?device_sn=${deviceSn}`
|
||||
|
||||
// 生成二维码
|
||||
const qrCodeDataUrl = await QRCode.toDataURL(traceUrl, {
|
||||
width: 250,
|
||||
margin: 2
|
||||
})
|
||||
|
||||
qrcodeUrl.value = qrCodeDataUrl
|
||||
qrcodeVisible.value = true
|
||||
} catch (error) {
|
||||
console.error('生成二维码失败:', error)
|
||||
message.error('生成二维码失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭绑定信息模态框
|
||||
@@ -773,6 +818,13 @@ const handleBindingInfoCancel = () => {
|
||||
activeTab.value = 'basic'
|
||||
}
|
||||
|
||||
// 关闭二维码模态框
|
||||
const handleQRCodeCancel = () => {
|
||||
qrcodeVisible.value = false
|
||||
qrcodeUrl.value = ''
|
||||
currentDeviceSn.value = ''
|
||||
}
|
||||
|
||||
// 显示绑定信息
|
||||
const showBindingInfo = async (record) => {
|
||||
try {
|
||||
@@ -1238,6 +1290,39 @@ onUnmounted(() => {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 二维码模态框样式 */
|
||||
.qrcode-modal-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.qrcode-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.qrcode-image {
|
||||
width: 250px;
|
||||
height: 250px;
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.device-sn-display {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.search-bar .ant-col {
|
||||
margin-bottom: 12px;
|
||||
|
||||
@@ -96,9 +96,9 @@
|
||||
<a-button type="link" class="action-link" @click="viewLocation(record)">
|
||||
查看定位
|
||||
</a-button>
|
||||
<a-button type="link" class="action-link" @click="viewCollectionInfo(record)">
|
||||
<!-- <a-button type="link" class="action-link" @click="viewCollectionInfo(record)">
|
||||
查看采集信息
|
||||
</a-button>
|
||||
</a-button> -->
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -60,7 +60,7 @@ export default defineConfig(({ mode }) => {
|
||||
__APP_ENV__: JSON.stringify(env),
|
||||
// 在生产环境中强制使用正确的API URL
|
||||
'import.meta.env.VITE_API_BASE_URL': JSON.stringify(
|
||||
mode === 'production' ? 'https://ad.ningmuyun.com/farm/api' : (env.VITE_API_BASE_URL || '/api')
|
||||
mode === 'production' ? 'https://ad.liaoniuyun.com/farm/api' : (env.VITE_API_BASE_URL || '/api')
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user