Compare commits
564 Commits
2024-11
...
NPQS9100V1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2f0382bd9 | ||
|
|
9fecf0ce3f | ||
|
|
290586d0ff | ||
|
|
ddc45af223 | ||
|
|
0e6f123306 | ||
|
|
7b93363b23 | ||
|
|
2fd0dcb8a3 | ||
|
|
86ee05f8af | ||
|
|
38814b9f44 | ||
|
|
fb5d13671d | ||
|
|
310a769092 | ||
|
|
8c63edabdc | ||
|
|
5363625a2f | ||
| efcd6e1cfe | |||
| acc4d0ca67 | |||
| 772f38feca | |||
|
|
1eb141e559 | ||
|
|
16b446bf20 | ||
|
|
bc0de34c15 | ||
|
|
15f2c1ee41 | ||
|
|
81a944062a | ||
|
|
3c19b05f4b | ||
|
|
c1f53cdc69 | ||
|
|
6ef2a6049b | ||
|
|
9989cc98cb | ||
|
|
e192158deb | ||
|
|
2e5d551e5d | ||
|
|
4622eb36d9 | ||
|
|
9c53b7c18e | ||
|
|
7b3805060f | ||
|
|
629600bc00 | ||
|
|
8b144b63fc | ||
|
|
098ab3a41d | ||
|
|
2a53f577aa | ||
|
|
f8b7c224b7 | ||
|
|
f0b3bdd37c | ||
|
|
bb35eb749b | ||
|
|
b3750d6a7f | ||
|
|
33ebb91ab6 | ||
|
|
3e00f2fee7 | ||
|
|
68e9856641 | ||
|
|
51b2e80493 | ||
|
|
cf77572f41 | ||
| fe6524404c | |||
|
|
ccda7218f4 | ||
|
|
ddd0e6a22b | ||
|
|
ed85453de1 | ||
|
|
04939606fc | ||
|
|
2df455b667 | ||
|
|
8fb214d7a7 | ||
|
|
4f2c8a8016 | ||
|
|
c2974dbe0d | ||
|
|
3891e5459a | ||
|
|
9ed47ac5bc | ||
|
|
114fcd140d | ||
|
|
19a30894f8 | ||
|
|
2134fea518 | ||
|
|
82f495ce3b | ||
|
|
f2ecff54a3 | ||
|
|
f56004ac15 | ||
|
|
5303c47248 | ||
| 37731592f7 | |||
|
|
c9e41e0c82 | ||
|
|
4a80a88e6e | ||
|
|
30b219e14d | ||
|
|
ecec9adeea | ||
|
|
1853152138 | ||
| 5619413f37 | |||
|
|
5b736bc475 | ||
|
|
2aa37c3fe3 | ||
|
|
4e0cb72f32 | ||
|
|
ce74ec4db7 | ||
|
|
9938306884 | ||
|
|
ef63fcf807 | ||
|
|
08cffa4256 | ||
|
|
e1a740f8bf | ||
|
|
56d035253b | ||
|
|
e7348107d0 | ||
|
|
ea38b4eb21 | ||
| 67ef976739 | |||
| 60145ec4f7 | |||
|
|
81600ddc69 | ||
|
|
e0941d628b | ||
|
|
760dcbf723 | ||
|
|
b75ecb8c66 | ||
|
|
39f4cfa670 | ||
|
|
862251b83c | ||
|
|
312490ce59 | ||
|
|
d7df999cf2 | ||
|
|
e0b1b5907b | ||
|
|
f06ca03881 | ||
|
|
a9b80ed33c | ||
|
|
834230b26a | ||
|
|
403ddbfb6e | ||
|
|
ffb44ea909 | ||
|
|
b729e4efa1 | ||
|
|
962c286fd5 | ||
|
|
c215f51554 | ||
| 859c85b427 | |||
|
|
5fe637e84f | ||
|
|
5f68071c77 | ||
|
|
1675a5af31 | ||
|
|
ec1d09dbd0 | ||
|
|
eda7b516f6 | ||
|
|
630eb48d28 | ||
|
|
0d2f8a7788 | ||
| 230c68f454 | |||
| 68934060e6 | |||
| 846e7514b7 | |||
| 410cfb0f7a | |||
|
|
c892410b07 | ||
|
|
7caa4a5303 | ||
|
|
c17efbf9f6 | ||
| c46abeecf5 | |||
|
|
0947097932 | ||
|
|
50fc02d4eb | ||
|
|
a122e9e1b3 | ||
|
|
d7cfcc7855 | ||
|
|
05948aebf5 | ||
|
|
cca214aaf7 | ||
|
|
0111954c5e | ||
|
|
ce31499964 | ||
|
|
059864d193 | ||
|
|
6d2fb4dde8 | ||
|
|
49059d9c59 | ||
|
|
d2f7041988 | ||
|
|
f94372d20b | ||
|
|
9af98b034f | ||
|
|
341b8df5a9 | ||
|
|
7470f697bd | ||
|
|
c058b99a0d | ||
|
|
d5eed13f38 | ||
|
|
c27ee88182 | ||
|
|
e2559ffa65 | ||
|
|
a0bd32453c | ||
|
|
54e7a91841 | ||
|
|
042f6eef51 | ||
| c9857326c6 | |||
| 9c4e0094f9 | |||
| 781b27af51 | |||
|
|
37e257afc8 | ||
| 4d4fdd6190 | |||
|
|
0fd2d8252d | ||
|
|
3cf5019880 | ||
|
|
258d3d692f | ||
|
|
667ed3bcc0 | ||
|
|
a882189022 | ||
|
|
686e009243 | ||
|
|
30d5f3390c | ||
|
|
3398b414ca | ||
|
|
b6a2c42feb | ||
|
|
cb5a9050f2 | ||
|
|
661b27abd0 | ||
|
|
59a24c9ea2 | ||
|
|
6cf5da5d48 | ||
|
|
537f5e2f4c | ||
|
|
70531a0729 | ||
|
|
ded15e5c8b | ||
|
|
3021f7e4d3 | ||
|
|
876d9cfa00 | ||
|
|
8f28825162 | ||
|
|
0e6612f6bd | ||
|
|
39183fde5d | ||
|
|
b967419cb1 | ||
|
|
0712698638 | ||
|
|
d3a74e830f | ||
|
|
f68da773ab | ||
|
|
8db814dba4 | ||
|
|
7dcff99de5 | ||
|
|
97100dfa63 | ||
|
|
d41707fcf9 | ||
|
|
2377916f29 | ||
|
|
be2f40715a | ||
|
|
489c0882ac | ||
|
|
492db88b45 | ||
|
|
3b198eb4ed | ||
|
|
5efc27d4b6 | ||
|
|
ec9f270d04 | ||
|
|
afd2d467f3 | ||
|
|
ff0798450d | ||
|
|
fbefc70368 | ||
|
|
faa0bc54a6 | ||
|
|
bf5f4eab77 | ||
| 188456c970 | |||
|
|
c06334e96f | ||
| 82e8bf2e0b | |||
| 30382fb34d | |||
| c7e5ee0862 | |||
|
|
d6ac63586b | ||
|
|
e0fd42199f | ||
|
|
d9e3168484 | ||
|
|
dc7e91ca66 | ||
|
|
692358d278 | ||
| 3750031d6b | |||
| 0bae200241 | |||
|
|
61bd1a0d6a | ||
|
|
37cf3dfdd7 | ||
|
|
8be96ca64e | ||
|
|
d225391248 | ||
|
|
f2fd0b078e | ||
|
|
f71963ea3b | ||
|
|
6a635246bb | ||
|
|
d338ca6b25 | ||
|
|
193c3b963c | ||
|
|
cad4965b1b | ||
|
|
79306d846f | ||
|
|
f4ea510c5d | ||
|
|
07cc26fa8d | ||
|
|
f87e268242 | ||
|
|
1aeceffe0b | ||
|
|
fc97087767 | ||
|
|
61be97b04b | ||
|
|
934162875c | ||
|
|
4b3991099a | ||
|
|
b14a961c1a | ||
|
|
cbe41d80ce | ||
|
|
28203f2621 | ||
|
|
b8492dfbe6 | ||
|
|
15faac8079 | ||
|
|
ad850ca4ee | ||
|
|
6c05c6e06e | ||
|
|
8b2cda80b1 | ||
|
|
3f7756b417 | ||
|
|
5004e319b6 | ||
|
|
19035f2dc9 | ||
|
|
9d8a5c76b2 | ||
|
|
6300eb2f43 | ||
|
|
da58ffb621 | ||
|
|
1500fafb92 | ||
|
|
df53eea432 | ||
|
|
cc1771c208 | ||
|
|
5e881c0804 | ||
|
|
5666e01ae0 | ||
|
|
4acec8a2d6 | ||
|
|
426a511099 | ||
|
|
89303b44ae | ||
|
|
ffb82066bb | ||
|
|
f46b8c0a56 | ||
|
|
280289af37 | ||
| a0c7f79302 | |||
| bd1eecc106 | |||
|
|
1a23bcb510 | ||
|
|
942c28d3bd | ||
| 034b31ba47 | |||
|
|
7a76c2da8a | ||
|
|
1a9d8e8606 | ||
| 14583d919d | |||
|
|
629fd174e4 | ||
|
|
9080fe06a4 | ||
|
|
0e183bb5c1 | ||
| 8caf856d2d | |||
|
|
d28669e6b0 | ||
| 700884d01a | |||
| c06bd9fa24 | |||
| ce92a1d645 | |||
|
|
4f622da52c | ||
| 7d3e86a5fc | |||
|
|
c66d181b98 | ||
| f860630bfb | |||
|
|
6db4d79839 | ||
| e2924d5e57 | |||
| 92b9a82f21 | |||
|
|
c3f89ca1f8 | ||
|
|
8c435c91dd | ||
|
|
6e6cfa5be0 | ||
|
|
ea203d0ccc | ||
|
|
370cd52774 | ||
|
|
942bae3045 | ||
|
|
356548c8fb | ||
| 5c012c2bc9 | |||
| 9c9b8015a0 | |||
| bba0ced7f9 | |||
|
|
e8de7b56d9 | ||
|
|
95022f62a8 | ||
|
|
1d918f3335 | ||
|
|
f992637ad2 | ||
|
|
40f18bbdf8 | ||
|
|
3bb9cec08a | ||
|
|
6842260f59 | ||
|
|
305c30d725 | ||
|
|
e799dd2f08 | ||
| 1e83172e9a | |||
|
|
475d236b7e | ||
|
|
ddeb84fcfe | ||
|
|
b3aeebb7c7 | ||
|
|
b11f4839f4 | ||
|
|
4adc28a055 | ||
|
|
e46e9e1d3a | ||
|
|
4fcb26bbde | ||
|
|
6bd0e891fa | ||
|
|
15f1308557 | ||
|
|
9689197db9 | ||
|
|
4ad490657f | ||
|
|
9f8f8244e3 | ||
|
|
9206be2562 | ||
|
|
6065fd1f67 | ||
|
|
c16560a0ca | ||
|
|
440cfe1ac5 | ||
|
|
1ad1a0198e | ||
|
|
b603ac9bdb | ||
|
|
68aa4c409b | ||
|
|
f22b4e7fb8 | ||
|
|
400328d5fa | ||
|
|
cce3e6861a | ||
|
|
55368ce9b8 | ||
|
|
c6ef54f7d3 | ||
| 6f97c48226 | |||
| 5f45bc98fb | |||
|
|
5738594be2 | ||
|
|
ce47831992 | ||
| 634c2d84fc | |||
| 70855c5a21 | |||
|
|
b1e5e70411 | ||
|
|
bf2e3219fc | ||
|
|
2f5aeb9ffc | ||
| 9e8ed310fc | |||
| 07a5e32579 | |||
|
|
fe1bb04922 | ||
| a75e964adc | |||
|
|
87d22032e6 | ||
|
|
55ae64b3e1 | ||
|
|
891c6d8e93 | ||
|
|
ba7747dfe9 | ||
| b148c04059 | |||
|
|
4e179d61b5 | ||
|
|
b23ee84543 | ||
|
|
d02f85cea5 | ||
| ab02f8f1b3 | |||
| 8fc1d1ffc9 | |||
|
|
44b1da94c1 | ||
|
|
c2b63a7a3f | ||
|
|
56619c9140 | ||
|
|
99bbb5434d | ||
| 40c9c5fdad | |||
|
|
3ea2c93e43 | ||
|
|
6369c8ee63 | ||
|
|
da4bbf1e2c | ||
|
|
14e5535fd8 | ||
|
|
4e53bb3b27 | ||
| e793fdbe42 | |||
| 0e41a5b9f1 | |||
|
|
ac9dfd1669 | ||
|
|
72eb3e189b | ||
| 0cace11975 | |||
| b8e502b168 | |||
|
|
15502d0107 | ||
| cb4e4646bd | |||
| 93ce1b4994 | |||
|
|
1c452b5574 | ||
|
|
876c06ef54 | ||
|
|
37d65a944d | ||
|
|
7bc9321c86 | ||
|
|
ee564dccb6 | ||
| cdbb386c7c | |||
| 325ade7cdc | |||
|
|
fcd8c1a0dd | ||
|
|
fa1cb02a51 | ||
|
|
40fe12cd96 | ||
|
|
d83c04dc8b | ||
|
|
23b2974597 | ||
|
|
f5e78316ef | ||
|
|
cc2020f3d6 | ||
|
|
26cda335c5 | ||
|
|
171533cef0 | ||
|
|
69de6dd7a3 | ||
|
|
9039ed4bdc | ||
|
|
131d3b7018 | ||
|
|
454aabdc97 | ||
|
|
089c97d859 | ||
|
|
9ff5423368 | ||
|
|
f29d6e8d88 | ||
|
|
5199ee2db0 | ||
|
|
6de9e22b4c | ||
|
|
52968d9aaa | ||
|
|
b584142f5e | ||
|
|
edea30a406 | ||
|
|
1f3024eb91 | ||
| 8b9abba74b | |||
|
|
4dec1392f7 | ||
|
|
e54cbfbc0a | ||
|
|
505cd93446 | ||
|
|
f3ee11ebab | ||
|
|
45295ef898 | ||
|
|
0635dda6a0 | ||
|
|
f58f7b97e5 | ||
|
|
7556f0e5bc | ||
|
|
17fe29cb1b | ||
|
|
4bb4eb80d9 | ||
| ae1507e775 | |||
|
|
85d8a57bf7 | ||
|
|
42cf23a516 | ||
|
|
858cf75b46 | ||
|
|
de8a392d2c | ||
|
|
b614767b2d | ||
|
|
5ebb8549bf | ||
|
|
ead1feb379 | ||
|
|
1474c15bd9 | ||
|
|
f24f87dcc8 | ||
|
|
d416f46b3a | ||
| 352df35205 | |||
|
|
e5f201515e | ||
|
|
40520a7d30 | ||
|
|
cffbfe1380 | ||
|
|
839777ea4d | ||
|
|
5be1d22115 | ||
|
|
80d1912fd5 | ||
|
|
b94e0323d9 | ||
|
|
90f4e53e9f | ||
|
|
7ebad7d6b9 | ||
|
|
34534a1dbf | ||
| 645fac0681 | |||
| 0a23700403 | |||
|
|
c00f8843c0 | ||
|
|
8869974471 | ||
|
|
8125d60105 | ||
|
|
5a32d5b7a8 | ||
|
|
a1d113562b | ||
|
|
4a7535e4f5 | ||
|
|
de5548bbbd | ||
|
|
87c46e8477 | ||
|
|
edda224847 | ||
|
|
5ac6bbf04b | ||
|
|
b0a5329937 | ||
|
|
7a0626413d | ||
| fe04ad1573 | |||
|
|
689cc39bbc | ||
|
|
ba0c577514 | ||
|
|
a629907196 | ||
|
|
bf60bcfe12 | ||
|
|
27eb9a7d93 | ||
|
|
336ee843cc | ||
|
|
9eac101794 | ||
|
|
085fcc62aa | ||
|
|
99e6abbcfd | ||
| a4b96066e0 | |||
|
|
c4e2da8d67 | ||
|
|
1be15ee849 | ||
|
|
99bc54349b | ||
|
|
bf823ddff0 | ||
|
|
23e72f38a6 | ||
|
|
2d993b2f73 | ||
| 9703d35a3a | |||
|
|
d10a7a4884 | ||
|
|
938b9054d3 | ||
|
|
8a5bcca901 | ||
|
|
410cd53e51 | ||
|
|
4031724fa9 | ||
|
|
e95552e6b9 | ||
|
|
012f7e3346 | ||
|
|
cbe6c4a98d | ||
|
|
aa52778e99 | ||
|
|
5e8dda0b75 | ||
|
|
081aeacff7 | ||
|
|
65e54ee2b5 | ||
|
|
0fd6ebf810 | ||
|
|
fa4b5d26e5 | ||
|
|
23f45b38cb | ||
|
|
d76b055730 | ||
|
|
c334c07b39 | ||
|
|
45a5dcb068 | ||
|
|
3d9ba8b1cb | ||
|
|
c6836cad06 | ||
|
|
e70d1cb3f2 | ||
|
|
af454e1a56 | ||
|
|
6ce58e86ad | ||
| 2e17531c52 | |||
|
|
6b76d89507 | ||
|
|
e4025e39cb | ||
|
|
af12dc8d0a | ||
|
|
f0edeaee85 | ||
|
|
5cbdadecc4 | ||
|
|
30c1f90513 | ||
| c241d8b819 | |||
| 24f12a3590 | |||
|
|
f17f5c9925 | ||
|
|
99877b1c98 | ||
|
|
fdf91965d9 | ||
|
|
fd21d32f4a | ||
|
|
0a4385f29b | ||
|
|
63c6693d04 | ||
|
|
ff7084a332 | ||
|
|
b63e8897f5 | ||
|
|
dc3976f525 | ||
|
|
9b8765f001 | ||
| bbe23e1b14 | |||
|
|
5f0b36b3bb | ||
|
|
f0b75eae2f | ||
|
|
45e62b2750 | ||
|
|
d11e4822ed | ||
|
|
93b67fe845 | ||
|
|
ebc2ac1a41 | ||
|
|
4fd2f10ec6 | ||
|
|
2715871017 | ||
|
|
4cfca89895 | ||
| 53ead0e62f | |||
|
|
b00967159a | ||
|
|
1b37684e3c | ||
|
|
48f393be25 | ||
|
|
645fb83bce | ||
|
|
fe8bc407d3 | ||
|
|
d20cab57be | ||
|
|
68df3d5e23 | ||
|
|
8984bc577e | ||
|
|
07d02307e2 | ||
|
|
a027dc75c3 | ||
|
|
5da07d8631 | ||
|
|
d061fc9b32 | ||
|
|
ae47d429ba | ||
|
|
396d6a7336 | ||
|
|
fdf826d5f8 | ||
|
|
0db5fa650f | ||
|
|
53b4616a87 | ||
|
|
b923b7c35d | ||
|
|
8bd5351d29 | ||
|
|
726f7841e8 | ||
|
|
47883ce426 | ||
|
|
2459fc1848 | ||
|
|
cbc11f636a | ||
|
|
5dbd6eb8be | ||
|
|
167716e61b | ||
|
|
6d7f045bce | ||
|
|
a73417ea02 | ||
|
|
9c3850db98 | ||
| 393ad5fa0b | |||
|
|
9e8fe2c91f | ||
|
|
b57a7edf28 | ||
|
|
85cc5ebb27 | ||
| 0cd32fbb5f | |||
|
|
2833e65f57 | ||
|
|
5a29403636 | ||
|
|
9c0b9a7c93 | ||
|
|
69a4cbbbc2 | ||
|
|
e2b2382cc4 | ||
|
|
f8a4d05f57 | ||
|
|
d996c43f9f | ||
|
|
c195a58eb4 | ||
| b1c9375873 | |||
|
|
6010cbf20a | ||
|
|
11c32ed360 | ||
|
|
0494822ff4 | ||
|
|
2611f43d1f | ||
| ea4edfadd0 | |||
|
|
8e2a22cf61 | ||
|
|
3a1cfe0f31 | ||
|
|
5bdc44b301 | ||
|
|
92a1736667 | ||
|
|
57f9238033 | ||
|
|
1b171d4b8d | ||
|
|
c5acb84d97 | ||
|
|
63a1e9ec56 | ||
|
|
f06a8d6b15 | ||
| 92df927453 | |||
|
|
2878dce69d | ||
|
|
7d5d128b54 | ||
|
|
6e9e3db358 | ||
|
|
a415ffa12a | ||
|
|
9e8cdaead6 | ||
|
|
e5d4aae846 | ||
|
|
d6af35828d | ||
|
|
aa86c5e662 | ||
|
|
f99aa94b8f | ||
|
|
f5c226ba28 | ||
|
|
741020fe79 | ||
|
|
33004e081d |
@@ -1,112 +0,0 @@
|
||||
import axios, { AxiosInstance, AxiosError, AxiosRequestConfig, InternalAxiosRequestConfig, AxiosResponse } from "axios";
|
||||
import { showFullScreenLoading, tryHideFullScreenLoading } from "@/components/Loading/fullScreen";
|
||||
import { LOGIN_URL } from "@/config";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { ResultData } from "@/api/interface";
|
||||
import { ResultEnum } from "@/enums/httpEnum";
|
||||
import { checkStatus } from "./helper/checkStatus";
|
||||
import { useUserStore } from "@/stores/modules/user";
|
||||
import router from "@/routers";
|
||||
|
||||
export interface CustomAxiosRequestConfig extends InternalAxiosRequestConfig {
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
const config = {
|
||||
// 默认地址请求地址,可在 .env.** 文件中修改
|
||||
baseURL: import.meta.env.VITE_API_URL as string,
|
||||
// 设置超时时间
|
||||
timeout: ResultEnum.TIMEOUT as number,
|
||||
// 跨域时候允许携带凭证
|
||||
withCredentials: true,
|
||||
// post请求指定数据类型以及编码
|
||||
headers: { 'Content-Type': 'application/json;charset=utf-8' }
|
||||
};
|
||||
|
||||
class RequestHttp {
|
||||
service: AxiosInstance;
|
||||
public constructor(config: AxiosRequestConfig) {
|
||||
// 创建实例
|
||||
this.service = axios.create(config);
|
||||
|
||||
/**
|
||||
* @description 请求拦截器
|
||||
* 客户端发送请求 -> [请求拦截器] -> 服务器
|
||||
* token校验(JWT) : 接受服务器返回的 token,存储到 vuex/pinia/本地储存当中
|
||||
*/
|
||||
this.service.interceptors.request.use(
|
||||
(config: CustomAxiosRequestConfig) => {
|
||||
const userStore = useUserStore();
|
||||
// 当前请求不需要显示 loading,在 api 服务中通过指定的第三个参数: { loading: false } 来控制
|
||||
config.loading ?? (config.loading = true);
|
||||
config.loading && showFullScreenLoading();
|
||||
if (config.headers && typeof config.headers.set === "function") {
|
||||
config.headers.set("x-access-token", userStore.token);
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error: AxiosError) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* @description 响应拦截器
|
||||
* 服务器换返回信息 -> [拦截统一处理] -> 客户端JS获取到信息
|
||||
*/
|
||||
this.service.interceptors.response.use(
|
||||
(response: AxiosResponse) => {
|
||||
const { data } = response;
|
||||
const userStore = useUserStore();
|
||||
tryHideFullScreenLoading();
|
||||
// 登陆失效
|
||||
if (data.code == ResultEnum.OVERDUE) {
|
||||
userStore.setToken("");
|
||||
router.replace(LOGIN_URL);
|
||||
ElMessage.error(data.message);
|
||||
return Promise.reject(data);
|
||||
}
|
||||
// 全局错误信息拦截(防止下载文件的时候返回数据流,没有 code 直接报错)
|
||||
if (data.code && data.code !== ResultEnum.SUCCESS) {
|
||||
ElMessage.error(data.message);
|
||||
return Promise.reject(data);
|
||||
}
|
||||
// 成功请求(在页面上除非特殊情况,否则不用处理失败逻辑)
|
||||
return data;
|
||||
},
|
||||
async (error: AxiosError) => {
|
||||
const { response } = error;
|
||||
tryHideFullScreenLoading();
|
||||
// 请求超时 && 网络错误单独判断,没有 response
|
||||
if (error.message.indexOf("timeout") !== -1) ElMessage.error("请求超时!请您稍后重试");
|
||||
if (error.message.indexOf("Network Error") !== -1) ElMessage.error("网络错误!请您稍后重试");
|
||||
// 根据服务器响应的错误状态码,做不同的处理
|
||||
if (response) checkStatus(response.status);
|
||||
// 服务器结果都没有返回(可能服务器错误可能客户端断网),断网处理:可以跳转到断网页面
|
||||
if (!window.navigator.onLine) router.replace("/500");
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 常用请求方法封装
|
||||
*/
|
||||
get<T>(url: string, params?: object, _object = {}): Promise<ResultData<T>> {
|
||||
return this.service.get(url, { params, ..._object });
|
||||
}
|
||||
post<T>(url: string, params?: object | string, _object = {}): Promise<ResultData<T>> {
|
||||
return this.service.post(url, params, _object);
|
||||
}
|
||||
put<T>(url: string, params?: object, _object = {}): Promise<ResultData<T>> {
|
||||
return this.service.put(url, params, _object);
|
||||
}
|
||||
delete<T>(url: string, params?: any, _object = {}): Promise<ResultData<T>> {
|
||||
return this.service.delete(url, { params, ..._object });
|
||||
}
|
||||
download(url: string, params?: object, _object = {}): Promise<BlobPart> {
|
||||
return this.service.post(url, params, { ..._object, responseType: "blob" });
|
||||
}
|
||||
}
|
||||
|
||||
export default new RequestHttp(config);
|
||||
12
.vscode/settings.json
vendored
12
.vscode/settings.json
vendored
@@ -1,18 +1,28 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"Analyse",
|
||||
"CHNFACTOR",
|
||||
"CHNPACTOR",
|
||||
"Chns",
|
||||
"Combox",
|
||||
"Datasource",
|
||||
"daterange",
|
||||
"devicedata",
|
||||
"errordata",
|
||||
"errordetail",
|
||||
"Interharmonic",
|
||||
"IRMS",
|
||||
"logdata",
|
||||
"MSQI",
|
||||
"Pids",
|
||||
"plandata",
|
||||
"PQDIF",
|
||||
"Preinvestment",
|
||||
"resourcedata",
|
||||
"resourcename",
|
||||
"rmark",
|
||||
"showtest"
|
||||
"showtest",
|
||||
"UNBAN",
|
||||
"VRMS"
|
||||
]
|
||||
}
|
||||
@@ -25,10 +25,10 @@ module.exports = (appInfo) => {
|
||||
*/
|
||||
config.windowsOption = {
|
||||
title: '自动检测平台',
|
||||
width: 1280,
|
||||
height: 850,
|
||||
minWidth: 1280,
|
||||
minHeight: 850,
|
||||
width: 1600,
|
||||
height: 950,
|
||||
minWidth: 1600,
|
||||
minHeight: 950,
|
||||
webPreferences: {
|
||||
//webSecurity: false,
|
||||
contextIsolation: false, // false -> 可在渲染进程中使用electron的api,true->需要bridge.js(contextBridge)
|
||||
|
||||
@@ -19,6 +19,7 @@ VITE_API_URL=/api
|
||||
|
||||
# 开发环境跨域代理,支持配置多个
|
||||
|
||||
#VITE_PROXY=[["/api","http://127.0.0.1:18092/"]]
|
||||
VITE_PROXY=[["/api","http://192.168.1.124:18092/"]]
|
||||
# VITE_PROXY=[["/api","http://192.168.1.125:18092/"]]
|
||||
#VITE_PROXY=[["/api","http://192.168.1.125:18092/"]]
|
||||
# VITE_PROXY=[["/api","http://192.168.1.138:8080/"]]张文
|
||||
|
||||
@@ -22,4 +22,5 @@ VITE_DROP_CONSOLE=true
|
||||
VITE_PWA=true
|
||||
|
||||
# 线上环境接口地址
|
||||
#VITE_API_URL="/api" # 打包时用
|
||||
VITE_API_URL="http://192.168.1.125:18092/"
|
||||
|
||||
11
frontend/.prettierrc
Normal file
11
frontend/.prettierrc
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"tabWidth": 4,
|
||||
"printWidth": 120,
|
||||
"useTabs": false,
|
||||
"semi": false,
|
||||
"arrowParens": "avoid",
|
||||
"endOfLine": "lf",
|
||||
"htmlWhitespaceSensitivity": "ignore"
|
||||
}
|
||||
@@ -22,9 +22,11 @@
|
||||
"echarts": "^5.4.3",
|
||||
"echarts-liquidfill": "^3.1.0",
|
||||
"element-plus": "^2.7.8",
|
||||
"html2canvas": "^1.4.1",
|
||||
"md5": "^2.3.0",
|
||||
"mitt": "^3.0.1",
|
||||
"mkdirp": "^3.0.1",
|
||||
"node-forge": "^1.3.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.2.1",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
@@ -41,11 +43,14 @@
|
||||
"devDependencies": {
|
||||
"@rushstack/eslint-patch": "^1.8.0",
|
||||
"@tsconfig/node20": "^20.1.4",
|
||||
"@types/html2canvas": "^1.0.0",
|
||||
"@types/md5": "^2.3.2",
|
||||
"@types/node": "^20.14.14",
|
||||
"@types/node-forge": "^1.3.11",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/qs": "^6.9.8",
|
||||
"@types/sortablejs": "^1.15.2",
|
||||
"@types/xlsx": "^0.0.36",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.0",
|
||||
"@typescript-eslint/parser": "^6.7.0",
|
||||
"@vitejs/plugin-vue": "^5.0.5",
|
||||
@@ -71,7 +76,7 @@
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-eslint": "^1.8.1",
|
||||
"vite-plugin-html": "^3.2.0",
|
||||
"vite-plugin-node-polyfills": "^0.22.0",
|
||||
"vite-plugin-node-polyfills": "^0.23.0",
|
||||
"vite-plugin-pwa": "^0.16.5",
|
||||
"vite-plugin-svg-icons": "^2.0.1",
|
||||
"vue-tsc": "^2.0.21"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
:size='assemblySize'
|
||||
:button='buttonConfig'
|
||||
>
|
||||
<router-view :key='$route.fullPath' />
|
||||
<router-view />
|
||||
</el-config-provider>
|
||||
</template>
|
||||
|
||||
|
||||
205
frontend/src/api/check/interface/index.ts
Normal file
205
frontend/src/api/check/interface/index.ts
Normal file
@@ -0,0 +1,205 @@
|
||||
export namespace CheckData {
|
||||
export interface DataCheck {
|
||||
scriptName: string,
|
||||
errorSysId: string,
|
||||
dataRule: string,
|
||||
deviceName: string,
|
||||
chnNum: string,
|
||||
}
|
||||
|
||||
export interface PhaseCheckResult {
|
||||
// 检测源定值-标准值
|
||||
resultData: number,
|
||||
// 装置原始数据-被检值
|
||||
data: number,
|
||||
|
||||
// 误差值
|
||||
errorData: number,
|
||||
// 第几次谐波
|
||||
num?: number,
|
||||
//符合、不符合
|
||||
isData?: number,
|
||||
//最大误差值
|
||||
radius?: string,
|
||||
unit?: string,
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于定义 查看(设备)通道检测结果响应数据 类型
|
||||
*/
|
||||
export interface ResCheckResult {
|
||||
dataA?: PhaseCheckResult | null,
|
||||
dataB?: PhaseCheckResult | null,
|
||||
dataC?: PhaseCheckResult | null,
|
||||
dataT?: PhaseCheckResult | null,
|
||||
|
||||
// 第几次谐波
|
||||
//num: number | null,
|
||||
//符合、不符合
|
||||
isData?: number,
|
||||
//最大误差值
|
||||
radius?: string,
|
||||
//单位
|
||||
unit?: string,
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于定义 查看(设备)通道检测结果表格展示数据 类型
|
||||
*/
|
||||
export interface CheckResult {
|
||||
stdA?: string,
|
||||
dataA?: string,
|
||||
errorA?: string,
|
||||
maxErrorA?: string,
|
||||
isDataA?: number,
|
||||
unitA?: string,
|
||||
stdB?: string,
|
||||
dataB?: string,
|
||||
errorB?: string,
|
||||
maxErrorB?: string,
|
||||
isDataB?: number,
|
||||
unitB?: string,
|
||||
stdC?: string,
|
||||
dataC?: string,
|
||||
errorC?: string,
|
||||
maxErrorC?: string,
|
||||
isDataC?: number,
|
||||
unitC?: string,
|
||||
stdT?: string,
|
||||
dataT?: string,
|
||||
errorT?: string,
|
||||
maxErrorT?: string,
|
||||
isDataT?: number,
|
||||
unitT?: string,
|
||||
|
||||
//最大误差值
|
||||
maxError?: string,
|
||||
unit?: string,
|
||||
//符合、不符合
|
||||
result?: number,
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于定义 具体通道的原始数据类型
|
||||
*/
|
||||
export interface RawDataItem {
|
||||
time?: string,
|
||||
harmNum?: number | null,
|
||||
dataA?: string,
|
||||
dataB?: string,
|
||||
dataC?: string,
|
||||
dataT?: string,
|
||||
unit?: string | null
|
||||
}
|
||||
|
||||
export interface Device {
|
||||
deviceId: string; //装置序号Id
|
||||
deviceName: string; //设备名称
|
||||
chnNum: number; //设备通道数
|
||||
|
||||
planId: string; //计划Id
|
||||
devType: string; //设备类型
|
||||
devVolt: number; //设备电压
|
||||
devCurr: number; //设备电流
|
||||
factorFlag: number; //是否支持系数校准
|
||||
checkResult:number; //检测结果
|
||||
}
|
||||
|
||||
// 用来描述检测脚本类型
|
||||
export interface ScriptItem {
|
||||
id: string,
|
||||
code: string,
|
||||
scriptName: string,
|
||||
}
|
||||
|
||||
// 用来描述 检测数据-左侧树结构
|
||||
export interface TreeItem {
|
||||
id: string | null,
|
||||
scriptTypeName: string | null,
|
||||
sourceDesc: string | null,
|
||||
harmNum: number | null,
|
||||
index: number | null,
|
||||
fly: number | null,
|
||||
children: TreeItem[] | null,
|
||||
}
|
||||
|
||||
// 用来描述 通道检测结果
|
||||
export enum ChnCheckResultEnum {
|
||||
UNKNOWN = -1,
|
||||
LOADING = 0,
|
||||
SUCCESS = 1,
|
||||
FAIL = 2,
|
||||
TIMEOUT = 3,
|
||||
ERRORDATA = 4,
|
||||
NOT_PART_IN_ERROR = 5
|
||||
}
|
||||
|
||||
export interface DeviceCheckResult {
|
||||
deviceId: string,
|
||||
deviceName: string,
|
||||
chnResult: ChnCheckResultEnum[] //通道检测结果
|
||||
}
|
||||
|
||||
//用来描述 某个脚本测试项对所有通道的检测结果
|
||||
export interface ScriptChnItem {
|
||||
scriptType: string
|
||||
scriptName?: string //可以不要该属性,有点多余
|
||||
|
||||
// 设备
|
||||
devices: Array<DeviceCheckResult>
|
||||
}
|
||||
|
||||
export enum ButtonColorEnum {
|
||||
INFO = '#909399',
|
||||
LOADING = 'var(--el-color-primary)',
|
||||
SUCCESS = '#91cc75',
|
||||
WARNING = '#e6a23c',
|
||||
DANGER = '#f56c6c',
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于描述 (设备)通道检测结果展示的按钮类型
|
||||
*/
|
||||
export interface ButtonResult {
|
||||
color: ButtonColorEnum
|
||||
icon: 'More' | 'Loading' | 'Close' | 'CircleCheckFilled' | 'Link' | 'WarnTriangleFilled' | 'Minus'
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于描述 脚本检测结果展示的按钮类型
|
||||
*/
|
||||
export interface ScriptChnViewItem {
|
||||
scriptType: string,
|
||||
scriptName?: string //脚本项名称,可以不要该属性,有点多余
|
||||
|
||||
// 设备
|
||||
devices: Array<{
|
||||
deviceId: string,
|
||||
deviceName: string,
|
||||
chnResult: ButtonResult[],
|
||||
}>
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 定义检测日志类型
|
||||
*/
|
||||
export interface LogItem {
|
||||
type: 'info' | 'warning' | 'error'
|
||||
log: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义手动检测时,勾选的测试项
|
||||
*/
|
||||
export interface SelectTestItem {
|
||||
preTest: boolean,
|
||||
timeTest: boolean,
|
||||
channelsTest: boolean,
|
||||
test: boolean
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
99
frontend/src/api/check/test/index.ts
Normal file
99
frontend/src/api/check/test/index.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import http from "@/api";
|
||||
import {CheckData} from "@/api/check/interface";
|
||||
|
||||
export const getBigTestItem = (params: {
|
||||
reCheckType: number,
|
||||
planId: string,
|
||||
devIds: string[],
|
||||
}) => {
|
||||
return http.post(`/adPlan/getBigTestItem`, params, {loading: false});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取弹出框表单数据
|
||||
* @param params 当为scriptType为null时,表示查询所有脚本类型,否则只查询指定脚本类型。当为chnNum为-1时,表示查询所有通道,否则只查询指定通道。
|
||||
*/
|
||||
export const getFormData = (params: {
|
||||
planId: string,
|
||||
deviceId: string,
|
||||
chnNum: string,
|
||||
scriptType: string | null
|
||||
}) => {
|
||||
return http.post("/result/formContent/", params, {loading: false});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取树形结构数据
|
||||
* @param params
|
||||
*/
|
||||
export const getTreeData = (params: {
|
||||
scriptId?: string,
|
||||
devId?: string,
|
||||
devNum?: string,
|
||||
scriptType?: string | null,
|
||||
code?: string,
|
||||
}) => {
|
||||
return http.post<CheckData.TreeItem[]>("/result/treeData/", params, {loading: false});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取检查数据
|
||||
* @param params
|
||||
*/
|
||||
export const getTableData = (params: {
|
||||
scriptType: string | null,
|
||||
scriptId: string,
|
||||
devId: string,
|
||||
devNum: string,
|
||||
code: string,
|
||||
index: number,
|
||||
}) => {
|
||||
return http.post("/result/resultData/", params, {loading: false});
|
||||
}
|
||||
|
||||
export const exportRawData = (params: {
|
||||
scriptType: string | null,
|
||||
scriptId: string,
|
||||
devId: string,
|
||||
devNum: string,
|
||||
code: string,
|
||||
index: number,
|
||||
}) => {
|
||||
return http.download("/result/exportRawData", params, {loading: false});
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新计算
|
||||
* @param params
|
||||
*/
|
||||
export const reCalculate = (params: {
|
||||
planId: string,
|
||||
scriptId: string,
|
||||
errorSysId: string,
|
||||
deviceId: string,
|
||||
code: string
|
||||
}) => {
|
||||
return http.post("/result/reCalculate", params, {loading: true});
|
||||
}
|
||||
|
||||
/**
|
||||
* 更换误差体系
|
||||
* @param params
|
||||
*/
|
||||
export const changeErrorSystem = (params: {
|
||||
planId: string,
|
||||
scriptId: string,
|
||||
errorSysId: string,
|
||||
deviceId: string,
|
||||
code: string
|
||||
}) => {
|
||||
return http.post("/result/changeErrorSystem", params, {loading: true});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除(误差体系切换时产生的)临时表
|
||||
* @param code
|
||||
*/
|
||||
export const deleteTempTable = (code: string) => {
|
||||
return http.get(`/result/deleteTempTable?code=${code}`, null, {loading: false})
|
||||
}
|
||||
24
frontend/src/api/device/controlSource/index.ts
Normal file
24
frontend/src/api/device/controlSource/index.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
import type { controlSource } from '@/api/device/interface/controlSource'
|
||||
import http from '@/api'
|
||||
|
||||
/**
|
||||
* @name 程控源管理模块
|
||||
*/
|
||||
|
||||
//通讯校验
|
||||
export const checkSimulate = (params: controlSource.ResControl) => {
|
||||
return http.post(`/prepare/ytxCheckSimulate`,params)
|
||||
}
|
||||
|
||||
//启动
|
||||
export const startSimulateTest = (params: controlSource.ResControl) => {
|
||||
return http.post(`prepare/startSimulateTest`,params,{loading:false})
|
||||
}
|
||||
|
||||
//停止
|
||||
export const closeSimulateTest = (params: controlSource.ResControl) => {
|
||||
return http.post(`/prepare/closeSimulateTest`,params,{loading:false})
|
||||
}
|
||||
|
||||
|
||||
29
frontend/src/api/device/devType/index.ts
Normal file
29
frontend/src/api/device/devType/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import type { DevType } from '@/api/device/interface/devType'
|
||||
import http from '@/api'
|
||||
|
||||
/**
|
||||
* @name 设备类型管理模块
|
||||
*/
|
||||
|
||||
//获取设备类型
|
||||
export const getDevTypeList = (params: DevType.ReqPqDevTypeParams) => {
|
||||
return http.post(`/devType/list`, params)
|
||||
}
|
||||
|
||||
//添加设备类型
|
||||
export const addDevType = (params: DevType.ResPqDevType) => {
|
||||
return http.post(`/devType/add`, params)
|
||||
}
|
||||
|
||||
//编辑设备类型
|
||||
export const updateDevType = (params: DevType.ResPqDevType) => {
|
||||
return http.post(`/devType/update`, params)
|
||||
}
|
||||
|
||||
//删除设备类型
|
||||
export const deleteDevType = (params: string[]) => {
|
||||
return http.post(`/devType/delete`, params)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -48,64 +48,64 @@ const data = [
|
||||
{
|
||||
id: '1', //装置序号ID
|
||||
name: '240001', //设备名称
|
||||
dev_Type: 'PQS882A',//设备类型
|
||||
dev_Chns: 1, //设备通道数
|
||||
check_Result: '未检测', //检测结果
|
||||
dev_Type: 'PQS-882B4',//设备类型
|
||||
dev_Chns: 4, //设备通道数
|
||||
check_Result: '未检', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'未检测',//检测状态
|
||||
check_State:'未检',//检测状态
|
||||
reCheck_Num: 0, //复检次数
|
||||
},
|
||||
{
|
||||
id: '2', //装置序号ID
|
||||
name: '240002', //设备名称
|
||||
dev_Type: 'PQS882B4',//设备类型
|
||||
dev_Type: 'PQS-882B4',//设备类型
|
||||
dev_Chns: 4, //设备通道数
|
||||
check_Result: '未检测', //检测结果
|
||||
check_Result: '未检', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'未检测',//检测状态
|
||||
check_State:'未检',//检测状态
|
||||
reCheck_Num: 0, //复检次数
|
||||
},
|
||||
{
|
||||
id: '3', //装置序号ID
|
||||
name: '240003', //设备名称
|
||||
dev_Type: 'PQS882B4',//设备类型
|
||||
dev_Type: 'PQS-882B4',//设备类型
|
||||
dev_Chns: 4, //设备通道数
|
||||
check_Result: '未检测', //检测结果
|
||||
check_Result: '未检', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'未检测',//检测状态
|
||||
check_State:'未检',//检测状态
|
||||
reCheck_Num: 0, //复检次数
|
||||
},
|
||||
{
|
||||
id: '4', //装置序号ID
|
||||
name: '240004', //设备名称
|
||||
dev_Type: 'PQS882A',//设备类型
|
||||
dev_Chns: 1, //设备通道数
|
||||
check_Result: '未检测', //检测结果
|
||||
dev_Type: 'PQS-882B4',//设备类型
|
||||
dev_Chns: 4, //设备通道数
|
||||
check_Result: '未检', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'未检测',//检测状态
|
||||
check_State:'未检',//检测状态
|
||||
reCheck_Num: 0, //复检次数
|
||||
},
|
||||
{
|
||||
id: '5', //装置序号ID
|
||||
name: '240005', //设备名称
|
||||
dev_Type: 'PQS882A',//设备类型
|
||||
dev_Type: 'PQS-882A',//设备类型
|
||||
dev_Chns: 1, //设备通道数
|
||||
check_Result: '有不合格项', //检测结果
|
||||
check_Result: '不符合', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'检测完成',//检测状态
|
||||
reCheck_Num: 0, //复检次数
|
||||
reCheck_Num: 1, //复检次数
|
||||
},
|
||||
{
|
||||
id: '6', //装置序号ID
|
||||
name: '240006', //设备名称
|
||||
dev_Type: 'PQS882B4',//设备类型
|
||||
dev_Type: 'PQS-882B4',//设备类型
|
||||
dev_Chns: 4, //设备通道数
|
||||
check_Result: '有不合格项', //检测结果
|
||||
check_Result: '不符合', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'检测完成',//检测状态
|
||||
@@ -114,9 +114,9 @@ const data = [
|
||||
{
|
||||
id: '7', //装置序号ID
|
||||
name: '240007', //设备名称
|
||||
dev_Type: 'PQS882A',//设备类型
|
||||
dev_Type: 'PQS-882A',//设备类型
|
||||
dev_Chns: 1, //设备通道数
|
||||
check_Result: '全部合格', //检测结果
|
||||
check_Result: '符合', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'检测完成',//检测状态
|
||||
@@ -125,20 +125,20 @@ const data = [
|
||||
{
|
||||
id: '8', //装置序号ID
|
||||
name: '240008', //设备名称
|
||||
dev_Type: 'PQS882B4',//设备类型
|
||||
dev_Type: 'PQS-882B4',//设备类型
|
||||
dev_Chns: 4, //设备通道数
|
||||
check_Result: '全部合格', //检测结果
|
||||
check_Result: '符合', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'检测完成',//检测状态
|
||||
reCheck_Num: 0, //复检次数
|
||||
reCheck_Num: 1, //复检次数
|
||||
},
|
||||
{
|
||||
id: '9', //装置序号ID
|
||||
name: '240009', //设备名称
|
||||
dev_Type: 'PQS882B4',//设备类型
|
||||
dev_Type: 'PQS-882B4',//设备类型
|
||||
dev_Chns: 4, //设备通道数
|
||||
check_Result: '有不合格项', //检测结果
|
||||
check_Result: '不符合', //检测结果
|
||||
report_State: '已生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'检测完成',//检测状态
|
||||
@@ -147,9 +147,9 @@ const data = [
|
||||
{
|
||||
id: '10', //装置序号ID
|
||||
name: '240010', //设备名称
|
||||
dev_Type: 'PQS882A',//设备类型
|
||||
dev_Type: 'PQS-882A',//设备类型
|
||||
dev_Chns: 1, //设备通道数
|
||||
check_Result: '全部合格', //检测结果
|
||||
check_Result: '符合', //检测结果
|
||||
report_State: '已生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'检测完成',//检测状态
|
||||
@@ -158,9 +158,9 @@ const data = [
|
||||
{
|
||||
id: '11', //装置序号ID
|
||||
name: '240011', //设备名称
|
||||
dev_Type: 'PQS882A',//设备类型
|
||||
dev_Type: 'PQS-882A',//设备类型
|
||||
dev_Chns: 1, //设备通道数
|
||||
check_Result: '全部合格', //检测结果
|
||||
check_Result: '符合', //检测结果
|
||||
report_State: '已生成', //报告状态
|
||||
document_State: '已归档', //归档状态
|
||||
check_State:'检测完成',//检测状态
|
||||
@@ -169,9 +169,9 @@ const data = [
|
||||
{
|
||||
id: '12', //装置序号ID
|
||||
name: '240012', //设备名称
|
||||
dev_Type: 'PQS882B4',//设备类型
|
||||
dev_Type: 'PQS-882B4',//设备类型
|
||||
dev_Chns: 4, //设备通道数
|
||||
check_Result: '全部合格', //检测结果
|
||||
check_Result: '符合', //检测结果
|
||||
report_State: '已生成', //报告状态
|
||||
document_State: '已归档', //归档状态
|
||||
check_State:'检测完成',//检测状态
|
||||
@@ -180,89 +180,89 @@ const data = [
|
||||
{
|
||||
id: '13', //装置序号ID
|
||||
name: '240013', //设备名称
|
||||
dev_Type: 'PQS882A',//设备类型
|
||||
dev_Type: 'PQS-882A',//设备类型
|
||||
dev_Chns: 1, //设备通道数
|
||||
check_Result: '未检测', //检测结果
|
||||
check_Result: '未检', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'未检测',//检测状态
|
||||
check_State:'未检',//检测状态
|
||||
reCheck_Num: 0, //复检次数
|
||||
},
|
||||
{
|
||||
id: '14', //装置序号ID
|
||||
name: '240014', //设备名称
|
||||
dev_Type: 'PQS882A',//设备类型
|
||||
dev_Type: 'PQS-882A',//设备类型
|
||||
dev_Chns: 1, //设备通道数
|
||||
check_Result: '未检测', //检测结果
|
||||
check_Result: '未检', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'未检测',//检测状态
|
||||
check_State:'未检',//检测状态
|
||||
reCheck_Num: 0, //复检次数
|
||||
},
|
||||
{
|
||||
id: '15', //装置序号ID
|
||||
name: '240013', //设备名称
|
||||
dev_Type: 'PQS882A',//设备类型
|
||||
name: '240015', //设备名称
|
||||
dev_Type: 'PQS-882A',//设备类型
|
||||
dev_Chns: 1, //设备通道数
|
||||
check_Result: '未检测', //检测结果
|
||||
check_Result: '未检', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'未检测',//检测状态
|
||||
check_State:'未检',//检测状态
|
||||
reCheck_Num: 0, //复检次数
|
||||
},
|
||||
{
|
||||
id: '16', //装置序号ID
|
||||
name: '240014', //设备名称
|
||||
dev_Type: 'PQS882A',//设备类型
|
||||
name: '240016', //设备名称
|
||||
dev_Type: 'PQS-882A',//设备类型
|
||||
dev_Chns: 1, //设备通道数
|
||||
check_Result: '未检测', //检测结果
|
||||
check_Result: '未检', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'未检测',//检测状态
|
||||
check_State:'未检',//检测状态
|
||||
reCheck_Num: 0, //复检次数
|
||||
},
|
||||
{
|
||||
id: '17', //装置序号ID
|
||||
name: '240017', //设备名称
|
||||
dev_Type: 'PQS882A',//设备类型
|
||||
dev_Type: 'PQS-882A',//设备类型
|
||||
dev_Chns: 1, //设备通道数
|
||||
check_Result: '未检测', //检测结果
|
||||
check_Result: '未检', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'未检测',//检测状态
|
||||
check_State:'未检',//检测状态
|
||||
reCheck_Num: 0, //复检次数
|
||||
},
|
||||
{
|
||||
id: '18', //装置序号ID
|
||||
name: '240018', //设备名称
|
||||
dev_Type: 'PQS882A',//设备类型
|
||||
dev_Type: 'PQS-882A',//设备类型
|
||||
dev_Chns: 1, //设备通道数
|
||||
check_Result: '未检测', //检测结果
|
||||
check_Result: '未检', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'未检测',//检测状态
|
||||
check_State:'未检',//检测状态
|
||||
reCheck_Num: 0, //复检次数
|
||||
},
|
||||
{
|
||||
id: '19', //装置序号ID
|
||||
name: '240019', //设备名称
|
||||
dev_Type: 'PQS882A',//设备类型
|
||||
dev_Type: 'PQS-882A',//设备类型
|
||||
dev_Chns: 1, //设备通道数
|
||||
check_Result: '未检测', //检测结果
|
||||
check_Result: '未检', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'未检测',//检测状态
|
||||
check_State:'未检',//检测状态
|
||||
reCheck_Num: 0, //复检次数
|
||||
},
|
||||
{
|
||||
id: '20', //装置序号ID
|
||||
name: '240020', //设备名称
|
||||
dev_Type: 'PQS882A',//设备类型
|
||||
dev_Type: 'PQS-882A',//设备类型
|
||||
dev_Chns: 1, //设备通道数
|
||||
check_Result: '未检测', //检测结果
|
||||
check_Result: '未检', //检测结果
|
||||
report_State: '未生成', //报告状态
|
||||
document_State: '未归档', //归档状态
|
||||
check_State:'未检测',//检测状态
|
||||
check_State:'未检',//检测状态
|
||||
reCheck_Num: 0, //复检次数
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Device } from '@/api/device/interface/device'
|
||||
import type {Device} from '@/api/device/interface/device'
|
||||
import http from '@/api'
|
||||
|
||||
/**
|
||||
@@ -7,33 +7,60 @@ import http from '@/api'
|
||||
|
||||
//获取被检设备
|
||||
export const getPqDevList = (params: Device.ReqPqDevParams) => {
|
||||
return http.post(`/pqDev/list`, params)
|
||||
return http.post(`/pqDev/list`, params)
|
||||
}
|
||||
|
||||
//添加被检设备
|
||||
export const addPqDev = (params: Device.ResPqDev) => {
|
||||
return http.post(`/pqDev/add`, params)
|
||||
return http.post(`/pqDev/add`, params)
|
||||
}
|
||||
|
||||
//编辑被检设备
|
||||
export const updatePqDev = (params: Device.ResPqDev) => {
|
||||
return http.post(`/pqDev/update`, params)
|
||||
return http.post(`/pqDev/update`, params)
|
||||
}
|
||||
|
||||
//删除被检设备
|
||||
export const deletePqDev = (params: string[]) => {
|
||||
return http.post(`/pqDev/delete`, params)
|
||||
return http.post(`/pqDev/delete`, params)
|
||||
}
|
||||
|
||||
//导出被检设备
|
||||
export const exportPqDev=(params: Device.ReqPqDevParams)=>{
|
||||
return http.download(`/pqDev/export`, params)
|
||||
export const exportPqDev = (params: Device.ReqPqDevParams) => {
|
||||
return http.download(`/pqDev/export`, params)
|
||||
}
|
||||
// 下载导入文件模板
|
||||
export const downloadTemplate = () => {
|
||||
return http.download(`/pqDev/downloadTemplate`)
|
||||
}
|
||||
//导入被检设备
|
||||
export const importPqDev=(params: Device.ReqPqDevParams)=>{
|
||||
return http.upload(`/pqDev/import`, params)
|
||||
return http.download(`/pqDev/downloadTemplate`)
|
||||
}
|
||||
|
||||
//导入被检设备
|
||||
export const importPqDev = (params: Device.ReqPqDevParams) => {
|
||||
return http.uploadExcel(`/pqDev/import`, params)
|
||||
}
|
||||
|
||||
//导入比对式被检设备
|
||||
export const importContrastPqDev = (params: Device.ReqPqDevParams) => {
|
||||
return http.upload(`/pqDev/importContrast`, params)
|
||||
}
|
||||
|
||||
// //导出灿能二楼设备
|
||||
// export const exportCNDev = (params: Device.ReqPqDevParams) => {
|
||||
// return http.download(`/pqDev/exportCNDev`, params)
|
||||
// }
|
||||
//
|
||||
// // 下载灿能二楼设备导入文件模板
|
||||
// export const downloadCNDevTemplate = () => {
|
||||
// return http.download(`/pqDev/downloadCNDevTemplate`)
|
||||
// }
|
||||
//
|
||||
// //导入灿能二楼设备
|
||||
// export const importCNDev = (params: Device.ReqPqDevParams) => {
|
||||
// return http.uploadExcel(`/pqDev/importCNDev`, params)
|
||||
// }
|
||||
|
||||
|
||||
//根据设备类型决定(电源、icd、模板、通道数、额定电压、额定电流);
|
||||
export const getPqDev = () => {
|
||||
return http.get(`/devType/listAll`)
|
||||
}
|
||||
|
||||
@@ -30,177 +30,202 @@ const errordata = ref<ErrorSystem.ErrorSystemList[]>([
|
||||
},
|
||||
])
|
||||
|
||||
const errordetail = ref<ErrorSystem.Error_detail[]>([
|
||||
const errorADetail = ref<ErrorSystem.Error_detail[]>([
|
||||
{
|
||||
measured: '电压偏差',
|
||||
col1: '电压偏差',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电压',
|
||||
condition: '10%~150%标称电压',
|
||||
maxErrorValue: '±0.1%Un'
|
||||
},
|
||||
{
|
||||
measured: '频率偏差',
|
||||
col1:'频率偏差',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'频率',
|
||||
condition: '42.5~57.5 Hz',
|
||||
maxErrorValue: '±0.01Hz'
|
||||
},
|
||||
{
|
||||
measured: '三相不平衡度',
|
||||
col1:'三相不平衡度',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电压',
|
||||
condition: '0.5%~5%',
|
||||
maxErrorValue: '±0.15%'
|
||||
},
|
||||
{
|
||||
measured: '三相不平衡度',
|
||||
col1:'三相不平衡度',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电压',
|
||||
condition: '5%(不包含)~ 40%',
|
||||
maxErrorValue: '±0.3%'
|
||||
},
|
||||
{
|
||||
measured: '三相不平衡度',
|
||||
col1:'三相不平衡度',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电流',
|
||||
condition: '',
|
||||
maxErrorValue: '±1%'
|
||||
},
|
||||
{
|
||||
measured: '电压波动幅值',
|
||||
col1:'电压波动',
|
||||
col2: '电压幅值',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电压',
|
||||
condition: '',
|
||||
maxErrorValue: '±0.2%Un'
|
||||
},
|
||||
{
|
||||
measured: '电压波动持续时间',
|
||||
col1:'电压波动',
|
||||
col2: '持续时间',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'时间',
|
||||
condition: '',
|
||||
maxErrorValue: '±1周波'
|
||||
},
|
||||
{
|
||||
measured: '闪变',
|
||||
col1:'闪变',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'短时间闪变',
|
||||
condition: 'Pst:0.2~10',
|
||||
maxErrorValue: '±5%'
|
||||
},
|
||||
{
|
||||
measured: '谐波和间谐波',
|
||||
col1:'谐波和间谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电压',
|
||||
condition: 'Uh≥1%Un',
|
||||
maxErrorValue: '±5%Uh'
|
||||
},
|
||||
{
|
||||
measured: '谐波和间谐波',
|
||||
col1:'谐波和间谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电压',
|
||||
condition: 'Uh<1%Un',
|
||||
maxErrorValue: '±0.05%Un'
|
||||
},
|
||||
{
|
||||
measured: '谐波和间谐波',
|
||||
col1:'谐波和间谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电流',
|
||||
condition: 'In≥3%In',
|
||||
maxErrorValue: '±5%Ih'
|
||||
},
|
||||
{
|
||||
measured: '谐波和间谐波',
|
||||
col1:'谐波和间谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电流',
|
||||
condition: 'In<3%In',
|
||||
maxErrorValue: '±0.15%In'
|
||||
},
|
||||
{
|
||||
measured: '谐波和间谐波',
|
||||
col1:'谐波和间谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'相角',
|
||||
condition: '',
|
||||
maxErrorValue: 'h≤5,±1°*h'
|
||||
},
|
||||
{
|
||||
measured: '谐波和间谐波',
|
||||
col1:'谐波和间谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'相角',
|
||||
condition: '',
|
||||
maxErrorValue: 'h>5,±5°'
|
||||
},
|
||||
{
|
||||
measured: '谐波和间谐波',
|
||||
col1:'谐波和间谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'功率',
|
||||
condition: 'Ph≥150W',
|
||||
maxErrorValue: '±1%Ph'
|
||||
},
|
||||
{
|
||||
measured: '谐波和间谐波',
|
||||
col1:'谐波和间谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'功率',
|
||||
condition: 'Ph<150W',
|
||||
maxErrorValue: '±1.5W'
|
||||
},
|
||||
{
|
||||
measured: '高频次谐波',
|
||||
col1:'高频次谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电压',
|
||||
condition: 'Uh≥1%Un',
|
||||
maxErrorValue: '±5%Uh'
|
||||
},
|
||||
{
|
||||
measured: '高频次谐波',
|
||||
col1:'高频次谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电压',
|
||||
condition: 'Uh<1%Un',
|
||||
maxErrorValue: '±0.05%Un'
|
||||
},
|
||||
{
|
||||
measured: '高频次谐波',
|
||||
col1:'高频次谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电流',
|
||||
condition: 'In≥3%In',
|
||||
maxErrorValue: '±5%Ih'
|
||||
},
|
||||
{
|
||||
measured: '高频次谐波',
|
||||
col1:'高频次谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电流',
|
||||
condition: 'In<3%In',
|
||||
maxErrorValue: '±0.15%In'
|
||||
},
|
||||
{
|
||||
measured: '功率',
|
||||
col1:'功率',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'功率',
|
||||
condition: '',
|
||||
maxErrorValue: '±0.5%'
|
||||
},
|
||||
{
|
||||
measured: '电流',
|
||||
col1:'电流',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电流',
|
||||
condition: 'I≥0.05In',
|
||||
maxErrorValue: '±0.5%'
|
||||
},
|
||||
{
|
||||
measured: '电流',
|
||||
col1:'电流',
|
||||
col2: '',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电流',
|
||||
condition: '0.01In≤I<0.05In',
|
||||
maxErrorValue: '±1%'
|
||||
},
|
||||
{
|
||||
measured: '暂态电压幅值',
|
||||
col1: '电压暂降、电压暂升和短时中断',
|
||||
col2: '电压幅值',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'电压',
|
||||
condition: '',
|
||||
maxErrorValue: '±0.2%Un'
|
||||
},
|
||||
{
|
||||
measured: '暂态持续时间',
|
||||
col1: '电压暂降、电压暂升和短时中断',
|
||||
col2: '持续时间',
|
||||
deviceLevel: 'A',
|
||||
measurementType:'时间',
|
||||
condition: '',
|
||||
@@ -208,5 +233,191 @@ const errordata = ref<ErrorSystem.ErrorSystemList[]>([
|
||||
},
|
||||
])
|
||||
|
||||
const errorSDetail = ref<ErrorSystem.Error_detail[]>([
|
||||
{
|
||||
col1: '电压偏差',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电压',
|
||||
condition: '20%~120%标称电压',
|
||||
maxErrorValue: '±0.5%'
|
||||
},
|
||||
{
|
||||
col1:'频率偏差',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'频率',
|
||||
condition: '42.5~57.5 Hz',
|
||||
maxErrorValue: '±0.05Hz'
|
||||
},
|
||||
{
|
||||
col1:'三相不平衡度',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电压',
|
||||
condition: '1%~5%',
|
||||
maxErrorValue: '±0.2%'
|
||||
},
|
||||
{
|
||||
col1:'三相不平衡度',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电压',
|
||||
condition: '5%(不包含)~ 40%',
|
||||
maxErrorValue: '±0.6%'
|
||||
},
|
||||
{
|
||||
col1:'三相不平衡度',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电流',
|
||||
condition: '',
|
||||
maxErrorValue: '±1%'
|
||||
},
|
||||
{
|
||||
col1:'电压波动',
|
||||
col2: '电压幅值',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电压',
|
||||
condition: '',
|
||||
maxErrorValue: '±1.0%Un'
|
||||
},
|
||||
{
|
||||
col1:'电压波动',
|
||||
col2: '持续时间',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'时间',
|
||||
condition: '使用半波刷新方均根值',
|
||||
maxErrorValue: '±1周波'
|
||||
},
|
||||
{
|
||||
col1:'电压波动',
|
||||
col2: '持续时间',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'时间',
|
||||
condition: '使用全波刷新方均根值',
|
||||
maxErrorValue: '±2周波'
|
||||
},
|
||||
{
|
||||
col1:'闪变',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'短时间闪变',
|
||||
condition: 'Pst:0.4~4',
|
||||
maxErrorValue: '±10%'
|
||||
},
|
||||
{
|
||||
col1:'谐波和间谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电压',
|
||||
condition: 'Uh≥3%Un',
|
||||
maxErrorValue: '±5%Uh'
|
||||
},
|
||||
{
|
||||
col1:'谐波和间谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电压',
|
||||
condition: 'Uh<3%Un',
|
||||
maxErrorValue: '±0.15%Un'
|
||||
},
|
||||
{
|
||||
col1:'谐波和间谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电流',
|
||||
condition: 'In≥10%In',
|
||||
maxErrorValue: '±5%Ih'
|
||||
},
|
||||
{
|
||||
col1:'谐波和间谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电流',
|
||||
condition: 'In<10%In',
|
||||
maxErrorValue: '±0.5%In'
|
||||
},
|
||||
{
|
||||
col1:'高频次谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电压',
|
||||
condition: 'Uh≥3%Un',
|
||||
maxErrorValue: '±5%Uh'
|
||||
},
|
||||
{
|
||||
col1:'高频次谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电压',
|
||||
condition: 'Uh<3%Un',
|
||||
maxErrorValue: '±0.15%Un'
|
||||
},
|
||||
{
|
||||
col1:'高频次谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电流',
|
||||
condition: 'In≥10%In',
|
||||
maxErrorValue: '±5%Ih'
|
||||
},
|
||||
{
|
||||
col1:'高频次谐波',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电流',
|
||||
condition: 'In<10%In',
|
||||
maxErrorValue: '±0.5%In'
|
||||
},
|
||||
{
|
||||
col1:'功率',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'功率',
|
||||
condition: '',
|
||||
maxErrorValue: '±0.5%'
|
||||
},
|
||||
{
|
||||
col1:'电流',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电流',
|
||||
condition: 'I≥0.05In',
|
||||
maxErrorValue: '±0.5%'
|
||||
},
|
||||
{
|
||||
col1:'电流',
|
||||
col2: '',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电流',
|
||||
condition: '0.01In≤I<0.05In',
|
||||
maxErrorValue: '±1%'
|
||||
},
|
||||
{
|
||||
col1: '电压暂降、电压暂升和短时中断',
|
||||
col2: '电压幅值',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'电压',
|
||||
condition: '',
|
||||
maxErrorValue: '±1.0%Un'
|
||||
},
|
||||
{
|
||||
col1: '电压暂降、电压暂升和短时中断',
|
||||
col2: '持续时间',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'时间',
|
||||
condition: '使用半波刷新方均根值',
|
||||
maxErrorValue: '±1周波'
|
||||
},
|
||||
{
|
||||
col1: '电压暂降、电压暂升和短时中断',
|
||||
col2: '持续时间',
|
||||
deviceLevel: 'S',
|
||||
measurementType:'时间',
|
||||
condition: '使用全波刷新方均根值',
|
||||
maxErrorValue: '±2周波'
|
||||
},
|
||||
])
|
||||
|
||||
export default {errordata,errordetail}
|
||||
export default {errordata,errorADetail,errorSDetail}
|
||||
@@ -30,5 +30,7 @@ export const deletePqErrSys = (params: string[]) => {
|
||||
return http.post(`/pqErrSys/delete`, params)
|
||||
}
|
||||
|
||||
|
||||
|
||||
//复制误差体系
|
||||
export const copyPqErrSys = (params: ErrorSystem.ErrorSystemList) => {
|
||||
return http.get(`/pqErrSys/copy?id=${params.id}`)
|
||||
}
|
||||
38
frontend/src/api/device/icd/index.ts
Normal file
38
frontend/src/api/device/icd/index.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import type { ICD } from '@/api/device/interface/icd'
|
||||
import http from '@/api'
|
||||
import { pa } from 'element-plus/es/locale/index.mjs'
|
||||
|
||||
/**
|
||||
* @name ICD管理模块
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//获取ICD分页
|
||||
export const getICDList = (params: ICD.ReqICDParams) => {
|
||||
return http.post(`/icd/list`,params)
|
||||
}
|
||||
|
||||
|
||||
//获取ICD
|
||||
export const getICDAllList = (params: ICD.ResICD) => {
|
||||
return http.get(`/icd/listAll`,params)
|
||||
}
|
||||
|
||||
//添加ICD
|
||||
export const addICD = (params: ICD.ResICD) => {
|
||||
return http.post(`/icd/add`, params)
|
||||
}
|
||||
|
||||
//编辑ICD
|
||||
export const updateICD = (params: ICD.ResICD) => {
|
||||
return http.post(`/icd/update`, params)
|
||||
}
|
||||
|
||||
//删除ICD
|
||||
export const deleteICD = (params: string[]) => {
|
||||
return http.post(`/icd/delete`, params)
|
||||
}
|
||||
|
||||
|
||||
|
||||
15
frontend/src/api/device/interface/controlSource.ts
Normal file
15
frontend/src/api/device/interface/controlSource.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import type { ReqPage,ResPage } from '@/api/interface'
|
||||
|
||||
// 被检设备模块
|
||||
export namespace controlSource {
|
||||
|
||||
/**
|
||||
* 被检设备新增、修改、根据id查询返回的对象
|
||||
*/
|
||||
export interface ResControl {
|
||||
userPageId: string;
|
||||
scriptId: string;
|
||||
scriptIndex: number;
|
||||
sourceId: string;
|
||||
}
|
||||
}
|
||||
40
frontend/src/api/device/interface/devType.ts
Normal file
40
frontend/src/api/device/interface/devType.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import type { ReqPage, ResPage } from '@/api/interface'
|
||||
|
||||
// 设备类型模块
|
||||
export namespace DevType {
|
||||
|
||||
/**
|
||||
* 设备类型数据表格分页查询参数
|
||||
*/
|
||||
export interface ReqPqDevTypeParams extends ReqPage {
|
||||
id: string; // 装置序号id 必填
|
||||
devType?: string; // 设备名称
|
||||
createTime?: string; //创建时间
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备类型新增、修改、根据id查询返回的对象
|
||||
*/
|
||||
export interface ResPqDevType {
|
||||
id: string; //设备类型ID
|
||||
name: string;//设备类型名称
|
||||
icd: string| null;//设备关联的ICD
|
||||
power: string| null;//工作电源
|
||||
devVolt: number; //额定电压(V)
|
||||
devCurr: number; //额定电流(A)
|
||||
devChns: number; //设备通道数
|
||||
reportName: string| null;//报告模版名称
|
||||
state: number;
|
||||
createBy?: string| null; //创建用户
|
||||
createTime?: string| null; //创建时间
|
||||
updateBy?: string| null; //更新用户
|
||||
updateTime?: string| null; //更新时间
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备类型表格查询分页返回的对象;
|
||||
*/
|
||||
export interface ResPqDevTypePage extends ResPage<ResPqDevType> {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,33 @@
|
||||
import type { ReqPage,ResPage } from '@/api/interface'
|
||||
import type {ReqPage, ResPage} from '@/api/interface'
|
||||
|
||||
// 被检设备模块
|
||||
export namespace Device {
|
||||
|
||||
/**
|
||||
* 电能质量指标字典数据表格分页查询参数
|
||||
*/
|
||||
export interface ReqPqDevParams extends ReqPage{
|
||||
id: string; // 装置序号id 必填
|
||||
devType?: string; // 设备名称
|
||||
createTime?:string; //创建时间
|
||||
}
|
||||
/**
|
||||
* 被检设备表格分页查询参数
|
||||
*/
|
||||
export interface ReqPqDevParams extends ReqPage {
|
||||
id: string; // 装置序号id 必填
|
||||
name: string; //设备名称
|
||||
devType?: string; // 设备名称
|
||||
createTime?: string; //创建时间
|
||||
pattern: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 被检设备新增、修改、根据id查询返回的对象
|
||||
*/
|
||||
* 被检设备表格分页查询参数
|
||||
*/
|
||||
export interface ReqDevReportParams extends ReqPage {
|
||||
planId?: string; // 计划id
|
||||
devId?: string; // 装置id
|
||||
scriptId?: string; // 脚本id
|
||||
planCode?: string;
|
||||
devIdList?: string[]; // 装置id列表
|
||||
}
|
||||
|
||||
/**
|
||||
* 被检设备新增、修改、根据id查询返回的对象
|
||||
*/
|
||||
export interface ResPqDev {
|
||||
id: string; //装置序号ID
|
||||
name: string; //设备名称
|
||||
@@ -23,41 +36,62 @@ export namespace Device {
|
||||
devChns: number; //设备通道数
|
||||
devVolt: number; //额定电压(V)
|
||||
devCurr: number; //额定电流(A)
|
||||
manufacturer: string;//生产厂家
|
||||
manufacturer?: string | null;//生产厂家
|
||||
createDate: string; //生产日期
|
||||
createId: string; //出厂编号
|
||||
hardwareVersion: string; //固件版本
|
||||
softwareVersion: string; //软件版本
|
||||
protocol:string; //通讯协议
|
||||
protocol: string; //通讯协议
|
||||
ip: string; //IP地址
|
||||
port: number; //端口号
|
||||
encryptionFlag: number; //装置是否为加密版本
|
||||
series?: string| null; //装置识别码(3ds加密)
|
||||
devKey?: string| null; //装置秘钥(3ds加密)
|
||||
sampleID?: string| null; //样品编号
|
||||
series?: string | null; //装置识别码(3ds加密)
|
||||
devKey?: string | null; //装置秘钥(3ds加密)
|
||||
sampleId?: string | null; //样品编号
|
||||
arrivedDate?: string; //送样日期
|
||||
cityName?: string| null; //所属地市名称
|
||||
gDName?: string| null; //所属供电公司名称
|
||||
subName?: string| null; //所属电站名称
|
||||
checkState?: number| null; //检测状态
|
||||
checkResult?: number| null; //检测结果
|
||||
reportState?: number| null; //报告状态
|
||||
documentState?: number| null; //归档状态
|
||||
reportPath?: string| null; //报告路径
|
||||
qRCode?: string| null; //设备关键信息二维码
|
||||
cityName?: string | null; //所属地市名称
|
||||
gDName?: string | null; //所属供电公司名称
|
||||
subName?: string | null; //所属电站名称
|
||||
checkState?: number | null; //检测状态
|
||||
checkResult?: number | null; //检测结果
|
||||
reportState?: number | null; //报告状态
|
||||
reportPath?: string | null; //报告路径
|
||||
qRCode?: string | null; //设备关键信息二维码
|
||||
reCheckNum: number; //复检次数
|
||||
planId?: string;//检测计划Id
|
||||
timeCheckResult?: number;//守时检测结果(0:不符合1:符合)
|
||||
factorFlag?: number;//是否支持系数校准(0:不支持,1:支持)
|
||||
factorCheckResult?: number;//系数校准结果(0:不合格,1:合格,2:/表示没有做系数校准)
|
||||
state: number; //状态
|
||||
createBy?: string| null; //创建用户
|
||||
createTime?: string| null; //创建时间
|
||||
updateBy?: string| null; //更新用户
|
||||
updateTime?: string| null; //更新时间
|
||||
|
||||
createBy?: string | null; //创建用户
|
||||
createTime?: string | null; //创建时间
|
||||
updateBy?: string | null; //更新用户
|
||||
updateTime?: string | null; //更新时间
|
||||
icdId: string | null;
|
||||
power: string | null;//工作电源
|
||||
preinvestmentPlan: string | null;
|
||||
delegate: string | null; //委托方
|
||||
}
|
||||
|
||||
/**
|
||||
* 被检设备表格查询分页返回的对象;
|
||||
*/
|
||||
export interface ResPqDevPage extends ResPage<ResPqDev> {
|
||||
|
||||
}
|
||||
}
|
||||
export interface ResDev {
|
||||
id: string;
|
||||
name: string,
|
||||
icd: string,
|
||||
power: string,
|
||||
devVolt: number,
|
||||
devCurr: number,
|
||||
devChns: number,
|
||||
}
|
||||
|
||||
export interface ResTH {
|
||||
temperature :number | null;//温度
|
||||
humidity:number | null;//湿度
|
||||
}
|
||||
/**
|
||||
* 被检设备表格查询分页返回的对象;
|
||||
*/
|
||||
export interface ResPqDevPage extends ResPage<ResPqDev> {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -22,25 +22,29 @@ export namespace ErrorSystem {
|
||||
|
||||
// 查看详细误差体系
|
||||
export interface ErrorSystemDetail {
|
||||
nextId: number;
|
||||
sort: number;
|
||||
id:string;//误差体系子表ID
|
||||
errorSysId:string;//所属误差体系ID
|
||||
type: string;//检测脚本类型,树形字典表(没有树形表则需要拆分字段)
|
||||
startValue?:number;//误差判断起始值(误差范围)
|
||||
errorType: string;//误差类型,树形字典表(没有树形表则需要拆分字段)
|
||||
scriptType: string;//脚本类型
|
||||
startValue?:number | null;//误差判断起始值(误差范围)
|
||||
startFlag?:number;//是否包含起始值
|
||||
endValue?:number;//;误差判断结束值(误差范围)
|
||||
endValue?:number | null;//;误差判断结束值(误差范围)
|
||||
endFlag?:number;//是否包含结束值
|
||||
conditionType?:string;//判断条件值类型(包括值类型,绝对值、相对值)
|
||||
maxErrorValue:number;//误差最大值
|
||||
errorValueType:string;//误差值类型(包括值类型,绝对值、相对值1、相对值2)
|
||||
errorValueType:any;//误差值类型(0标称值、1标准值、2值类型)
|
||||
valueType:number;//值类型(1绝对值、2相对值)
|
||||
errorUnit:string;//误差单位
|
||||
}
|
||||
|
||||
// 查看详细误差体系
|
||||
// export interface Error_detail {
|
||||
// measured: string;
|
||||
// deviceLevel: string;
|
||||
// measurementType:string;
|
||||
// condition: string;
|
||||
// maxErrorValue: string;
|
||||
// }
|
||||
//查看详细误差体系
|
||||
export interface Error_detail {
|
||||
col1: string;
|
||||
col2: string;
|
||||
deviceLevel: string;
|
||||
measurementType:string;
|
||||
condition: string;
|
||||
maxErrorValue: string;
|
||||
}
|
||||
}
|
||||
35
frontend/src/api/device/interface/icd.ts
Normal file
35
frontend/src/api/device/interface/icd.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { ReqPage, ResPage } from '@/api/interface'
|
||||
|
||||
// ICD模块
|
||||
export namespace ICD {
|
||||
|
||||
/**
|
||||
* ICD表格分页查询参数
|
||||
*/
|
||||
export interface ReqICDParams extends ReqPage {
|
||||
id: string; // 装置序号id 必填
|
||||
devType?: string; // 设备名称
|
||||
createTime?: string; //创建时间
|
||||
}
|
||||
|
||||
/**
|
||||
* ICD新增、修改、根据id查询返回的对象
|
||||
*/
|
||||
export interface ResICD {
|
||||
id: string; //icdID
|
||||
name: string;//icd名称
|
||||
path: string;//icd存储地址
|
||||
state: number;
|
||||
createBy?: string| null; //创建用户
|
||||
createTime?: string| null; //创建时间
|
||||
updateBy?: string| null; //更新用户
|
||||
updateTime?: string| null; //更新时间
|
||||
}
|
||||
|
||||
/**
|
||||
* ICD表格查询分页返回的对象;
|
||||
*/
|
||||
export interface ResICDPage extends ResPage<ResICD> {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ReqPage,ResPage } from '@/api/interface'
|
||||
import type { ReqPage, ResPage } from '@/api/interface'
|
||||
|
||||
// 被检设备模块
|
||||
export namespace Monitor {
|
||||
@@ -6,30 +6,30 @@ export namespace Monitor {
|
||||
/**
|
||||
* 电能质量指标字典数据表格分页查询参数
|
||||
*/
|
||||
export interface ReqPqMonParams extends ReqPage{
|
||||
export interface ReqPqMonParams extends ReqPage {
|
||||
id: string; // 装置序号id 必填
|
||||
devType?: string; // 设备名称
|
||||
createTime?:string; //创建时间
|
||||
createTime?: string; //创建时间
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* 被检设备新增、修改、根据id查询返回的对象
|
||||
*/
|
||||
export interface ResPqMon {
|
||||
id: string; //监测点ID
|
||||
code: string; //默认与谐波系统监测点ID相同
|
||||
devId: string; //所属设备ID
|
||||
name: string; //所属母线
|
||||
num: number; //监测点序号
|
||||
pt: number; //PT变比
|
||||
ct: number; //CT变比
|
||||
ptType:string; //接线方式,字典表
|
||||
}
|
||||
export interface ResPqMon {
|
||||
id: string; //监测点ID
|
||||
code: string; //默认与谐波系统监测点ID相同
|
||||
devId: string; //所属设备ID
|
||||
name: string; //所属母线
|
||||
num: number; //监测点序号
|
||||
pt: number; //PT变比
|
||||
ct: number; //CT变比
|
||||
ptType: string; //接线方式,字典表
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* 被检设备表格查询分页返回的对象;
|
||||
*/
|
||||
export interface ResPqMonPage extends ResPage<ResPqMon> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
39
frontend/src/api/device/interface/report.ts
Normal file
39
frontend/src/api/device/interface/report.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import type { ReqPage, ResPage } from '@/api/interface'
|
||||
import type { UploadFile } from 'element-plus';
|
||||
|
||||
// 报告模版接口
|
||||
export namespace PqReport {
|
||||
|
||||
/**
|
||||
* 报告模版表格分页查询参数
|
||||
*/
|
||||
export interface ReqReportParams extends ReqPage {
|
||||
id: string; // 装置序号id 必填
|
||||
name?: string; // 设备名称
|
||||
createTime?: string; //创建时间
|
||||
}
|
||||
|
||||
/**
|
||||
* 报告模版新增、修改、根据id查询返回的对象
|
||||
*/
|
||||
export interface ResReport {
|
||||
id: string; //报告模板id
|
||||
name: string;//报告模板名称
|
||||
version:string;//版本号
|
||||
baseFile?:string;//基础模板文件路径
|
||||
detailFile?:string;//检测项模版文件路径
|
||||
description:string;//描述信息
|
||||
state:number;//状态:8-删除 1-正常
|
||||
createBy?: string| null; //创建用户
|
||||
createTime?: string| null; //创建时间
|
||||
updateBy?: string| null; //更新用户
|
||||
updateTime?: string| null; //更新时间
|
||||
}
|
||||
|
||||
/**
|
||||
* 报告模版表格查询分页返回的对象;
|
||||
*/
|
||||
export interface ResReportPage extends ResPage<ResReport> {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,37 +2,37 @@ import type { ReqPage, ResPage } from '@/api/interface'
|
||||
|
||||
// 检测脚本模块
|
||||
export namespace TestScript {
|
||||
|
||||
|
||||
/**
|
||||
* 检测脚本表格分页查询参数
|
||||
*/
|
||||
export interface ReqTestScriptParams extends ReqPage{
|
||||
id: string; // 装置序号id 必填
|
||||
name: string;
|
||||
type: string;
|
||||
}
|
||||
/**
|
||||
* 检测脚本表格分页查询参数
|
||||
*/
|
||||
export interface ReqTestScriptParams extends ReqPage {
|
||||
id: string // 装置序号id 必填
|
||||
name: string
|
||||
type: string
|
||||
pattern: string
|
||||
}
|
||||
|
||||
// 检测脚本接口
|
||||
export interface ResTestScript {
|
||||
id?: string; //检测脚本ID
|
||||
name: string; //检测脚本名称
|
||||
type: string; //检测脚本类型(字典表Code字段,脚本还是模板)
|
||||
pattern: string;//检测脚本模式(字典表Code字段,数字、模拟、比对)
|
||||
valueType?: string;//脚本值类型(字典表Code字段,相对值脚本、绝对值脚本、无)
|
||||
standardName: string;//参照标准名称
|
||||
standardTime: string;//标准推行时间
|
||||
state:number;//
|
||||
createBy?: string;
|
||||
createTime?: string;
|
||||
updateBy?: string;
|
||||
updateTime?: string;
|
||||
id?: string //检测脚本ID
|
||||
name: string //检测脚本名称
|
||||
type: string //设定0为脚本,1为模板
|
||||
pattern: string //检测脚本模式(字典表Code字段,数字、模拟、比对)
|
||||
valueType?: string //脚本值类型(字典表Code字段,相对值脚本、绝对值脚本、无)
|
||||
standardName: string //参照标准名称
|
||||
standardTime: string //标准推行时间
|
||||
state?: number //
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
selectedValue?: string
|
||||
ratedCurr?: number
|
||||
ratedVolt?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测脚本查询分页返回的对象;
|
||||
*/
|
||||
export interface ResTestScriptPage extends ResPage<ResTestScript> {
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 检测脚本查询分页返回的对象;
|
||||
*/
|
||||
export interface ResTestScriptPage extends ResPage<ResTestScript> {}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ export namespace TestSource {
|
||||
// 检测源接口
|
||||
export interface ResTestSource {
|
||||
id: string; //检测源ID
|
||||
name: string; //检测源名称(检测源类型 + 设备类型 + 数字自动生成)
|
||||
name?: string; //检测源名称(检测源类型 + 设备类型 + 数字自动生成)
|
||||
pattern: string;//检测源模式(字典表Code字段,数字、模拟、比对)
|
||||
type: string; //检测源类型(字典表Code字段,标准源、高精度设备)
|
||||
devType: string;//检测源设备类型(字典表Code字段)
|
||||
@@ -34,9 +34,9 @@ export namespace TestSource {
|
||||
}
|
||||
export interface ParameterType{
|
||||
id:string;
|
||||
sourceParamType:string;
|
||||
sourceParamDesc:string;
|
||||
sourceParamValue:string;
|
||||
type:string;
|
||||
desc:string;
|
||||
value:string|null;
|
||||
sort:number;
|
||||
pId:string;
|
||||
children?:ParameterType[];
|
||||
|
||||
46
frontend/src/api/device/report/index.ts
Normal file
46
frontend/src/api/device/report/index.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import type {PqReport} from '@/api/device/interface/report'
|
||||
import http from '@/api'
|
||||
|
||||
/**
|
||||
* @name 报告模版模块
|
||||
*/
|
||||
|
||||
//获取报告模版
|
||||
export const getPqReportList = (params: PqReport.ReqReportParams) => {
|
||||
return http.post(`/report/list`, params)
|
||||
}
|
||||
|
||||
//新增报告模版
|
||||
export const addPqReport = (params: PqReport.ResReport) => {
|
||||
return http.upload(`/report/add`, params)
|
||||
}
|
||||
|
||||
//删除报告模版
|
||||
export const deletePqReport = (params: string[]) => {
|
||||
return http.post(`/report/delete`, params)
|
||||
}
|
||||
|
||||
//查询报告模板详情
|
||||
export const getPqReportById = (params: PqReport.ResReport) => {
|
||||
return http.get(`/report/getById?id=${params.id}`)
|
||||
}
|
||||
|
||||
//修改报告模板
|
||||
export const updatePqReport = (params: PqReport.ResReport) => {
|
||||
return http.upload(`/report/update`, params)
|
||||
}
|
||||
|
||||
//查询所有报告模板名称
|
||||
export const getPqReportAllName = () => {
|
||||
return http.get(`/report/listAllName`)
|
||||
}
|
||||
|
||||
//根据名称查询指定报告模板的所有版本
|
||||
export const getPqReportAllVersion = (params:any) => {
|
||||
return http.get(`/report/listAllVersion?name=${params.name}`)
|
||||
}
|
||||
|
||||
//被检设备归档
|
||||
export const documentedPqDev = (ids: string[]) => {
|
||||
return http.post(`/report/documented`, ids)
|
||||
}
|
||||
@@ -1,21 +1,53 @@
|
||||
import type { TestScript } from '@/api/device/interface/testScript'
|
||||
import http from '@/api'
|
||||
import { Loading } from '@element-plus/icons-vue'
|
||||
|
||||
/**
|
||||
* @name 检测脚本管理模块
|
||||
*/
|
||||
// 新增脚本
|
||||
export const pqScriptAdd = (params: TestScript.ResTestScript) => {
|
||||
return http.post(`/pqScript/add`, params)
|
||||
}
|
||||
// 修改脚本
|
||||
export const pqScriptUpdate = (params: TestScript.ResTestScript) => {
|
||||
return http.post(`/pqScript/update`, params)
|
||||
}
|
||||
// 获取检测脚本列表
|
||||
export const getPqScriptList = (params: TestScript.ReqTestScriptParams) => {
|
||||
return http.post(`/pqScript/list`, params)
|
||||
return http.post(`/pqScript/list`, params)
|
||||
}
|
||||
|
||||
|
||||
//升级为模版
|
||||
export const updatePqScript = (params: TestScript.ResTestScript) => {
|
||||
return http.get(`/pqScript/upgradeToTemplate?id=${params.id}`)
|
||||
return http.get(`/pqScript/upgradeToTemplate?id=${params.id}`)
|
||||
}
|
||||
|
||||
//删除检测脚本
|
||||
export const deletePqScript = (params: string[]) => {
|
||||
return http.post(`/pqScript/delete`, params)
|
||||
return http.post(`/pqScript/delete`, params)
|
||||
}
|
||||
//添加检测脚本
|
||||
export const addScriptDtls = (params: any) => {
|
||||
return http.post(`/pqScript/addScriptDtls`, params)
|
||||
}
|
||||
//根据脚本id查询检测脚本详情
|
||||
export const dlsDetails = (params: any) => {
|
||||
return http.post(`/pqScript/dlsDetails`, params)
|
||||
}
|
||||
// 删除脚本
|
||||
export const deleteDtls = (params: any) => {
|
||||
return http.post(`/pqScript/deleteDtls`, params)
|
||||
}
|
||||
// 启用关闭脚本
|
||||
export const updateDtls = (params: any) => {
|
||||
return http.post(`/pqScript/updateDtls`, params)
|
||||
}
|
||||
// 根据通讯参数生成装置下发原始数据公式
|
||||
export const scriptDtlsCheckDataList = (params: any) => {
|
||||
return http.post(`/pqScript/scriptDtlsCheckDataList`, params,{loading: false})
|
||||
}
|
||||
// 通讯脚本回显
|
||||
export const checkDataList = (params: any) => {
|
||||
return http.post(`/pqScript/checkDataList`, params, { loading: true })
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ export const checkStatus = (status: number) => {
|
||||
case 400:
|
||||
ElMessage.error("请求失败!请您稍后重试");
|
||||
break;
|
||||
case 401:
|
||||
ElMessage.error("登录失效!请您重新登录");
|
||||
break;
|
||||
// case 401:
|
||||
// ElMessage.error("登录失效!请您重新登录");
|
||||
// break;
|
||||
case 403:
|
||||
ElMessage.error("当前账号无权限访问!");
|
||||
break;
|
||||
|
||||
6
frontend/src/api/home/channelsTest/index.ts
Normal file
6
frontend/src/api/home/channelsTest/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import http from "@/api";
|
||||
|
||||
//系数校准发送基本信息
|
||||
export const getCoefficientCheck = (params: any) => {
|
||||
return http.post(`/prepare/coefficientCheck`, params,{loading: false})
|
||||
}
|
||||
31
frontend/src/api/home/interface/channelsTest.ts
Normal file
31
frontend/src/api/home/interface/channelsTest.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
// 系数校准模块
|
||||
export namespace ChannelsTest {
|
||||
|
||||
// 系数校准列表
|
||||
export interface CoefficientVO {
|
||||
devName?: string;//设备名称
|
||||
type?:string;//区分大小电压
|
||||
monitorNum: string;//监测点序号
|
||||
desc: string;//描述
|
||||
aVuData:string;//电压通道A数据
|
||||
aVuXi:string;//电压通道A系数
|
||||
bVuData:string;//电压通道B数据
|
||||
bVuXi:string;//电压通道B系数
|
||||
cVuData:string;//电压通道C数据
|
||||
cVuXi:string;//电压通道C系数
|
||||
aIeData:string;//电流通道A数据
|
||||
aIeXi:string;//电流通道A系数
|
||||
bIeData:string;//电流通道B数据
|
||||
bIeXi:string;//电流通道B系数
|
||||
cIeData:string;//电流通道C数据
|
||||
cIeXi:string;//电流通道C系数
|
||||
loading: boolean;
|
||||
aV:string;
|
||||
bV:string;
|
||||
cV:string;
|
||||
aI:string;
|
||||
bI:string;
|
||||
cI:string;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ElMessage, ElTreeSelect } from 'element-plus';
|
||||
import axios, { AxiosInstance, AxiosError, AxiosRequestConfig, InternalAxiosRequestConfig, AxiosResponse } from 'axios'
|
||||
import { showFullScreenLoading, tryHideFullScreenLoading } from '@/components/Loading/fullScreen'
|
||||
import { LOGIN_URL } from '@/config'
|
||||
@@ -7,6 +8,7 @@ import { ResultEnum } from '@/enums/httpEnum'
|
||||
import { checkStatus } from './helper/checkStatus'
|
||||
import { useUserStore } from '@/stores/modules/user'
|
||||
import router from '@/routers'
|
||||
import {refreshToken} from '@/api/user/login'
|
||||
|
||||
export interface CustomAxiosRequestConfig extends InternalAxiosRequestConfig {
|
||||
loading?: boolean;
|
||||
@@ -37,12 +39,14 @@ class RequestHttp {
|
||||
*/
|
||||
this.service.interceptors.request.use(
|
||||
(config: CustomAxiosRequestConfig) => {
|
||||
isFirst = true
|
||||
const userStore = useUserStore()
|
||||
// 当前请求不需要显示 loading,在 api 服务中通过指定的第三个参数: { loading: false } 来控制
|
||||
config.loading ?? (config.loading = true)
|
||||
config.loading && showFullScreenLoading()
|
||||
if (config.headers && typeof config.headers.set === 'function') {
|
||||
config.headers.set('Authorization', 'Bearer '+userStore.token)
|
||||
config.headers.set('Authorization', 'Bearer ' + userStore.accessToken)
|
||||
config.headers.set('Is-Refresh-Token', userStore.isRefreshToken+"")
|
||||
}
|
||||
return config
|
||||
},
|
||||
@@ -51,34 +55,82 @@ class RequestHttp {
|
||||
},
|
||||
)
|
||||
|
||||
let isFirst = true
|
||||
/**
|
||||
* @description 响应拦截器
|
||||
* 服务器换返回信息 -> [拦截统一处理] -> 客户端JS获取到信息
|
||||
*/
|
||||
this.service.interceptors.response.use(
|
||||
(response: AxiosResponse) => {
|
||||
async (response: AxiosResponse) => {
|
||||
const { data } = response
|
||||
const userStore = useUserStore()
|
||||
tryHideFullScreenLoading()
|
||||
|
||||
if(data.code === ResultEnum.ACCESSTOKEN_EXPIRED){
|
||||
// 用长token去换短token
|
||||
userStore.setAccessToken(userStore.refreshToken)
|
||||
userStore.setIsRefreshToken(true)
|
||||
const result = await refreshToken()
|
||||
if (result) { //获取新token成功的话
|
||||
// 有新的token后,重新请求
|
||||
userStore.setAccessToken(result.data.accessToken)
|
||||
userStore.setRefreshToken(result.data.refreshToken)
|
||||
userStore.setIsRefreshToken(false)
|
||||
userStore.setExp(1000 * 60 * 60 * 24 * 30)
|
||||
response.config.headers.Authorization = `Bearer ${result.data.accessToken}`//重新请求前需要将更新后的新token更换掉之前无效的token,不然会死循环
|
||||
const resp = await this.service.request(response.config)
|
||||
return resp
|
||||
} else {
|
||||
// 刷新失效,跳转登录页
|
||||
}
|
||||
}
|
||||
// 登陆失效
|
||||
if (data.code == ResultEnum.OVERDUE) {
|
||||
userStore.setToken('')
|
||||
userStore.setUserInfo({name: ''})
|
||||
router.replace(LOGIN_URL)
|
||||
ElMessage.error(data.message)
|
||||
if (data.code === ResultEnum.OVERDUE) {
|
||||
console.log("登陆失效")
|
||||
userStore.setAccessToken('')
|
||||
userStore.setRefreshToken('')
|
||||
userStore.setIsRefreshToken(false)
|
||||
userStore.setUserInfo({ id:'',name: '' })
|
||||
userStore.setExp(0)
|
||||
await router.replace(LOGIN_URL)
|
||||
if(isFirst){//临时处理token失效弹窗多次
|
||||
ElMessage.error(data.message)
|
||||
isFirst = false
|
||||
}
|
||||
return Promise.reject(data)
|
||||
}
|
||||
// 全局错误信息拦截(防止下载文件的时候返回数据流,没有 code 直接报错)
|
||||
if (data.code && data.code !== ResultEnum.SUCCESS) {
|
||||
if(data.message.includes('&')){
|
||||
let formattedMessage = data.message.split('&').join('<br>');
|
||||
if (data.message.includes(':')) {
|
||||
formattedMessage = formattedMessage.replace(':', '')
|
||||
}
|
||||
ElMessage.error({ message: formattedMessage, dangerouslyUseHTMLString: true });
|
||||
return Promise.reject(data)
|
||||
}
|
||||
|
||||
ElMessage.error(data.message)
|
||||
return Promise.reject(data)
|
||||
}
|
||||
// 成功请求(在页面上除非特殊情况,否则不用处理失败逻辑)
|
||||
|
||||
if (userStore.exp <= Date.now() && userStore.exp !== 0) {
|
||||
userStore.setAccessToken('')
|
||||
userStore.setRefreshToken('')
|
||||
userStore.setIsRefreshToken(false)
|
||||
userStore.setUserInfo({ id:'',name: '' })
|
||||
userStore.setExp(0)
|
||||
ElMessage.error('登录已过期,请重新登录!')
|
||||
await router.replace(LOGIN_URL)
|
||||
return Promise.reject(data)
|
||||
}
|
||||
return data
|
||||
},
|
||||
async (error: AxiosError) => {
|
||||
const { response } = error
|
||||
tryHideFullScreenLoading()
|
||||
console.log('error', error.message)
|
||||
// 请求超时 && 网络错误单独判断,没有 response
|
||||
if (error.message.indexOf('timeout') !== -1) ElMessage.error('请求超时!请您稍后重试')
|
||||
if (error.message.indexOf('Network Error') !== -1) ElMessage.error('网络错误!请您稍后重试')
|
||||
@@ -115,9 +167,24 @@ class RequestHttp {
|
||||
}
|
||||
|
||||
upload(url: string, params?: object, _object = {}): Promise<BlobPart> {
|
||||
return this.service.post(url, params, { ..._object, headers: { 'Content-Type': 'multipart/form-data' } })
|
||||
return this.service.post(url, params, {
|
||||
..._object,
|
||||
headers: { 'Content-Type': 'multipart/form-data' }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 针对excel的上传,默认返回的是blob类型,Excel没问题时返回json特殊处理
|
||||
*/
|
||||
uploadExcel(url: string, params?: object, _object = {}): Promise<BlobPart> {
|
||||
return this.service.post(url, params, {
|
||||
..._object,
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
responseType: 'blob',
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
export default new RequestHttp(config)
|
||||
|
||||
@@ -1,227 +1,194 @@
|
||||
{
|
||||
"code": "A0000",
|
||||
"data": [
|
||||
"code": "A0000",
|
||||
"data": [
|
||||
{
|
||||
"id": "1",
|
||||
"pid": "0",
|
||||
"name": "频率准确度检测",
|
||||
"children": [
|
||||
{
|
||||
"id": "0",
|
||||
"name": "频率准确度检测",
|
||||
"children": [
|
||||
{
|
||||
"pid": 0,
|
||||
"id": "0-1",
|
||||
"name": "额定工作条件下的检测",
|
||||
"children": [
|
||||
{
|
||||
"scriptIdx":1,
|
||||
"isChildNode":true,
|
||||
"pid": "0-1",
|
||||
"id": "0-1-1",
|
||||
"name": "输入:频率 42.5Hz..."
|
||||
},
|
||||
{
|
||||
"scriptIdx":2,
|
||||
"isChildNode":true,
|
||||
"pid": "0-1",
|
||||
"id": "0-1-2",
|
||||
"name": "输入:频率 50.0Hz..."
|
||||
},
|
||||
{
|
||||
"scriptIdx":3,
|
||||
"isChildNode":true,
|
||||
"pid": "0-1",
|
||||
"id": "0-1-3",
|
||||
"name": "输入:频率 50.05Hz..."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pid": 0,
|
||||
"id": "0-2",
|
||||
"name": "电压对频率测量的影响",
|
||||
"children": [
|
||||
{
|
||||
"scriptIdx":4,
|
||||
"isChildNode":true,
|
||||
"pid": "0-2",
|
||||
"id": "0-2-1",
|
||||
"name": "输入:频率 50.05Hz Ua =10%Un..."
|
||||
},
|
||||
{
|
||||
"scriptIdx":5,
|
||||
"isChildNode":true,
|
||||
"pid": "0-2",
|
||||
"id": "0-2-1",
|
||||
"name": "输入:频率 51.05Hz Ua =10%Un..."
|
||||
},
|
||||
{
|
||||
"scriptIdx":6,
|
||||
"isChildNode":true,
|
||||
"pid": "0-2",
|
||||
"id": "0-2-2",
|
||||
"name": "输入:频率 52.05Hz Ua =10%Un..."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pid": 0,
|
||||
"id": "0-3",
|
||||
"name": "谐波对频率测量的影响",
|
||||
"children": [
|
||||
{
|
||||
"scriptIdx":7,
|
||||
"isChildNode":true,
|
||||
"pid": "0-3",
|
||||
"id": "0-3-1",
|
||||
"name": "输入:频率 50.05Hz Ua =100%Un..."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"id": "1-1",
|
||||
"pid": "1",
|
||||
"name": "额定工作条件下的检测",
|
||||
"children": [
|
||||
{
|
||||
"id": "1-1-1",
|
||||
"pid": "1-1",
|
||||
"name": "输入:频率 42.5Hz..."
|
||||
},
|
||||
{
|
||||
"id": "1-1-2",
|
||||
"pid": "1-1",
|
||||
"name": "输入:频率 50.0Hz..."
|
||||
},
|
||||
{
|
||||
"id": "1-1-3",
|
||||
"pid": "1-1",
|
||||
"name": "输入:频率 50.05Hz...."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1",
|
||||
"name": "电压准确度检测",
|
||||
"children": [
|
||||
{
|
||||
"pid": 1,
|
||||
"id": "1-1",
|
||||
"name": "额定工作条件下的检测",
|
||||
"children": [
|
||||
{
|
||||
"scriptIdx":8,
|
||||
"isChildNode":true,
|
||||
"pid": "1-1",
|
||||
"id": "1-1-1",
|
||||
"name": "输入:频率 42.5Hz..."
|
||||
},
|
||||
{
|
||||
"scriptIdx":9,
|
||||
"isChildNode":true,
|
||||
"pid": "1-1",
|
||||
"id": "1-1-2",
|
||||
"name": "输入:频率 50.0Hz..."
|
||||
},
|
||||
{
|
||||
"scriptIdx":10,
|
||||
"isChildNode":true,
|
||||
"pid": "1-1",
|
||||
"id": "1-1-3",
|
||||
"name": "输入:频率 50.05Hz..."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pid": 0,
|
||||
"id": "1-2",
|
||||
"name": "电压对频率测量的影响",
|
||||
"children": [
|
||||
{
|
||||
"scriptIdx":11,
|
||||
"isChildNode":true,
|
||||
"pid": "1-2",
|
||||
"id": "1-2-1",
|
||||
"name": "输入:频率 50.05Hz Ua =10%Un..."
|
||||
},
|
||||
{
|
||||
"scriptIdx":12,
|
||||
"isChildNode":true,
|
||||
"pid": "1-2",
|
||||
"id": "1-2-1",
|
||||
"name": "输入:频率 51.05Hz Ua =10%Un..."
|
||||
},
|
||||
{
|
||||
"scriptIdx":13,
|
||||
"isChildNode":true,
|
||||
"pid": "1-2",
|
||||
"id": "1-2-2",
|
||||
"name": "输入:频率 52.05Hz Ua =10%Un..."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pid": 0,
|
||||
"id": "0-3",
|
||||
"name": "谐波对频率测量的影响",
|
||||
"children": [
|
||||
{
|
||||
"scriptIdx":14,
|
||||
"isChildNode":true,
|
||||
"pid": "0-3",
|
||||
"id": "0-3-1",
|
||||
"name": "输入:频率 50.05Hz Ua =100%Un..."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"id": "1-2",
|
||||
"pid": "1",
|
||||
"name": "电压对频率测量的影响",
|
||||
"children": [
|
||||
{
|
||||
"id": "1-2-1",
|
||||
"pid": "1-2",
|
||||
"name": "输入:频率 50.05Hz Ua =10%Un..."
|
||||
},
|
||||
{
|
||||
"id": "1-2-1",
|
||||
"pid": "1-2",
|
||||
"name": "输入:频率 51.05Hz Ua =10%Un..."
|
||||
},
|
||||
{
|
||||
"id": "1-2-2",
|
||||
"pid": "1-2",
|
||||
"name": "输入:频率 52.05Hz Ua =10%Un..."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id": "2",
|
||||
"name": "谐波准确度检测",
|
||||
"children": [
|
||||
{
|
||||
"pid": 2,
|
||||
"id": "2-1",
|
||||
"name": "额定工作条件下的检测",
|
||||
"children": [
|
||||
{
|
||||
"scriptIdx":15,
|
||||
"pid": "2-1",
|
||||
"id": "2-1-1",
|
||||
"name": "输入:频率 42.5Hz..."
|
||||
},
|
||||
{
|
||||
"scriptIdx":16,
|
||||
"pid": "2-1",
|
||||
"id": "2-1-2",
|
||||
"name": "输入:频率 50.0Hz..."
|
||||
},
|
||||
{
|
||||
"scriptIdx":17,
|
||||
"pid": "2-1",
|
||||
"id": "2-1-3",
|
||||
"name": "输入:频率 50.05Hz..."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pid": 2,
|
||||
"id": "2-2",
|
||||
"name": "电压对频率测量的影响",
|
||||
"children": [
|
||||
{
|
||||
"scriptIdx":18,
|
||||
"pid": "2-2",
|
||||
"id": "2-2-1",
|
||||
"name": "输入:频率 50.05Hz Ua =10%Un..."
|
||||
},
|
||||
{
|
||||
"scriptIdx":19,
|
||||
"pid": "2-2",
|
||||
"id": "2-2-1",
|
||||
"name": "输入:频率 51.05Hz Ua =10%Un..."
|
||||
},
|
||||
{
|
||||
"scriptIdx":20,
|
||||
"pid": "2-2",
|
||||
"id": "2-2-2",
|
||||
"name": "输入:频率 52.05Hz Ua =10%Un..."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pid": 2,
|
||||
"id": "2-3",
|
||||
"name": "谐波对频率测量的影响",
|
||||
"children": [
|
||||
{
|
||||
"scriptIdx":21,
|
||||
"pid": "2-3",
|
||||
"id": "2-3-1",
|
||||
"name": "输入:频率 50.05Hz Ua =100%Un..."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"id": "1-3",
|
||||
"pid": "1",
|
||||
"name": "谐波对频率测量的影响",
|
||||
"children": [
|
||||
{
|
||||
"id": "1-3-1",
|
||||
"pid": "1-3",
|
||||
"name": "输入:频率 50.05Hz Ua =100%Un..."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"pid": "0",
|
||||
"name": "电压准确度检测",
|
||||
"children": [
|
||||
{
|
||||
"pid": "2",
|
||||
"id": "2-1",
|
||||
"name": "额定工作条件下的检测",
|
||||
"children": [
|
||||
{
|
||||
"id": "2-1-1",
|
||||
"pid": "2-1",
|
||||
"name": "输入:频率 42.5Hz..."
|
||||
},
|
||||
{
|
||||
"id": "2-1-2",
|
||||
"pid": "2-1",
|
||||
"name": "输入:频率 50.0Hz..."
|
||||
},
|
||||
{
|
||||
"id": "2-1-3",
|
||||
"pid": "2-1",
|
||||
"name": "输入:频率 50.05Hz..."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pid": "2",
|
||||
"id": "2-2",
|
||||
"name": "电压对频率测量的影响",
|
||||
"children": [
|
||||
{
|
||||
"id": "2-2-1",
|
||||
"pid": "2-2",
|
||||
"name": "输入:频率 50.05Hz Ua =10%Un..."
|
||||
},
|
||||
{
|
||||
"id": "2-2-1",
|
||||
"pid": "2-2",
|
||||
"name": "输入:频率 51.05Hz Ua =10%Un..."
|
||||
},
|
||||
{
|
||||
"id": "2-2-2",
|
||||
"pid": "2-2",
|
||||
"name": "输入:频率 52.05Hz Ua =10%Un..."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pid": "2",
|
||||
"id": "2-3",
|
||||
"name": "谐波对频率测量的影响",
|
||||
"children": [
|
||||
{
|
||||
"id": "2-3-1",
|
||||
"pid": "2-3",
|
||||
"name": "输入:频率 50.05Hz Ua =100%Un..."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"pid": "0",
|
||||
"name": "谐波准确度检测",
|
||||
"children": [
|
||||
{
|
||||
"id": "3-1",
|
||||
"pid": "3",
|
||||
"name": "额定工作条件下的检测",
|
||||
"children": [
|
||||
{
|
||||
"id": "3-1-1",
|
||||
"pid": "3-1",
|
||||
"name": "输入:频率 42.5Hz..."
|
||||
},
|
||||
{
|
||||
"id": "3-1-2",
|
||||
"pid": "3-1",
|
||||
"name": "输入:频率 50.0Hz..."
|
||||
},
|
||||
{
|
||||
"id": "3-1-3",
|
||||
"pid": "3-1",
|
||||
"name": "输入:频率 50.05Hz..."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "3-2",
|
||||
"pid": "3",
|
||||
"name": "电压对频率测量的影响",
|
||||
"children": [
|
||||
{
|
||||
"id": "3-2-1",
|
||||
"pid": "3-2",
|
||||
"name": "输入:频率 50.05Hz Ua =10%Un..."
|
||||
},
|
||||
{
|
||||
"id": "3-2-1",
|
||||
"pid": "3-2",
|
||||
"name": "输入:频率 51.05Hz Ua =10%Un..."
|
||||
},
|
||||
{
|
||||
"id": "3-2-2",
|
||||
"pid": "3-2",
|
||||
"name": "输入:频率 52.05Hz Ua =10%Un..."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "3-3",
|
||||
"pid": "3",
|
||||
"name": "谐波对频率测量的影响",
|
||||
"children": [
|
||||
{
|
||||
"id": "3-3-1",
|
||||
"pid": "3-3",
|
||||
"name": "输入:频率 50.05Hz Ua =100%Un..."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,72 +1,49 @@
|
||||
import type { ReqPage } from '@/api/interface'
|
||||
import type { DatetimeFormatProps } from 'vue-i18n';
|
||||
|
||||
// 检测计划模块
|
||||
export namespace Plan {
|
||||
|
||||
// 检测计划接口
|
||||
export interface PlanBO {
|
||||
id?: string; //检测计划ID
|
||||
export interface ResPlan {
|
||||
id: string; //检测计划ID
|
||||
name: string; //检测计划名称
|
||||
pattern: string; //模式,字典表(数字、模拟、比对)
|
||||
father_Plan_Id?: string; //父计划ID
|
||||
dataSource_Id: string[]; //数据源ID
|
||||
script_Id: string; //检测脚本ID
|
||||
error_Sys_Id: string;//误差体系ID
|
||||
test_State: string; //检测状态
|
||||
report_State: string; //报告生成状态
|
||||
result: string;//检测结果
|
||||
create_Time?: string;//创建时间
|
||||
pattern?: string; //模式,字典表(数字、模拟、比对)
|
||||
fatherPlanId?: string; //父计划ID
|
||||
dataSourceId: string; //数据源ID
|
||||
scriptId: string; //检测脚本ID
|
||||
errorSysId: string;//误差体系ID
|
||||
timeCheck:number;//守时检测:0否,1。是
|
||||
testState: number; //检测状态:0:未检、1:检测中、2:检测完成,默认为 0
|
||||
reportState: number; //报告生成状态:0:未生成、1:部分生成、2:全部生成,默认为 0
|
||||
result: number;//检测结果:0:不符合、1:符合、2:/,默认为 2
|
||||
code:number; //自动生成,用于生成数据表后缀
|
||||
state: number;//;状态:0-删除 1-正常
|
||||
createBy?:string; //创建用户
|
||||
createTime?:string; //创建时间
|
||||
updateBy?:string; //更新用户
|
||||
updateTime?:string; //更新时间
|
||||
|
||||
associateReport:number;//是否关联报告模板 0否 1是
|
||||
reportTemplateName:string;
|
||||
reportTemplateVersion:string;
|
||||
dataRule:string //数据处理原则
|
||||
}
|
||||
|
||||
// 检测计划 + 分页
|
||||
export interface ReqPlanParams extends ReqPage,PlanBO {
|
||||
export interface ReqPlanParams extends ReqPage,ResPlan {
|
||||
|
||||
}
|
||||
|
||||
// 检测计划 + 检测源
|
||||
export interface PlanAndSourceBO extends PlanBO {
|
||||
testSourceName: string;//计划所属检测源
|
||||
source_Id: string[];
|
||||
device_Id?: string[];
|
||||
testSourceList?: string[];//临时测试
|
||||
dataSource_Ids:string;
|
||||
}
|
||||
// // 检测计划列表
|
||||
// export interface PlanList {
|
||||
// id: string; //检测计划ID
|
||||
// name: string; //检测计划名称
|
||||
// pattern: string; //模式,字典表(数字、模拟、比对)
|
||||
// father_Plan_Id: string; //父计划ID
|
||||
// dataSource_Id: string; //数据源ID
|
||||
// script_Id: string; //检测脚本ID
|
||||
// error_Sys_Id: string;//误差体系ID
|
||||
// test_State: string; //检测状态
|
||||
// report_State: string; //报告生成状态
|
||||
// result: string;//检测结果
|
||||
// state: number; //状态
|
||||
// create_By?: string; //创建用户
|
||||
// create_Time?: string;//创建时间
|
||||
// update_By?: string; //更新用户
|
||||
// update_Time?: string; //更新时间
|
||||
// }
|
||||
|
||||
// // 被检设备参数
|
||||
// export interface ReqPlanParams extends ReqPage {
|
||||
// id: string; //检测计划ID
|
||||
// name: string; //检测计划名称
|
||||
// pattern: string; //模式,字典表(数字、模拟、比对)
|
||||
// father_Plan_Id: string; //父计划ID
|
||||
// dataSource_Id: string; //数据源ID
|
||||
// script_Id: string; //检测脚本ID
|
||||
// error_Sys_Id: string;//误差体系ID
|
||||
// test_State: string; //检测状态
|
||||
// report_State: string; //报告生成状态
|
||||
// result: string;//检测结果
|
||||
// state: number; //状态
|
||||
// create_By?: string; //创建用户
|
||||
// create_Time?: string;//创建时间
|
||||
// update_By?: string; //更新用户
|
||||
// update_Time?: string; //更新时间
|
||||
// }
|
||||
export interface ReqPlan extends ResPlan {
|
||||
datasourceIds:string;
|
||||
sourceIds: string;
|
||||
planId:string;
|
||||
scriptName: string ;
|
||||
errorSysName: string;
|
||||
sourceName: string ;
|
||||
devIds: string[];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,27 +1,92 @@
|
||||
import { ResPage } from '@/api/interface'
|
||||
import { Plan } from './interface'
|
||||
import { ADMIN as rePrefix } from '@/api/config/serviceName'
|
||||
import type { Plan } from './interface'
|
||||
import http from '@/api'
|
||||
import type { ErrorSystem } from '../device/interface/error'
|
||||
import type { Device } from '../device/interface/device'
|
||||
import { ReqDevReportParams } from '@/api/device/interface/device'
|
||||
|
||||
/**
|
||||
* @name 检测计划管理模块
|
||||
*/
|
||||
// 获取检测计划列表
|
||||
export const getPlanList = (params: Plan.ReqPlanParams) => {
|
||||
return http.post<ResPage<Plan.PlanBO>>(`/plan/list`, params)
|
||||
return http.post(`/adPlan/list`, params)
|
||||
}
|
||||
|
||||
// 新增检测计划
|
||||
export const addPlan = (params: Plan.PlanBO) => {
|
||||
return http.post(`/role/add`, params)
|
||||
export const addPlan = (params: any) => {
|
||||
return http.post(`/adPlan/add`, params)
|
||||
}
|
||||
|
||||
// 编辑检测计划
|
||||
export const editPlan = (params: Plan.PlanBO) => {
|
||||
return http.post(`/role/edit`, params)
|
||||
export const updatePlan = (params: any) => {
|
||||
return http.post(`/adPlan/update`, params)
|
||||
}
|
||||
|
||||
// 删除检测计划
|
||||
export const deletePlan = (params: { id: string[] }) => {
|
||||
return http.post(`/role/del`, params)
|
||||
return http.post(`/adPlan/delete`, params)
|
||||
}
|
||||
|
||||
// 获取指定模式下所有检测源
|
||||
export const getTestSourceList = (params: Plan.ReqPlan) => {
|
||||
return http.get(`/pqSource/getAll?patternId=${params.pattern}`)
|
||||
}
|
||||
|
||||
// 获取指定模式下所有检测脚本
|
||||
export const getPqScriptList = (params: Plan.ReqPlan) => {
|
||||
return http.get(`/pqScript/getAll?patternId=${params.pattern}`)
|
||||
}
|
||||
|
||||
//获取所有误差体系
|
||||
export const getPqErrSysList = () => {
|
||||
return http.get<ErrorSystem.ErrorSystemList>(`/pqErrSys/getAll`)
|
||||
}
|
||||
|
||||
//获取指定模式下所有未绑定的设备
|
||||
export const getUnboundPqDevList = (params: Plan.ReqPlan) => {
|
||||
return http.get(`/pqDev/listUnbound?pattern=${params.pattern}`)
|
||||
}
|
||||
|
||||
//根据检测计划id查询出所有已绑定的设备
|
||||
export const getBoundPqDevList = (params: any) => {
|
||||
return http.post(`/pqDev/listByPlanId`, params)
|
||||
}
|
||||
|
||||
//检测计划绑定设备
|
||||
// export const BindPqDevList = (params: any) => {
|
||||
// return http.post(`/pqDev/bindDev`,params)
|
||||
// }
|
||||
|
||||
// 按照模式查询检测计划(用于首页展示)
|
||||
export const getPlanListByPattern = (params: Plan.ReqPlan) => {
|
||||
return http.get(`/adPlan/listByPattern?pattern=${params.pattern}`)
|
||||
}
|
||||
|
||||
// 导出检测计划
|
||||
export const exportPlan = (params: Device.ReqPqDevParams) => {
|
||||
return http.download(`/adPlan/export`, params)
|
||||
}
|
||||
|
||||
// 下载模板
|
||||
export const downloadTemplate = (params: { patternId: string }) => {
|
||||
return http.download(`/adPlan/downloadTemplate`, params)
|
||||
}
|
||||
// 导入检测计划
|
||||
export const importPlan = (params: Device.ReqPqDevParams) => {
|
||||
return http.uploadExcel(`/adPlan/import`, params)
|
||||
}
|
||||
|
||||
// 装置检测报告生成
|
||||
export const generateDevReport = (params: Device.ReqDevReportParams) => {
|
||||
return http.post(`/report/generateReport`, params)
|
||||
}
|
||||
|
||||
// 装置检测报告下载
|
||||
export const downloadDevData = (params: Device.ReqDevReportParams) => {
|
||||
return http.download(`/report/downloadReport`, params)
|
||||
}
|
||||
|
||||
export const staticsAnalyse = (params: { id: string[] }) => {
|
||||
return http.download('/adPlan/analyse', params)
|
||||
}
|
||||
|
||||
|
||||
@@ -58,11 +58,15 @@ const dictReportState: Dict[] = [
|
||||
const dictResult: Dict[] = [
|
||||
{
|
||||
id: "0",
|
||||
label: '符合',
|
||||
label: '不符合',
|
||||
},
|
||||
{
|
||||
id: "1",
|
||||
label: '不符合',
|
||||
label: '符合',
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
label: '/',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -170,35 +174,35 @@ const testFatherPlanList: Dict[] = [
|
||||
const sourceDataList: Dict[] = [
|
||||
{
|
||||
id: "1",
|
||||
label: '标准源-福禄克-6100A',
|
||||
label: '标准源-FLUKE.6100A电能功率标准源-1',
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
label: '标准源-昂立-PF2',
|
||||
label: '标准源-ANGLI-FP2高性能数字信号源-1',
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
label: '标准源-丹迪克-DKLN1',
|
||||
label: '标准源-DKLN-1电能质量测试分析仪智能检定装置-1',
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
label: '标准源-博电源-PQC600A',
|
||||
label: '标准源-PQC600A高精度电能功率标准源-1',
|
||||
},
|
||||
{
|
||||
id: "5",
|
||||
label: '高精度设备-PQV520-1',
|
||||
label: '高精度设备-PQV-520便携式电能质量监测装置-1',
|
||||
},
|
||||
{
|
||||
id: "6",
|
||||
label: '高精度设备-PQV520-2',
|
||||
label: '高精度设备-PQV-520便携式电能质量监测装置-2',
|
||||
},
|
||||
{
|
||||
id: "7",
|
||||
label: '高精度设备-PQV520-3',
|
||||
label: '高精度设备-PQV-520便携式电能质量监测装置-3',
|
||||
},
|
||||
{
|
||||
id: "8",
|
||||
label: '高精度设备-PQV520-4',
|
||||
label: '高精度设备-PQV-520便携式电能质量监测装置-4',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -206,46 +210,80 @@ const sourceDataList: Dict[] = [
|
||||
const deviceDataList: Dict[] = [
|
||||
{
|
||||
id: "1",
|
||||
label: '模拟装置1',
|
||||
label: '240001',
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
label: '模拟装置2',
|
||||
label: '240002',
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
label: '模拟装置3',
|
||||
label: '240003',
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
label: '模拟装置4',
|
||||
label: '240004',
|
||||
},
|
||||
{
|
||||
id: "5",
|
||||
label: '中电送检装置',
|
||||
label: '240005',
|
||||
},
|
||||
{
|
||||
id: "6",
|
||||
label: '易司拓测试装置',
|
||||
label: '240006',
|
||||
},
|
||||
{
|
||||
id: "7",
|
||||
label: '山大电力测试装置1',
|
||||
label: '240007',
|
||||
},
|
||||
{
|
||||
id: "8",
|
||||
label: '山大电力测试装置2',
|
||||
label: '240008',
|
||||
},
|
||||
|
||||
]
|
||||
// const deviceDataList: Dict[] = [
|
||||
// {
|
||||
// id: "1",
|
||||
// label: '模拟装置1',
|
||||
// },
|
||||
// {
|
||||
// id: "2",
|
||||
// label: '模拟装置2',
|
||||
// },
|
||||
// {
|
||||
// id: "3",
|
||||
// label: '模拟装置3',
|
||||
// },
|
||||
// {
|
||||
// id: "4",
|
||||
// label: '模拟装置4',
|
||||
// },
|
||||
// {
|
||||
// id: "5",
|
||||
// label: '中电送检装置',
|
||||
// },
|
||||
// {
|
||||
// id: "6",
|
||||
// label: '易司拓测试装置',
|
||||
// },
|
||||
// {
|
||||
// id: "7",
|
||||
// label: '山大电力测试装置1',
|
||||
// },
|
||||
// {
|
||||
// id: "8",
|
||||
// label: '山大电力测试装置2',
|
||||
// },
|
||||
|
||||
// ]
|
||||
|
||||
const planData = ref<Plan.PlanAndSourceBO[]>([
|
||||
{
|
||||
'id': '1',
|
||||
'name': '检测计划1',
|
||||
'name': '沧州110kV东光站装置送检',
|
||||
'pattern':'1',
|
||||
"source_Id" : ['1'],
|
||||
"testSourceName":'标准源-福禄克-6100A',
|
||||
"testSourceName":'标准源-FLUKE.6100A电能功率标准源-1',
|
||||
'dataSource_Id':['1'],
|
||||
'dataSource_Ids':'实时数据',
|
||||
'script_Id':'1',
|
||||
@@ -256,32 +294,32 @@ const planData = ref<Plan.PlanAndSourceBO[]>([
|
||||
},
|
||||
{
|
||||
'id': '2',
|
||||
'name': '检测计划2',
|
||||
'name': '邯郸2台安徽振兴终端送检',
|
||||
'pattern':'1',
|
||||
"source_Id" : ['5','6','7','8'],
|
||||
"testSourceName":'高精度设备-PQV520-1',
|
||||
"testSourceName":'高精度设备-PQV-520便携式电能质量监测装置-1',
|
||||
'father_Plan_Id':'1',
|
||||
'dataSource_Id':['5'],
|
||||
'dataSource_Ids':'分钟统计数据CP95值',
|
||||
'dataSource_Id':['1'],
|
||||
'dataSource_Ids':'实时数据',
|
||||
'script_Id':'2',
|
||||
'error_Sys_Id':'2',
|
||||
'test_State':'2',
|
||||
'report_State':'2',
|
||||
'result':'0',
|
||||
"testSourceList":[
|
||||
'高精度设备-PQV520-2','高精度设备-PQV520-3','高精度设备-PQV520-4'
|
||||
'高精度设备-PQV-520便携式电能质量监测装置-2','高精度设备-PQV-520便携式电能质量监测装置-3','高精度设备-PQV-520便携式电能质量监测装置-4'
|
||||
]
|
||||
},
|
||||
{
|
||||
'id': '3',
|
||||
'name': '检测子计划3',
|
||||
'name': '浙江分布式光伏电能质量试点',
|
||||
'pattern':'1',
|
||||
"source_Id" : ['3'],
|
||||
"testSourceName":'标准源-丹迪克-DKLN1',
|
||||
"testSourceName":'标准源-DKLN-1电能质量测试分析仪智能检定装置-1',
|
||||
'father_Plan_Id':'1',
|
||||
'dataSource_Id':['1'],
|
||||
'dataSource_Ids':'实时数据',
|
||||
'script_Id':'3',
|
||||
'script_Id':'4',
|
||||
'error_Sys_Id':'3',
|
||||
'test_State':'1',
|
||||
'report_State':'1',
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
"code": "200",
|
||||
"data": [
|
||||
{
|
||||
"name": "未检测",
|
||||
"name": "未检",
|
||||
"children": [
|
||||
{
|
||||
"id": 4,
|
||||
"pid": 1,
|
||||
"name": "邯郸220kV团城站等4座站电能质量检测"
|
||||
"name": "邯郸220kV团城站电能质量检测"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
@@ -17,7 +17,7 @@
|
||||
{
|
||||
"id": 6,
|
||||
"pid": 1,
|
||||
"name": "深圳市中电软件有限公司委托送检"
|
||||
"name": "深圳市中电公司委托送检"
|
||||
}
|
||||
],
|
||||
"id": 1
|
||||
@@ -28,17 +28,17 @@
|
||||
{
|
||||
"id": 7,
|
||||
"pid": 2,
|
||||
"name": "沧州220kV留古等4座变电站电能质量检测"
|
||||
"name": "沧州220kV留古站电能质量检测"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"pid": 2,
|
||||
"name": "沧州供电公司110kV东光站等10台装置送检"
|
||||
"name": "沧州110kV东光站装置送检"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"pid": 2,
|
||||
"name": "保定分布式光伏电能质量监测试点"
|
||||
"name": "浙江分布式光伏电能质量试点"
|
||||
}
|
||||
],
|
||||
"id": 2
|
||||
@@ -54,7 +54,7 @@
|
||||
{
|
||||
"id": 11,
|
||||
"pid": 3,
|
||||
"name": "北京2024现场检测"
|
||||
"name": "深圳2台中电终端委托送检"
|
||||
}
|
||||
],
|
||||
"id": 3
|
||||
|
||||
34
frontend/src/api/socket/socket.ts
Normal file
34
frontend/src/api/socket/socket.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import http from '@/api'
|
||||
|
||||
|
||||
export const startPreTest = (params) => {
|
||||
return http.post(`/prepare/startPreTest`, params, {loading: false})
|
||||
}
|
||||
|
||||
export const closePreTest = (params) => {
|
||||
return http.post(`/prepare/closePreTest`, params,{ loading: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始正式检测
|
||||
* @param params
|
||||
*/
|
||||
// export const startTest = (params) => {
|
||||
// return http.post(`/prepare/startTest`, params, {loading: false})
|
||||
// }
|
||||
|
||||
/**
|
||||
* 暂停正式检测
|
||||
* @param params
|
||||
*/
|
||||
export const pauseTest = () => {
|
||||
return http.get(`/prepare/closePreTest`, {loading: false})
|
||||
}
|
||||
|
||||
/**
|
||||
* 继续正式检测
|
||||
* @param params
|
||||
*/
|
||||
export const resumeTest = (params) => {
|
||||
return http.post(`/prepare/restartTemTest/`, params, {loading: false})
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import http from '@/api'
|
||||
import {type Base} from '@/api/system/base/interface'
|
||||
|
||||
@@ -12,6 +13,10 @@ export const updateTestConfig = (params: Base.ResTestConfig) => {
|
||||
return http.post(`/sysTestConfig/update`, params)
|
||||
}
|
||||
|
||||
//场景切换
|
||||
export const updateScene = (params: any) => {
|
||||
return http.post(`/sysTestConfig/update`,params)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ export namespace Base {
|
||||
id: string; //系统配置表Id
|
||||
autoGenerate:number;//检测报告是否自动生成0 否;1是
|
||||
maxTime:number;//最大复检次数,默认3次
|
||||
dataRule:string;//数据处理原则,关联字典(所有值、部分值、cp95值、平均值、任意值),默认任意值
|
||||
state: number; //状态
|
||||
scale:number;//小数位
|
||||
createBy?: string| null; //创建用户
|
||||
createTime?: string| null; //创建时间
|
||||
updateBy?: string| null; //更新用户
|
||||
|
||||
@@ -216,7 +216,7 @@ const dictData: Dict[] = [
|
||||
children: [
|
||||
{
|
||||
id: "0",
|
||||
label: 'FLUKE6100A电能功率标准源',
|
||||
label: 'FLUKE.6100A电能功率标准源',
|
||||
code: 0,
|
||||
},
|
||||
{
|
||||
@@ -236,7 +236,7 @@ const dictData: Dict[] = [
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
label: 'PQV-520电能质量检测装置',
|
||||
label: 'PQV-520便携式电能质量监测装置',
|
||||
code: 4,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import http from '@/api'
|
||||
import { type Dict } from '@/api/system/dictionary/interface'
|
||||
import { c } from 'vite/dist/node/types.d-aGj9QkWt'
|
||||
|
||||
//获取字典类型
|
||||
export const getDictTreeList = (params: Dict.ResDictTree) => {
|
||||
const name = params.name || '';
|
||||
return http.get(`/dictTree/getTree?keyword=${name}`, params)
|
||||
export const getDictTreeByCode = (params: Dict.ResDictTree) => {
|
||||
const code = params.code || ''
|
||||
return http.get(`/dictTree/getTreeByCode?code=${code}`, { loading: true })
|
||||
}
|
||||
|
||||
export const getDictTreeByName = (params: Dict.ResDictTree) => {
|
||||
const name = params.name || ''
|
||||
return http.get(`/dictTree/getTreeByName?name=${name}`)
|
||||
}
|
||||
|
||||
//添加字典类型
|
||||
@@ -21,4 +27,3 @@ export const updateDictTree = (params: Dict.ResDictTree) => {
|
||||
export const deleteDictTree = (params: Dict.ResDictTree) => {
|
||||
return http.post(`/dictTree/delete?id=${params.id}`)
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ export namespace Dict {
|
||||
name: string; // 名称
|
||||
code: string; // 编码
|
||||
sort: number; // 排序
|
||||
openValue?: number | null;
|
||||
level?: number | null; // 事件等级:0-普通;1-中等;2-严重 (默认为0)
|
||||
algoDescribe?: number | null; // 与高级算法内部Id描述对应
|
||||
value?: string | null; // 字典针对电压等级
|
||||
@@ -116,10 +117,10 @@ export namespace Dict {
|
||||
storeFlag?:string ;//sts、di的是否存储 1:存储 0:不存 储;
|
||||
curSts?:number | null;//sts、do的当前值;
|
||||
ctlSts?:number;//do的是否可远程控制 1:是 0:否;
|
||||
maxNum?:number ;//设置最大值
|
||||
minNum?: number;//设置最小值
|
||||
maxNum?:number | null;//设置最大值
|
||||
minNum?: number| null;//设置最小值
|
||||
setValue?:string | null;//参数为enum可设置的所有值序列
|
||||
strlen?:number ;//参数string可设置字符串的长度上 限
|
||||
strlen?:number | null;//参数string可设置字符串的长度上 限
|
||||
defaultValue?:string | null; //参数缺省值、告警code值
|
||||
resourcesId?:string ; //报表数据来源(统计表表名)
|
||||
limitName?:string | null; //限值字段名称
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import type {AuditLog } from '@/api/system/log/interface/log.ts'
|
||||
import http from '@/api'
|
||||
|
||||
/**
|
||||
* @name 审计日志管理模块
|
||||
*/
|
||||
|
||||
//获取审计日志
|
||||
export const getAuditLog = (params: AuditLog.ReqAuditLogParams) => {
|
||||
return http.post(`/sysLog/list`, params)
|
||||
}
|
||||
|
||||
|
||||
export const exportCsv = (params: AuditLog.ReqAuditLogParams) => {
|
||||
return http.download(`/sysLog/exportCSV`, params)
|
||||
}
|
||||
@@ -1,15 +1,36 @@
|
||||
import type { ReqPage, ResPage } from '@/api/interface'
|
||||
|
||||
// 审计日志管理模块
|
||||
export namespace Sys_Log_Audit {
|
||||
// 日志列表
|
||||
export interface Audit_LogList {
|
||||
id: string;//日志表Id
|
||||
operate_Type:string;//日志类型
|
||||
ip:string;//操作IP
|
||||
result: string;//事件结果
|
||||
remark: string;//事件描述
|
||||
warn:number;//告警标志
|
||||
create_By:string;//创建用户
|
||||
create_Time:string;//创建时间
|
||||
}
|
||||
export namespace AuditLog {
|
||||
|
||||
/**
|
||||
* 设备类型数据表格分页查询参数
|
||||
*/
|
||||
export interface ReqAuditLogParams extends ReqPage {
|
||||
id: string; //审计日志Id 必填
|
||||
createTime?: string; //创建时间
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备类型新增、修改、根据id查询返回的对象
|
||||
*/
|
||||
export interface ResAuditLog {
|
||||
id: string;//审计日志Id
|
||||
operate_Type:string;//操作类型
|
||||
ip:string;//操作IP
|
||||
result: string;//事件结果
|
||||
remark: string;//事件描述
|
||||
level:number;//告警等级
|
||||
warn:number;//告警标志
|
||||
create_By:string;//创建用户
|
||||
create_Time:string;//创建时间
|
||||
sort:number;//排序
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备类型表格查询分页返回的对象;
|
||||
*/
|
||||
export interface ResAuditLogPage extends ResPage<ResAuditLog> {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,13 @@ export namespace Login {
|
||||
export interface ReqLoginForm {
|
||||
username: string;
|
||||
password: string;
|
||||
checked: boolean;
|
||||
}
|
||||
export interface ResLogin {
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
userInfo:{
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +1,59 @@
|
||||
import type { Login } from '@/api/user/interface/user'
|
||||
import { ADMIN as rePrefix } from '@/api/system/config/serviceName'
|
||||
import type {Login} from '@/api/user/interface/user'
|
||||
import {ADMIN as rePrefix} from '@/api/system/config/serviceName'
|
||||
import http from '@/api'
|
||||
import type { Dict } from '@/api/interface'
|
||||
import type {Dict} from '@/api/interface'
|
||||
|
||||
/**
|
||||
* @name 登录模块
|
||||
*/
|
||||
// 用户登录
|
||||
export const loginApi = (params: Login.ReqLoginForm) => {
|
||||
return http.post<Login.ResLogin>(`${rePrefix}/login`, params, { loading: false })
|
||||
// return http.post<Login.ResLogin>(`/Register1`, params, { loading: false })
|
||||
export const loginApi = (params: { username: string; password: string}) => {
|
||||
return http.post<Login.ResLogin>(`${rePrefix}/login`, params, {loading: false})
|
||||
// return http.post<Login.ResLogin>(`/Register1`, params, { loading: false })
|
||||
}
|
||||
// 获取菜单列表
|
||||
export const getAuthMenuListApi = () => {
|
||||
return http.get<Menu.MenuOptions[]>(`/sysFunction/getMenu`, {}, { loading: false })
|
||||
// return http.post<Menu.MenuOptions[]>(`/Register2`, {}, { loading: false })
|
||||
return http.get<Menu.MenuOptions[]>(`/sysFunction/getMenu`, {}, {loading: false})
|
||||
// return http.post<Menu.MenuOptions[]>(`/Register2`, {}, { loading: false })
|
||||
}
|
||||
// 获取按钮权限
|
||||
export const getAuthButtonListApi = () => {
|
||||
return http.get<Login.ResAuthButtons>(`/sysFunction/getButton`, {}, { loading: false })
|
||||
// return http.post<Login.ResAuthButtons>(`/Register3`, {}, { loading: false })
|
||||
return http.get<Login.ResAuthButtons>(`/sysFunction/getButton`, {}, {loading: false})
|
||||
// return http.post<Login.ResAuthButtons>(`/Register3`, {}, { loading: false })
|
||||
}
|
||||
// 用户退出登录
|
||||
export const logoutApi = () => {
|
||||
return http.post(`${rePrefix}/logout`)
|
||||
return http.post(`${rePrefix}/logout`)
|
||||
}
|
||||
|
||||
//获取下拉框列表
|
||||
export const getDictList = () =>{
|
||||
return http.get<Dict>('/dictData/dictDataCache')
|
||||
export const getDictList = () => {
|
||||
return http.get<Dict>('/dictData/dictDataCache')
|
||||
}
|
||||
|
||||
//token刷新
|
||||
export const refreshToken = () => {
|
||||
return http.get<Login.ResLogin>(`${rePrefix}/refreshToken`,
|
||||
{},
|
||||
{loading: false}
|
||||
)
|
||||
}
|
||||
|
||||
//获取场景
|
||||
export const getCurrentScene = () => {
|
||||
return http.get('/sysTestConfig/getCurrentScene', {}, {loading: false})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取RSA公钥
|
||||
*/
|
||||
export const getPublicKey = (username: string) => {
|
||||
return http.get(`/admin/getPublicKey?username=${username}`, {}, {loading: false})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取是否在检测中自动生成报告
|
||||
*/
|
||||
export const getAutoGenerate = () => {
|
||||
return http.get('/sysTestConfig/getAutoGenerate', {}, {loading: false})
|
||||
}
|
||||
|
||||
BIN
frontend/src/assets/images/transient.png
Normal file
BIN
frontend/src/assets/images/transient.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
@@ -1,53 +1,53 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" :title="`批量添加${parameter.title}`" :destroy-on-close="true" width="580px" draggable>
|
||||
<el-form class="drawer-multiColumn-form" label-width="100px">
|
||||
<el-form-item label="模板下载 :">
|
||||
<el-button type="primary" :icon="Download" @click="downloadTemp"> 点击下载 </el-button>
|
||||
<el-dialog v-model='dialogVisible' :title='`批量添加${parameter.title}`' :destroy-on-close='true' width='580px'
|
||||
draggable>
|
||||
<el-form class='drawer-multiColumn-form' label-width='100px'>
|
||||
<el-form-item label='模板下载 :'>
|
||||
<el-button type='primary' :icon='Download' @click='downloadTemp'> 点击下载</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="文件上传 :">
|
||||
<el-form-item label='文件上传 :'>
|
||||
<el-upload
|
||||
action="#"
|
||||
class="upload"
|
||||
:drag="true"
|
||||
:limit="excelLimit"
|
||||
:multiple="true"
|
||||
:show-file-list="true"
|
||||
:http-request="uploadExcel"
|
||||
:before-upload="beforeExcelUpload"
|
||||
:on-exceed="handleExceed"
|
||||
:on-success="excelUploadSuccess"
|
||||
:on-error="excelUploadError"
|
||||
action='#'
|
||||
class='upload'
|
||||
:drag='true'
|
||||
:limit='excelLimit'
|
||||
:multiple='true'
|
||||
:show-file-list='true'
|
||||
:http-request='uploadExcel'
|
||||
:before-upload='beforeExcelUpload'
|
||||
:on-exceed='handleExceed'
|
||||
:accept="parameter.fileType!.join(',')"
|
||||
>
|
||||
<slot name="empty">
|
||||
<el-icon class="el-icon--upload">
|
||||
<slot name='empty'>
|
||||
<el-icon class='el-icon--upload'>
|
||||
<upload-filled />
|
||||
</el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<div class='el-upload__text'>将文件拖到此处,或<em>点击上传</em></div>
|
||||
</slot>
|
||||
<template #tip>
|
||||
<slot name="tip">
|
||||
<div class="el-upload__tip">请上传 .xls , .xlsx 标准格式文件,文件最大为 {{ parameter.fileSize }}M</div>
|
||||
<slot name='tip'>
|
||||
<div class='el-upload__tip'>请上传 .xls , .xlsx 标准格式文件,文件最大为 {{ parameter.fileSize }}M</div>
|
||||
</slot>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="parameter.showCover" label="数据覆盖 :">
|
||||
<el-switch v-model="isCover" />
|
||||
<el-form-item v-if='parameter.showCover' label='数据覆盖 :'>
|
||||
<el-switch v-model='isCover' />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ImportExcel">
|
||||
import { ref } from "vue";
|
||||
import { useDownload } from "@/hooks/useDownload";
|
||||
import { Download } from "@element-plus/icons-vue";
|
||||
import { ElNotification, UploadRequestOptions, UploadRawFile } from "element-plus";
|
||||
<script setup lang='ts' name='ImportExcel'>
|
||||
import { ref } from 'vue'
|
||||
import { useDownload } from '@/hooks/useDownload'
|
||||
import { Download } from '@element-plus/icons-vue'
|
||||
import { ElNotification, UploadRequestOptions, UploadRawFile, ElMessage } from 'element-plus'
|
||||
|
||||
export interface ExcelParameterProps {
|
||||
title: string; // 标题
|
||||
showCover?: boolean; // 是否显示”数据覆盖“选项
|
||||
patternId?: string; // 模式ID
|
||||
fileSize?: number; // 上传文件的大小
|
||||
fileType?: File.ExcelMimeType[]; // 上传文件的类型
|
||||
tempApi?: (params: any) => Promise<any>; // 下载模板的Api
|
||||
@@ -56,96 +56,132 @@ export interface ExcelParameterProps {
|
||||
}
|
||||
|
||||
// 是否覆盖数据
|
||||
const isCover = ref(false);
|
||||
const isCover = ref(false)
|
||||
// 最大文件上传数
|
||||
const excelLimit = ref(1);
|
||||
const excelLimit = ref(1)
|
||||
// dialog状态
|
||||
const dialogVisible = ref(false);
|
||||
const dialogVisible = ref(false)
|
||||
// 父组件传过来的参数
|
||||
const parameter = ref<ExcelParameterProps>({
|
||||
title: "",
|
||||
title: '',
|
||||
fileSize: 5,
|
||||
fileType: ["application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]
|
||||
});
|
||||
fileType: ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
|
||||
})
|
||||
|
||||
// 接收父组件参数
|
||||
const acceptParams = (params: ExcelParameterProps) => {
|
||||
parameter.value = { ...parameter.value, ...params };
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
parameter.value = { ...parameter.value, ...params }
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
// Excel 导入模板下载
|
||||
const downloadTemp = () => {
|
||||
if (!parameter.value.tempApi) return;
|
||||
useDownload(parameter.value.tempApi, `${parameter.value.title}模板`,{},true);
|
||||
};
|
||||
if (!parameter.value.tempApi) return
|
||||
useDownload(parameter.value.tempApi, `${parameter.value.title}模板`, {'patternId':parameter.value.patternId}, false)
|
||||
}
|
||||
|
||||
// 文件上传
|
||||
const uploadExcel = async (param: UploadRequestOptions) => {
|
||||
debugger
|
||||
let excelFormData = new FormData();
|
||||
excelFormData.append("file", param.file);
|
||||
isCover.value && excelFormData.append("isCover", isCover.value as unknown as Blob);
|
||||
await parameter.value.importApi!(excelFormData);
|
||||
parameter.value.getTableList && parameter.value.getTableList();
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
let excelFormData = new FormData()
|
||||
excelFormData.append('file', param.file)
|
||||
if (parameter.value.patternId) {
|
||||
excelFormData.append('patternId', parameter.value.patternId)
|
||||
}
|
||||
isCover.value && excelFormData.append('isCover', isCover.value as unknown as Blob)
|
||||
//await parameter.value.importApi!(excelFormData);
|
||||
await parameter.value.importApi!(excelFormData)
|
||||
.then(res => handleImportResponse(res))
|
||||
parameter.value.getTableList && parameter.value.getTableList()
|
||||
dialogVisible.value = false
|
||||
}
|
||||
|
||||
|
||||
async function handleImportResponse(res: any) {
|
||||
console.log(res)
|
||||
|
||||
if (res.type === 'application/json') {
|
||||
const fileReader = new FileReader()
|
||||
fileReader.onloadend = () => {
|
||||
try {
|
||||
const jsonData = JSON.parse(fileReader.result)
|
||||
if (jsonData.code === 'A0000') {
|
||||
ElMessage.success('导入成功')
|
||||
} else {
|
||||
ElMessage.error(jsonData.message)
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
}
|
||||
fileReader.readAsText(res)
|
||||
} else {
|
||||
ElMessage.error('导入失败,请查看下载附件!')
|
||||
let blob = new Blob([res], { type: 'application/vnd.ms-excel' })
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = '导入失败数据'
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
link.remove()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 文件上传之前判断
|
||||
* @param file 上传的文件
|
||||
* */
|
||||
const beforeExcelUpload = (file: UploadRawFile) => {
|
||||
const isExcel = parameter.value.fileType!.includes(file.type as File.ExcelMimeType);
|
||||
const fileSize = file.size / 1024 / 1024 < parameter.value.fileSize!;
|
||||
const isExcel = parameter.value.fileType!.includes(file.type as File.ExcelMimeType)
|
||||
const fileSize = file.size / 1024 / 1024 < parameter.value.fileSize!
|
||||
if (!isExcel)
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: "上传文件只能是 xls / xlsx 格式!",
|
||||
type: "warning"
|
||||
});
|
||||
title: '温馨提示',
|
||||
message: '上传文件只能是 xls / xlsx 格式!',
|
||||
type: 'warning',
|
||||
})
|
||||
if (!fileSize)
|
||||
setTimeout(() => {
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
title: '温馨提示',
|
||||
message: `上传文件大小不能超过 ${parameter.value.fileSize}MB!`,
|
||||
type: "warning"
|
||||
});
|
||||
}, 0);
|
||||
return isExcel && fileSize;
|
||||
};
|
||||
type: 'warning',
|
||||
})
|
||||
}, 0)
|
||||
return isExcel && fileSize
|
||||
}
|
||||
|
||||
// 文件数超出提示
|
||||
const handleExceed = () => {
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: "最多只能上传一个文件!",
|
||||
type: "warning"
|
||||
});
|
||||
};
|
||||
title: '温馨提示',
|
||||
message: '最多只能上传一个文件!',
|
||||
type: 'warning',
|
||||
})
|
||||
}
|
||||
|
||||
// 上传错误提示
|
||||
const excelUploadError = () => {
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: `批量添加${parameter.value.title}失败,请您重新上传!`,
|
||||
type: "error"
|
||||
});
|
||||
};
|
||||
// const excelUploadError = () => {
|
||||
// ElNotification({
|
||||
// title: '温馨提示',
|
||||
// message: `批量添加${parameter.value.title}失败,请您重新上传!`,
|
||||
// type: 'error',
|
||||
// })
|
||||
// }
|
||||
|
||||
// 上传成功提示
|
||||
const excelUploadSuccess = () => {
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: `批量添加${parameter.value.title}成功!`,
|
||||
type: "success"
|
||||
});
|
||||
};
|
||||
// const excelUploadSuccess = () => {
|
||||
// ElNotification({
|
||||
// title: '温馨提示',
|
||||
// message: `批量添加${parameter.value.title}成功!`,
|
||||
// type: 'success',
|
||||
// })
|
||||
// }
|
||||
|
||||
defineExpose({
|
||||
acceptParams
|
||||
});
|
||||
acceptParams,
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
<style lang='scss' scoped>
|
||||
@import "./index.scss";
|
||||
</style>
|
||||
|
||||
@@ -8,9 +8,8 @@
|
||||
:search-param='searchParam'
|
||||
:search-col='searchCol'
|
||||
/>
|
||||
|
||||
<!-- 表格主体 -->
|
||||
<div class='card table-main'>
|
||||
<div class='table-main' :class='{ card: showCard }' >
|
||||
<!-- 表格头部 操作按钮 -->
|
||||
<div class='table-header'>
|
||||
<div class='header-button-lf'>
|
||||
@@ -43,10 +42,11 @@
|
||||
>
|
||||
<!-- 默认插槽 -->
|
||||
<slot />
|
||||
|
||||
<template v-for='item in tableColumns' :key='item'>
|
||||
<!-- selection || radio || index || expand || sort -->
|
||||
<el-table-column
|
||||
v-if='item.type && columnTypes.includes(item.type)'
|
||||
v-if='item.type && columnTypes.includes(item.type) && item.isShow'
|
||||
v-bind='item'
|
||||
:align="item.align ?? 'center'"
|
||||
:reserve-selection="item.type == 'selection'"
|
||||
@@ -126,6 +126,7 @@ export interface ProTableProps {
|
||||
requestError?: (params: any) => void; // 表格 api 请求错误监听 ==> 非必传
|
||||
dataCallback?: (data: any) => any; // 返回数据的回调函数,可以对数据进行处理 ==> 非必传
|
||||
title?: string; // 表格标题 ==> 非必传
|
||||
showCard?: boolean; // 下个是否需要卡片
|
||||
pagination?: boolean; // 是否需要分页组件 ==> 非必传(默认为true)
|
||||
initParam?: any; // 初始化请求参数 ==> 非必传(默认为{})
|
||||
border?: boolean; // 是否带有纵向边框 ==> 非必传(默认为true)
|
||||
@@ -141,6 +142,7 @@ const props = withDefaults(defineProps<ProTableProps>(), {
|
||||
pagination: true,
|
||||
initParam: {},
|
||||
border: true,
|
||||
showCard: true,
|
||||
toolButton: true,
|
||||
rowKey: 'id',
|
||||
searchCol: () => ({ xs: 1, sm: 2, md: 2, lg: 3, xl: 4 }),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class='icon-box'>
|
||||
<div class='icon-box' >
|
||||
<el-input
|
||||
ref='inputRef'
|
||||
v-model='valueIcon'
|
||||
@@ -13,7 +13,7 @@
|
||||
<el-button :icon='customIcons[iconValue]' />
|
||||
</template>
|
||||
</el-input>
|
||||
<el-dialog v-model='dialogVisible' :title='placeholder' top='50px' width='66%'>
|
||||
<el-dialog v-model='dialogVisible' :title='placeholder' top='5%' width='30%' >
|
||||
<el-input v-model='inputValue' placeholder='搜索图标' size='large' :prefix-icon='Icons.Search' />
|
||||
<el-scrollbar v-if='Object.keys(iconsList).length'>
|
||||
<div class='icon-list'>
|
||||
|
||||
@@ -126,6 +126,15 @@ const handleChange = (unit: string) => {
|
||||
endDate.value = new Date()
|
||||
}
|
||||
timeUnit.value = unit
|
||||
|
||||
// 确保开始时间和结束时间不为空
|
||||
if (!startDate.value) {
|
||||
startDate.value = new Date()
|
||||
}
|
||||
if (!endDate.value) {
|
||||
endDate.value = new Date()
|
||||
}
|
||||
|
||||
emitDateChange() // 变化时也发出更新事件
|
||||
updateNextButtonStatus()
|
||||
}
|
||||
@@ -172,7 +181,13 @@ const updateDateRange = () => {
|
||||
// endDate.value.setHours(23, 59, 59, 999); // 设置结束时间为今天的23:59:59.999
|
||||
// }
|
||||
}
|
||||
|
||||
// 确保开始时间和结束时间不为空
|
||||
if (!startDate.value) {
|
||||
startDate.value = new Date()
|
||||
}
|
||||
if (!endDate.value) {
|
||||
endDate.value = new Date()
|
||||
}
|
||||
|
||||
updateNextButtonStatus()
|
||||
}
|
||||
@@ -285,7 +300,10 @@ const disableEndDate = (date: Date) => {
|
||||
|
||||
|
||||
// 格式化日期yyyy-mm-dd
|
||||
function formatDate(date:Date) {
|
||||
function formatDate(date: Date | null): string {
|
||||
if (!date) {
|
||||
return '';
|
||||
}
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
|
||||
282
frontend/src/components/echarts/line/index.vue
Normal file
282
frontend/src/components/echarts/line/index.vue
Normal file
@@ -0,0 +1,282 @@
|
||||
<template>
|
||||
<div class="chart">
|
||||
<div ref="chartRef" class="my-chart" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onBeforeUnmount, onMounted, ref, defineExpose, watch, nextTick } from 'vue'
|
||||
// import echarts from './echarts'
|
||||
import * as echarts from 'echarts' // 全引入
|
||||
// import 'echarts/lib/component/dataZoom'
|
||||
|
||||
const color = [
|
||||
'var(--el-color-primary)',
|
||||
'#07CCCA',
|
||||
'#00BFF5',
|
||||
'#FFBF00',
|
||||
'#77DA63',
|
||||
'#D5FF6B',
|
||||
'#Ff6600',
|
||||
'#FF9100',
|
||||
'#5B6E96',
|
||||
'#66FFCC',
|
||||
'#B3B3B3'
|
||||
]
|
||||
|
||||
const chartRef = ref<HTMLDivElement>()
|
||||
|
||||
const props = defineProps(['options', 'isInterVal', 'pieInterVal'])
|
||||
let chart: echarts.ECharts | any = null
|
||||
const resizeHandler = () => {
|
||||
// 不在视野中的时候不进行resize
|
||||
if (!chartRef.value) return
|
||||
if (chartRef.value.offsetHeight == 0) return
|
||||
chart.getZr().painter.getViewportRoot().style.display = 'none'
|
||||
requestAnimationFrame(() => {
|
||||
chart.resize()
|
||||
chart.getZr().painter.getViewportRoot().style.display = ''
|
||||
})
|
||||
}
|
||||
const initChart = () => {
|
||||
if (!props.isInterVal && !props.pieInterVal) {
|
||||
chart?.dispose()
|
||||
}
|
||||
// chart?.dispose()
|
||||
chart = echarts.init(chartRef.value as HTMLDivElement)
|
||||
const options = {
|
||||
title: {
|
||||
left: 'center',
|
||||
// textStyle: {
|
||||
color: '#000',
|
||||
fontSize: 18,
|
||||
// },
|
||||
...(props.options?.title || null)
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0,
|
||||
confine: true,
|
||||
...(props.options?.tooltip || null)
|
||||
},
|
||||
|
||||
legend: {
|
||||
right: 20,
|
||||
top: 0,
|
||||
itemGap: 10,
|
||||
itemStyle: {},
|
||||
// textStyle: {
|
||||
fontSize: 12,
|
||||
padding: [2, 0, 0, 0], //[上、右、下、左]
|
||||
// },
|
||||
itemWidth: 15,
|
||||
itemHeight: 10,
|
||||
...(props.options?.legend || null)
|
||||
},
|
||||
grid: {
|
||||
top: '60px',
|
||||
left: '30px',
|
||||
right: '70px',
|
||||
bottom: props.options?.options?.dataZoom === null ? '10px' : '40px',
|
||||
containLabel: true,
|
||||
...(props.options?.grid || null)
|
||||
},
|
||||
xAxis: props.options?.xAxis ? handlerXAxis() : null,
|
||||
yAxis: props.options?.yAxis ? handlerYAxis() : null,
|
||||
dataZoom: props.options?.dataZoom || [
|
||||
{
|
||||
type: 'inside',
|
||||
height: 13,
|
||||
start: 0,
|
||||
bottom: '20px',
|
||||
end: 100
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
height: 13,
|
||||
bottom: '20px',
|
||||
end: 100
|
||||
}
|
||||
],
|
||||
color: props.options?.color || color,
|
||||
series: props.options?.series,
|
||||
...props.options?.options
|
||||
}
|
||||
// console.log(options.series,"获取x轴");
|
||||
handlerBar(options)
|
||||
|
||||
// 处理柱状图
|
||||
chart.setOption(options, true)
|
||||
|
||||
setTimeout(() => {
|
||||
chart.resize()
|
||||
}, 0)
|
||||
}
|
||||
const handlerBar = (options: any) => {
|
||||
if (Array.isArray(options.series)) {
|
||||
options.series.forEach((item: any) => {
|
||||
if (item.type === 'bar') {
|
||||
item.barMinHeight = 10
|
||||
item.barMaxWidth = 20
|
||||
item.itemStyle = Object.assign(
|
||||
{
|
||||
color: (params: any) => {
|
||||
if (params.value == 0 || params.value == 3.14159) {
|
||||
return '#ccc'
|
||||
} else {
|
||||
return props.options?.color
|
||||
? props.options?.color[params.seriesIndex]
|
||||
: color[params.seriesIndex]
|
||||
}
|
||||
}
|
||||
},
|
||||
item.itemStyle
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
const handlerYAxis = () => {
|
||||
let temp = {
|
||||
type: 'value',
|
||||
nameGap: 15,
|
||||
nameTextStyle: {
|
||||
color: '#000'
|
||||
},
|
||||
splitNumber: 5,
|
||||
minInterval: 1,
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#000'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#000',
|
||||
fontSize: 14,
|
||||
formatter: function (value) {
|
||||
return value.toFixed(0) // 格式化显示为一位小数
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
// 使用深浅的间隔色
|
||||
color: ['#ccc'],
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
// props.options?.xAxis 是数组还是对象
|
||||
if (Array.isArray(props.options?.yAxis)) {
|
||||
return props.options?.yAxis.map((item: any) => {
|
||||
return {
|
||||
...temp,
|
||||
...item
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return {
|
||||
...temp,
|
||||
...props.options?.yAxis
|
||||
}
|
||||
}
|
||||
}
|
||||
const handlerXAxis = () => {
|
||||
let temp = {
|
||||
type: 'category',
|
||||
axisTick: { show: false },
|
||||
nameTextStyle: {
|
||||
color: '#000'
|
||||
},
|
||||
axisLine: {
|
||||
// lineStyle: {
|
||||
color: '#000'
|
||||
// }
|
||||
},
|
||||
axisLabel: {
|
||||
// textStyle: {
|
||||
fontFamily: 'dinproRegular',
|
||||
color: '#000',
|
||||
fontSize: '12'
|
||||
// }
|
||||
}
|
||||
// boundaryGap: false,
|
||||
}
|
||||
// props.options?.xAxis 是数组还是对象
|
||||
if (Array.isArray(props.options?.xAxis)) {
|
||||
return props.options?.xAxis.map((item: any) => {
|
||||
return {
|
||||
...temp,
|
||||
...item
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return {
|
||||
...temp,
|
||||
...props.options?.xAxis
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let throttle: ReturnType<typeof setTimeout>
|
||||
// 动态计算table高度
|
||||
const resizeObserver = new ResizeObserver(entries => {
|
||||
for (const entry of entries) {
|
||||
if (throttle) {
|
||||
clearTimeout(throttle)
|
||||
}
|
||||
throttle = setTimeout(() => {
|
||||
resizeHandler()
|
||||
}, 100)
|
||||
}
|
||||
})
|
||||
onMounted(() => {
|
||||
initChart()
|
||||
resizeObserver.observe(chartRef.value!)
|
||||
})
|
||||
defineExpose({ initChart })
|
||||
onBeforeUnmount(() => {
|
||||
resizeObserver.unobserve(chartRef.value!)
|
||||
chart?.dispose()
|
||||
})
|
||||
watch(
|
||||
() => props.options,
|
||||
(newVal, oldVal) => {
|
||||
initChart()
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
.el-button {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: -60px;
|
||||
}
|
||||
|
||||
.my-chart {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import * as echarts from "echarts";
|
||||
import { ref } from "vue";
|
||||
const chartsRef = ref();
|
||||
const props = defineProps({
|
||||
//饼图数据
|
||||
@@ -21,11 +22,16 @@ const props = defineProps({
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
|
||||
});
|
||||
const customData: any = ref({}),
|
||||
legendData: any = ref({}),
|
||||
chart: any = ref();
|
||||
|
||||
const labelIsShow = ref(true)//引导线台数和鼠标点击饼图是否弹出提示显示
|
||||
const init = () => {
|
||||
|
||||
|
||||
customData.value = {
|
||||
title: "", //标题
|
||||
textAlign: "left", //标题位置可选属性left 可选属性值 left,right,center
|
||||
@@ -34,13 +40,16 @@ const init = () => {
|
||||
isRadius: false, //是否圆角
|
||||
isSpace: false, //是否显示间隔
|
||||
isLabelLine: true, //是否显示引导线
|
||||
titleFontSize: '14px', //标题字体大小
|
||||
|
||||
...props.customData,
|
||||
|
||||
};
|
||||
legendData.value = {
|
||||
icon: "roundRect", // 图例项的icon,类型包括 circle(圆形),rect(正方形),//roundRect(圆角正方形),triangle(三角形),diamond(菱形),//pin(大头针行),arrow(箭头形),none(无图例项的icon)
|
||||
orient: "vertical", //图例排列方向
|
||||
left: "right", //可选属性left,right,top,bottom,可选属性值 left,right,top,bottom,px,百分比,数值,
|
||||
itemGap: 1, // 设置图例项之间的间隔为20
|
||||
itemGap: 10, // 设置图例项之间的间隔为20
|
||||
...props.legendData,
|
||||
};
|
||||
chart.value = chartsRef.value && echarts.init(chartsRef.value);
|
||||
@@ -48,10 +57,27 @@ const init = () => {
|
||||
title: {
|
||||
text: customData.value.title,
|
||||
left: customData.value.textAlign,
|
||||
textStyle: {
|
||||
fontSize: customData.value.titleFontSize, // 使用 titleFontSize 属性
|
||||
},
|
||||
},
|
||||
legend: legendData.value,
|
||||
legend:legendData.value,
|
||||
// legend: {
|
||||
// icon: legendData.value.icon, // 图例项的icon,类型包括 circle(圆形),rect(正方形),//roundRect(圆角正方形),triangle(三角形),diamond(菱形),//pin(大头针行),arrow(箭头形),none(无图例项的icon)
|
||||
// orient: "vertical", //图例排列方向
|
||||
// left: legendData.value.left, //可选属性left,right,top,bottom,可选属性值 left,right,top,bottom,px,百分比,数值,
|
||||
// itemGap: 1, // 设置图例项之间的间隔为20
|
||||
// formatter: function (name) {
|
||||
|
||||
// const item = props.chartsData.filter(item=>item.name==name)
|
||||
// console.log(item)
|
||||
// if(item)
|
||||
// return item[0].value;
|
||||
|
||||
// },
|
||||
// },
|
||||
tooltip: {
|
||||
show: true,
|
||||
show: labelIsShow.value,
|
||||
trigger: "item",
|
||||
formatter: customData.value.ratio ? `{b} : {c} ({d}%)` : "{b} :{c} ",
|
||||
borderWidth: 1,
|
||||
@@ -61,7 +87,13 @@ const init = () => {
|
||||
type: "pie",
|
||||
radius: customData.value.isRing ? ["55", "75"] : "80%",
|
||||
data: props.chartsData,
|
||||
center: ["55%", "50%"], // 设置饼图的中心位置
|
||||
formatter: function (name: any) {
|
||||
const item = props.chartsData.filter(item=>item.name==name)
|
||||
//console.log(item)
|
||||
if(item)
|
||||
return item[0].value;
|
||||
},
|
||||
center: ["55%", "55%"], // 设置饼图的中心位置
|
||||
// padAngle: 2,
|
||||
minAngle: 15, //最小角度
|
||||
startAngle: 270, //起始角度
|
||||
@@ -74,12 +106,15 @@ const init = () => {
|
||||
},
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
position: "inside",
|
||||
show: labelIsShow.value,
|
||||
position: "outside",
|
||||
textStyle: {
|
||||
color: "#fff",
|
||||
//color: "#fff",
|
||||
fontSize: 12,
|
||||
},
|
||||
formatter: function (data) {
|
||||
return labelIsShow.value ? data.value + '台' : '';
|
||||
}
|
||||
},
|
||||
},
|
||||
itemStyle: {
|
||||
@@ -93,6 +128,7 @@ const init = () => {
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
option && chart.value && chart.value.setOption(option);
|
||||
setTimeout(() => {
|
||||
chart.value.resize();
|
||||
@@ -108,7 +144,7 @@ const reSize = (widthValue: number,heightValue: number,silentValue: boolean) =>
|
||||
}
|
||||
};
|
||||
const resizeCharts = () => {
|
||||
console.log(chart.value,111111);
|
||||
//console.log(chart.value,111111);
|
||||
|
||||
if (chart.value) {
|
||||
chart.value.resize();
|
||||
@@ -128,6 +164,12 @@ watch(
|
||||
() => props.chartsData,
|
||||
(val, oldVal) => {
|
||||
if (val) {
|
||||
const item = props.chartsData.find(item => item.value === 0);
|
||||
if(item != undefined){
|
||||
labelIsShow.value = false;
|
||||
}else{
|
||||
labelIsShow.value = true;
|
||||
}
|
||||
init();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
// 首页地址(默认)
|
||||
export const HOME_URL: string = "/home/index";
|
||||
|
||||
// export const HOME_URL: string = "/machine/controlSource";
|
||||
|
||||
// 登录页地址(默认)
|
||||
export const LOGIN_URL: string = "/login";
|
||||
|
||||
// 默认主题颜色
|
||||
export const DEFAULT_PRIMARY: string = "#003078";
|
||||
export const DEFAULT_PRIMARY: string = "#526ADE";
|
||||
|
||||
// 路由白名单地址(本地存在的路由 staticRouter.ts 中)
|
||||
export const ROUTER_WHITE_LIST: string[] = ["/500"];
|
||||
@@ -17,3 +19,5 @@ export const AMAP_MAP_KEY: string = "";
|
||||
|
||||
// 百度地图 key
|
||||
export const BAIDU_MAP_KEY: string = "";
|
||||
|
||||
|
||||
|
||||
@@ -10,12 +10,14 @@ const auth: Directive = {
|
||||
const { value } = binding
|
||||
const authStore = useAuthStore()
|
||||
const currentPageRoles = authStore.authButtonListGet[authStore.routeName] ?? []
|
||||
// console.log('1234',authStore.routeName)
|
||||
// console.log('123',currentPageRoles)
|
||||
// console.log('1234',authStore.routeName)
|
||||
// console.log('123',currentPageRoles)
|
||||
if (value instanceof Array && value.length) {
|
||||
//console.log('123456',value)
|
||||
const hasPermission = value.every(item => currentPageRoles.includes(item))
|
||||
if (!hasPermission) el.remove()
|
||||
} else {
|
||||
//console.log('12345',value)
|
||||
if (!currentPageRoles.includes(value)) el.remove()
|
||||
}
|
||||
},
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
export enum ResultEnum {
|
||||
SUCCESS = "A0000",
|
||||
ERROR = 500,
|
||||
OVERDUE = "401",
|
||||
ACCESSTOKEN_EXPIRED = "A0024",
|
||||
OVERDUE = "A0025",
|
||||
TIMEOUT = 30000,
|
||||
TYPE = "success"
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ export const useTheme = () => {
|
||||
|
||||
// 修改主题颜色
|
||||
const changePrimary = (val: string | null) => {
|
||||
|
||||
if (!val) {
|
||||
val = DEFAULT_PRIMARY;
|
||||
ElMessage({ type: "success", message: `主题颜色已重置为 ${DEFAULT_PRIMARY}` });
|
||||
@@ -40,10 +41,13 @@ export const useTheme = () => {
|
||||
for (let i = 1; i <= 9; i++) {
|
||||
const primaryColor = isDark.value ? `${getDarkColor(val, i / 10)}` : `${getLightColor(val, i / 10)}`;
|
||||
document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, primaryColor);
|
||||
|
||||
// const colorValue = document.documentElement.style.getPropertyValue(`--el-color-primary-light-${i}`).trim();
|
||||
// console.log(`--el-color-primary-light-${i}: ${colorValue}`);
|
||||
}
|
||||
globalStore.setGlobalState("primary", val);
|
||||
};
|
||||
|
||||
}
|
||||
// 灰色和弱色切换
|
||||
const changeGreyOrWeak = (type: Theme.GreyOrWeakType, value: boolean) => {
|
||||
const body = document.body as HTMLElement;
|
||||
|
||||
@@ -26,6 +26,8 @@ export default {
|
||||
changePassword: "Change Password",
|
||||
changeMode:"Change Mode",
|
||||
versionRegister:"Version Register",
|
||||
changeTheme: "Change Theme",
|
||||
changeScene: "Change Scene",
|
||||
logout: "Logout"
|
||||
}
|
||||
};
|
||||
|
||||
@@ -26,6 +26,8 @@ export default {
|
||||
changePassword: "修改密码",
|
||||
changeMode:"模式切换",
|
||||
versionRegister:"版本注册",
|
||||
changeTheme:"主题切换",
|
||||
changeScene: "场景切换",
|
||||
logout: "退出登录"
|
||||
}
|
||||
};
|
||||
|
||||
@@ -39,7 +39,9 @@
|
||||
}
|
||||
.el-menu-item:hover {
|
||||
color: #fff; //一级导航划过颜色
|
||||
background-color: #5274a5 !important; //一级导航划过背景色
|
||||
//background-color: #5274a5 !important; //一级导航划过背景色
|
||||
background-color:var(--el-color-primary-light-3) !important;
|
||||
|
||||
}
|
||||
.el-sub-menu__hide-arrow {
|
||||
width: 65px;
|
||||
@@ -47,7 +49,9 @@
|
||||
}
|
||||
.el-menu-item.is-active {
|
||||
color: #fff !important; //一级导航文字选中颜色
|
||||
background-color: #5274a5 !important; //一级导航选中背景色
|
||||
//background-color: #5274a5 !important; //一级导航选中背景色
|
||||
background-color: var(--el-color-primary-light-3) !important;
|
||||
|
||||
border-bottom: 0 !important;
|
||||
}
|
||||
.el-sub-menu__title {
|
||||
@@ -67,7 +71,9 @@
|
||||
color: #fff !important; //二级导航文字选中颜色
|
||||
// background-color: var(--el-color-primary) !important;
|
||||
// background-color: #5274a5 !important;//二级导航选中背景色
|
||||
background-color: #5274a5 !important;
|
||||
|
||||
//background-color: #7588e5 !important;
|
||||
background-color: var(--el-color-primary-light-3) !important;
|
||||
border-bottom-color: var(--el-color-primary) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,19 +18,19 @@
|
||||
<!-- </el-button> -->
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="title = '模拟式模块'"
|
||||
<el-dropdown-item @click="handelOpen('模拟式')"
|
||||
>模拟式模块</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item @click="title = '数字式模块'"
|
||||
<el-dropdown-item @click="handelOpen('数字式')"
|
||||
>数字式模块</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item @click="title = '比对式模块'"
|
||||
>比对式模块</el-dropdown-item
|
||||
<el-dropdown-item @click="handelOpen('比对式')"
|
||||
disabled>比对式模块</el-dropdown-item
|
||||
>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<p style="margin: 0;">
|
||||
<p style="margin: 0;" >
|
||||
<a href="http://www.shining-electric.com/" target="_blank">
|
||||
2024 © 南京灿能电力自动化股份有限公司
|
||||
</a>
|
||||
@@ -39,26 +39,30 @@
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, computed, onMounted, watch } from "vue";
|
||||
const title = ref("模拟式模块");
|
||||
import { useAuthStore } from "@/stores/modules/auth";
|
||||
import { useModeStore } from '@/stores/modules/mode'; // 引入模式 store
|
||||
|
||||
import { useRouter } from "vue-router";
|
||||
const router = useRouter();
|
||||
const authStore = useAuthStore();
|
||||
const modeStore = useModeStore();
|
||||
watch(() => modeStore.currentMode, (newVal) => {
|
||||
//console.log('当前模式:', newVal);
|
||||
switch (newVal) {
|
||||
case '模拟式':
|
||||
title.value = '模拟式模块';
|
||||
break;
|
||||
case '数字式':
|
||||
title.value = '数字式模块';
|
||||
break;
|
||||
case '比对式':
|
||||
title.value = '比对式模块';
|
||||
break;
|
||||
default:
|
||||
title.value = '模拟式模块';
|
||||
}
|
||||
|
||||
const title = computed(() => {
|
||||
return modeStore.currentMode=== ''? '模拟式模块' : modeStore.currentMode+'模块';
|
||||
});
|
||||
|
||||
const handelOpen = async (item: string) => {
|
||||
await authStore.setShowMenu();
|
||||
modeStore.setCurrentMode(item); // 将模式code存入 store
|
||||
|
||||
//if (router.currentRoute.value.path === '/home/index') {
|
||||
// 强制刷新页面
|
||||
window.location.reload();
|
||||
//} else {
|
||||
// router.push({ path: '/home/index' });
|
||||
//}
|
||||
|
||||
};
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "./index.scss";
|
||||
@@ -100,10 +104,11 @@ watch(() => modeStore.currentMode, (newVal) => {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
text-align: right;
|
||||
line-height: 40px;
|
||||
a {
|
||||
color: #fff;
|
||||
margin-right: 25px; // 增加右边距
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<template>
|
||||
<!-- <div class="userInfo">-->
|
||||
<!-- <div class="icon">-->
|
||||
<!-- <Avatar/>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="username">-->
|
||||
<!-- {{ username }}-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<el-dropdown trigger="click">
|
||||
<div class="userInfo">
|
||||
<div class="icon">
|
||||
@@ -10,18 +18,42 @@
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="openDialog('themeRef')">
|
||||
<el-icon><Sunny /></el-icon>{{ t("header.changeTheme") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click="openDialog('infoRef')">
|
||||
<el-icon><User /></el-icon>{{ $t("header.personalData") }}
|
||||
<el-icon><User /></el-icon>{{ t("header.personalData") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click="openDialog('passwordRef')">
|
||||
<el-icon><Edit /></el-icon>{{ $t("header.changePassword") }}
|
||||
<el-icon><Edit /></el-icon>{{ t("header.changePassword") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click="changeMode">
|
||||
<el-icon><Edit /></el-icon>{{ $t("header.changeMode") }}
|
||||
<el-icon><Switch /></el-icon>{{ t("header.changeMode") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click="openDialog('versionRegisterRef')">
|
||||
<el-icon><SetUp /></el-icon>{{ $t("header.versionRegister") }}
|
||||
<el-icon><SetUp /></el-icon>{{ t("header.versionRegister") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown trigger="hover" placement="left-start" v-if="userStore.userInfo.loginName == 'root'">
|
||||
<div class="custom-dropdown-trigger">
|
||||
<el-icon><Tools /></el-icon>
|
||||
<span>{{ t("header.changeScene") }}</span>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-for="item in dictStore.getDictData('app_scene')"
|
||||
:key="item.value"
|
||||
:class="{
|
||||
'custom-dropdown-item': true,
|
||||
active: item.value === appSceneStore.currentScene
|
||||
}"
|
||||
@click="changeScene(item.value?? '')"
|
||||
>
|
||||
{{ item.name }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
@@ -34,6 +66,9 @@
|
||||
<PasswordDialog ref="passwordRef"></PasswordDialog>
|
||||
<!-- versionRegisterDialog -->
|
||||
<VersionDialog ref="versionRegisterRef"></VersionDialog>
|
||||
<!-- ThemeDialog -->
|
||||
<ThemeDialog ref="themeRef"></ThemeDialog>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -42,12 +77,13 @@ import { LOGIN_URL } from "@/config";
|
||||
import { useRouter } from "vue-router";
|
||||
import { logoutApi } from "@/api/user/login";
|
||||
import { useUserStore } from "@/stores/modules/user";
|
||||
import { ElMessageBox, ElMessage } from "element-plus";
|
||||
import { ElMessageBox, ElMessage, CHANGE_EVENT } from "element-plus";
|
||||
import InfoDialog from "./InfoDialog.vue";
|
||||
import PasswordDialog from "./PasswordDialog.vue";
|
||||
import ThemeDialog from "./ThemeDialog.vue";
|
||||
import VersionDialog from "@/views/system/versionRegister/index.vue";
|
||||
import { computed } from "vue";
|
||||
import { Avatar } from "@element-plus/icons-vue";
|
||||
import { ArrowLeft, Avatar, Delete, Document, Sunny, Switch ,Tools} from "@element-plus/icons-vue";
|
||||
import AssemblySize from "./components/AssemblySize.vue";
|
||||
import Language from "./components/Language.vue";
|
||||
import SearchMenu from "./components/SearchMenu.vue";
|
||||
@@ -56,13 +92,24 @@ import Message from "./components/Message.vue";
|
||||
import Fullscreen from "./components/Fullscreen.vue";
|
||||
import { useAuthStore } from "@/stores/modules/auth";
|
||||
import {useDictStore} from "@/stores/modules/dict";
|
||||
import { useModeStore } from "@/stores/modules/mode";
|
||||
import { useModeStore,useAppSceneStore } from "@/stores/modules/mode";
|
||||
const userStore = useUserStore();
|
||||
const dictStore = useDictStore();
|
||||
const username = computed(() => userStore.userInfo.name);
|
||||
|
||||
const router = useRouter();
|
||||
const authStore = useAuthStore();
|
||||
const modeStore = useModeStore();
|
||||
const AppSceneStore = useAppSceneStore();
|
||||
import { useTheme } from "@/hooks/useTheme";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import {updateScene} from '@/api/system/base/index'
|
||||
|
||||
|
||||
const { changePrimary} = useTheme();
|
||||
|
||||
// 初始化 i18n
|
||||
const { t } = useI18n(); // 使用 t 方法替代 $t
|
||||
|
||||
// 退出登录
|
||||
const logout = () => {
|
||||
@@ -74,10 +121,14 @@ const logout = () => {
|
||||
// 1.执行退出登录接口
|
||||
await logoutApi();
|
||||
// 2.清除 Token
|
||||
userStore.setToken("");
|
||||
userStore.setUserInfo({name: ""});
|
||||
userStore.setAccessToken("");
|
||||
userStore.setRefreshToken("");
|
||||
userStore.setExp(0)
|
||||
userStore.setUserInfo({id: "", name: ""});
|
||||
userStore.setIsRefreshToken(false)
|
||||
dictStore.setDictData([]);
|
||||
modeStore.setCurrentMode('');
|
||||
AppSceneStore.setCurrentMode('');
|
||||
// 3.重定向到登陆页
|
||||
router.replace(LOGIN_URL);
|
||||
ElMessage.success("退出登录成功!");
|
||||
@@ -90,12 +141,26 @@ const logout = () => {
|
||||
const infoRef = ref<InstanceType<typeof InfoDialog> | null>(null);
|
||||
const passwordRef = ref<InstanceType<typeof PasswordDialog> | null>(null);
|
||||
const versionRegisterRef = ref<InstanceType<typeof VersionDialog> | null>(null);
|
||||
|
||||
const themeRef = ref<InstanceType<typeof ThemeDialog> | null>(null);
|
||||
const openDialog = (ref: string) => {
|
||||
if (ref == "infoRef") infoRef.value?.openDialog();
|
||||
if (ref == "passwordRef") passwordRef.value?.openDialog();
|
||||
if (ref == "versionRegisterRef") versionRegisterRef.value?.openDialog();
|
||||
if (ref == "themeRef") themeRef.value?.openDialog();
|
||||
|
||||
};
|
||||
|
||||
|
||||
const appSceneStore = useAppSceneStore();
|
||||
|
||||
const changeScene = async (value: string) => {
|
||||
appSceneStore.setCurrentMode(value);
|
||||
await updateScene({scene :dictStore.getDictData('app_scene').find(item => item.value == value)?.id});
|
||||
// 强制刷新页面
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
|
||||
//模式切换
|
||||
const changeMode = () => {
|
||||
authStore.changeModel();
|
||||
@@ -135,4 +200,18 @@ const changeMode = () => {
|
||||
// height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-dropdown-trigger {
|
||||
padding: 8px 15px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
:deep(.el-dropdown-menu__item.custom-dropdown-item.active),
|
||||
:deep(.el-dropdown-menu__item.custom-dropdown-item.active:hover) {
|
||||
background-color: var(--el-color-primary-light-9) !important;
|
||||
color: var(--el-color-primary)
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" title="主题切换" width="500px" draggable>
|
||||
<el-divider content-position="center">主题颜色</el-divider>
|
||||
<div style="display: flex; justify-content: center;">
|
||||
<el-color-picker v-model="color" />
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="sure">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from "vue";
|
||||
import { useTheme } from "@/hooks/useTheme";
|
||||
import { on } from "events";
|
||||
const color = ref('')
|
||||
const { changePrimary} = useTheme();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const openDialog = () => {
|
||||
// 修复:使用可选链和空值合并运算符确保不会出现 null 或 undefined
|
||||
const storedColor = JSON.parse(localStorage.getItem('cn-global') ?? '{}').primary;
|
||||
color.value = storedColor ?? '#526ADE'; // 默认值为 '#526ADE'
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
const sure = () => {
|
||||
changePrimary(color.value); // 切换主题
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
// onMounted(() => {
|
||||
// // 修复:使用可选链和空值合并运算符确保不会出现 null 或 undefined
|
||||
// const storedColor = JSON.parse(localStorage.getItem('cn-global') ?? '{}').primary;
|
||||
// console.log('123',storedColor)
|
||||
// color.value = storedColor ?? '#526ADE'; // 默认值为 '#526ADE'
|
||||
// })
|
||||
|
||||
defineExpose({ openDialog });
|
||||
</script>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.el-main {
|
||||
box-sizing: border-box;
|
||||
padding: 20px;//主体padding
|
||||
overflow-x: hidden;
|
||||
padding: 15px;//主体padding
|
||||
overflow: hidden;
|
||||
background-color: var(--el-bg-color-page);
|
||||
}
|
||||
.el-footer {
|
||||
|
||||
@@ -2,21 +2,16 @@
|
||||
<Maximize v-show="maximize" />
|
||||
<Tabs v-if="tabs && showMenuFlag" />
|
||||
<el-main>
|
||||
<!-- style="height: calc(100vh - 157px);overflow-y:auto; overflow-x:hidden;" :style='{height:showMenuFlag?"calc(100vh - 157px)":" calc(100vh - 120px)"}' -->
|
||||
<router-view v-slot="{ Component, route }" style="height:100%;">
|
||||
<transition appear name="fade-transform" mode="out-in">
|
||||
<keep-alive :include="keepAliveName">
|
||||
<component
|
||||
:is="Component"
|
||||
v-if="isRouterShow"
|
||||
:key="route.fullPath"
|
||||
/>
|
||||
<!-- {{ keepAliveName}} -->
|
||||
<!-- <transition name="slide-right" mode="out-in"> -->
|
||||
<keep-alive :include="tabsMenuList" >
|
||||
<component :is="Component" :key="route.fullPath" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
<!-- </transition> -->
|
||||
</router-view>
|
||||
</el-main>
|
||||
<el-footer >
|
||||
<!-- v-show="footer" -->
|
||||
<el-footer>
|
||||
<Footer />
|
||||
</el-footer>
|
||||
</template>
|
||||
@@ -31,12 +26,15 @@ import Maximize from "./components/Maximize.vue";
|
||||
import Tabs from "@/layouts/components/Tabs/index.vue";
|
||||
import Footer from "@/layouts/components/Footer/index.vue";
|
||||
import { useAuthStore } from "@/stores/modules/auth";
|
||||
import { useTabsStore } from '@/stores/modules/tabs'
|
||||
const tabStore = useTabsStore()
|
||||
const globalStore = useGlobalStore();
|
||||
const tabsMenuList = computed(() => tabStore.tabsMenuList.map(item => item.name))
|
||||
const authStore = useAuthStore();
|
||||
const { maximize, isCollapse, layout, tabs, footer } = storeToRefs(globalStore);
|
||||
|
||||
const keepAliveStore = useKeepAliveStore();
|
||||
const { keepAliveName } = storeToRefs(keepAliveStore);
|
||||
// console.log("🚀 ~ keepAliveName:", keepAliveName)
|
||||
//是否显示导航栏
|
||||
const showMenuFlag = computed(() => authStore.showMenuFlagGet);
|
||||
// 注入刷新页面方法
|
||||
@@ -65,6 +63,7 @@ watch(
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
|
||||
// 监听窗口大小变化,折叠侧边栏
|
||||
const screenWidth = ref(0);
|
||||
const listeningWindow = useDebounceFn(() => {
|
||||
|
||||
@@ -33,14 +33,19 @@ const handleClickMenu = (subItem: Menu.MenuOptions) => {
|
||||
// color: var(--el-menu-hover-text-color) !important;
|
||||
// background-color: transparent !important;
|
||||
color: #fff !important;//一级导航文字选中颜色
|
||||
background-color: #5274a5 !important; //一级导航选中背景色
|
||||
//background-color: #5274a5 !important; //一级导航选中背景色
|
||||
|
||||
background-color: var(--el-color-primary-light-3) !important;
|
||||
|
||||
}
|
||||
.el-menu--collapse {
|
||||
.is-active {
|
||||
.el-sub-menu__title {
|
||||
color: #ffffff !important;
|
||||
// background-color: var(--el-color-primary) !important;
|
||||
background-color: #5274a5 !important;
|
||||
//background-color: #5274a5 !important;
|
||||
background-color: var(--el-color-primary-light-3) !important;
|
||||
|
||||
border-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
@@ -53,7 +58,9 @@ const handleClickMenu = (subItem: Menu.MenuOptions) => {
|
||||
// color: var(--el-menu-active-color) !important;
|
||||
// background-color: var(--el-menu-active-bg-color) !important;
|
||||
color: #fff !important;//一级导航文字选中颜色
|
||||
background-color: #5274a5 !important; //一级导航选中背景色
|
||||
//background-color: #5274a5 !important; //一级导航选中背景色
|
||||
background-color: var(--el-color-primary-light-3) !important;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
||||
@@ -1,23 +1,28 @@
|
||||
<template>
|
||||
<div class='tabs-box'>
|
||||
<div class='tabs-menu'>
|
||||
<el-tabs v-model='tabsMenuValue' type='card' @tab-click='tabClick' @tab-remove='tabRemove'>
|
||||
<el-tab-pane v-for='item in tabsMenuList' :key='item.path' :label='item.title' :name='item.path'
|
||||
:closable='item.close'>
|
||||
<template #label>
|
||||
<el-icon v-show='item.icon && tabsIcon' class='tabs-icon'>
|
||||
<component :is='item.icon'></component>
|
||||
</el-icon>
|
||||
{{ item.title }}
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<MoreButton />
|
||||
<div class="tabs-box">
|
||||
<div class="tabs-menu">
|
||||
<el-tabs v-model="tabsMenuValue" type="card" @tab-click="tabClick" @tab-remove="tabRemove">
|
||||
<el-tab-pane
|
||||
v-for="item in tabsMenuList"
|
||||
:key="item.path"
|
||||
:label="item.title"
|
||||
:name="item.path"
|
||||
:closable="item.close"
|
||||
>
|
||||
<template #label>
|
||||
<el-icon v-show="item.icon && tabsIcon" class="tabs-icon">
|
||||
<component :is="item.icon"></component>
|
||||
</el-icon>
|
||||
{{ item.title }}
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<MoreButton />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang='ts'>
|
||||
<script setup lang="ts">
|
||||
import Sortable from 'sortablejs'
|
||||
import { ref, computed, watch, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
@@ -38,77 +43,80 @@ const tabsMenuList = computed(() => tabStore.tabsMenuList)
|
||||
const tabsIcon = computed(() => globalStore.tabsIcon)
|
||||
|
||||
onMounted(() => {
|
||||
tabsDrop()
|
||||
initTabs()
|
||||
tabsDrop()
|
||||
initTabs()
|
||||
})
|
||||
|
||||
|
||||
// 监听路由的变化(防止浏览器后退/前进不变化 tabsMenuValue)
|
||||
watch(
|
||||
() => route.fullPath,
|
||||
() => {
|
||||
if (route.meta.isFull) return
|
||||
if (route.meta.hideTab){
|
||||
tabsMenuValue.value = route.meta.parentPath as string
|
||||
}else{
|
||||
tabsMenuValue.value = route.fullPath
|
||||
const tabsParams = {
|
||||
icon: route.meta.icon as string,
|
||||
title: route.meta.title as string,
|
||||
path: route.fullPath,
|
||||
name: route.name as string,
|
||||
close: !route.meta.isAffix,
|
||||
isKeepAlive: route.meta.isKeepAlive as boolean,
|
||||
}
|
||||
tabStore.addTabs(tabsParams)
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
() => route.fullPath,
|
||||
() => {
|
||||
if (route.meta.isFull) return
|
||||
if (route.meta.hideTab) {
|
||||
tabsMenuValue.value = route.meta.parentPath as string
|
||||
} else {
|
||||
tabsMenuValue.value = route.fullPath
|
||||
const tabsParams = {
|
||||
icon: route.meta.icon as string,
|
||||
title: route.meta.title as string,
|
||||
path: route.fullPath,
|
||||
name: route.name as string,
|
||||
close: !route.meta.isAffix,
|
||||
isKeepAlive: route.meta.isKeepAlive as boolean
|
||||
}
|
||||
tabStore.addTabs(tabsParams)
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
// 初始化需要固定的 tabs
|
||||
const initTabs = () => {
|
||||
authStore.flatMenuListGet.forEach(item => {
|
||||
if (item.meta.isAffix && !item.meta.isHide && !item.meta.isFull) {
|
||||
const tabsParams = {
|
||||
icon: item.meta.icon,
|
||||
title: item.meta.title,
|
||||
path: item.path,
|
||||
name: item.name,
|
||||
close: !item.meta.isAffix,
|
||||
isKeepAlive: item.meta.isKeepAlive,
|
||||
}
|
||||
tabStore.addTabs(tabsParams)
|
||||
}
|
||||
})
|
||||
authStore.flatMenuListGet.forEach(item => {
|
||||
if (item.meta.isAffix && !item.meta.isHide && !item.meta.isFull) {
|
||||
const tabsParams = {
|
||||
icon: item.meta.icon,
|
||||
title: item.meta.title,
|
||||
path: item.path,
|
||||
name: item.name,
|
||||
close: !item.meta.isAffix,
|
||||
isKeepAlive: item.meta.isKeepAlive,
|
||||
unshift: true
|
||||
}
|
||||
tabStore.addTabs(tabsParams)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// tabs 拖拽排序
|
||||
const tabsDrop = () => {
|
||||
Sortable.create(document.querySelector('.el-tabs__nav') as HTMLElement, {
|
||||
draggable: '.el-tabs__item',
|
||||
animation: 300,
|
||||
onEnd({ newIndex, oldIndex }) {
|
||||
const tabsList = [...tabStore.tabsMenuList]
|
||||
const currRow = tabsList.splice(oldIndex as number, 1)[0]
|
||||
tabsList.splice(newIndex as number, 0, currRow)
|
||||
tabStore.setTabs(tabsList)
|
||||
},
|
||||
})
|
||||
Sortable.create(document.querySelector('.el-tabs__nav') as HTMLElement, {
|
||||
draggable: '.el-tabs__item',
|
||||
animation: 300,
|
||||
onEnd({ newIndex, oldIndex }) {
|
||||
const tabsList = [...tabStore.tabsMenuList]
|
||||
const currRow = tabsList.splice(oldIndex as number, 1)[0]
|
||||
tabsList.splice(newIndex as number, 0, currRow)
|
||||
tabStore.setTabs(tabsList)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Tab Click
|
||||
const tabClick = (tabItem: TabsPaneContext) => {
|
||||
const fullPath = tabItem.props.name as string
|
||||
router.push(fullPath)
|
||||
const fullPath = tabItem.props.name as string
|
||||
// console.log("🚀 ~ tabClick ~ fullPath:", tabItem)
|
||||
router.push(fullPath)
|
||||
}
|
||||
|
||||
// Remove Tab
|
||||
const tabRemove = (fullPath: TabPaneName) => {
|
||||
tabStore.removeTabs(fullPath as string, fullPath == route.fullPath)
|
||||
|
||||
|
||||
tabStore.removeTabs(fullPath as string, fullPath == route.fullPath || '/machine/testScriptAdd' == route.fullPath)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
@import "./index.scss";
|
||||
<style scoped lang="scss">
|
||||
@import './index.scss';
|
||||
</style>
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
border-radius: 3px;
|
||||
}
|
||||
.layout-light {
|
||||
background-color: var(--el-color-primary-light-5);
|
||||
background-color: var(--el-color-primary-light-3);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.layout-content {
|
||||
|
||||
@@ -65,5 +65,6 @@ const setupAll = async () => {
|
||||
|
||||
//挂载app
|
||||
setupAll().then(() => {
|
||||
|
||||
app.mount('#app')
|
||||
})
|
||||
|
||||
@@ -30,6 +30,7 @@ const routerMode = {
|
||||
* @param meta.isKeepAlive ==> 当前路由是否缓存
|
||||
* */
|
||||
const router = createRouter({
|
||||
|
||||
history: routerMode[mode](),
|
||||
routes: [...staticRouter],
|
||||
// 不区分路由大小写,非严格模式下提供了更宽松的路径匹配
|
||||
@@ -46,14 +47,13 @@ router.beforeEach(async (to, from, next) => {
|
||||
const authStore = useAuthStore()
|
||||
// 1.NProgress 开始
|
||||
NProgress.start()
|
||||
|
||||
// 2.动态设置标题
|
||||
const title = import.meta.env.VITE_GLOB_APP_TITLE
|
||||
document.title = to.meta.title ? `${to.meta.title} - ${title}` : title
|
||||
|
||||
// 3.判断是访问登陆页,有 Token 就在当前页面,没有 Token 重置路由到登陆页
|
||||
if (to.path.toLocaleLowerCase() === LOGIN_URL) {
|
||||
if (userStore.token) return next(from.fullPath)
|
||||
if (userStore.accessToken) return next(from.fullPath)
|
||||
resetRouter()
|
||||
return next()
|
||||
}
|
||||
@@ -62,17 +62,16 @@ router.beforeEach(async (to, from, next) => {
|
||||
if (ROUTER_WHITE_LIST.includes(to.path)) return next()
|
||||
|
||||
// 5.判断是否有 Token,没有重定向到 login 页面
|
||||
if (!userStore.token) return next({ path: LOGIN_URL, replace: true })
|
||||
if (!userStore.accessToken) return next({ path: LOGIN_URL, replace: true })
|
||||
|
||||
// 6.如果没有菜单列表,就重新请求菜单列表并添加动态路由
|
||||
if (!authStore.authMenuListGet.length) {
|
||||
await initDynamicRouter()
|
||||
return next({ ...to, replace: true })
|
||||
}
|
||||
//console.log(to)
|
||||
|
||||
// 7.存储 routerName 做按钮权限筛选
|
||||
authStore.setRouteName(to.name as string)
|
||||
|
||||
// 8.正常访问页面
|
||||
next()
|
||||
})
|
||||
|
||||
@@ -28,7 +28,9 @@ export const initDynamicRouter = async () => {
|
||||
type: "warning",
|
||||
duration: 3000
|
||||
});
|
||||
userStore.setToken("");
|
||||
userStore.setAccessToken("");
|
||||
userStore.setRefreshToken("");
|
||||
userStore.setExp(0)
|
||||
router.replace(LOGIN_URL);
|
||||
return Promise.reject("No permission");
|
||||
}
|
||||
@@ -36,9 +38,11 @@ export const initDynamicRouter = async () => {
|
||||
// 3.添加动态路由
|
||||
authStore.flatMenuListGet.forEach(item => {
|
||||
item.children && delete item.children;
|
||||
|
||||
if (item.component && typeof item.component == "string") {
|
||||
item.component = modules["/src/views" + item.component + ".vue"];
|
||||
}
|
||||
|
||||
if (item.meta.isFull) {
|
||||
router.addRoute(item as unknown as RouteRecordRaw);
|
||||
} else {
|
||||
@@ -47,7 +51,9 @@ export const initDynamicRouter = async () => {
|
||||
});
|
||||
} catch (error) {
|
||||
// 当按钮 || 菜单请求出错时,重定向到登陆页
|
||||
userStore.setToken("");
|
||||
userStore.setAccessToken("");
|
||||
userStore.setRefreshToken("");
|
||||
userStore.setExp(0)
|
||||
router.replace(LOGIN_URL);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
@@ -1,122 +1,139 @@
|
||||
import { RouteRecordRaw } from "vue-router";
|
||||
import { HOME_URL, LOGIN_URL } from "@/config";
|
||||
export const Layout = () => import('@/layouts/index.vue');
|
||||
import { RouteRecordRaw } from 'vue-router'
|
||||
import { HOME_URL, LOGIN_URL } from '@/config'
|
||||
export const Layout = () => import('@/layouts/index.vue')
|
||||
/**
|
||||
* staticRouter (静态路由)
|
||||
*/
|
||||
export const staticRouter: RouteRecordRaw[] = [
|
||||
{
|
||||
path: "/",
|
||||
redirect: HOME_URL,
|
||||
},
|
||||
{
|
||||
path: LOGIN_URL,
|
||||
name: "login",
|
||||
component: () => import("@/views/login/index.vue"),
|
||||
meta: {
|
||||
title: "登录",
|
||||
{
|
||||
path: '/',
|
||||
redirect: HOME_URL
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/layout",
|
||||
name: "layout",
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
path: "/plan",
|
||||
name: "plan",
|
||||
redirect: "/plan/planList",
|
||||
{
|
||||
path: LOGIN_URL,
|
||||
name: 'login',
|
||||
component: () => import('@/views/login/index.vue'),
|
||||
meta: {
|
||||
title: '登录'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/layout',
|
||||
name: 'layout',
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
path: "/plan/planList",
|
||||
name: "planList",
|
||||
component: () => import("@/views/plan/planList/index.vue"),
|
||||
meta: {
|
||||
title: "检测计划列表",
|
||||
icon: "List",
|
||||
isLink: "",
|
||||
isHide: false,
|
||||
isFull: false,
|
||||
isAffix: false,
|
||||
isKeepAlive: false,
|
||||
{
|
||||
path: '/plan',
|
||||
name: 'plan',
|
||||
redirect: '/plan/planList',
|
||||
children: [
|
||||
// {
|
||||
// path: "/plan/planList",
|
||||
// name: "planList",
|
||||
// component: () => import("@/views/plan/planList/index.vue"),
|
||||
// meta: {
|
||||
// title: "检测计划列表",
|
||||
// icon: "List",
|
||||
// isLink: "",
|
||||
// isHide: false,
|
||||
// isFull: false,
|
||||
// isAffix: false,
|
||||
// isKeepAlive: true,//缓存改成true
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// path: "/plan/singlePlanList",
|
||||
// name: "singlePlanList",
|
||||
// component: () => import("@/views/plan/singlePlanList/index.vue"),
|
||||
// meta: {
|
||||
// title: "单个计划列表",
|
||||
// icon: "List",
|
||||
// isLink: "",
|
||||
// isHide: false,
|
||||
// isFull: false,
|
||||
// isAffix: false,
|
||||
// isKeepAlive: true,
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// path: "/plan/preTest",
|
||||
// name: "preTest",
|
||||
// component: () => import("@/views/plan/preTest/index.vue"),
|
||||
// meta: {
|
||||
// title: "预检测",
|
||||
// icon: "List",
|
||||
// isLink: "",
|
||||
// isHide: false,
|
||||
// isFull: false,
|
||||
// isAffix: false,
|
||||
// isKeepAlive: false,
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// path: "/plan/autoTest",
|
||||
// name: "autoTest",
|
||||
// component: () => import("@/views/plan/autoTest/index.vue"),
|
||||
// meta: {
|
||||
// title: "自动检测",
|
||||
// icon: "List",
|
||||
// isLink: "",
|
||||
// hideTab:true,
|
||||
// parentPath:'/system/proTable',
|
||||
// isHide: false,
|
||||
// isFull: false,
|
||||
// isAffix: false,
|
||||
// isKeepAlive: true,
|
||||
// },
|
||||
// },
|
||||
|
||||
// 错误页面路由
|
||||
{
|
||||
path: '/403',
|
||||
name: '403',
|
||||
component: () => import('@/components/ErrorMessage/403.vue'),
|
||||
meta: {
|
||||
title: '403页面'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/404',
|
||||
name: '404',
|
||||
component: () => import('@/components/ErrorMessage/404.vue'),
|
||||
meta: {
|
||||
title: '404页面'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/500',
|
||||
name: '500',
|
||||
component: () => import('@/components/ErrorMessage/500.vue'),
|
||||
meta: {
|
||||
title: '500页面'
|
||||
}
|
||||
},
|
||||
// Resolve refresh page, route warnings
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
component: () => import('@/components/ErrorMessage/404.vue')
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/plan/singlePlanList",
|
||||
name: "singlePlanList",
|
||||
component: () => import("@/views/plan/singlePlanList/index.vue"),
|
||||
meta: {
|
||||
title: "单个计划列表",
|
||||
icon: "List",
|
||||
isLink: "",
|
||||
isHide: false,
|
||||
isFull: false,
|
||||
isAffix: false,
|
||||
isKeepAlive: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/plan/preTest",
|
||||
name: "preTest",
|
||||
component: () => import("@/views/plan/preTest/index.vue"),
|
||||
meta: {
|
||||
title: "预检测",
|
||||
icon: "List",
|
||||
isLink: "",
|
||||
isHide: false,
|
||||
isFull: false,
|
||||
isAffix: false,
|
||||
isKeepAlive: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/plan/autoTest",
|
||||
name: "autoTest",
|
||||
component: () => import("@/views/plan/autoTest/index.vue"),
|
||||
meta: {
|
||||
title: "自动检测",
|
||||
icon: "List",
|
||||
isLink: "",
|
||||
hideTab:true,
|
||||
parentPath:'/system/proTable',
|
||||
isHide: false,
|
||||
isFull: false,
|
||||
isAffix: false,
|
||||
isKeepAlive: false,
|
||||
},
|
||||
},
|
||||
// 错误页面路由
|
||||
{
|
||||
path: "/403",
|
||||
name: "403",
|
||||
component: () => import("@/components/ErrorMessage/403.vue"),
|
||||
meta: {
|
||||
title: "403页面",
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/404",
|
||||
name: "404",
|
||||
component: () => import("@/components/ErrorMessage/404.vue"),
|
||||
meta: {
|
||||
title: "404页面",
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/500",
|
||||
name: "500",
|
||||
component: () => import("@/components/ErrorMessage/500.vue"),
|
||||
meta: {
|
||||
title: "500页面",
|
||||
},
|
||||
},
|
||||
// Resolve refresh page, route warnings
|
||||
{
|
||||
path: "/:pathMatch(.*)*",
|
||||
component: () => import("@/components/ErrorMessage/404.vue"),
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
},
|
||||
];
|
||||
{
|
||||
path: '/machine/testScriptAdd',
|
||||
name: 'testScriptAdd',
|
||||
component: () => import('@/views/machine/testScript/components/testScriptPopup.vue'),
|
||||
meta: {
|
||||
title: '检测脚本配置',
|
||||
icon: 'List',
|
||||
isLink: '',
|
||||
hideTab: true,
|
||||
parentPath: '/machine/testScript',
|
||||
isHide: false,
|
||||
isFull: false,
|
||||
isAffix: false,
|
||||
isKeepAlive: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -17,3 +17,5 @@ export const USER_STORE_KEY = "cn-user";
|
||||
// pinia中dict store的key
|
||||
export const DICT_STORE_KEY = "cn-dictData";
|
||||
|
||||
export const CHECK_STORE_KEY = "cn-check";
|
||||
|
||||
|
||||
@@ -6,57 +6,60 @@ export type LanguageType = 'zh' | 'en' | null;
|
||||
|
||||
/* GlobalState */
|
||||
export interface GlobalState {
|
||||
layout: LayoutType;
|
||||
assemblySize: AssemblySizeType;
|
||||
language: LanguageType;
|
||||
maximize: boolean;
|
||||
primary: string;
|
||||
isDark: boolean;
|
||||
isGrey: boolean;
|
||||
isWeak: boolean;
|
||||
asideInverted: boolean;
|
||||
headerInverted: boolean;
|
||||
isCollapse: boolean;
|
||||
accordion: boolean;
|
||||
breadcrumb: boolean;
|
||||
breadcrumbIcon: boolean;
|
||||
tabs: boolean;
|
||||
tabsIcon: boolean;
|
||||
footer: boolean;
|
||||
layout: LayoutType;
|
||||
assemblySize: AssemblySizeType;
|
||||
language: LanguageType;
|
||||
maximize: boolean;
|
||||
primary: string;
|
||||
isDark: boolean;
|
||||
isGrey: boolean;
|
||||
isWeak: boolean;
|
||||
asideInverted: boolean;
|
||||
headerInverted: boolean;
|
||||
isCollapse: boolean;
|
||||
accordion: boolean;
|
||||
breadcrumb: boolean;
|
||||
breadcrumbIcon: boolean;
|
||||
tabs: boolean;
|
||||
tabsIcon: boolean;
|
||||
footer: boolean;
|
||||
}
|
||||
|
||||
/* UserState */
|
||||
export interface UserState {
|
||||
token: string;
|
||||
userInfo: { name: string };
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
isRefreshToken: boolean;
|
||||
userInfo: { id: string, name: string,loginName:string };
|
||||
}
|
||||
|
||||
/* tabsMenuProps */
|
||||
export interface TabsMenuProps {
|
||||
icon: string;
|
||||
title: string;
|
||||
path: string;
|
||||
name: string;
|
||||
close: boolean;
|
||||
isKeepAlive: boolean;
|
||||
icon: string;
|
||||
title: string;
|
||||
path: string;
|
||||
name: string;
|
||||
close: boolean;
|
||||
isKeepAlive: boolean;
|
||||
unshift?: boolean;
|
||||
}
|
||||
|
||||
/* TabsState */
|
||||
export interface TabsState {
|
||||
tabsMenuList: TabsMenuProps[];
|
||||
tabsMenuList: TabsMenuProps[];
|
||||
}
|
||||
|
||||
/* AuthState */
|
||||
export interface AuthState {
|
||||
routeName: string;
|
||||
authButtonList: {
|
||||
[key: string]: string[];
|
||||
};
|
||||
authMenuList: Menu.MenuOptions[];
|
||||
showMenuFlag: boolean;
|
||||
routeName: string;
|
||||
authButtonList: {
|
||||
[key: string]: string[];
|
||||
};
|
||||
authMenuList: Menu.MenuOptions[];
|
||||
showMenuFlag: boolean;
|
||||
}
|
||||
|
||||
/* KeepAliveState */
|
||||
export interface KeepAliveState {
|
||||
keepAliveName: string[];
|
||||
keepAliveName: string[];
|
||||
}
|
||||
|
||||
63
frontend/src/stores/modules/check.ts
Normal file
63
frontend/src/stores/modules/check.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import {defineStore} from "pinia";
|
||||
import {CHECK_STORE_KEY} from "@/stores/constant";
|
||||
import type {CheckData} from "@/api/check/interface";
|
||||
import type {Plan} from '@/api/plan/interface'
|
||||
import {useAppSceneStore} from "@/stores/modules/mode";
|
||||
import { set } from "lodash";
|
||||
|
||||
const AppSceneStore = useAppSceneStore()
|
||||
export const useCheckStore = defineStore("check", {
|
||||
id: CHECK_STORE_KEY,
|
||||
|
||||
state: () => ({
|
||||
devices: Array<CheckData.Device>(),
|
||||
plan: Object<Plan.ResPlan>(),
|
||||
selectTestItems: Object<CheckData.SelectTestItem>({preTest: true, timeTest: false, channelsTest: false, test: true}),
|
||||
checkType:1, // 0:手动检测 1:自动检测
|
||||
reCheckType: 1, // 0:不合格项复检 1:全部复检
|
||||
showDetailType: 0 ,// 0:数据查询 1:误差体系跟换 2:正式检测
|
||||
temperature: 0,
|
||||
humidity: 0
|
||||
}),
|
||||
|
||||
getters: {},
|
||||
|
||||
actions: {
|
||||
addDevices(device: CheckData.Device[]) {
|
||||
this.devices.push(...device);
|
||||
},
|
||||
setPlan(plan: Plan.ResPlan) {
|
||||
this.plan = plan
|
||||
},
|
||||
clearDevices() {
|
||||
this.devices = [];
|
||||
},
|
||||
initSelectTestItems() {
|
||||
this.selectTestItems.preTest = true
|
||||
if (AppSceneStore.currentScene === '1') {
|
||||
this.selectTestItems.channelsTest = true
|
||||
} else {
|
||||
this.selectTestItems.channelsTest = false
|
||||
}
|
||||
this.selectTestItems.test = true
|
||||
},
|
||||
setSelectTestItems(selectTestItems: CheckData.SelectTestItem) {
|
||||
this.selectTestItems = selectTestItems
|
||||
},
|
||||
setCheckType(checkType: number) {
|
||||
this.checkType = checkType
|
||||
},
|
||||
setReCheckType(reCheckType: number) {
|
||||
this.reCheckType = reCheckType
|
||||
},
|
||||
setShowDetailType(showDetailType: number) {
|
||||
this.showDetailType = showDetailType
|
||||
},
|
||||
setTemperature(temperature: number) {
|
||||
this.temperature = temperature
|
||||
},
|
||||
setHumidity(humidity: number) {
|
||||
this.humidity = humidity
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { GlobalState } from "@/stores/interface";
|
||||
import { DEFAULT_PRIMARY } from "@/config";
|
||||
import { DEFAULT_PRIMARY} from "@/config";
|
||||
import piniaPersistConfig from "@/stores/helper/persist";
|
||||
import {GLOBAL_STORE_KEY} from "@/stores/constant";
|
||||
|
||||
@@ -31,7 +31,7 @@ export const useGlobalStore = defineStore({
|
||||
// 折叠菜单
|
||||
isCollapse: false,
|
||||
// 菜单手风琴
|
||||
accordion: true,
|
||||
accordion: false,
|
||||
// 面包屑导航
|
||||
breadcrumb: true,
|
||||
// 面包屑导航图标
|
||||
@@ -42,12 +42,14 @@ export const useGlobalStore = defineStore({
|
||||
tabsIcon: true,
|
||||
// 页脚
|
||||
footer: false
|
||||
|
||||
}),
|
||||
getters: {},
|
||||
actions: {
|
||||
// Set GlobalState
|
||||
setGlobalState(...args: ObjToKeyValArray<GlobalState>) {
|
||||
this.$patch({ [args[0]]: args[1] });
|
||||
console.log(DEFAULT_PRIMARY);
|
||||
}
|
||||
},
|
||||
persist: piniaPersistConfig(GLOBAL_STORE_KEY)
|
||||
|
||||
@@ -24,3 +24,16 @@ export const useModeStore = defineStore('mode', {
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const useAppSceneStore = defineStore('scene', {
|
||||
state: () => ({
|
||||
currentScene: localStorage.getItem('currentScene') || '' as string,
|
||||
}),
|
||||
actions: {
|
||||
setCurrentMode(sceneName: string) {
|
||||
this.currentScene = sceneName;
|
||||
localStorage.setItem('currentScene', sceneName); // 保存到 localStorage
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -16,8 +16,14 @@ export const useTabsStore = defineStore({
|
||||
actions: {
|
||||
// Add Tabs
|
||||
async addTabs(tabItem: TabsMenuProps) {
|
||||
|
||||
if (this.tabsMenuList.every(item => item.path !== tabItem.path)) {
|
||||
this.tabsMenuList.push(tabItem);
|
||||
if (tabItem?.unshift) {
|
||||
this.tabsMenuList.unshift(tabItem);
|
||||
}else{
|
||||
this.tabsMenuList.push(tabItem);
|
||||
|
||||
}
|
||||
}
|
||||
if (!keepAliveStore.keepAliveName.includes(tabItem.name) && tabItem.isKeepAlive) {
|
||||
keepAliveStore.addKeepAliveName(tabItem.name);
|
||||
|
||||
@@ -1,24 +1,36 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { UserState } from "@/stores/interface";
|
||||
import {defineStore} from "pinia";
|
||||
import {UserState} from "@/stores/interface";
|
||||
import piniaPersistConfig from "@/stores/helper/persist";
|
||||
import { USER_STORE_KEY } from "@/stores/constant";
|
||||
import {USER_STORE_KEY} from "@/stores/constant";
|
||||
|
||||
export const useUserStore = defineStore({
|
||||
id: USER_STORE_KEY,
|
||||
state: (): UserState => ({
|
||||
token: "",
|
||||
userInfo: { name: "admin" },
|
||||
accessToken: "",
|
||||
refreshToken: "",
|
||||
isRefreshToken:false,
|
||||
exp: Number(0),
|
||||
userInfo: {id:"", name: "" ,loginName:""},
|
||||
}),
|
||||
getters: {},
|
||||
actions: {
|
||||
// Set Token
|
||||
setToken(token: string) {
|
||||
this.token = token;
|
||||
setAccessToken(accessToken: string) {
|
||||
this.accessToken = accessToken;
|
||||
},
|
||||
setRefreshToken(refreshToken: string) {
|
||||
this.refreshToken = refreshToken;
|
||||
},
|
||||
setIsRefreshToken(isRefreshToken: boolean) {
|
||||
this.isRefreshToken = isRefreshToken;
|
||||
},
|
||||
// Set setUserInfo
|
||||
setUserInfo(userInfo: UserState["userInfo"]) {
|
||||
this.userInfo = userInfo;
|
||||
},
|
||||
setExp(exp: number) {
|
||||
this.exp = exp;
|
||||
}
|
||||
},
|
||||
persist: piniaPersistConfig(USER_STORE_KEY),
|
||||
});
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
/* flex */
|
||||
.flx-center {
|
||||
display: flex;
|
||||
@@ -77,8 +79,8 @@
|
||||
|
||||
/* scroll bar */
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 200px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
// background-color: var(--el-color-primary);
|
||||
}
|
||||
/* 滚动条实际可拖动部分的颜色 */
|
||||
|
||||
@@ -143,13 +143,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
.el-table__body {
|
||||
// border-left: 1px solid var(--el-table-border-color)
|
||||
}
|
||||
|
||||
// el-table 表格样式
|
||||
.el-table {
|
||||
// border: 1px solid var(--el-table-border-color);
|
||||
// flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
// 修复 safari 浏览器表格错位 https://github.com/HalseySpicy/Geeker-Admin/issues/83
|
||||
border-left: 1px solid var(--el-table-border-color) // 修复 safari 浏览器表格错位 https://github.com/HalseySpicy/Geeker-Admin/issues/83
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -398,7 +402,7 @@
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 8px !important;
|
||||
height: 200px !important;
|
||||
height: 8px !important;
|
||||
// background-color: var(--el-color-primary);
|
||||
z-index: 3001;
|
||||
}
|
||||
@@ -441,7 +445,7 @@
|
||||
|
||||
.dialog-small {
|
||||
.el-dialog__body {
|
||||
max-height: 260px;
|
||||
max-height: 350px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,6 +461,81 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.cn-render-buttons {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
margin-left: 13px;
|
||||
line-height: 18px;
|
||||
padding: 2px;
|
||||
|
||||
.icon {
|
||||
font-size: 12px !important;
|
||||
// color: var(--ba-bg-color-overlay) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-message-box {
|
||||
padding: 0px !important;
|
||||
|
||||
.el-message-box__header {
|
||||
background-color: var(--el-color-primary);
|
||||
|
||||
.el-message-box__title {
|
||||
color: #fff;
|
||||
padding: 10px 10px 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.el-message-box__headerbtn {
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
.el-message-box__close {
|
||||
svg {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
.el-message-box__content {
|
||||
padding: 10px;
|
||||
border-bottom: 1px solid #cccccc;
|
||||
}
|
||||
|
||||
.el-message-box__btns {
|
||||
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-one {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
|
||||
.el-form-item {
|
||||
display: flex;
|
||||
width: 98%;
|
||||
margin-bottom: 15px !important;
|
||||
|
||||
.el-form-item__content {
|
||||
flex: 1;
|
||||
|
||||
.el-select,
|
||||
.el-cascader,
|
||||
.el-input__inner,
|
||||
.el-date-editor {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-two {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -479,14 +558,48 @@
|
||||
}
|
||||
}
|
||||
|
||||
.cn-render-buttons {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
margin-left: 13px;
|
||||
line-height: 18px;
|
||||
padding: 2px;
|
||||
.icon {
|
||||
font-size: 12px !important;
|
||||
// color: var(--ba-bg-color-overlay) !important;
|
||||
.form-three {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
// justify-content: space-between;
|
||||
.el-form-item {
|
||||
display: flex;
|
||||
width: 32.3%;
|
||||
|
||||
.el-form-item__content {
|
||||
flex: 1;
|
||||
|
||||
.el-select,
|
||||
.el-cascader,
|
||||
.el-input__inner,
|
||||
.el-date-editor {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.form-four {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
// justify-content: space-between;
|
||||
.el-form-item {
|
||||
display: flex;
|
||||
width: 24%;
|
||||
|
||||
.el-form-item__content {
|
||||
flex: 1;
|
||||
|
||||
.el-select,
|
||||
.el-cascader,
|
||||
.el-input__inner,
|
||||
.el-date-editor {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-table__cell {
|
||||
border-right: 1px solid #ebeef5 !important;
|
||||
border-left: 1px solid #ebeef5 !important;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ export function rgbToHex(r: any, g: any, b: any) {
|
||||
* @returns {String} 返回处理后的颜色值
|
||||
*/
|
||||
export function getDarkColor(color: string, level: number) {
|
||||
|
||||
let reg = /^\#?[0-9A-Fa-f]{6}$/;
|
||||
if (!reg.test(color)) return ElMessage.warning("输入错误的hex颜色值");
|
||||
let rgb = hexToRgb(color);
|
||||
@@ -51,6 +52,7 @@ export function getDarkColor(color: string, level: number) {
|
||||
* @returns {String} 返回处理后的颜色值
|
||||
*/
|
||||
export function getLightColor(color: string, level: number) {
|
||||
|
||||
let reg = /^\#?[0-9A-Fa-f]{6}$/;
|
||||
if (!reg.test(color)) return ElMessage.warning("输入错误的hex颜色值");
|
||||
let rgb = hexToRgb(color);
|
||||
|
||||
@@ -4,24 +4,24 @@ import { ElNotification } from "element-plus";
|
||||
* @description 全局代码错误捕捉
|
||||
* */
|
||||
const errorHandler = (error: any) => {
|
||||
// 过滤 HTTP 请求错误
|
||||
if (error.status || error.status == 0) return false;
|
||||
let errorMap: { [key: string]: string } = {
|
||||
InternalError: "Javascript引擎内部错误",
|
||||
ReferenceError: "未找到对象",
|
||||
TypeError: "使用了错误的类型或对象",
|
||||
RangeError: "使用内置对象时,参数超范围",
|
||||
SyntaxError: "语法错误",
|
||||
EvalError: "错误的使用了Eval",
|
||||
URIError: "URI错误"
|
||||
};
|
||||
let errorName = errorMap[error.name] || "未知错误";
|
||||
ElNotification({
|
||||
title: errorName,
|
||||
message: error,
|
||||
type: "error",
|
||||
duration: 3000
|
||||
});
|
||||
// // 过滤 HTTP 请求错误
|
||||
// if (error.status || error.status == 0) return false;
|
||||
// let errorMap: { [key: string]: string } = {
|
||||
// InternalError: "Javascript引擎内部错误",
|
||||
// ReferenceError: "未找到对象",
|
||||
// TypeError: "使用了错误的类型或对象",
|
||||
// RangeError: "使用内置对象时,参数超范围",
|
||||
// SyntaxError: "语法错误",
|
||||
// EvalError: "错误的使用了Eval",
|
||||
// URIError: "URI错误"
|
||||
// };
|
||||
// let errorName = errorMap[error.name] || "未知错误";
|
||||
// ElNotification({
|
||||
// title: errorName,
|
||||
// message: error,
|
||||
// type: "error",
|
||||
// duration: 3000
|
||||
// });
|
||||
};
|
||||
|
||||
export default errorHandler;
|
||||
|
||||
185
frontend/src/utils/webSocketClient.ts
Normal file
185
frontend/src/utils/webSocketClient.ts
Normal file
@@ -0,0 +1,185 @@
|
||||
import {ElMessage} from "element-plus";
|
||||
|
||||
|
||||
export default class SocketService {
|
||||
static instance = null;
|
||||
static get Instance() {
|
||||
if (!this.instance) {
|
||||
this.instance = new SocketService();
|
||||
}
|
||||
return this.instance;
|
||||
}
|
||||
// 和服务端连接的socket对象
|
||||
ws = null;
|
||||
// 存储回调函数
|
||||
callBackMapping = {};
|
||||
// 标识是否连接成功
|
||||
connected = false;
|
||||
// 记录重试的次数
|
||||
sendRetryCount = 0;
|
||||
// 重新连接尝试的次数
|
||||
connectRetryCount = 0;
|
||||
work:any;
|
||||
workerBlobUrl:any;
|
||||
lastActivityTime= 0; // 上次活动时间戳
|
||||
lastResponseHeartTime = Date.now();//最后一次收到心跳回复时间
|
||||
|
||||
reconnectDelay= 5000; // 重新连接延迟,单位毫秒
|
||||
|
||||
// 定义连接服务器的方法
|
||||
connect() {
|
||||
|
||||
// 连接服务器
|
||||
if (!window.WebSocket) {
|
||||
return console.log('您的浏览器不支持WebSocket');
|
||||
}
|
||||
|
||||
// let token = $.cookie('123');
|
||||
// let token = '4E6EF539AAF119D82AC4C2BC84FBA21F';
|
||||
|
||||
|
||||
const url = 'ws://127.0.0.1:7777/hello?name=cdf'
|
||||
this.ws = new WebSocket(url);
|
||||
// 连接成功的事件
|
||||
this.ws.onopen = () => {
|
||||
ElMessage.success("webSocket连接服务端成功了");
|
||||
console.log('连接服务端成功了');
|
||||
this.connected = true;
|
||||
// 重置重新连接的次数
|
||||
this.connectRetryCount = 0;
|
||||
this.updateLastActivityTime();
|
||||
this.startHeartbeat();
|
||||
};
|
||||
// 1.连接服务端失败
|
||||
// 2.当连接成功之后, 服务器关闭的情况
|
||||
this.ws.onclose = () => {
|
||||
console.log('连接webSocket服务端关闭');
|
||||
this.connected = false;
|
||||
this.connectRetryCount++;
|
||||
this.clearHeartbeat();
|
||||
/* setTimeout(() => {
|
||||
this.connect();
|
||||
}, 500 * this.connectRetryCount);*/
|
||||
|
||||
|
||||
};
|
||||
|
||||
this.ws.onerror = () => {
|
||||
ElMessage.error("webSocket连接异常!");
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
// 得到服务端发送过来的数据
|
||||
this.ws.onmessage = (event) => {
|
||||
// console.log('🚀 ~ SocketService ~ connect ~ event:', event)
|
||||
if(event.data == 'over') {
|
||||
//心跳消息处理
|
||||
this.lastResponseHeartTime = Date.now();
|
||||
this.updateLastActivityTime(); // 收到心跳响应时更新活动时间
|
||||
}else {
|
||||
let message: { [key: string]: any };
|
||||
try {
|
||||
console.log('Received message:',event.data)
|
||||
message = JSON.parse(event.data);
|
||||
} catch (e) {
|
||||
return console.error("消息解析失败", event.data, e);
|
||||
}
|
||||
|
||||
/* 通过接受服务端发送的type字段来回调函数 */
|
||||
if (message?.type && this.callBackMapping[message.type]) {
|
||||
this.callBackMapping[message.type](message);
|
||||
} else {
|
||||
console.log("抛弃====>")
|
||||
console.log(event.data)
|
||||
/* 丢弃或继续写你的逻辑 */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
startHeartbeat() {
|
||||
this.lastResponseHeartTime = Date.now();
|
||||
const _this = this
|
||||
_this.workerBlobUrl = window.URL.createObjectURL(new Blob(['(function(e){setInterval(function(){this.postMessage(null)},9000)})()']));
|
||||
|
||||
this.work = new Worker(_this.workerBlobUrl);
|
||||
this.work.onmessage = function(e){
|
||||
//判断多久没收到心跳响应
|
||||
|
||||
if(_this.lastActivityTime - _this.lastResponseHeartTime > 30000){
|
||||
//说明已经三轮心跳没收到回复了,关闭检测,提示用户。
|
||||
ElMessage.error("业务主体模块发生未知异常,请尝试重新启动!");
|
||||
_this.clearHeartbeat();
|
||||
return;
|
||||
}
|
||||
_this.sendHeartbeat();
|
||||
}
|
||||
|
||||
}
|
||||
sendHeartbeat() {
|
||||
console.log(new Date()+"进入心跳消息发送。。。。。。。。。。。。。")
|
||||
this.ws.send('alive');
|
||||
this.updateLastActivityTime(); // 发送心跳后更新活动时间
|
||||
}
|
||||
|
||||
|
||||
updateLastActivityTime() {
|
||||
this.lastActivityTime = Date.now();
|
||||
}
|
||||
|
||||
clearHeartbeat() {
|
||||
const _this = this
|
||||
if (_this.work) {
|
||||
_this.work.terminate();
|
||||
_this.work = null;
|
||||
}
|
||||
if (_this.workerBlobUrl) {
|
||||
window.URL.revokeObjectURL(_this.workerBlobUrl); // 释放临时的Blob URL
|
||||
_this.workerBlobUrl = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 回调函数的注册
|
||||
registerCallBack(socketType, callBack) {
|
||||
this.callBackMapping[socketType] = callBack;
|
||||
}
|
||||
// 取消某一个回调函数
|
||||
unRegisterCallBack(socketType) {
|
||||
this.callBackMapping[socketType] = null;
|
||||
}
|
||||
// 发送数据的方法
|
||||
send(data) {
|
||||
// 判断此时此刻有没有连接成功
|
||||
if (this.connected) {
|
||||
this.sendRetryCount = 0;
|
||||
try {
|
||||
this.ws.send(JSON.stringify(data));
|
||||
} catch (e) {
|
||||
this.ws.send(data);
|
||||
}
|
||||
} else {
|
||||
this.sendRetryCount++;
|
||||
setTimeout(() => {
|
||||
this.send(data);
|
||||
}, this.sendRetryCount * 500);
|
||||
}
|
||||
}
|
||||
|
||||
// 断开方法
|
||||
closeWs() {
|
||||
if (this.connected) {
|
||||
this.ws.close()
|
||||
}
|
||||
console.log('执行WS关闭命令..');
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<el-dialog :title="dialogTitle" :model-value="dialogVisible" @close="close" v-bind="dialogMiddle">
|
||||
<el-form :model="formContent" ref='dialogFormRef' :rules='rules' >
|
||||
<el-form :model="formContent" ref='dialogFormRef' :rules='rules' class="form-two">
|
||||
<el-form-item label="上级菜单" prop="pid" :label-width="100">
|
||||
<el-tree-select
|
||||
v-model="displayPid"
|
||||
@@ -14,12 +14,12 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="name" :label-width="100">
|
||||
<el-input v-model="formContent.name" />
|
||||
<el-input v-model="formContent.name" maxlength="32" show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item label="编码" prop="code" :label-width="100">
|
||||
<el-input v-model="formContent.code" />
|
||||
<el-input v-model="formContent.code" maxlength="32" show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item label="图标" prop="icon" :label-width="100">
|
||||
<el-form-item v-if="!formContent.type" label="图标" prop="icon" :label-width="100">
|
||||
<IconSelect
|
||||
v-model="formContent.icon"
|
||||
:iconValue="formContent.icon"
|
||||
@@ -27,11 +27,11 @@
|
||||
placeholder="选择一个图标"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="路由地址" prop="path" :label-width="100">
|
||||
<el-input v-model="formContent.path" />
|
||||
<el-form-item v-if="!formContent.type" label="路由地址" prop="path" :label-width="100" >
|
||||
<el-input v-model="formContent.path" maxlength="32" show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item label="组件地址" prop="component" :label-width="100">
|
||||
<el-input v-model="formContent.component" />
|
||||
<el-form-item v-if="!formContent.type" label="组件地址" prop="component" :label-width="100">
|
||||
<el-input v-model="formContent.component" maxlength="32" show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort" :label-width="100">
|
||||
<el-input-number v-model="formContent.sort" :min='1' :max='999' />
|
||||
@@ -199,6 +199,8 @@ const displayPid = computed({
|
||||
functionList.value = response.data as unknown as Function.ResFunction[]
|
||||
titleType.value = sign
|
||||
dialogVisible.value = true
|
||||
rules.value.path = [{ required: true, trigger: 'blur', message: '路由地址必填!' }];
|
||||
rules.value.component = [{ required: true, trigger: 'blur', message: '组件地址必填!' }];
|
||||
|
||||
if (formContent.value.pid ==='0') {
|
||||
formContent.value.pid = '';
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
import ResourcePopup from './components/resourcePopup.vue'
|
||||
import {deleteFunction,getFunctionList} from '@/api/user/function/index'
|
||||
import * as Icons from '@element-plus/icons-vue'
|
||||
defineOptions({
|
||||
name: 'resource'
|
||||
})
|
||||
const dictStore = useDictStore()
|
||||
const resourcePopup = ref()
|
||||
// ProTable 实例
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
:rules='rules'
|
||||
>
|
||||
<el-form-item label="名称" prop='name' :label-width="100" >
|
||||
<el-input v-model="formContent.name" placeholder="请输入名称" autocomplete="off" :disabled="rootIsEdit"/>
|
||||
<el-input v-model="formContent.name" placeholder="请输入名称" autocomplete="off" :disabled="rootIsEdit" maxlength="32" show-word-limit/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="编码" prop='code' :label-width="100">
|
||||
<el-input v-model="formContent.code" placeholder="请输入编码" autocomplete="off" :disabled="rootIsEdit"/>
|
||||
<el-input v-model="formContent.code" placeholder="请输入编码" autocomplete="off" :disabled="rootIsEdit" maxlength="32" show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item label='类型' prop='type' :label-width="100">
|
||||
<el-select v-model="formContent.type" clearable placeholder="请选择类型" :disabled="rootIsEdit">
|
||||
|
||||
@@ -146,7 +146,6 @@ const open = async (sign: string, data: Role.RoleBO, AllFunction: Function.ResFu
|
||||
const allIds = getAllIds(AllFunction);
|
||||
// 匹配 roleFunctions 中的 id 并设置 checkedKeys
|
||||
const checkedKeys = allIds.filter(id => roleFunctions.some(roleFunc => roleFunc.id === id));
|
||||
|
||||
// 过滤出叶子节点
|
||||
const leafCheckedKeys = filterLeafNodes(AllFunction, checkedKeys);
|
||||
|
||||
|
||||
@@ -8,17 +8,17 @@
|
||||
<!-- :requestApi="getRoleList" -->
|
||||
<!-- 表格 header 按钮 -->
|
||||
<template #tableHeader='scope'>
|
||||
<el-button v-auth.role="'add'" type='primary' :icon='CirclePlus' @click="openDrawer('新增角色')">新增</el-button>
|
||||
<el-button v-auth.role="'batchDelete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
|
||||
<el-button v-auth.role="'add'" type='primary' :icon='CirclePlus' @click="openDrawer('add')">新增</el-button>
|
||||
<el-button v-auth.role="'delete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
|
||||
@click='batchDelete(scope.selectedListIds)'>
|
||||
批量删除
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
<!-- 表格操作 -->
|
||||
<template #operation='scope'>
|
||||
<el-button v-auth.role="'edit'" type='primary' link :icon='EditPen' @click="openDrawer('编辑角色', scope.row)">编辑</el-button>
|
||||
<el-button v-auth.role="'delete'" v-if="scope.row.type !== 0 && scope.row.type !== 1" type='primary' link :icon='Delete' @click='deleteAccount(scope.row)'>删除</el-button>
|
||||
<el-button v-auth.role="'SetPermissions'" type='primary' link :icon='Share' @click="openDrawer('设置权限', scope.row)">设置权限</el-button>
|
||||
<el-button v-auth.role="'edit'" type='primary' link :icon='EditPen' @click="openDrawer('edit', scope.row)" :disabled="scope.row.code == 'root'">编辑</el-button>
|
||||
<el-button v-auth.role="'delete'" type='primary' link :icon='Delete' @click='deleteAccount(scope.row)' :disabled="scope.row.code == 'root'">删除</el-button>
|
||||
<el-button v-auth.role="'SetPermissions'" type='primary' link :icon='Share' @click="openDrawer('设置权限', scope.row)" :disabled="scope.row.code == 'root'">设置权限</el-button>
|
||||
</template>
|
||||
|
||||
</ProTable>
|
||||
@@ -39,6 +39,9 @@ import RolePopup from './components/rolePopup.vue'
|
||||
import RoleResourcePopup from './components/roleResourcePopup.vue'
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import {useDictStore} from '@/stores/modules/dict'
|
||||
defineOptions({
|
||||
name: 'role'
|
||||
})
|
||||
const rolePopup = ref()
|
||||
const roleResourcePopup = ref()
|
||||
const dictStore = useDictStore()
|
||||
@@ -91,6 +94,22 @@ const columns = reactive<ColumnProps<Role.RoleBO>[]>([
|
||||
search: { el: 'input' },
|
||||
minWidth: 200,
|
||||
},
|
||||
{
|
||||
prop: 'type',
|
||||
label: '类型',
|
||||
minWidth: 200,
|
||||
render: (scope) => {
|
||||
const typeMap: { [key: number]: { label: string; type: string } } = {
|
||||
0: { label: '超级管理员', type: 'primary' },
|
||||
1: { label: '管理员角色', type: 'success' },
|
||||
2: { label: '普通角色', type: 'info' },
|
||||
};
|
||||
const typeInfo = typeMap[scope.row.type] || { label: '未知', type: 'danger' };
|
||||
return (
|
||||
<el-tag type={typeInfo.type}>{typeInfo.label}</el-tag>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
prop: 'remark',
|
||||
label: '描述',
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
:rules='rules'
|
||||
>
|
||||
<el-form-item label="原密码" prop='oldPassword' :label-width="100">
|
||||
<el-input type="oldPassword" v-model="formContent.oldPassword" show-password placeholder="请输入原密码" autocomplete="off" />
|
||||
<el-input type="oldPassword" v-model="formContent.oldPassword" show-password placeholder="请输入原密码" autocomplete="off" maxlength="32" show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop='newPassword' :label-width="100">
|
||||
<el-input type="newPassword" v-model="formContent.newPassword" show-password placeholder="请输入新密码" autocomplete="off" />
|
||||
<el-input type="newPassword" v-model="formContent.newPassword" show-password placeholder="请输入新密码" autocomplete="off" maxlength="32" show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop='surePassword' :label-width="100">
|
||||
<el-input type="surePassword" v-model="formContent.surePassword" show-password placeholder="请再次输入确认密码" autocomplete="off" />
|
||||
<el-input type="surePassword" v-model="formContent.surePassword" show-password placeholder="请再次输入确认密码" autocomplete="off" maxlength="32" show-word-limit/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<template>
|
||||
<!-- 基础信息弹出框 -->
|
||||
<el-dialog v-model='dialogVisible' :title="dialogTitle" v-bind="dialogSmall" @close="close">
|
||||
<el-dialog v-model='dialogVisible' :title="dialogTitle" v-bind="dialogSmall" @close="close" >
|
||||
<div>
|
||||
<el-form :model="formContent"
|
||||
ref='dialogFormRef'
|
||||
:rules='rules'
|
||||
>
|
||||
<el-form-item label="用户名" prop='name' :label-width="100">
|
||||
<el-input v-model="formContent.name" placeholder="请输入用户名" autocomplete="off" />
|
||||
<el-input v-model="formContent.name" placeholder="请输入用户名" autocomplete="off" maxlength="32" show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item label="登录名" prop='loginName' :label-width="100" >
|
||||
<el-input v-model="formContent.loginName" placeholder="请输入登录名" autocomplete="off" :disabled="LoginNameIsShow"/>
|
||||
<el-input v-model="formContent.loginName" placeholder="请输入登录名" autocomplete="off" :disabled="LoginNameIsShow" maxlength="32" show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" prop='password' :label-width="100" v-if="IsPasswordShow">
|
||||
<el-input type="password" v-model="formContent.password" show-password placeholder="请输入密码" autocomplete="off" />
|
||||
<el-input type="password" v-model="formContent.password" show-password placeholder="请输入密码" autocomplete="off" maxlength="32" show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item label='角色' :label-width='100' prop='roles'>
|
||||
<el-select v-model="formContent.roleIds" multiple placeholder="请选择角色">
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
<!-- 表格 header 按钮 -->
|
||||
<template #tableHeader='scope'>
|
||||
<el-button v-auth.user="'add'" type='primary' :icon='CirclePlus' @click="openDialog('add')">新增</el-button>
|
||||
<el-button v-auth.user="'batchDelete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
|
||||
<el-button v-auth.user="'delete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
|
||||
@click='batchDelete(scope.selectedListIds)'>
|
||||
批量删除
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
<!-- 表格操作 -->
|
||||
<template #operation='scope'>
|
||||
<el-button v-auth.user="'edit'" type='primary' link :icon='EditPen' @click="openDialog('edit', scope.row)">编辑</el-button>
|
||||
<el-button v-auth.user="'delete'" type='primary' link :icon='Delete' @click='handleDelete(scope.row)'>删除</el-button>
|
||||
<el-button v-auth.user="'editPassWord'" type='primary' link :icon='Delete' @click='EditPassWord(scope.row)'>修改密码</el-button>
|
||||
<el-button v-auth.user="'edit'" type='primary' link :icon='EditPen' @click="openDialog('edit', scope.row)" :disabled="scope.row.loginName == 'root'">编辑</el-button>
|
||||
<el-button v-auth.user="'delete'" type='primary' link :icon='Delete' @click='handleDelete(scope.row)' :disabled="scope.row.loginName == 'root'">删除</el-button>
|
||||
<el-button v-auth.user="'editPassWord'" type='primary' link :icon='Delete' @click='EditPassWord(scope.row)' :disabled="scope.row.loginName == 'root'">修改密码</el-button>
|
||||
</template>
|
||||
|
||||
</ProTable>
|
||||
@@ -43,6 +43,9 @@
|
||||
import {getUserList, deleteUser,getRoleList} from '@/api/user/user'
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { type Role } from '@/api/user/interface/role'
|
||||
defineOptions({
|
||||
name: 'user'
|
||||
})
|
||||
const roleList = ref<Role.RoleBO[]>([])
|
||||
const dictStore = useDictStore()
|
||||
const userPopup = ref()
|
||||
@@ -61,8 +64,8 @@
|
||||
// 默认不做操作就直接在 ProTable 组件上绑定 :requestApi="getUserList"
|
||||
const getTableList = (params: any) => {
|
||||
let newParams = JSON.parse(JSON.stringify(params))
|
||||
newParams.searchEndTime = endDate.value
|
||||
newParams.searchBeginTime = startDate.value
|
||||
// newParams.searchEndTime = endDate.value
|
||||
// newParams.searchBeginTime = startDate.value
|
||||
return getUserList(newParams)
|
||||
}
|
||||
|
||||
@@ -88,6 +91,7 @@
|
||||
render: (scope) => {
|
||||
const roleNames = scope.row.roleNames;
|
||||
const roleArray = Array.isArray(roleNames) ? roleNames : [roleNames];
|
||||
|
||||
if (roleArray.length > 1) {
|
||||
return roleArray.join(', ');
|
||||
}
|
||||
@@ -108,19 +112,19 @@
|
||||
prop: 'loginTime',
|
||||
label: '最后一次登录时间',
|
||||
minWidth: 180,
|
||||
search: {
|
||||
render: () => {
|
||||
return (
|
||||
<div class='flx-flex-start'>
|
||||
<TimeControl
|
||||
include={['日', '周', '月', '自定义']}
|
||||
default={'月'}
|
||||
onUpdate-dates={handleDateChange}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
},
|
||||
// search: {
|
||||
// render: () => {
|
||||
// return (
|
||||
// <div class='flx-flex-start'>
|
||||
// <TimeControl
|
||||
// include={['日', '周', '月', '自定义']}
|
||||
// default={'月'}
|
||||
// onUpdate-dates={handleDateChange}
|
||||
// />
|
||||
// </div>
|
||||
// )
|
||||
// },
|
||||
// },
|
||||
},
|
||||
{
|
||||
prop: 'state',
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
<!--双列-->
|
||||
<template>
|
||||
<el-dialog v-model='dialogVisible' :title='title' v-bind='dialogMiddle' >
|
||||
<el-scrollbar>
|
||||
<el-form :inline="false" label-width="auto" ref="formRef" class='form-two'>
|
||||
<el-form-item label="姓名" prop="username" >
|
||||
<el-input
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<el-input
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="年龄" prop="age">
|
||||
<el-input
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="身份证号" prop="id">
|
||||
<el-input
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="居住地址" prop="address">
|
||||
<el-input
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="手机" prop="phone">
|
||||
<el-input
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="来源" prop="source">
|
||||
<el-input
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
|
||||
<template #footer>
|
||||
<div class='dialog-footer'>
|
||||
<el-button @click='close()'>取消</el-button>
|
||||
<el-button type='primary' @click='confirmForm()'>确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup lang='ts'>
|
||||
import { dialogMiddle } from '@/utils/elementBind'
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const title = ref('单列弹出框')
|
||||
const open = (textTitle: string) => {
|
||||
dialogVisible.value = true
|
||||
title.value = textTitle
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
|
||||
const confirmForm = () => {
|
||||
ElMessage.info('业务数据提交')
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
|
||||
</script>
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -1,210 +0,0 @@
|
||||
<template>
|
||||
<div class='table-box' ref='popupBaseView'>
|
||||
<ProTable
|
||||
ref='proTable'
|
||||
:columns='columns'
|
||||
:data='userData'
|
||||
>
|
||||
<!-- 表格 header 按钮 -->
|
||||
<template #tableHeader='scope'>
|
||||
<el-button type='primary' :icon='CirclePlus' @click="openDrawer('新增')">新增用户</el-button>
|
||||
<el-button type='primary' :icon='Upload' plain @click='batchAdd'>批量添加用户</el-button>
|
||||
<el-button type='primary' :icon='Download' plain @click='downloadFile'>导出用户数据</el-button>
|
||||
<el-button type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
|
||||
@click='batchDelete(scope.selectedListIds)'>
|
||||
批量删除用户
|
||||
</el-button>
|
||||
</template>
|
||||
<!-- 表格操作 -->
|
||||
<template #operation='scope'>
|
||||
<el-button type='primary' link :icon='View'
|
||||
@click="openDrawer('查看', scope.row)">查看
|
||||
</el-button>
|
||||
<el-button type='primary' link :icon='EditPen' @click="openDrawer('编辑', scope.row)">编辑</el-button>
|
||||
<el-button type='primary' link :icon='Refresh' @click='resetPass(scope.row)'>重置密码</el-button>
|
||||
<el-button type='primary' link :icon='CirclePlus' @click='deleteAccount()'>下钻</el-button>
|
||||
</template>
|
||||
</ProTable>
|
||||
</div>
|
||||
<single-column ref='singleColumn' />
|
||||
<double-column ref='doubleColumn' />
|
||||
<open :width='viewWidth' :height='viewHeight' ref='openView' />
|
||||
</template>
|
||||
<script setup lang='tsx' name='useProTable'>
|
||||
import { ref, reactive } from 'vue'
|
||||
import { User } from '@/api/user/interface'
|
||||
import { useHandleData } from '@/hooks/useHandleData'
|
||||
import { useDownload } from '@/hooks/useDownload'
|
||||
import { useAuthButtons } from '@/hooks/useAuthButtons'
|
||||
import ProTable from '@/components/ProTable/index.vue'
|
||||
import ImportExcel from '@/components/ImportExcel/index.vue'
|
||||
import { ProTableInstance, ColumnProps } from '@/components/ProTable/interface'
|
||||
import { CirclePlus, Delete, EditPen, Download, Upload, View, Refresh } from '@element-plus/icons-vue'
|
||||
import userDataList from '@/api/user/userData'
|
||||
import { useDictStore } from '@/stores/modules/dict'
|
||||
import SingleColumn from '@/views/demo/proTable/singleColumn.vue'
|
||||
import Open from '@/views/demo/proTable/Open.vue'
|
||||
import DoubleColumn from '@/views/demo/proTable/doubleColumn.vue'
|
||||
import { useViewSize } from '@/hooks/useViewSize'
|
||||
|
||||
const { popupBaseView, viewWidth, viewHeight } = useViewSize()
|
||||
|
||||
const dictStore = useDictStore()
|
||||
import {
|
||||
getUserList,
|
||||
deleteUser,
|
||||
changeUserStatus,
|
||||
exportUserInfo,
|
||||
BatchAddUser,
|
||||
} from '@/api/user/user'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
|
||||
const userData = userDataList
|
||||
const singleColumn = ref()
|
||||
const doubleColumn = ref()
|
||||
const openView = ref()
|
||||
// ProTable 实例
|
||||
const proTable = ref<ProTableInstance>()
|
||||
// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
|
||||
const initParam = reactive({ type: 1 })
|
||||
// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
|
||||
// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
|
||||
const dataCallback = (data: any) => {
|
||||
return {
|
||||
list: data.list,
|
||||
total: data.total,
|
||||
}
|
||||
}
|
||||
// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
|
||||
// 默认不做操作就直接在 ProTable 组件上绑定 :requestApi="getUserList"
|
||||
const getTableList = (params: any) => {
|
||||
let newParams = JSON.parse(JSON.stringify(params))
|
||||
newParams.createTime && (newParams.startTime = newParams.createTime[0])
|
||||
newParams.createTime && (newParams.endTime = newParams.createTime[1])
|
||||
delete newParams.createTime
|
||||
return getUserList(newParams)
|
||||
}
|
||||
// 页面按钮权限(按钮权限既可以使用 hooks,也可以直接使用 v-auth 指令,指令适合直接绑定在按钮上,hooks 适合根据按钮权限显示不同的内容)
|
||||
const { BUTTONS } = useAuthButtons()
|
||||
// 表格配置项
|
||||
const columns = reactive<ColumnProps<User.ResUserList>[]>([
|
||||
{ type: 'selection', fixed: 'left', width: 70 },
|
||||
{ type: 'index', fixed: 'left', width: 70, label: '序号' },
|
||||
{
|
||||
prop: 'username',
|
||||
label: '姓名',
|
||||
width: 120,
|
||||
search: { el: 'input' },
|
||||
},
|
||||
{
|
||||
prop: 'gender',
|
||||
label: '性别',
|
||||
// 字典数据(本地数据)
|
||||
enum: dictStore.getDictData('sex'),
|
||||
search: { el: 'select', props: { filterable: true } },
|
||||
fieldNames: { label: 'label', value: 'code' },
|
||||
},
|
||||
{
|
||||
prop: 'age',
|
||||
label: '年龄',
|
||||
search: {
|
||||
// 自定义 search 显示内容
|
||||
render: ({ searchParam }) => {
|
||||
return (
|
||||
<div class='flx-center'>
|
||||
<el-input vModel_trim={searchParam.minAge} placeholder='最小年龄' />
|
||||
<span class='mr10 ml10'>-</span>
|
||||
<el-input vModel_trim={searchParam.maxAge} placeholder='最大年龄' />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
},
|
||||
},
|
||||
{ prop: 'idCard', label: '身份证号' },
|
||||
{ prop: 'email', label: '邮箱' },
|
||||
{ prop: 'address', label: '居住地址', width: 120 },
|
||||
{
|
||||
prop: 'status',
|
||||
label: '状态',
|
||||
enum: dictStore.getDictData('status'),
|
||||
search: { el: 'tree-select', props: { filterable: true } },
|
||||
fieldNames: { label: 'userLabel', value: 'userStatus' },
|
||||
render: scope => {
|
||||
return (
|
||||
<>
|
||||
{BUTTONS.value.status ? (
|
||||
<el-switch
|
||||
model-value={scope.row.status}
|
||||
active-text={scope.row.status ? '启用' : '禁用'}
|
||||
active-value={1}
|
||||
inactive-value={0}
|
||||
onClick={() => changeStatus(scope.row)}
|
||||
/>
|
||||
) : (
|
||||
<el-tag type={scope.row.status ? 'success' : 'danger'}>{scope.row.status ? '启用' : '禁用'}</el-tag>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
label: '创建时间',
|
||||
width: 180,
|
||||
search: {
|
||||
el: 'date-picker',
|
||||
span: 1,
|
||||
props: { type: 'daterange', valueFormat: 'YYYY-MM-DD' },
|
||||
defaultValue: ['2024-11-12', '2024-12-12'],
|
||||
},
|
||||
},
|
||||
{ prop: 'operation', label: '操作', fixed: 'right', width: 330 },
|
||||
])
|
||||
|
||||
|
||||
// 下钻
|
||||
const deleteAccount = async () => {
|
||||
openView.value.open('测试弹出框')
|
||||
}
|
||||
// 批量删除用户信息
|
||||
const batchDelete = async (id: string[]) => {
|
||||
await useHandleData(deleteUser, { id }, '删除所选用户信息')
|
||||
proTable.value?.clearSelection()
|
||||
proTable.value?.getTableList()
|
||||
}
|
||||
// 重置用户密码
|
||||
const resetPass = async (params: User.ResUserList) => {
|
||||
// await useHandleData(resetUserPassWord, { id: params.id }, `重置【${params.username}】用户密码`)
|
||||
// proTable.value?.getTableList()
|
||||
doubleColumn.value.open('双列弹出框')
|
||||
}
|
||||
// 切换用户状态
|
||||
const changeStatus = async (row: User.ResUserList) => {
|
||||
await useHandleData(changeUserStatus, {
|
||||
id: row.id,
|
||||
status: row.status == 1 ? 0 : 1,
|
||||
}, `切换【${row.username}】用户状态`)
|
||||
proTable.value?.getTableList()
|
||||
}
|
||||
// 导出用户列表
|
||||
const downloadFile = async () => {
|
||||
ElMessageBox.confirm('确认导出用户数据?', '温馨提示', { type: 'warning' }).then(() =>
|
||||
useDownload(exportUserInfo, '用户列表', proTable.value?.searchParam),
|
||||
)
|
||||
}
|
||||
// 批量添加用户
|
||||
const dialogRef = ref<InstanceType<typeof ImportExcel> | null>(null)
|
||||
const batchAdd = () => {
|
||||
const params = {
|
||||
title: '用户',
|
||||
tempApi: exportUserInfo,
|
||||
importApi: BatchAddUser,
|
||||
getTableList: proTable.value?.getTableList,
|
||||
}
|
||||
dialogRef.value?.acceptParams(params)
|
||||
}
|
||||
// 打开 drawer(新增、查看、编辑)
|
||||
const openDrawer = (title: string, row: Partial<User.ResUserList> = {}) => {
|
||||
singleColumn.value.open('单列弹出框')
|
||||
}
|
||||
</script>
|
||||
@@ -1,177 +0,0 @@
|
||||
<!--单列-->
|
||||
<template>
|
||||
<el-dialog class='table-box'
|
||||
v-model='dialogVisible'
|
||||
top='114px'
|
||||
:style="{height:height+'px',maxHeight:height+'px',overflow:'hidden'}"
|
||||
:title='title'
|
||||
:width='width'
|
||||
:modal='false'>
|
||||
<div class='table-box' :style="{height:(height-64)+'px',maxHeight:(height-64)+'px',overflow:'hidden'}">
|
||||
<ProTable
|
||||
ref='proTable'
|
||||
:columns='columns'
|
||||
:data='userData'
|
||||
>
|
||||
<!-- 表格 header 按钮 -->
|
||||
<template #tableHeader='scope'>
|
||||
<el-button type='primary' :icon='CirclePlus' @click="openDrawer('新增')">新增用户</el-button>
|
||||
</template>
|
||||
<!-- 表格操作 -->
|
||||
<template #operation='scope'>
|
||||
<el-button type='primary' link :icon='View'
|
||||
@click="openDrawer('查看', scope.row)">查看
|
||||
</el-button>
|
||||
<el-button type='primary' link :icon='EditPen' @click="openDrawer('编辑', scope.row)">编辑</el-button>
|
||||
<el-button type='primary' link :icon='Refresh' @click='resetPass(scope.row)'>重置密码</el-button>
|
||||
<el-button type='primary' link :icon='Delete' @click='deleteAccount(scope.row)'>删除</el-button>
|
||||
</template>
|
||||
</ProTable>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup lang='tsx'>
|
||||
import { CirclePlus, Delete, EditPen, Refresh, View } from '@element-plus/icons-vue'
|
||||
import ProTable from '@/components/ProTable/index.vue'
|
||||
import { useHandleData } from '@/hooks/useHandleData'
|
||||
import { useAuthButtons } from '@/hooks/useAuthButtons'
|
||||
import { reactive } from 'vue'
|
||||
import { ColumnProps } from '@/components/ProTable/interface'
|
||||
import { User } from '@/api/user/interface'
|
||||
import { useDictStore } from '@/stores/modules/dict'
|
||||
|
||||
const dictStore = useDictStore()
|
||||
import {
|
||||
changeUserStatus,
|
||||
} from '@/api/user/user'
|
||||
import userDataList from '@/api/user/userData'
|
||||
|
||||
const userData = userDataList
|
||||
const proTable = ref()
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const title = ref('单列弹出框')
|
||||
|
||||
const { BUTTONS } = useAuthButtons()
|
||||
// 表格配置项
|
||||
const columns = reactive<ColumnProps<User.ResUserList>[]>([
|
||||
{ type: 'selection', fixed: 'left', width: 70 },
|
||||
{ type: 'index', fixed: 'left', width: 70, label: '序号' },
|
||||
{
|
||||
prop: 'username',
|
||||
label: '姓名',
|
||||
width: 120,
|
||||
search: { el: 'input' },
|
||||
},
|
||||
{
|
||||
prop: 'gender',
|
||||
label: '性别',
|
||||
// 字典数据(本地数据)
|
||||
enum: dictStore.getDictData('sex'),
|
||||
search: { el: 'select', props: { filterable: true } },
|
||||
fieldNames: { label: 'label', value: 'code' },
|
||||
},
|
||||
{
|
||||
prop: 'age',
|
||||
label: '年龄',
|
||||
search: {
|
||||
// 自定义 search 显示内容
|
||||
render: ({ searchParam }) => {
|
||||
return (
|
||||
<div class='flx-center'>
|
||||
<el-input vModel_trim={searchParam.minAge} placeholder='最小年龄' />
|
||||
<span class='mr10 ml10'>-</span>
|
||||
<el-input vModel_trim={searchParam.maxAge} placeholder='最大年龄' />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
},
|
||||
},
|
||||
{ prop: 'idCard', label: '身份证号', search: { el: 'input' } },
|
||||
{ prop: 'email', label: '邮箱' },
|
||||
{ prop: 'address', label: '居住地址', width: 120 },
|
||||
{
|
||||
prop: 'status',
|
||||
label: '状态',
|
||||
enum: dictStore.getDictData('status'),
|
||||
search: { el: 'tree-select', props: { filterable: true } },
|
||||
fieldNames: { label: 'userLabel', value: 'userStatus' },
|
||||
render: scope => {
|
||||
return (
|
||||
<>
|
||||
{BUTTONS.value.status ? (
|
||||
<el-switch
|
||||
model-value={scope.row.status}
|
||||
active-text={scope.row.status ? '启用' : '禁用'}
|
||||
active-value={1}
|
||||
inactive-value={0}
|
||||
onClick={() => changeStatus(scope.row)}
|
||||
/>
|
||||
) : (
|
||||
<el-tag type={scope.row.status ? 'success' : 'danger'}>{scope.row.status ? '启用' : '禁用'}</el-tag>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
label: '创建时间',
|
||||
width: 180,
|
||||
search: {
|
||||
el: 'date-picker',
|
||||
span: 1,
|
||||
props: { type: 'daterange', valueFormat: 'YYYY-MM-DD' },
|
||||
defaultValue: ['2024-11-12', '2024-12-12'],
|
||||
},
|
||||
},
|
||||
{ prop: 'operation', label: '操作', fixed: 'right', width: 330 },
|
||||
])
|
||||
|
||||
|
||||
const open = (textTitle: string) => {
|
||||
dialogVisible.value = true
|
||||
title.value = textTitle
|
||||
}
|
||||
|
||||
|
||||
defineExpose({ open })
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
width: {
|
||||
type: Number,
|
||||
default: 800,
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 744,
|
||||
},
|
||||
})
|
||||
|
||||
// 切换用户状态
|
||||
const changeStatus = async (row: User.ResUserList) => {
|
||||
await useHandleData(changeUserStatus, {
|
||||
id: row.id,
|
||||
status: row.status == 1 ? 0 : 1,
|
||||
}, `切换【${row.username}】用户状态`)
|
||||
proTable.value?.getTableList()
|
||||
}
|
||||
|
||||
// 删除用户信息
|
||||
const deleteAccount = async (params: User.ResUserList) => {
|
||||
|
||||
}
|
||||
// 重置用户密码
|
||||
const resetPass = async (params: User.ResUserList) => {
|
||||
|
||||
}
|
||||
|
||||
// 打开 drawer(新增、查看、编辑)
|
||||
const openDrawer = (title: string, row: Partial<User.ResUserList> = {}) => {
|
||||
}
|
||||
|
||||
</script>
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -1,169 +0,0 @@
|
||||
<!--单列-->
|
||||
<template>
|
||||
<el-dialog v-model='dialogVisible' :title='title' v-bind='dialogSmall'>
|
||||
<el-scrollbar>
|
||||
<el-form
|
||||
:model='form'
|
||||
:inline='false'
|
||||
label-width='auto'
|
||||
ref='formRuleRef'
|
||||
:rules='rules'
|
||||
>
|
||||
<el-form-item label='姓名' prop='username'>
|
||||
<el-input
|
||||
v-model='form.username'
|
||||
placeholder='请输入姓名'
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label='性别' prop='gender'>
|
||||
<el-radio-group v-model='form.gender'>
|
||||
<el-radio-button :label='0'>男</el-radio-button>
|
||||
<el-radio-button :label='1'>女</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label='年龄' prop='age'>
|
||||
<el-input
|
||||
v-model='form.age'
|
||||
placeholder='年龄'
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label='身份证号' prop='idCard'>
|
||||
<el-input
|
||||
v-model='form.idCard'
|
||||
placeholder='身份证号'
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label='邮箱' prop='email'>
|
||||
<el-input
|
||||
v-model='form.email'
|
||||
placeholder='邮箱'
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label='居住地址' prop='address'>
|
||||
<el-input
|
||||
v-model='form.address'
|
||||
placeholder='居住地址'
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
|
||||
<template #footer>
|
||||
<div class='dialog-footer'>
|
||||
<el-button @click='close()'>取消</el-button>
|
||||
<el-button type='primary' @click='confirmForm()'>确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup lang='ts'>
|
||||
import { dialogSmall } from '@/utils/elementBind'
|
||||
import { FormInstance, FormItemRule } from 'element-plus'
|
||||
|
||||
interface userForm {
|
||||
id?: string; //用户ID,作为唯一标识
|
||||
username: string; //用户名
|
||||
gender: number; // 性别
|
||||
age: number; // 年龄
|
||||
idCard: string; // 身份证
|
||||
email: string; // 邮箱
|
||||
address?: string; // 地址
|
||||
}
|
||||
|
||||
const form: Ref<userForm> = ref({
|
||||
username: '',
|
||||
gender: 0,
|
||||
age: 1,
|
||||
idCard: '',
|
||||
email: '',
|
||||
})
|
||||
|
||||
const formRuleRef = ref<FormInstance>()
|
||||
//定义校验规则
|
||||
const rules: Ref<Record<string, Array<FormItemRule>>> = ref({
|
||||
username: [{ required: true, message: '用户名必填!', trigger: 'blur' }],
|
||||
age: [
|
||||
{ required: true, message: '年龄必填!', trigger: 'blur' },
|
||||
// 指定正则,此处是数字正则
|
||||
{ pattern: /^[1-9][0-9]?$|^100$/, message: '年龄必须在1到100之间', trigger: 'blur' },
|
||||
],
|
||||
idCard: [
|
||||
{ required: true, message: '身份证必填!', trigger: 'blur' },
|
||||
// 指定正则,此处是身份证正则
|
||||
{ pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, message: '请输入正确的身份证号码', trigger: 'blur' },
|
||||
],
|
||||
email: [
|
||||
{ required: true, message: '邮箱必填!', trigger: 'blur' },
|
||||
// 指定校验类型
|
||||
{ type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] },
|
||||
],
|
||||
})
|
||||
|
||||
/**
|
||||
* 重置表单
|
||||
*/
|
||||
const resetForm = () => {
|
||||
form.value = {
|
||||
username: '',
|
||||
gender: 0,
|
||||
age: 1,
|
||||
idCard: '',
|
||||
email: '',
|
||||
address: '',
|
||||
}
|
||||
}
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const title = ref('单列弹出框')
|
||||
const open = (textTitle: string) => {
|
||||
dialogVisible.value = true
|
||||
title.value = textTitle
|
||||
}
|
||||
|
||||
// 关闭弹出框
|
||||
const close = () => {
|
||||
//重置表单内容
|
||||
//取消表单校验状态
|
||||
formRuleRef.value && formRuleRef.value.resetFields()
|
||||
dialogVisible.value = false
|
||||
resetForm()
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验表单数据
|
||||
* 数据没问题,提交数据,并根据业务情况请求新增接口还是修改接口
|
||||
*/
|
||||
const confirmForm = () => {
|
||||
ElMessage.info('业务数据提交')
|
||||
try {
|
||||
formRuleRef.value?.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
// 将表单数据转为json,发送到后端
|
||||
let confirmFormData = JSON.parse(JSON.stringify(form.value))
|
||||
|
||||
if ('是否新增') {
|
||||
// 执行新增接口
|
||||
} else {
|
||||
// 执行修改接口
|
||||
}
|
||||
} else {
|
||||
ElMessage.error('表单验证失败!')
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('验证过程中发生错误', error)
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
|
||||
</script>
|
||||
<style>
|
||||
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,127 +1,343 @@
|
||||
<template>
|
||||
|
||||
<div class="table-container">
|
||||
<el-table :data="tableData" :header-cell-style="{ textAlign: 'center' } " :cell-style="{ textAlign: 'center' }" style="width: 100%" >
|
||||
|
||||
<el-table-column prop="id" label="序号" width="70" />
|
||||
<el-table-column prop="updateTime" label="上送时刻" />
|
||||
<el-table-column prop="deviceName" label="设备名称" />
|
||||
<el-table-column prop="MonitorIdx" label="监测点序号" />
|
||||
|
||||
<div class="table-container table-main">
|
||||
<el-table :data="tableData"
|
||||
:header-cell-style="{ textAlign: 'center' } "
|
||||
:cell-style="{ textAlign: 'center' }"
|
||||
style="width: 100%"
|
||||
max-height="400px"
|
||||
:span-method="objectSpanMethod">
|
||||
<el-table-column prop="monitorNum" label="监测点序号" width="80"/>
|
||||
<el-table-column prop="desc" label="描述" width="90"/>
|
||||
<el-table-column label="电压通道" >
|
||||
<el-table-column prop="Ua" label="L1">
|
||||
|
||||
<el-table-column prop="Ua" label="A相">
|
||||
<el-table-column prop="aVuData" label="被检值(V)" width="100px">
|
||||
<template #default="scope">
|
||||
<el-icon v-if="scope.row.aVuData === '—'&& scope.row.loading" class="loading-box">
|
||||
<el-icon-loading />
|
||||
</el-icon>
|
||||
<span v-else>
|
||||
{{ scope.row.aVuData }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="aVuXi" label="检测结果" width="90px">
|
||||
<template #default="scope">
|
||||
<el-tooltip
|
||||
v-if="scope.row.aVuXi === '不合格'"
|
||||
class="item"
|
||||
effect="dark"
|
||||
placement="bottom-start"
|
||||
>
|
||||
<template #content>
|
||||
误差范围: {{ (-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4)+ 'V'}}<br/>
|
||||
误差值:{{ scope.row.aV + 'V'}}
|
||||
</template>
|
||||
<el-tag type="danger" class="tooltip-content">
|
||||
{{ scope.row.aVuXi }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
v-else-if="scope.row.aVuXi === '合格'"
|
||||
class="item"
|
||||
effect="dark"
|
||||
placement="bottom-start"
|
||||
>
|
||||
<template #content>
|
||||
误差范围: {{ (-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4)+ 'V'}}<br/>
|
||||
误差值:{{ scope.row.aV + 'V'}}
|
||||
</template>
|
||||
<el-tag type="success" class="tooltip-content">{{ scope.row.aVuXi }}</el-tag>
|
||||
</el-tooltip>
|
||||
<!-- <el-tag type="danger" v-if="scope.row.aVuXi === '不合格'">
|
||||
{{ scope.row.aVuXi }}
|
||||
</el-tag> -->
|
||||
<el-icon v-else-if="scope.row.aVuXi === '—'&& scope.row.loading" class="loading-box">
|
||||
<el-icon-loading />
|
||||
</el-icon>
|
||||
<!-- <span v-else>
|
||||
{{ scope.row.aVuXi }}
|
||||
</span> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Ub" label="L2">
|
||||
|
||||
<el-table-column prop="Ub" label="B相">
|
||||
<el-table-column prop="bVuData" label="被检值(V)" width="100px">
|
||||
<template #default="scope">
|
||||
<el-icon v-if="scope.row.bVuData === '—'&& scope.row.loading" class="loading-box">
|
||||
<el-icon-loading />
|
||||
</el-icon>
|
||||
<span v-else>
|
||||
{{ scope.row.bVuData }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bVuXi" label="检测结果" width="90px">
|
||||
<template #default="scope">
|
||||
<el-tooltip
|
||||
v-if="scope.row.bVuXi === '不合格'"
|
||||
class="item"
|
||||
effect="dark"
|
||||
placement="bottom-start"
|
||||
>
|
||||
<template #content>
|
||||
误差范围: {{ (-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4)+ 'V'}}<br/>
|
||||
误差值:{{ scope.row.bV + 'V'}}
|
||||
</template>
|
||||
<el-tag type="danger" class="tooltip-content">
|
||||
{{ scope.row.bVuXi }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
v-else-if="scope.row.bVuXi === '合格'"
|
||||
class="item"
|
||||
effect="dark"
|
||||
placement="bottom-start"
|
||||
>
|
||||
<template #content>
|
||||
误差范围: {{ (-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4)+ 'V'}}<br/>
|
||||
误差值:{{ scope.row.bV + 'V'}}
|
||||
</template>
|
||||
<el-tag type="success" class="tooltip-content">{{ scope.row.bVuXi }}</el-tag>
|
||||
</el-tooltip>
|
||||
<el-icon v-else-if="scope.row.bVuXi === '—'&& scope.row.loading" class="loading-box">
|
||||
<el-icon-loading />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Uc" label="L3">
|
||||
|
||||
<el-table-column prop="Uc" label="C相">
|
||||
<el-table-column prop="cVuData" label="被检值(V)" width="100px">
|
||||
<template #default="scope">
|
||||
<el-icon v-if="scope.row.cVuData === '—'&& scope.row.loading" class="loading-box">
|
||||
<el-icon-loading />
|
||||
</el-icon>
|
||||
<span v-else>
|
||||
{{ scope.row.cVuData }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="cVuXi" label="检测结果" width="90px">
|
||||
<template #default="scope">
|
||||
<el-tooltip
|
||||
v-if="scope.row.cVuXi === '不合格'"
|
||||
class="item"
|
||||
effect="dark"
|
||||
placement="bottom-start"
|
||||
>
|
||||
<template #content>
|
||||
误差范围: {{ (-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4)+ 'V'}}<br/>
|
||||
误差值:{{ scope.row.cV + 'V'}}
|
||||
</template>
|
||||
<el-tag type="danger" class="tooltip-content">
|
||||
{{ scope.row.cVuXi }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
v-else-if="scope.row.cVuXi === '合格'"
|
||||
class="item"
|
||||
effect="dark"
|
||||
placement="bottom-start"
|
||||
>
|
||||
<template #content>
|
||||
误差范围: {{ (-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4) + 'V'}}<br/>
|
||||
误差值:{{ scope.row.cV + 'V'}}
|
||||
</template>
|
||||
<el-tag type="success" class="tooltip-content">{{ scope.row.cVuXi }}</el-tag>
|
||||
</el-tooltip>
|
||||
<el-icon v-else-if="scope.row.cVuXi === '—'&& scope.row.loading" class="loading-box">
|
||||
<el-icon-loading />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column label="电流通道" >
|
||||
<el-table-column prop="Ia" label="L1">
|
||||
|
||||
<el-table-column prop="Ia" label="A相">
|
||||
<el-table-column prop="aIeData" label="被检值(A)" width="100px">
|
||||
<template #default="scope">
|
||||
<el-icon v-if="scope.row.aIeData === '—'&& scope.row.loading" class="loading-box">
|
||||
<el-icon-loading />
|
||||
</el-icon>
|
||||
<span v-else>
|
||||
{{ scope.row.aIeData }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="aIeXi" label="检测结果" width="90px">
|
||||
<template #default="scope">
|
||||
<el-tooltip
|
||||
v-if="scope.row.aIeXi === '不合格'"
|
||||
class="item"
|
||||
effect="dark"
|
||||
placement="bottom-start"
|
||||
>
|
||||
<template #content>
|
||||
误差范围: {{-0.5 + "%~" +0.5 + "%" }}<br/>
|
||||
误差值:{{ scope.row.aI + '%'}}
|
||||
</template>
|
||||
<el-tag type="danger" class="tooltip-content">
|
||||
{{ scope.row.aIeXi }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
v-else-if="scope.row.aIeXi === '合格'"
|
||||
class="item"
|
||||
effect="dark"
|
||||
placement="bottom-start"
|
||||
>
|
||||
<template #content>
|
||||
误差范围: {{ -0.5 + "%~" +0.5 + "%" }}<br/>
|
||||
误差值:{{ scope.row.aI + '%'}}
|
||||
</template>
|
||||
<el-tag type="success" class="tooltip-content">{{ scope.row.aIeXi }}</el-tag>
|
||||
</el-tooltip>
|
||||
<el-icon v-else-if="scope.row.aIeXi === '—'&& scope.row.loading" class="loading-box">
|
||||
<el-icon-loading />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Ib" label="L2">
|
||||
|
||||
<el-table-column prop="Ib" label="B相">
|
||||
<el-table-column prop="bIeData" label="被检值(A)" width="100px">
|
||||
<template #default="scope">
|
||||
<el-icon v-if="scope.row.bIeData === '—'&& scope.row.loading" class="loading-box">
|
||||
<el-icon-loading />
|
||||
</el-icon>
|
||||
<span v-else>
|
||||
{{ scope.row.bIeData }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bIeXi" label="检测结果" width="90px">
|
||||
<template #default="scope">
|
||||
<el-tooltip
|
||||
v-if="scope.row.bIeXi === '不合格'"
|
||||
class="item"
|
||||
effect="dark"
|
||||
placement="bottom-start"
|
||||
>
|
||||
<template #content>
|
||||
误差范围: {{ -0.5 + "%~" +0.5 + "%" }}<br/>
|
||||
误差值:{{ scope.row.bI + '%'}}
|
||||
</template>
|
||||
<el-tag type="danger" class="tooltip-content">
|
||||
{{ scope.row.bIeXi }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
v-else-if="scope.row.bIeXi === '合格'"
|
||||
class="item"
|
||||
effect="dark"
|
||||
placement="bottom-start"
|
||||
>
|
||||
<template #content>
|
||||
误差范围: {{ -0.5 + "%~" +0.5 + "%" }}<br/>
|
||||
误差值:{{ scope.row.bI + '%'}}
|
||||
</template>
|
||||
<el-tag type="success" class="tooltip-content">{{ scope.row.bIeXi }}</el-tag>
|
||||
</el-tooltip>
|
||||
<el-icon v-else-if="scope.row.bIeXi === '—'&& scope.row.loading" class="loading-box">
|
||||
<el-icon-loading />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Ic" label="L3">
|
||||
|
||||
<el-table-column prop="Ic" label="C相">
|
||||
<el-table-column prop="cIeData" label="被检值(A)" width="100px">
|
||||
<template #default="scope">
|
||||
<el-icon v-if="scope.row.cIeData === '—'&& scope.row.loading" class="loading-box">
|
||||
<el-icon-loading />
|
||||
</el-icon>
|
||||
<span v-else>
|
||||
{{ scope.row.cIeData }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="cIeXi" label="检测结果" width="90px">
|
||||
<template #default="scope">
|
||||
<el-tooltip
|
||||
v-if="scope.row.cIeXi === '不合格'"
|
||||
class="item"
|
||||
effect="dark"
|
||||
placement="bottom-start"
|
||||
>
|
||||
<template #content>
|
||||
误差范围: {{ -0.5 + "%~" +0.5 + "%" }}<br/>
|
||||
误差值:{{ scope.row.cI + '%'}}
|
||||
</template>
|
||||
<el-tag type="danger" class="tooltip-content">
|
||||
{{ scope.row.cIeXi }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
v-else-if="scope.row.cIeXi === '合格'"
|
||||
class="item"
|
||||
effect="dark"
|
||||
placement="bottom-start"
|
||||
>
|
||||
<template #content>
|
||||
误差范围: {{ -0.5 + "%~" +0.5 + "%" }}<br/>
|
||||
误差值:{{ scope.row.cI + '%'}}
|
||||
</template>
|
||||
<el-tag type="success" class="tooltip-content">{{ scope.row.cIeXi }}</el-tag>
|
||||
</el-tooltip>
|
||||
<el-icon v-else-if="scope.row.cIeXi === '—'&& scope.row.loading" class="loading-box">
|
||||
<el-icon-loading />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column label="校准结果">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.Result === '合格' ? 'success' : 'danger'">{{ scope.row.Result }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="ErrorSystemDialog">
|
||||
import{ElMessage, FormInstance,FormItemRule}from'element-plus'
|
||||
import { defineProps, defineEmits, reactive,watch,ref, Ref } from 'vue';
|
||||
import { dialogBig,dialogMiddle} from '@/utils/elementBind'
|
||||
//import IndicatorTypeDialog from "@/views/machine/errorSystem/components/IndicatorTypeDialog.vue"; // 导入子组件
|
||||
import {CirclePlus, Delete, EditPen,FolderOpened,CopyDocument} from '@element-plus/icons-vue'
|
||||
import { useDictStore } from '@/stores/modules/dict'
|
||||
const dictStore = useDictStore()
|
||||
const props = defineProps<{
|
||||
tableData: {
|
||||
id: string;
|
||||
updateTime: string;
|
||||
deviceName:string;
|
||||
MonitorIdx:number;
|
||||
Ua:number;
|
||||
Ub:number;
|
||||
Uc:number;
|
||||
Ia:number;
|
||||
Ib:number;
|
||||
Ic:number;
|
||||
Result: string;
|
||||
};
|
||||
}>();
|
||||
import { defineProps, type PropType } from 'vue';
|
||||
import { ElIcon, ElLoading, ElTag } from 'element-plus';
|
||||
import type { ChannelsTest } from '@/api/home/interface/channelsTest';
|
||||
import { number } from 'echarts';
|
||||
|
||||
interface Props {
|
||||
tableData: ChannelsTest.CoefficientVO[];
|
||||
big_V_loading: boolean;
|
||||
curV: number;
|
||||
}
|
||||
|
||||
// const tableData = ref([
|
||||
// {
|
||||
// id: '1',
|
||||
// updateTime: '2024-10-10 10:30:00',
|
||||
// deviceName:'被检设备1',
|
||||
// MonitorIdx: 1,
|
||||
// Ua:1.0003,
|
||||
// Ub:1.0003,
|
||||
// Uc:0.0096,
|
||||
// Ia:1.0003,
|
||||
// Ib:1.0003,
|
||||
// Ic:1.0008,
|
||||
// Result: '合格',
|
||||
// },
|
||||
// {
|
||||
// id: '2',
|
||||
// updateTime: '2024-10-10 10:30:00',
|
||||
// deviceName:'被检设备1',
|
||||
// MonitorIdx: 2,
|
||||
// Ua:1.0003,
|
||||
// Ub:1.0003,
|
||||
// Uc:0.0096,
|
||||
// Ia:1.0003,
|
||||
// Ib:1.0003,
|
||||
// Ic:1.0008,
|
||||
// Result: '合格',
|
||||
// },
|
||||
// {
|
||||
// id: '3',
|
||||
// updateTime: '2024-10-10 10:30:00',
|
||||
// deviceName:'被检设备1',
|
||||
// MonitorIdx: 3,
|
||||
// Ua:1.0003,
|
||||
// Ub:1.0003,
|
||||
// Uc:0.0096,
|
||||
// Ia:1.0003,
|
||||
// Ib:1.0003,
|
||||
// Ic:1.0008,
|
||||
// Result: '合格',
|
||||
// },
|
||||
// {
|
||||
// id: '4',
|
||||
// updateTime: '2024-10-10 10:30:00',
|
||||
// deviceName:'被检设备1',
|
||||
// MonitorIdx: 4,
|
||||
// Ua:1.0003,
|
||||
// Ub:1.0003,
|
||||
// Uc:0.0096,
|
||||
// Ia:1.0003,
|
||||
// Ib:1.0003,
|
||||
// Ic:1.0008,
|
||||
// Result: '合格',
|
||||
// },
|
||||
// ])
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
tableData: () => [],
|
||||
big_V_loading: false,
|
||||
curV: 0,
|
||||
});
|
||||
|
||||
function objectSpanMethod({ row, column, rowIndex, columnIndex }: { row: any, column: any, rowIndex: number, columnIndex: number }) {
|
||||
if (columnIndex === 0) {
|
||||
if (rowIndex % 4 === 0) {
|
||||
return {
|
||||
rowspan: 4,
|
||||
colspan: 1,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
rowspan: 0,
|
||||
colspan: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (columnIndex === 1) {
|
||||
if (rowIndex % 2 === 0) {
|
||||
return {
|
||||
rowspan: 2,
|
||||
colspan: 1,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
rowspan: 0,
|
||||
colspan: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@@ -157,4 +373,31 @@
|
||||
overflow-y: auto; /* 允许垂直滚动 */
|
||||
overflow-x: hidden; /* 隐藏水平滚动条 */
|
||||
}
|
||||
|
||||
/* 确保 el-icon-loading 的动画效果没有被覆盖 */
|
||||
.loading-box {
|
||||
animation: rotate 2s linear infinite;
|
||||
}
|
||||
|
||||
.icon-margin {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.icon-align {
|
||||
vertical-align: 0px;
|
||||
}
|
||||
|
||||
.tooltip-content {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
@keyframes rotate {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user