This commit is contained in:
oneao committed 2026-04-01 17:30:20 +08:00
1 parent 098fbfad0b
commit 4ef00e1d5d
24 files changed
+2461 -124

No files matched your search

-1
View File
@@ -1,5 +1,4 @@
{
"editor.cursorSmoothCaretAnimation": "on",
// Disable the default formatter, use eslint instead
"prettier.enable": false,
"editor.formatOnSave": false,
+2
View File
@@ -20,5 +20,7 @@ export default antfu({
'prefer-promise-reject-errors': 'off',
'unused-imports/no-unused-imports': 'warn',
'unused-imports/no-unused-vars': 'warn',
'prefer-const': 'off',
'no-eval': 'off',
},
})
+1 -1
View File
@@ -84,7 +84,7 @@
"dayjs": "^1.11.18",
"pinia": "^3.0.3",
"pinia-plugin-persistedstate": "^4.5.0",
"sard-uniapp": "^1.24.7",
"sard-uniapp": "^1.28.0",
"vue": "^3.5.21",
"wot-design-uni": "^1.13.0",
"z-paging": "^2.8.8"
+249 -79
View File
@@ -72,8 +72,8 @@ importers:
specifier: ^4.5.0
version: 4.5.0(pinia@3.0.3(typescript@5.8.3)(vue@3.5.22(typescript@5.8.3)))
sard-uniapp:
specifier: ^1.24.7
version: 1.24.7(@dcloudio/types@3.4.21)(vue@3.5.22(typescript@5.8.3))
specifier: ^1.28.0
version: 1.28.0(@dcloudio/types@3.4.21)(vue@3.5.22(typescript@5.8.3))
vue:
specifier: ^3.5.21
version: 3.5.22(typescript@5.8.3)
@@ -261,6 +261,10 @@ packages:
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
engines: {node: '>=6.9.0'}
'@babel/code-frame@7.29.0':
resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
engines: {node: '>=6.9.0'}
'@babel/compat-data@7.28.4':
resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==}
engines: {node: '>=6.9.0'}
@@ -273,6 +277,10 @@ packages:
resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==}
engines: {node: '>=6.9.0'}
'@babel/generator@7.29.1':
resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==}
engines: {node: '>=6.9.0'}
'@babel/helper-annotate-as-pure@7.27.3':
resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==}
engines: {node: '>=6.9.0'}
@@ -324,6 +332,10 @@ packages:
resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==}
engines: {node: '>=6.9.0'}
'@babel/helper-plugin-utils@7.28.6':
resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==}
engines: {node: '>=6.9.0'}
'@babel/helper-remap-async-to-generator@7.27.1':
resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==}
engines: {node: '>=6.9.0'}
@@ -348,6 +360,10 @@ packages:
resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
engines: {node: '>=6.9.0'}
'@babel/helper-validator-identifier@7.28.5':
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
engines: {node: '>=6.9.0'}
'@babel/helper-validator-option@7.27.1':
resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
engines: {node: '>=6.9.0'}
@@ -365,6 +381,11 @@ packages:
engines: {node: '>=6.0.0'}
hasBin: true
'@babel/parser@7.29.2':
resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==}
engines: {node: '>=6.0.0'}
hasBin: true
'@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1':
resolution: {integrity: sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==}
engines: {node: '>=6.9.0'}
@@ -434,6 +455,12 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-syntax-import-attributes@7.28.6':
resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-syntax-import-meta@7.10.4':
resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
peerDependencies:
@@ -498,6 +525,12 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-syntax-typescript@7.28.6':
resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-syntax-unicode-sets-regex@7.18.6':
resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==}
engines: {node: '>=6.9.0'}
@@ -835,14 +868,26 @@ packages:
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
engines: {node: '>=6.9.0'}
'@babel/template@7.28.6':
resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==}
engines: {node: '>=6.9.0'}
'@babel/traverse@7.28.4':
resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==}
engines: {node: '>=6.9.0'}
'@babel/traverse@7.29.0':
resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==}
engines: {node: '>=6.9.0'}
'@babel/types@7.28.4':
resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==}
engines: {node: '>=6.9.0'}
'@babel/types@7.29.0':
resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
engines: {node: '>=6.9.0'}
'@bcoe/v8-coverage@0.2.3':
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
@@ -1959,6 +2004,9 @@ packages:
'@types/node@20.19.18':
resolution: {integrity: sha512-KeYVbfnbsBCyKG8e3gmUqAfyZNcoj/qpEbHRkQkfZdKOBrU7QQ+BsTdfqLSWX9/m1ytYreMhpKvp+EZi3UFYAg==}
'@types/node@20.19.37':
resolution: {integrity: sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==}
'@types/prettier@2.7.3':
resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==}
@@ -1971,8 +2019,8 @@ packages:
'@types/yargs-parser@21.0.3':
resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==}
'@types/yargs@16.0.9':
resolution: {integrity: sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==}
'@types/yargs@16.0.11':
resolution: {integrity: sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==}
'@typescript-eslint/eslint-plugin@8.45.0':
resolution: {integrity: sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg==}
@@ -2287,6 +2335,11 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
acorn@8.16.0:
resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==}
engines: {node: '>=0.4.0'}
hasBin: true
address@1.2.2:
resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==}
engines: {node: '>= 10.0.0'}
@@ -2441,6 +2494,9 @@ packages:
brace-expansion@1.1.12:
resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
brace-expansion@1.1.13:
resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==}
brace-expansion@2.0.2:
resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
@@ -2592,8 +2648,8 @@ packages:
resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
collect-v8-coverage@1.0.2:
resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==}
collect-v8-coverage@1.0.3:
resolution: {integrity: sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==}
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
@@ -3286,6 +3342,10 @@ packages:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
get-intrinsic@1.3.0:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'}
get-intrinsic@1.3.1:
resolution: {integrity: sha512-fk1ZVEeOX9hVZ6QzoBNEC55+Ucqg4sTVwrVuigZhuRPESVFpMyXnd3sbXvPOwp7Y9riVyANiqhEuRF0G1aVSeQ==}
engines: {node: '>= 0.4'}
@@ -3705,8 +3765,8 @@ packages:
js-tokens@9.0.1:
resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
js-yaml@3.14.1:
resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
js-yaml@3.14.2:
resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==}
hasBin: true
js-yaml@4.1.0:
@@ -4050,6 +4110,9 @@ packages:
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
minimatch@3.1.5:
resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
minimatch@8.0.4:
resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==}
engines: {node: '>=16 || 14 >=14.17'}
@@ -4143,8 +4206,8 @@ packages:
nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
nwsapi@2.2.22:
resolution: {integrity: sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==}
nwsapi@2.2.23:
resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==}
nypm@0.5.4:
resolution: {integrity: sha512-X0SNNrZiGU8/e/zAB7sCTtdxWTMSIO73q+xuKgglm2Yvzwlo8UoC5FNySQFCvl84uPaeADkqHUZUkWy4aH4xOA==}
@@ -4301,6 +4364,10 @@ packages:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
picomatch@2.3.2:
resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==}
engines: {node: '>=8.6'}
picomatch@4.0.3:
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
engines: {node: '>=12'}
@@ -4591,6 +4658,11 @@ packages:
engines: {node: '>= 0.4'}
hasBin: true
resolve@1.22.11:
resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
engines: {node: '>= 0.4'}
hasBin: true
reusify@1.1.0:
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
@@ -4633,8 +4705,8 @@ packages:
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
sard-uniapp@1.24.7:
resolution: {integrity: sha512-QXk/zWH5j62VOUsaf8mSk0i8k/OMkUoSIqOTmxb7vpC+UpiJ5Uwypayb9HarlgStXpqIc3HmTOIG+2cNo+yFCA==}
sard-uniapp@1.28.0:
resolution: {integrity: sha512-hGvBbijLgsl+widSrM33TaTmZktAHlSYPlNeVOBTdk2LY8JU3lz/2/MnxsgFJ554kXfesLgjkOnSlS8dEeG+Hw==}
engines: {HBuilderX: ^3.6.0, uni-app: ^4.11, uni-app-x: ''}
peerDependencies:
'@dcloudio/types': ^3.4.8
@@ -4668,6 +4740,11 @@ packages:
engines: {node: '>=10'}
hasBin: true
semver@7.7.4:
resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
engines: {node: '>=10'}
hasBin: true
send@0.19.0:
resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==}
engines: {node: '>= 0.8.0'}
@@ -5375,6 +5452,12 @@ snapshots:
js-tokens: 4.0.0
picocolors: 1.1.1
'@babel/code-frame@7.29.0':
dependencies:
'@babel/helper-validator-identifier': 7.28.5
js-tokens: 4.0.0
picocolors: 1.1.1
'@babel/compat-data@7.28.4': {}
'@babel/core@7.28.4':
@@ -5405,6 +5488,14 @@ snapshots:
'@jridgewell/trace-mapping': 0.3.31
jsesc: 3.1.0
'@babel/generator@7.29.1':
dependencies:
'@babel/parser': 7.29.2
'@babel/types': 7.29.0
'@jridgewell/gen-mapping': 0.3.13
'@jridgewell/trace-mapping': 0.3.31
jsesc: 3.1.0
'@babel/helper-annotate-as-pure@7.27.3':
dependencies:
'@babel/types': 7.28.4
@@ -5479,6 +5570,8 @@ snapshots:
'@babel/helper-plugin-utils@7.27.1': {}
'@babel/helper-plugin-utils@7.28.6': {}
'@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
@@ -5508,6 +5601,8 @@ snapshots:
'@babel/helper-validator-identifier@7.27.1': {}
'@babel/helper-validator-identifier@7.28.5': {}
'@babel/helper-validator-option@7.27.1': {}
'@babel/helper-wrap-function@7.28.3':
@@ -5527,6 +5622,10 @@ snapshots:
dependencies:
'@babel/types': 7.28.4
'@babel/parser@7.29.2':
dependencies:
'@babel/types': 7.29.0
'@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
@@ -5569,22 +5668,22 @@ snapshots:
'@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.4)':
dependencies:
@@ -5596,6 +5695,11 @@ snapshots:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
@@ -5604,7 +5708,7 @@ snapshots:
'@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)':
dependencies:
@@ -5614,48 +5718,53 @@ snapshots:
'@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
'@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
@@ -6097,6 +6206,12 @@ snapshots:
'@babel/parser': 7.28.4
'@babel/types': 7.28.4
'@babel/template@7.28.6':
dependencies:
'@babel/code-frame': 7.29.0
'@babel/parser': 7.29.2
'@babel/types': 7.29.0
'@babel/traverse@7.28.4':
dependencies:
'@babel/code-frame': 7.27.1
@@ -6109,11 +6224,28 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@babel/traverse@7.29.0':
dependencies:
'@babel/code-frame': 7.29.0
'@babel/generator': 7.29.1
'@babel/helper-globals': 7.28.0
'@babel/parser': 7.29.2
'@babel/template': 7.28.6
'@babel/types': 7.29.0
debug: 4.4.3
transitivePeerDependencies:
- supports-color
'@babel/types@7.28.4':
dependencies:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.27.1
'@babel/types@7.29.0':
dependencies:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
'@bcoe/v8-coverage@0.2.3': {}
'@clack/core@0.5.0':
@@ -7135,7 +7267,7 @@ snapshots:
camelcase: 5.3.1
find-up: 4.1.0
get-package-type: 0.1.0
js-yaml: 3.14.1
js-yaml: 3.14.2
resolve-from: 5.0.0
'@istanbuljs/schema@0.1.3': {}
@@ -7143,7 +7275,7 @@ snapshots:
'@jest/console@27.5.1':
dependencies:
'@jest/types': 27.5.1
'@types/node': 20.19.18
'@types/node': 20.19.37
chalk: 4.1.2
jest-message-util: 27.5.1
jest-util: 27.5.1
@@ -7156,7 +7288,7 @@ snapshots:
'@jest/test-result': 27.5.1
'@jest/transform': 27.5.1
'@jest/types': 27.5.1
'@types/node': 20.19.18
'@types/node': 20.19.37
ansi-escapes: 4.3.2
chalk: 4.1.2
emittery: 0.8.1
@@ -7190,14 +7322,14 @@ snapshots:
dependencies:
'@jest/fake-timers': 27.5.1
'@jest/types': 27.5.1
'@types/node': 20.19.18
'@types/node': 20.19.37
jest-mock: 27.5.1
'@jest/fake-timers@27.5.1':
dependencies:
'@jest/types': 27.5.1
'@sinonjs/fake-timers': 8.1.0
'@types/node': 20.19.18
'@types/node': 20.19.37
jest-message-util: 27.5.1
jest-mock: 27.5.1
jest-util: 27.5.1
@@ -7215,9 +7347,9 @@ snapshots:
'@jest/test-result': 27.5.1
'@jest/transform': 27.5.1
'@jest/types': 27.5.1
'@types/node': 20.19.18
'@types/node': 20.19.37
chalk: 4.1.2
collect-v8-coverage: 1.0.2
collect-v8-coverage: 1.0.3
exit: 0.1.2
glob: 7.2.3
graceful-fs: 4.2.11
@@ -7249,7 +7381,7 @@ snapshots:
'@jest/console': 27.5.1
'@jest/types': 27.5.1
'@types/istanbul-lib-coverage': 2.0.6
collect-v8-coverage: 1.0.2
collect-v8-coverage: 1.0.3
'@jest/test-sequencer@27.5.1':
dependencies:
@@ -7284,8 +7416,8 @@ snapshots:
dependencies:
'@types/istanbul-lib-coverage': 2.0.6
'@types/istanbul-reports': 3.0.4
'@types/node': 20.19.18
'@types/yargs': 16.0.9
'@types/node': 20.19.37
'@types/yargs': 16.0.11
chalk: 4.1.2
'@jimp/bmp@0.10.3(@jimp/custom@0.10.3)':
@@ -7777,24 +7909,24 @@ snapshots:
'@types/babel__core@7.20.5':
dependencies:
'@babel/parser': 7.28.4
'@babel/types': 7.28.4
'@babel/parser': 7.29.2
'@babel/types': 7.29.0
'@types/babel__generator': 7.27.0
'@types/babel__template': 7.4.4
'@types/babel__traverse': 7.28.0
'@types/babel__generator@7.27.0':
dependencies:
'@babel/types': 7.28.4
'@babel/types': 7.29.0
'@types/babel__template@7.4.4':
dependencies:
'@babel/parser': 7.28.4
'@babel/types': 7.28.4
'@babel/parser': 7.29.2
'@babel/types': 7.29.0
'@types/babel__traverse@7.28.0':
dependencies:
'@babel/types': 7.28.4
'@babel/types': 7.29.0
'@types/debug@4.1.12':
dependencies:
@@ -7804,7 +7936,7 @@ snapshots:
'@types/graceful-fs@4.1.9':
dependencies:
'@types/node': 20.19.18
'@types/node': 20.19.37
'@types/istanbul-lib-coverage@2.0.6': {}
@@ -7828,6 +7960,10 @@ snapshots:
dependencies:
undici-types: 6.21.0
'@types/node@20.19.37':
dependencies:
undici-types: 6.21.0
'@types/prettier@2.7.3': {}
'@types/stack-utils@2.0.3': {}
@@ -7836,7 +7972,7 @@ snapshots:
'@types/yargs-parser@21.0.3': {}
'@types/yargs@16.0.9':
'@types/yargs@16.0.11':
dependencies:
'@types/yargs-parser': 21.0.3
@@ -8290,6 +8426,8 @@ snapshots:
acorn@8.15.0: {}
acorn@8.16.0: {}
address@1.2.2: {}
adm-zip@0.5.16: {}
@@ -8380,7 +8518,7 @@ snapshots:
babel-plugin-istanbul@6.1.1:
dependencies:
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-plugin-utils': 7.28.6
'@istanbuljs/load-nyc-config': 1.1.0
'@istanbuljs/schema': 0.1.3
istanbul-lib-instrument: 5.2.1
@@ -8390,8 +8528,8 @@ snapshots:
babel-plugin-jest-hoist@27.5.1:
dependencies:
'@babel/template': 7.27.2
'@babel/types': 7.28.4
'@babel/template': 7.28.6
'@babel/types': 7.29.0
'@types/babel__core': 7.20.5
'@types/babel__traverse': 7.28.0
@@ -8426,7 +8564,7 @@ snapshots:
'@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.4)
'@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.4)
'@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.4)
'@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.4)
'@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.28.4)
'@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.4)
'@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.4)
'@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.4)
@@ -8482,6 +8620,11 @@ snapshots:
balanced-match: 1.0.2
concat-map: 0.0.1
brace-expansion@1.1.13:
dependencies:
balanced-match: 1.0.2
concat-map: 0.0.1
brace-expansion@2.0.2:
dependencies:
balanced-match: 1.0.2
@@ -8639,7 +8782,7 @@ snapshots:
co@4.6.0: {}
collect-v8-coverage@1.0.2: {}
collect-v8-coverage@1.0.3: {}
color-convert@2.0.1:
dependencies:
@@ -8849,7 +8992,7 @@ snapshots:
es-set-tostringtag@2.1.0:
dependencies:
es-errors: 1.3.0
get-intrinsic: 1.3.1
get-intrinsic: 1.3.0
has-tostringtag: 1.0.2
hasown: 2.0.2
@@ -9410,6 +9553,19 @@ snapshots:
get-caller-file@2.0.5: {}
get-intrinsic@1.3.0:
dependencies:
call-bind-apply-helpers: 1.0.2
es-define-property: 1.0.1
es-errors: 1.3.0
es-object-atoms: 1.1.1
function-bind: 1.1.2
get-proto: 1.0.1
gopd: 1.2.0
has-symbols: 1.1.0
hasown: 2.0.2
math-intrinsics: 1.1.0
get-intrinsic@1.3.1:
dependencies:
async-function: 1.0.0
@@ -9464,7 +9620,7 @@ snapshots:
fs.realpath: 1.0.0
inflight: 1.0.6
inherits: 2.0.4
minimatch: 3.1.2
minimatch: 3.1.5
once: 1.4.0
path-is-absolute: 1.0.1
@@ -9635,7 +9791,7 @@ snapshots:
istanbul-lib-instrument@5.2.1:
dependencies:
'@babel/core': 7.28.4
'@babel/parser': 7.28.4
'@babel/parser': 7.29.2
'@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.2
semver: 6.3.1
@@ -9672,7 +9828,7 @@ snapshots:
'@jest/environment': 27.5.1
'@jest/test-result': 27.5.1
'@jest/types': 27.5.1
'@types/node': 20.19.18
'@types/node': 20.19.37
chalk: 4.1.2
co: 4.6.0
dedent: 0.7.0
@@ -9768,7 +9924,7 @@ snapshots:
'@jest/environment': 27.5.1
'@jest/fake-timers': 27.5.1
'@jest/types': 27.5.1
'@types/node': 20.19.18
'@types/node': 20.19.37
jest-mock: 27.5.1
jest-util: 27.5.1
jsdom: 16.7.0
@@ -9783,7 +9939,7 @@ snapshots:
'@jest/environment': 27.5.1
'@jest/fake-timers': 27.5.1
'@jest/types': 27.5.1
'@types/node': 20.19.18
'@types/node': 20.19.37
jest-mock: 27.5.1
jest-util: 27.5.1
@@ -9793,7 +9949,7 @@ snapshots:
dependencies:
'@jest/types': 27.5.1
'@types/graceful-fs': 4.1.9
'@types/node': 20.19.18
'@types/node': 20.19.37
anymatch: 3.1.3
fb-watchman: 2.0.2
graceful-fs: 4.2.11
@@ -9812,7 +9968,7 @@ snapshots:
'@jest/source-map': 27.5.1
'@jest/test-result': 27.5.1
'@jest/types': 27.5.1
'@types/node': 20.19.18
'@types/node': 20.19.37
chalk: 4.1.2
co: 4.6.0
expect: 27.5.1
@@ -9842,7 +9998,7 @@ snapshots:
jest-message-util@27.5.1:
dependencies:
'@babel/code-frame': 7.27.1
'@babel/code-frame': 7.29.0
'@jest/types': 27.5.1
'@types/stack-utils': 2.0.3
chalk: 4.1.2
@@ -9855,7 +10011,7 @@ snapshots:
jest-mock@27.5.1:
dependencies:
'@jest/types': 27.5.1
'@types/node': 20.19.18
'@types/node': 20.19.37
jest-pnp-resolver@1.2.3(jest-resolve@27.5.1):
optionalDependencies:
@@ -9880,7 +10036,7 @@ snapshots:
jest-pnp-resolver: 1.2.3(jest-resolve@27.5.1)
jest-util: 27.5.1
jest-validate: 27.5.1
resolve: 1.22.10
resolve: 1.22.11
resolve.exports: 1.1.1
slash: 3.0.0
@@ -9891,7 +10047,7 @@ snapshots:
'@jest/test-result': 27.5.1
'@jest/transform': 27.5.1
'@jest/types': 27.5.1
'@types/node': 20.19.18
'@types/node': 20.19.37
chalk: 4.1.2
emittery: 0.8.1
graceful-fs: 4.2.11
@@ -9924,7 +10080,7 @@ snapshots:
'@jest/types': 27.5.1
chalk: 4.1.2
cjs-module-lexer: 1.4.3
collect-v8-coverage: 1.0.2
collect-v8-coverage: 1.0.3
execa: 5.1.1
glob: 7.2.3
graceful-fs: 4.2.11
@@ -9942,16 +10098,16 @@ snapshots:
jest-serializer@27.5.1:
dependencies:
'@types/node': 20.19.18
'@types/node': 20.19.37
graceful-fs: 4.2.11
jest-snapshot@27.5.1:
dependencies:
'@babel/core': 7.28.4
'@babel/generator': 7.28.3
'@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.4)
'@babel/traverse': 7.28.4
'@babel/types': 7.28.4
'@babel/generator': 7.29.1
'@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.28.4)
'@babel/traverse': 7.29.0
'@babel/types': 7.29.0
'@jest/transform': 27.5.1
'@jest/types': 27.5.1
'@types/babel__traverse': 7.28.0
@@ -9968,18 +10124,18 @@ snapshots:
jest-util: 27.5.1
natural-compare: 1.4.0
pretty-format: 27.5.1
semver: 7.7.2
semver: 7.7.4
transitivePeerDependencies:
- supports-color
jest-util@27.5.1:
dependencies:
'@jest/types': 27.5.1
'@types/node': 20.19.18
'@types/node': 20.19.37
chalk: 4.1.2
ci-info: 3.9.0
graceful-fs: 4.2.11
picomatch: 2.3.1
picomatch: 2.3.2
jest-validate@27.5.1:
dependencies:
@@ -9994,7 +10150,7 @@ snapshots:
dependencies:
'@jest/test-result': 27.5.1
'@jest/types': 27.5.1
'@types/node': 20.19.18
'@types/node': 20.19.37
ansi-escapes: 4.3.2
chalk: 4.1.2
jest-util: 27.5.1
@@ -10002,7 +10158,7 @@ snapshots:
jest-worker@27.5.1:
dependencies:
'@types/node': 20.19.18
'@types/node': 20.19.37
merge-stream: 2.0.0
supports-color: 8.1.1
@@ -10039,7 +10195,7 @@ snapshots:
js-tokens@9.0.1: {}
js-yaml@3.14.1:
js-yaml@3.14.2:
dependencies:
argparse: 1.0.10
esprima: 4.0.1
@@ -10057,7 +10213,7 @@ snapshots:
jsdom@16.7.0:
dependencies:
abab: 2.0.6
acorn: 8.15.0
acorn: 8.16.0
acorn-globals: 6.0.0
cssom: 0.4.4
cssstyle: 2.3.0
@@ -10070,7 +10226,7 @@ snapshots:
http-proxy-agent: 4.0.1
https-proxy-agent: 5.0.1
is-potential-custom-element-name: 1.0.1
nwsapi: 2.2.22
nwsapi: 2.2.23
parse5: 6.0.1
saxes: 5.0.1
symbol-tree: 3.2.4
@@ -10200,7 +10356,7 @@ snapshots:
make-dir@4.0.0:
dependencies:
semver: 7.7.2
semver: 7.7.4
makeerror@1.0.12:
dependencies:
@@ -10560,6 +10716,10 @@ snapshots:
dependencies:
brace-expansion: 1.1.12
minimatch@3.1.5:
dependencies:
brace-expansion: 1.1.13
minimatch@8.0.4:
dependencies:
brace-expansion: 2.0.2
@@ -10632,7 +10792,7 @@ snapshots:
dependencies:
boolbase: 1.0.0
nwsapi@2.2.22: {}
nwsapi@2.2.23: {}
nypm@0.5.4:
dependencies:
@@ -10741,7 +10901,7 @@ snapshots:
parse-json@5.2.0:
dependencies:
'@babel/code-frame': 7.27.1
'@babel/code-frame': 7.29.0
error-ex: 1.3.4
json-parse-even-better-errors: 2.3.1
lines-and-columns: 1.2.4
@@ -10782,6 +10942,8 @@ snapshots:
picomatch@2.3.1: {}
picomatch@2.3.2: {}
picomatch@4.0.3: {}
pify@2.3.0: {}
@@ -11045,6 +11207,12 @@ snapshots:
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
resolve@1.22.11:
dependencies:
is-core-module: 2.16.1
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
reusify@1.1.0: {}
rfdc@1.4.1: {}
@@ -11100,7 +11268,7 @@ snapshots:
safer-buffer@2.1.2: {}
sard-uniapp@1.24.7(@dcloudio/types@3.4.21)(vue@3.5.22(typescript@5.8.3)):
sard-uniapp@1.28.0(@dcloudio/types@3.4.21)(vue@3.5.22(typescript@5.8.3)):
dependencies:
'@dcloudio/types': 3.4.21
vue: 3.5.22(typescript@5.8.3)
@@ -11129,6 +11297,8 @@ snapshots:
semver@7.7.2: {}
semver@7.7.4: {}
send@0.19.0:
dependencies:
debug: 2.6.9
@@ -11322,7 +11492,7 @@ snapshots:
dependencies:
'@istanbuljs/schema': 0.1.3
glob: 7.2.3
minimatch: 3.1.2
minimatch: 3.1.5
throat@6.0.2: {}
@@ -0,0 +1,236 @@
<script setup lang="ts">
</script>
<template>
<view class="overlay-center" style="pointer-events: none;">
<view class="boxes">
<view class="box">
<view />
<view />
<view />
<view />
</view>
<view class="box">
<view />
<view />
<view />
<view />
</view>
<view class="box">
<view />
<view />
<view />
<view />
</view>
<view class="box">
<view />
<view />
<view />
<view />
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
.boxes {
--size: 32px;
--duration: 800ms;
position: relative;
width: calc(var(--size) * 3);
height: calc(var(--size) * 2);
margin-top: calc(var(--size) * 1.5 * -1);
transform: rotateX(60deg) rotateZ(45deg) rotateY(0deg) translateZ(0px);
transform-origin: 50% 50%;
transform-style: preserve-3d;
}
.overlay-center {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.boxes .box {
position: absolute;
top: 0;
left: 0;
width: var(--size);
height: var(--size);
transform-style: preserve-3d;
}
.boxes .box:nth-child(1) {
transform: translate(100%, 0);
-webkit-animation: box1 var(--duration) linear infinite;
animation: box1 var(--duration) linear infinite;
}
.boxes .box:nth-child(2) {
transform: translate(0, 100%);
-webkit-animation: box2 var(--duration) linear infinite;
animation: box2 var(--duration) linear infinite;
}
.boxes .box:nth-child(3) {
transform: translate(100%, 100%);
-webkit-animation: box3 var(--duration) linear infinite;
animation: box3 var(--duration) linear infinite;
}
.boxes .box:nth-child(4) {
transform: translate(200%, 0);
-webkit-animation: box4 var(--duration) linear infinite;
animation: box4 var(--duration) linear infinite;
}
.boxes .box > view {
--background: #5c8df6;
--top: auto;
--right: auto;
--bottom: auto;
--left: auto;
--translateZ: calc(var(--size) / 2);
--rotateY: 0deg;
--rotateX: 0deg;
position: absolute;
top: var(--top);
right: var(--right);
bottom: var(--bottom);
left: var(--left);
width: 100%;
height: 100%;
background: var(--background);
transform: rotateY(var(--rotateY)) rotateX(var(--rotateX)) translateZ(var(--translateZ));
}
.boxes .box > view:nth-child(1) {
--top: 0;
--left: 0;
}
.boxes .box > view:nth-child(2) {
--background: #145af2;
--right: 0;
--rotateY: 90deg;
}
.boxes .box > view:nth-child(3) {
--background: #447cf5;
--rotateX: -90deg;
}
.boxes .box > view:nth-child(4) {
--background: #dbe3f4;
--top: 0;
--left: 0;
--translateZ: calc(var(--size) * 3 * -1);
}
@-webkit-keyframes box1 {
0%,
50% {
transform: translate(100%, 0);
}
100% {
transform: translate(200%, 0);
}
}
@keyframes box1 {
0%,
50% {
transform: translate(100%, 0);
}
100% {
transform: translate(200%, 0);
}
}
@-webkit-keyframes box2 {
0% {
transform: translate(0, 100%);
}
50% {
transform: translate(0, 0);
}
100% {
transform: translate(100%, 0);
}
}
@keyframes box2 {
0% {
transform: translate(0, 100%);
}
50% {
transform: translate(0, 0);
}
100% {
transform: translate(100%, 0);
}
}
@-webkit-keyframes box3 {
0%,
50% {
transform: translate(100%, 100%);
}
100% {
transform: translate(0, 100%);
}
}
@keyframes box3 {
0%,
50% {
transform: translate(100%, 100%);
}
100% {
transform: translate(0, 100%);
}
}
@-webkit-keyframes box4 {
0% {
transform: translate(200%, 0);
}
50% {
transform: translate(200%, 100%);
}
100% {
transform: translate(100%, 100%);
}
}
@keyframes box4 {
0% {
transform: translate(200%, 0);
}
50% {
transform: translate(200%, 100%);
}
100% {
transform: translate(100%, 100%);
}
}
</style>
@@ -0,0 +1,647 @@
<script lang="ts" setup>
import { toast } from 'sard-uniapp'
import { loaddataApi, loaddatabysqlApi } from '@/request/api'
import { useUserStore } from '@/store'
import { jsonToString } from '@/utils/common'
import { saveObjectHelper } from '@/utils/save'
import { getCurrentDateTimeWithSeconds } from '@/utils/time'
const props = defineProps({
componentData: {
type: null,
},
})
const emits = defineEmits(['success'])
const visible = defineModel({
type: Boolean,
default: false,
})
const userStore = useUserStore()
const loading = ref(true)
const formRef = ref()
const auditData = ref({
showSelect: true,
selectSearchCondition: '',
toShUsername: '',
toShUserid: '',
shMemo: '',
})
const shsetdatas = ref<any[]>([])
const midAuditShData = ref<{
state: string
shlevel: number
rowdata: any
}>({
state: '',
shlevel: 0,
rowdata: {},
})
const midAuditBhData = ref<{
now_level: number
ywownerid: string
nowstate: string
}>({
ywownerid: '',
nowstate: '',
now_level: 0,
})
async function handleAfterEnter() {
console.log('===after enter===')
loading.value = true
if (props.componentData.row === null || props.componentData.moduleId === '' || props.componentData.saveTable === '') {
toast.fail('传递参数有误,请联系管理人员!')
return
}
const req1 = await loaddataApi({
viewname: 'sh_b_set',
searchcondition: `b_module_id = '${props.componentData.moduleId}'`,
orderfield: 'b_level',
soption: '',
})
shsetdatas.value = req1.data
if (req1.data.length === 0) {
handleNoLevelSh()
}
else {
if (props.componentData.state === '审核通过') {
handleLevelSh()
}
else if (props.componentData.state === '审核驳回') {
handleLevelBh()
}
}
}
async function handleNoLevelSh() {
const { state, saveTable, moduleId, row } = props.componentData
let canuse_state = []
if (state === '送审') {
canuse_state = ['草拟', '审核驳回', '']
}
if (state === '归档') {
canuse_state = ['审核通过', '完成']
}
let subtable = []
let subinsertvalue = []
let subupdatevalue = []
let subdelvalue = []
let keyid = []
let logvalues = []
let LogArray = []
let updateRows = []
let updateFeeData = []
subtable.push(saveTable)
keyid.push('b_id')
subdelvalue.push('[]')
subinsertvalue.push('[]')
if (canuse_state.length === 0 || canuse_state.includes(row.b_state)) {
if (['cw_zdorder', 'cw_zdorder_f'].includes(moduleId)) {
if (state === '审核通过') {
// 暂时不做处理
}
if (state === '审核驳回') {
let sql = `select top 1 * from bs_business_cw where mx_zdorderid ='${row.b_id}' and (isnull(mx_invoiceid,'')<>'' or isnull(mx_sumamount,0)<>0)`
await loaddatabysqlApi({
sql,
orderfield: 'subid',
soption: '',
}).then((res) => {
if (res.data.length > 0) {
toast.fail('驳回失败!费用项已销账或开票!')
}
})
}
}
const updateObj = {
b_id: row.b_id,
b_state: state,
}
const oldState = row.b_state
let OpContent = `审核状态:${oldState}->${state}`
let logoldData = `审核状态:${oldState}`
let lognewData = `审核状态:${state}`
updateRows.push(updateObj)
LogArray.push({
OpType: state,
ModuleID: moduleId,
RecordID: row.b_id,
viewsubtable: saveTable,
OpContent,
modify_b: logoldData,
modify_h: lognewData,
})
}
else {
toast.fail(`只有${canuse_state.join(',')}的记录才能${state}!`)
}
if (updateRows.length > 0) {
subupdatevalue.push(jsonToString(updateRows))
logvalues.push(jsonToString(LogArray))
if (updateFeeData.length > 0) {
subtable.push('bs_business_cw')
keyid.push('subid')
subdelvalue.push('[]')
subinsertvalue.push('[]')
subupdatevalue.push(jsonToString(updateFeeData))
}
await saveObjectHelper({
tables: subtable,
insertValues: subinsertvalue,
delValues: subdelvalue,
updateValues: subupdatevalue,
keys: keyid,
logValues: logvalues,
}).then((data) => {
if (data === 'OK') {
handleCloseDialog()
toast.success(`${state}成功!`)
}
})
}
}
async function handleLevelSh() {
const { userid } = userStore.userInfo
const { saveTable, moduleId, row } = props.componentData
const ywid = row.b_id
let rowdata: any = {}
await loaddataApi({
viewname: saveTable,
searchcondition: `b_id='${ywid}'`,
orderfield: 'b_id',
soption: '',
}).then((res) => {
if (res.data.length === 0) {
toast.fail('当前业务单不存在')
handleCloseDialog()
return
}
rowdata = res.data[0]
})
let ywownerid = rowdata.b_owner_id
let shrecords = []
await loaddataApi({
viewname: 'sh_record',
searchcondition: `b_dj_id='${ywid}' and b_module_id='${moduleId}'`,
orderfield: 'b_id desc',
soption: '',
}).then((res) => {
if (res.data.length === 0) {
toast.fail('没有待审记录')
handleCloseDialog()
return
}
shrecords = res.data
})
let now_level = shrecords[0].b_level
let shlevel: any = Number.parseInt(now_level) + 1
let dsh_useid = shrecords[0].b_tosh_useid
let can_sh = false
let can_nextsh = false
let level_userid = []
if (dsh_useid !== userid) {
toast.fail('你没有该票业务的审批权限')
handleCloseDialog()
return
}
for (const item of shsetdatas.value) {
if (Number(item.b_level) === shlevel && item.b_user_id === dsh_useid) {
can_sh = true
}
if (Number(item.b_level) === Number.parseInt(shlevel) + 1) {
can_nextsh = true
level_userid.push(item.b_user_id)
}
}
if (!can_sh) {
toast.fail('你没有该票业务的审批权限')
handleCloseDialog()
return
}
midAuditShData.value.shlevel = shlevel
let sh_state = '审核通过'
let xxx = ['一', '二', '三', '四', '五', '六', '七', '八']
if (can_nextsh) {
sh_state = `${xxx[now_level]}审通过`
}
midAuditShData.value.state = sh_state
midAuditShData.value.rowdata = rowdata
let str_leveluserid = level_userid.map(item => `'${item}'`).join(',')
let searchcondition = `b_id in (${str_leveluserid})`
auditData.value.selectSearchCondition = searchcondition
if (level_userid.length === 1) {
auditData.value.toShUserid = level_userid[0]
auditData.value.showSelect = false
await loadShUserName(level_userid[0])
}
if (level_userid.length === 0) {
auditData.value.toShUserid = ywownerid
auditData.value.showSelect = false
await loadShUserName(ywownerid)
}
loading.value = false
}
async function loadShUserName(userid) {
if (!userid)
return
try {
const res = await loaddatabysqlApi({
sql: `select b_name from b_user where b_id = '${userid}'`,
soption: '',
orderfield: '',
})
const name = res?.data?.[0]?.b_name
auditData.value.toShUsername = name || userid
}
catch (err) {
console.error('获取审核人名称失败:', err)
auditData.value.toShUsername = userid
}
}
// 驳回
async function handleLevelBh() {
const { userid } = userStore.userInfo
const { saveTable, moduleId, row } = props.componentData
const ywid = row.b_id
let rowdata: any = {}
await loaddataApi({
viewname: saveTable,
searchcondition: `b_id='${ywid}'`,
orderfield: 'b_id',
soption: '',
}).then((res) => {
if (res.data.length === 0) {
toast.fail('当前业务单不存在')
handleCloseDialog()
return
}
rowdata = res.data[0]
})
let ywownerid = rowdata.b_owner_id
let nowstate = rowdata.b_state
if (nowstate === '审核驳回') {
toast.fail('已驳回!请检查!')
return false
}
let shrecords = []
let now_level = 0
await loaddataApi({
viewname: 'sh_record',
searchcondition: `b_dj_id='${ywid}' and b_module_id='${moduleId}'`,
orderfield: 'b_id',
soption: '',
}).then((res) => {
shrecords = res.data
})
if (shrecords.length === 0) {
await loaddataApi({
viewname: 'sh_b_set',
searchcondition: `b_module_id='${moduleId}' and b_user_id='${userid}'`,
orderfield: 'b_level',
soption: '',
}).then((res) => {
if (res.data.length === 0) {
toast.fail('你没有该票业务的驳回权限')
handleCloseDialog()
}
})
}
else {
now_level = shrecords[0].b_level
let dsh_useid = shrecords[0].b_tosh_useid
let sh_userid = shrecords[0].b_user_id
if (dsh_useid !== userid && sh_userid !== userid && now_level > 0) {
toast.fail('你没有该票业务的驳回权限')
handleCloseDialog()
return false
}
if (nowstate === '送审' && dsh_useid !== userid) {
toast.fail('你没有该票业务的驳回权限')
handleCloseDialog()
return false
}
}
auditData.value.toShUserid = ywownerid
auditData.value.showSelect = false
await loadShUserName(ywownerid)
midAuditBhData.value = {
ywownerid,
nowstate,
now_level,
}
loading.value = false
}
async function handleBeforeClose(type: string) {
if (type !== 'confirm')
return true
if (props.componentData.state === '审核通过') {
return await handleConfirmSh()
}
else if (props.componentData.state === '审核驳回') {
return await handleConfirmBh()
}
return true
}
async function handleConfirmSh() {
if (auditData.value.toShUserid === '') {
toast.fail('请指定审批人')
return false
}
if (midAuditShData.value.rowdata === undefined) {
return false
}
try {
loading.value = true
const { userid } = userStore.userInfo
const { rowdata, shlevel, state } = midAuditShData.value
const { saveTable, moduleId } = props.componentData
let subtable = []
let subinsertvalue = []
let subupdatevalue = []
let subdelvalue = []
let keyid = []
let logvalues = []
let updateRows = []
let LogArray = []
let insert_sh_records = []
let inputdatetime = getCurrentDateTimeWithSeconds()
let oldstate = rowdata.b_state
let obj: any = { b_id: rowdata.b_id, b_state: state }
if (state === '审核通过') {
obj.mx_shdate = inputdatetime
obj.mx_shman_id = userid
}
updateRows.push(obj)
let OpContent = `审核状态:${oldstate}->${state}`
let logoldData = `审核状态:${oldstate}`
let lognewData = `审核状态:${state}`
LogArray.push({ OpType: '修改', ModuleID: moduleId, RecordID: rowdata.b_id, viewsubtable: saveTable, OpContent, modify_b: logoldData, modify_h: lognewData })
insert_sh_records.push({
b_module_id: moduleId,
b_user_id: userid,
b_level: shlevel,
b_name: state,
b_dj_id: rowdata.b_id,
b_sh: '1',
b_sh_date: inputdatetime,
b_sh_memo: auditData.value.shMemo,
b_tosh_useid: auditData.value.toShUserid,
})
if (updateRows.length > 0) {
subtable.length = 0
subtable.push(saveTable)
keyid.push('b_id')
subdelvalue.push('[]')
subinsertvalue.push('[]')
subupdatevalue.push(jsonToString(updateRows))
logvalues.push(jsonToString(LogArray))
subtable.push('sh_record')
keyid.push('b_id')
subdelvalue.push('[]')
subinsertvalue.push(jsonToString(insert_sh_records))
subupdatevalue.push('[]')
logvalues.push('[]')
const sResult = await saveObjectHelper({ tables: subtable, insertValues: subinsertvalue, delValues: subdelvalue, updateValues: subupdatevalue, keys: keyid, logValues: logvalues })
if (sResult === 'OK') {
toast.success(`${state}成功!`)
emits('success')
return true
}
}
}
catch (e) {
toast.fail('操作失败')
return false
}
return false
}
async function handleConfirmBh() {
const { now_level, ywownerid, nowstate } = midAuditBhData.value
const { state, saveTable, moduleId, row } = props.componentData
const { userid } = userStore.userInfo
const ywid = row.b_id
let subtable = []
let subinsertvalue = []
let subupdatevalue = []
let subdelvalue = []
let keyid = []
let logvalues = []
let updateRows = []
let LogArray = []
let insert_sh_records = []
let inputdatetime = getCurrentDateTimeWithSeconds()
let obj: any = { b_id: ywid, b_state: state }
if (state === '审核驳回') {
obj.mx_shdate = ''
obj.mx_shman_id = ''
}
updateRows.push(obj)
let OpContent = `审核状态:${nowstate}->${state}`
let logoldData = `审核状态:${nowstate}`
let lognewData = `审核状态:${state}`
LogArray.push({ OpType: '修改', ModuleID: moduleId, RecordID: ywid, viewsubtable: saveTable, OpContent, modify_b: logoldData, modify_h: lognewData })
insert_sh_records.push({
b_module_id: moduleId,
b_user_id: userid,
b_level: now_level,
b_name: state,
b_dj_id: ywid,
b_sh: '0',
b_sh_date: inputdatetime,
b_sh_memo: auditData.value.shMemo,
b_tosh_useid: ywownerid,
})
if (updateRows.length > 0) {
subtable.length = 0
subtable.push(saveTable)
keyid.push('b_id')
subdelvalue.push('[]')
subinsertvalue.push('[]')
subupdatevalue.push(jsonToString(updateRows))
logvalues.push(jsonToString(LogArray))
subtable.push('sh_record')
keyid.push('b_id')
subdelvalue.push('[]')
subinsertvalue.push(jsonToString(insert_sh_records))
subupdatevalue.push('[]')
logvalues.push('[]')
const sResult = await saveObjectHelper({
tables: subtable,
insertValues: subinsertvalue,
delValues: subdelvalue,
updateValues: subupdatevalue,
keys: keyid,
logValues: logvalues,
})
if (sResult === 'OK') {
toast.success(`${state}成功!`)
emits('success')
return true
}
}
}
function handleAfterClose() {
loading.value = true
auditData.value = {
showSelect: true,
selectSearchCondition: '',
toShUserid: '',
toShUsername: '',
shMemo: '',
}
shsetdatas.value = []
midAuditShData.value = {
state: '',
shlevel: 0,
rowdata: {},
}
midAuditBhData.value = {
ywownerid: '',
nowstate: '',
now_level: 0,
}
}
function handleCloseDialog() {
visible.value = false
}
</script>
<template>
<sar-dialog
v-model:visible="visible"
popup-style="top: 50%"
:title="props.componentData.state"
button-type="text"
:before-close="handleBeforeClose"
@after-enter="handleAfterEnter"
@after-leave="handleAfterClose"
>
<scroll-view
style="max-height: 60vh; margin-top: 1px; margin-bottom: 16rpx"
scroll-y
>
<view v-if="loading" class="dialog-loading">
<sar-loading vertical>
加载中...
</sar-loading>
</view>
<sar-form v-else ref="formRef" :model="auditData" label-width="150rpx" label-align="start" star-position="right">
<sar-form-item
v-if="auditData.showSelect"
name="toShUserid"
label="送报审批人"
>
<picker-select-input
v-model:label="auditData.toShUsername"
v-model:value="auditData.toShUserid"
:searchcondition="auditData.selectSearchCondition"
search-type="ex"
viewname="b_user"
label-field="b_name"
value-field="b_id"
field1="b_id"
field2="b_name"
/>
</sar-form-item>
<sar-form-item
name="shMemo"
label="审核意见"
>
<sar-input v-model="auditData.shMemo" type="textarea" inlaid placeholder="请输入审核意见" />
</sar-form-item>
</sar-form>
</scroll-view>
</sar-dialog>
</template>
<style lang="scss" scoped>
.dialog-loading {
display: flex;
justify-content: center;
align-items: center;
height: 200rpx;
}
</style>
@@ -0,0 +1,38 @@
import { onMounted, ref } from 'vue'
export function useDeviceInfo() {
const isMobile = ref(false)
const screenWidth = ref(0)
// 判断是否为手机
function checkIsMobile() {
const ua = navigator.userAgent || ''
const isPhoneUA = /Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua)
const isMobileViewport = window.matchMedia('(max-width: 767px)').matches
// 平板 / iPad / 电脑都算 PC
isMobile.value = isPhoneUA && isMobileViewport
}
onMounted(() => {
// 首先用 UA + 媒体查询判断
checkIsMobile()
// 兜底:uni.getSystemInfo 获取屏幕宽度
if (typeof uni !== 'undefined' && uni.getSystemInfo) {
uni.getSystemInfo({
success: (res) => {
screenWidth.value = res.screenWidth
},
})
}
else {
screenWidth.value = window.innerWidth
}
// 可选:监听窗口大小变化
window.addEventListener('resize', checkIsMobile)
})
return { isMobile, screenWidth }
}
@@ -0,0 +1,11 @@
<script lang="ts" setup>
</script>
<template>
<view class="" />
</template>
<style lang="scss" scoped>
</style>
@@ -0,0 +1,487 @@
<script setup lang="ts">
import { toast } from 'sard-uniapp'
import { ref } from 'vue'
import ShDialog from '@/components/sh-dialog/index.vue'
import { useDeviceInfo } from '@/hooks/useDeviceInfo'
import { loaddataApi, searchdatapageindexApi } from '@/request/api'
import { useUserStore } from '@/store'
import { useCountsStore } from '@/store/counts'
import { groupFieldsBySpan } from '@/utils/common'
const countsStore = useCountsStore()
const userStore = useUserStore()
const { isMobile } = useDeviceInfo()
const auditComponentData = ref({
moduleId: 'cw_zdorder_f',
saveTable: 'cw_zdorder',
state: '',
row: null,
})
const pagingRef = ref<any>(null)
const dataList = ref<any[]>([])
const modLevelList = ref<any[]>([])
const showShDialog = ref(false)
// 自定义 tabs
const tabList = computed(() => [
{ name: '待审', count: countsStore.fukuan.v_dsh || 0 },
{ name: '已处理', count: countsStore.fukuan.v_ash || 0 },
{ name: '全部', count: countsStore.fukuan.all_cnt || 0 },
])
const activeTab = ref(tabList.value[0])
const itemFields = [
{ label: '账单日期', value: item => item.b_date, span: 12 },
{ label: '申请人', value: item => item.v_ownername, span: 6 },
{ label: '结算单位', value: item => item.v_dwname, span: 6 },
{ label: '应付RMB', value: item => item.yfrmb, span: 6 },
{ label: '应付USD', value: item => item.yfusd, span: 6 },
{ label: '未付RMB', value: item => item.notfrmb, span: 6 },
{ label: '未付USD', value: item => item.notfusd, span: 6 },
]
const groupedFields = groupFieldsBySpan(itemFields)
// 搜索关键字
const searchValue = ref('')
onShow(async () => {
await loadModLevelList()
// await pagingRef.value?.reload()
countsStore.loadTaskCounts(['fukuan'])
})
async function loadModLevelList() {
await loaddataApi({
viewname: 'v_sh_b_set',
searchcondition: `b_user_id='${userStore.userInfo.userid}'`,
orderfield: 'b_level',
soption: '',
}).then((res) => {
modLevelList.value = res.data.filter(item => item.b_module_id === 'cw_zdorder_f')
console.log(modLevelList.value)
})
}
// 切换 tab
function switchTab(tab: any) {
activeTab.value = tab
pagingRef.value.reload()
}
// 搜索
function handleSearch() {
pagingRef.value.reload()
}
function getTagType(state) {
switch (state) {
case '审核通过':
return 'success'
case '草拟':
return 'info'
case '审核驳回':
return 'danger'
default:
return 'primary'
}
}
// 分页请求
async function queryList(pageNo: number, pageSize: number) {
toast.loading('正在加载中')
const userid = userStore.userInfo.userid
let sql = '2 > 1 '
let mlvSearch = ''
let slevel = ''
for (let i in modLevelList.value) {
let item = modLevelList.value[i]
slevel = item.b_level
let viewname = item.b_ViewTable
let condition = item.b_condition
let j = Number.parseInt(slevel) - 1
if (mlvSearch !== '') {
mlvSearch = `${mlvSearch} or `
}
mlvSearch = `${mlvSearch}(b_module_id = '${item.b_module_id}'`
if (viewname !== '' && condition !== '') {
mlvSearch = `${mlvSearch} and b_id in (select b_id from ${viewname} where ${condition})`
}
let canlevel = ` and b_level in('${j}','${slevel}')`
if (activeTab.value.name === '待审') {
canlevel = ` and b_level = '${j}'`
}
if (activeTab.value.name === '已处理') {
canlevel = ` and b_level = '${slevel}'`
}
if (canlevel !== '') {
mlvSearch = mlvSearch + canlevel
}
mlvSearch = `${mlvSearch})`
}
if (mlvSearch) {
sql = `${sql} and (${mlvSearch})`
}
if (searchValue.value) {
sql = `${sql} and b_id like '%${searchValue.value}%'`
}
searchdatapageindexApi({
viewname: 'v_sh_recorddata',
searchcondition: sql,
userid,
page: pageNo,
rows: pageSize,
orderfield: 'b_ss_date desc',
})
.then((res) => {
const { rows, _total } = res.data
let idList = []
rows.forEach((row) => {
idList.push(row.b_id)
})
let sql2 = '2 > 1'
if (idList.length > 0) {
let idString = idList.map(id => `'${id}'`).join(',')
sql2 = `b_id IN (${idString})`
}
else {
sql2 = `b_id IN (NULL)`
}
loaddataApi({
viewname: 'v_cw_order_f',
searchcondition: sql2,
orderfield: 'b_date desc',
soption: '',
}).then((res) => {
let rows2 = res.data
rows2.forEach((row) => {
if (row.b_id) {
let slevel: string | number = ''
let cansh = false
let canbh = false
let bModuleId = ''
let bLevel: string | number = ''
const foundItem = rows.find(item => item.b_id === row.b_id)
if (foundItem) {
bModuleId = foundItem.b_module_id
bLevel = foundItem.b_level
row.b_module_id = bModuleId
}
for (const modLevel of modLevelList.value) {
if (modLevel.b_module_id === bModuleId) {
slevel = modLevel.b_level
slevel = Number.parseInt(slevel as string)
if (Number.isNaN(slevel)) {
slevel = 0
}
let j = slevel - 1
if (bLevel === j) {
cansh = true
}
if (bLevel === slevel) {
canbh = true
}
}
}
if (canbh || cansh) {
if (cansh) {
row.tongGuoButton = true
row.boHuiButton = true
}
else if (canbh) {
row.tongGuoButton = false
row.boHuiButton = true
}
}
else {
row.tongGuoButton = false
row.boHuiButton = false
}
}
})
if (rows) {
pagingRef.value.complete(rows2)
}
})
})
.finally(() => {
toast.hide()
})
}
async function handleApproval(item: any, state: string) {
auditComponentData.value.row = item
auditComponentData.value.state = state
showShDialog.value = true
}
function handleShSuccess() {
pagingRef.value.reload()
countsStore.loadTaskCounts(['fukuan'])
}
function handleToProcess(item) {
uni.navigateTo({
url: `/pages-sub/process/index?b_id=${item.b_id}&b_module_id=${item.b_module_id}&v_modulename=付款申请`,
})
}
</script>
<template>
<view>
<z-paging ref="pagingRef" v-model="dataList" auto-show-back-to-top @query="queryList">
<template #top>
<sar-search
v-model="searchValue"
placeholder="业务单号"
@search="handleSearch"
/>
<view class="tabs">
<view
v-for="tab in tabList"
:key="tab.name"
class="tabs__item"
:class="{ 'tabs__item--active': activeTab.name === tab.name }"
@click="switchTab(tab)"
>
<sar-badge v-if="tab.count > 0" :value="tab.count">
{{ tab.name }}
</sar-badge>
<text v-else>
{{ tab.name }}
</text>
</view>
</view>
</template>
<!-- 列表内容 -->
<view
v-for="(item, index) in dataList"
:key="index"
class="list-item"
:class="[!isMobile ? 'list-item--desktop' : '']"
@click="handleToProcess(item)"
>
<view class="list-item__header">
<view class="list-item__main">
<!-- <sar-checkbox size="36rpx" /> -->
<text>
{{ item.b_id }}
</text>
</view>
<view class="list-item__extra">
<sar-tag :theme="getTagType(item.b_state)">
{{ item.b_state }}
</sar-tag>
</view>
</view>
<view class="list-item__body">
<sar-row v-for="(row, rowIndex) in groupedFields" :key="rowIndex">
<sar-col
v-for="(col, colIndex) in row"
:key="colIndex"
:span="col.span || 6"
>
<view class="list-item__info">
<view class="list-item__label">
{{ col.label }}:
</view>
<view class="list-item__value">
{{ col.value(item) }}
</view>
</view>
</sar-col>
</sar-row>
</view>
<view class="list-item__footer">
<sar-button v-if="item.boHuiButton" theme="danger" size="mini" icon="close" inline @click="handleApproval(item, '审核驳回')">
驳回
</sar-button>
<sar-button v-if="item.tongGuoButton" size="mini" icon="success" inline @click="handleApproval(item, '审核通过')">
通过
</sar-button>
</view>
<view class="list-item__line" />
</view>
<!-- <template #bottom>
<view class="bottom-bar">
<sar-checkbox>
全选
</sar-checkbox>
<sar-button block size="small" icon="success">
批量通过
</sar-button>
</view>
</template> -->
</z-paging>
<ShDialog v-model="showShDialog" :component-data="auditComponentData" @success="handleShSuccess" />
</view>
</template>
<style scoped lang="scss">
@import '@/style/mixins.scss';
.dialog-loading {
display: flex;
justify-content: center;
align-items: center;
height: 200rpx;
}
.bottom-bar {
display: flex;
align-items: center;
padding: 24rpx 36rpx;
background: #fff;
border-top: 2rpx solid #ddd;
@include flexGap(32rpx, '');
}
/* tab 栏 */
.tabs {
display: flex;
border-bottom: 2rpx solid #eee;
background-color: #fff;
.tabs__item {
flex: 1;
text-align: center;
padding: 16rpx 0;
font-size: 30rpx;
color: #888;
}
.tabs__item--active {
color: var(--sar-primary);
font-weight: bold;
border-bottom: 4rpx solid var(--sar-primary);
}
}
/* 列表项 */
.list-item {
position: relative;
padding: 24rpx 16rpx;
background-color: #fff;
transition: all 0.2s;
&:active {
background-color: #f5f5f5;
}
&.list-item--desktop {
.list-item__header {
max-width: 1000rpx;
margin: 0 auto;
}
.list-item__body {
max-width: 1000rpx;
margin: 0 auto;
}
.list-item__footer {
max-width: 1000rpx;
margin: 0 auto;
}
}
.list-item__header {
display: flex;
justify-content: space-between;
.list-item__main {
display: flex;
align-items: center;
@include flexGap(16rpx, '');
font-weight: bold;
font-size: 36rpx;
}
.list-item__extra {
display: flex;
align-items: center;
@include flexGap(16rpx, '');
.list-item__finishdate {
font-size: 28rpx;
color: #666;
}
}
}
.list-item__body {
padding: 24rpx 0rpx;
display: flex;
flex-direction: column;
@include flexGap(16rpx, 'column');
.list-item__info {
display: flex;
align-items: start;
width: 100%;
font-size: 32rpx;
line-height: 1;
.list-item__label {
display: block;
min-width: 192rpx;
color: #4b5563;
text-align: right;
white-space: nowrap;
}
.list-item__value {
flex: 1;
color: #111827;
word-break: break-all;
}
}
}
.list-item__footer {
display: flex;
justify-content: flex-end;
@include flexGap(36rpx, '');
:deep(.sar-button) {
padding: 0rpx 48rpx;
font-size: 32rpx;
}
}
.list-item__line {
position: absolute;
bottom: 0rpx;
left: 0rpx;
height: 1px;
width: 100%;
background-color: #dcdcdc;
}
}
</style>
@@ -0,0 +1,116 @@
<script lang="ts" setup>
import Information from './information.vue'
import Step from './step.vue'
const data = ref({
b_id: '',
b_module_id: '',
v_modulename: '',
})
const segmentedValue = ref('流程')
const options = [
{
label: '流程',
value: '流程',
icon: 'liucheng',
iconFamily: 'iconfont',
},
{
label: '详细',
value: '详细',
icon: 'xiangxi',
iconFamily: 'iconfont',
},
{
label: '附件',
value: '附件',
icon: 'fujian',
iconFamily: 'iconfont',
},
]
onLoad((options) => {
if (options.b_id === '' || options.b_module_id === '') {
uni.navigateBack() // 返回上一页
return
}
data.value.b_id = options.b_id
data.value.b_module_id = options.b_module_id
data.value.v_modulename = options.v_modulename
})
</script>
<template>
<view class="process-container">
<view class="tip-card">
<view class="tip-item">
<view class="label">
审批单:
</view>
<view class="value">
{{ data.v_modulename }}
</view>
</view>
<view class="tip-item">
<view class="label">
业务编号:
</view>
<view class="value">
{{ data.b_id }}
</view>
</view>
</view>
<view class="segmented">
<sar-segmented v-model="segmentedValue" :options="options" shape="round" />
</view>
<Step v-if="segmentedValue === '流程'" :component-data="data" />
<Information v-else-if="segmentedValue === '详细'" :component-data="data" />
</view>
</template>
<style lang="scss" scoped>
page {
background-color: #fff;
}
.process-container {
padding: 16rpx 24rpx;
width: 100%;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
.tip-card {
padding: 16rpx 24rpx;
background-color: #f6f6f7;
border-radius: 12rpx;
display: flex;
flex-direction: column;
.tip-item {
display: flex;
align-items: center;
font-size: 32rpx;
line-height: 1.5;
.label {
font-weight: 600;
color: #333;
}
.value {
flex: 1;
color: #555;
word-break: break-word;
}
}
}
.segmented {
margin: 32rpx 0rpx;
}
</style>
@@ -0,0 +1,165 @@
<script lang="ts" setup>
import LoadingPage from '@/components/loading-page/index.vue'
import { getFieldValueById, loadColumnConfig, loaddataApi, loaddatabysqlApi } from '@/request/api'
const props = defineProps({
componentData: {
type: Object,
},
})
const loadingState = ref<{
isLoading: boolean
loadingTips: string
}>({
isLoading: true,
loadingTips: '正在加载中,请稍等...',
})
const list = ref([])
const listLoaded = ref(false)
onLoad(() => {
getDetailData()
})
const columns = ref([])
const dataList = ref([])
async function getDetailData() {
try {
loadingState.value.isLoading = true
const res1 = await loaddataApi({
viewname: 'sh_columnLib',
orderfield: 'mx_xh',
soption: '',
searchcondition: `b_moduleid = '${props.componentData.b_module_id}'`,
})
if (res1.data.length > 0) {
const res2 = await getFieldValueById({
viewname: 's_module',
desfield: 'b_ViewTable',
idfield: 'b_id',
idvalue: props.componentData.b_module_id,
})
const res3 = await loaddataApi({
viewname: res2.data,
searchcondition: `b_id = '${props.componentData.b_id}'`,
orderfield: 'b_id',
soption: '',
})
if (res3.data.length === 1) {
res1.data.forEach(async (item1) => {
list.value.push({
label: item1.col_Caption,
value: res3.data[0][item1.col_FieldName],
})
})
listLoaded.value = true
}
}
// Step 4: Load data from sh_mod_subview using SQL query
const sqlRes = await loaddatabysqlApi({
soption: '',
orderfield: '',
sql: `select * from sh_mod_subview where b_moduleid = '${props.componentData.b_module_id}'`,
})
if (sqlRes.data.length > 0) {
const subviewTable = sqlRes.data[0].b_sub_viewtable
if (subviewTable) {
// Step 5: Load column config
const columnConfigRes = await loadColumnConfig({
col_tablename: subviewTable,
})
const columnData = columnConfigRes.data
.filter(item => !item.hidden) // Filter out hidden columns
.map(item => ({
prop: item.field,
label: item.title,
}))
columns.value = columnData
if (columnData.length > 0) {
// Step 6: Load data for the subview table
const subviewDataRes = await loaddataApi({
soption: '',
searchcondition: `father = '${props.componentData.b_id}'`,
viewname: subviewTable,
orderfield: '',
})
dataList.value = subviewDataRes.data
}
}
}
}
catch (error) {
console.error('Error in getDetailData:', error)
}
finally {
loadingState.value.isLoading = false
}
}
</script>
<template>
<LoadingPage v-if="loadingState.isLoading" />
<view v-else-if="list.length > 0" class="basic-info">
<view v-for="(item, index) in list" :key="index">
<view class="info-item">
<view class="label">
{{ item.label }}
</view>
<view class="value">
{{ item.value }}
</view>
</view>
<sar-divider root-style="margin:4rpx 0; "/>
</view>
<view v-if="columns.length > 0" style="margin-top: 64rpx;">
<wd-table :data="dataList" :ellipsis="false">
<wd-table-col v-for="(item, index) in columns" :key="index" :prop="item.prop" :label="item.label" />
</wd-table>
</view>
</view>
<sar-result v-else status="info" title="空空如也" style="margin-top: 64rpx;" />
</template>
<style scoped lang="scss">
.basic-info {
box-sizing: border-box;
width: 100%;
}
.info-item {
display: flex;
align-items: flex-start; /* 改为顶部对齐更好看 */
width: 100%;
padding: 12rpx 0;
}
.label {
width: 180rpx;
margin-right: 16rpx;
font-size: 28rpx;
font-weight: 600;
text-align: right;
color: #666;
}
.value {
flex: 1;
font-size: 28rpx;
color: #1f2937;
word-break: break-all;
}
</style>
@@ -0,0 +1,194 @@
<script lang="ts" setup>
import LoadingPage from '@/components/loading-page/index.vue'
import { loaddataApi } from '@/request/api'
const props = defineProps({
componentData: {
type: Object,
},
})
const data = ref<any[]>([])
const loading = ref<boolean>(true)
onLoad(() => {
initData()
})
async function initData() {
loading.value = true
await loaddataApi({
viewname: 'v_sh_record',
orderfield: 'b_id desc',
searchcondition: `b_module_id = '${props.componentData.b_module_id}' and b_dj_id = '${props.componentData.b_id}'`,
soption: '',
}).then((res) => {
data.value = res.data
})
loading.value = false
}
function computedConsumeTime(index: number) {
if (index === data.value.length - 1) {
return ''
}
if (data.value.length === 1) {
return ''
}
return computedTimeDifference(data.value[index].b_sh_date, data.value[index + 1].b_sh_date)
}
function computedTimeDifference(date1: string, date2: string): string {
// 将日期字符串转换为 Date 对象
const d1 = new Date(date1)
const d2 = new Date(date2)
// 计算两个日期之间的毫秒差值
const diffInMilliseconds = Math.abs(d2.getTime() - d1.getTime())
// 将毫秒差值转换为对应的天、小时、分钟和秒
const days = Math.floor(diffInMilliseconds / (1000 * 60 * 60 * 24))
const hours = Math.floor((diffInMilliseconds % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
const minutes = Math.floor((diffInMilliseconds % (1000 * 60 * 60)) / (1000 * 60))
const seconds = Math.floor((diffInMilliseconds % (1000 * 60)) / 1000)
// 根据条件组合输出结果
const result: string[] = []
if (days > 0)
result.push(`${days}天`)
if (hours > 0)
result.push(`${hours}时`)
if (minutes > 0)
result.push(`${minutes}分`)
if (seconds > 0)
result.push(`${seconds}秒`)
// 如果没有任何值,说明两个日期相等,返回"0秒"
return result.length > 0 ? result.join('') : '0秒'
}
</script>
<template>
<LoadingPage v-if="loading" />
<view v-else-if="data.length > 0" class="timeline">
<view v-for="(item, index) in data" :key="index" class="timeline-item">
<view class="timeline-col left-col">
<view class="timeline-content left">
{{ item.b_name }}
</view>
</view>
<view class="timeline-col right-col">
<view class="timeline-content right">
<view v-if="item.v_user_name" class="title">
{{ item.v_user_name }}
<text v-if="item.v_tosh_user_name">
> {{ item.v_tosh_user_name }}
</text>
</view>
<view>{{ item.b_sh_date }}</view>
<view v-if="computedConsumeTime(index)">
审批耗时:{{ computedConsumeTime(index) }}
</view>
<view>{{ item.b_sh_memo }}</view>
</view>
</view>
<view class="timeline-center">
<view class="timeline-dot" />
</view>
</view>
</view>
<sar-result v-else status="info" title="空空如也" style="margin-top: 64rpx;"/>
</template>
<style lang="scss" scoped>
/* 整个容器 */
.timeline {
display: flex;
flex-direction: column;
}
/* 每个步骤项 */
.timeline-item {
position: relative;
display: flex;
align-items: center;
padding: 32rpx 0;
}
/* 左右列容器,用来固定左右比例,不受内容内 padding 影响 */
.timeline-col {
box-sizing: border-box;
}
.left-col {
width: 30%;
padding-right: 32rpx; /* 给中间圆点留出空间 */
font-size: 28rpx;
text-align: right;
}
.right-col {
width: 70%;
padding-left: 32rpx; /* 给中间圆点留出空间 */
text-align: left;
}
/* 左右内容,可以自由添加 padding */
.timeline-content {
font-size: 28rpx;
word-break: break-all;
border-radius: 12rpx;
}
.timeline-content.left {
padding: 8rpx;
font-weight: bold;
text-align: center;
background-color: #f0f2f5; /* 轻柔的灰色背景,避免视觉突兀 */
border-radius: 12rpx; /* 让边角更柔和 */
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1); /* 轻微阴影,增加层次感 */
}
.timeline-content.right {
display: flex;
flex-direction: column;
gap: 4rpx;
padding: 16rpx 32rpx;
color: #666;
background: #f5f5f5;
.title {
font-weight: bold;
color: black;
}
}
/* 中间圆点容器,绝对定位在左右列分界处 */
.timeline-center {
position: absolute;
left: calc(30%);
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
transform: translateX(-50%);
}
/* 圆点 */
.timeline-dot {
width: 24rpx;
height: 24rpx;
background: #007aff;
border-radius: 50%;
}
/* 使用每个步骤项的伪元素绘制竖线 */
.timeline-item::before {
position: absolute;
top: 0;
bottom: 0;
left: calc(30%);
width: 4rpx; /* 可随意调整宽度 */
content: '';
background: #409eff; /* 竖线颜色 */
transform: translateX(-50%);
}
/* 第一项:只显示圆点下方的线 */
.timeline-item:first-child::before {
top: 50%;
}
/* 最后一项:只显示圆点上方的线 */
.timeline-item:last-child::before {
bottom: 50%;
}
</style>
+21
View File
@@ -81,6 +81,27 @@
"navigationBarTitleText": "修改密码",
"navigationStyle": "default"
}
},
{
"path": "fukuan/index",
"style": {
"navigationBarTitleText": "付款申请",
"navigationStyle": "default"
}
},
{
"path": "baoxiao/index",
"style": {
"navigationBarTitleText": "费用报销",
"navigationStyle": "default"
}
},
{
"path": "process/index",
"style": {
"navigationBarTitleText": "审批进度",
"navigationStyle": "default"
}
}
]
}
+29 -9
View File
@@ -1,7 +1,8 @@
<script setup lang="ts">
import { useUserStore } from '@/store'
import { useCountsStore, useUserStore } from '@/store'
const userStore = useUserStore()
const countsStore = useCountsStore()
const swiperCurrent = ref(0)
const swiperList = [
@@ -10,6 +11,14 @@ const swiperList = [
{},
]
onShow(() => {
if (!userStore.isLogined) {
return
}
countsStore.loadTaskCounts()
})
function handleToLogin() {
uni.reLaunch({
url: '/pages-sub/login/index',
@@ -29,7 +38,11 @@ function toLinkUrl(url) {
<template>
<view>
<view class="swiper-container">
<swiper
<image
src="@/static/images/bg.jpg"
style="width: 100%;height: 400rpx"
/>
<!-- <swiper
:current="swiperCurrent"
autoplay
:interval="3000"
@@ -58,12 +71,13 @@ function toLinkUrl(url) {
<sar-swiper-dot
:current="swiperCurrent"
:list="swiperList"
/>
/> -->
</view>
<view v-if="userStore.isLogined" class="grid-container">
<sar-grid :columns="2" gap="24rpx">
<sar-grid-item
@click="toLinkUrl('/pages-sub/waybill/index')"
:badge="countsStore.fukuan.v_dsh"
@click="toLinkUrl('/pages-sub/fukuan/index')"
>
<view class="grid-item">
<image src="/static/images/home/paymentRequest.png" />
@@ -71,7 +85,8 @@ function toLinkUrl(url) {
</view>
</sar-grid-item>
<sar-grid-item
@click="toLinkUrl('/pages-sub/waybill-history/index')"
:badge="countsStore.baoxiao.v_dsh"
@click="toLinkUrl('/pages-sub/baoxiao/index')"
>
<view class="grid-item">
<image src="/static/images/home/receivableInvoice.png" />
@@ -91,6 +106,10 @@ function toLinkUrl(url) {
</template>
<style lang="scss" scoped>
page {
background-color: #fff;
}
.swiper-container {
position: relative;
.swiper {
@@ -100,10 +119,12 @@ function toLinkUrl(url) {
}
.grid-container {
padding-top: 32rpx;
padding: 16rpx;
background-color: #fff;
:deep(.sar-grid__content) {
background-color: #fff;
background-color: #f5f6f8;
border-radius: 16rpx;
}
:deep(.sar-grid) {
row-gap: 0 !important;
@@ -113,7 +134,6 @@ function toLinkUrl(url) {
}
:deep(.sar-grid__wrapper) {
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
}
:deep(.sar-badge) {
@@ -133,7 +153,7 @@ function toLinkUrl(url) {
}
text {
margin-top: 16rpx;
font-weight: 600;
font-weight: 500;
color: #000;
}
}
+17
View File
@@ -195,3 +195,20 @@ export function delObjApi(params: DelObjParams) {
export function getModuleQxApi() {
return request.postForm(`/getmoduleqx.jsp`)
}
interface loadColumnConfigParams {
col_tablename: string
}
export function loadColumnConfig(params: loadColumnConfigParams) {
return request.postForm<Array<any>>(`/loadcolumnconfig.jsp`, params)
}
interface getFieldValueByIdParams {
viewname: string
desfield: string
idfield: string
idvalue: string
}
export function getFieldValueById(params: getFieldValueByIdParams) {
return request.postForm<string>(`/getfieldvaluebyid.jsp`, params)
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 116 KiB

+114 -19
View File
@@ -1,22 +1,117 @@
const fleetCounts = reactive({
diaodu: {
todo: 0,
finished: 0,
total: 0,
},
})
import { defineStore } from 'pinia'
import { reactive } from 'vue'
// stores/taskCountsStore.js
import { loaddatabysqlApi } from '@/request/api'
import { useUserStore } from './user'
const driverCounts = reactive({
jindu: {
todo: 0,
finished: 0,
total: 0,
},
})
export const useCountsStore = defineStore('taskCounts', () => {
const userStore = useUserStore()
export function useCounts() {
return {
fleetCounts,
driverCounts,
// 定义任务统计对象
const fukuan = reactive({
v_dsh: 0,
v_ash: 0,
all_cnt: 0,
})
const baoxiao = reactive({
v_dsh: 0,
v_ash: 0,
all_cnt: 0,
})
// 定义加载任务数量的函数,可以根据传入参数选择加载哪些请求
const loadTaskCounts = async (requests = ['fukuan', 'baoxiao']) => {
try {
// 请求的 SQL 查询列表
const sqlQueries = {
fukuan: `
SELECT COUNT(*) AS all_cnt,
SUM(CASE WHEN rs.b_level >= st.b_level THEN 1 ELSE 0 END) AS v_ash,
SUM(CASE WHEN rs.b_level = st.b_level - 1 THEN 1 ELSE 0 END) AS v_dsh
FROM (
SELECT r.*
FROM (
SELECT b_dj_id, b_module_id, MAX(b_id) AS b_maxid
FROM dbo.sh_record
GROUP BY b_dj_id, b_module_id
) AS a
JOIN sh_record r ON a.b_maxid = r.b_id
WHERE r.b_sh = '1'
) AS rs
LEFT JOIN (
SELECT b_module_id, b_level
FROM sh_b_set
WHERE b_user_id = '${userStore.userInfo.userid}'
) AS st
ON rs.b_module_id = st.b_module_id
AND (rs.b_level = st.b_level - 1 OR rs.b_level = st.b_level)
WHERE rs.b_module_id = 'cw_zdorder_f';
`,
baoxiao: `
SELECT COUNT(*) AS all_cnt,
SUM(CASE WHEN rs.b_level >= st.b_level THEN 1 ELSE 0 END) AS v_ash,
SUM(CASE WHEN rs.b_level = st.b_level - 1 THEN 1 ELSE 0 END) AS v_dsh
FROM (
SELECT r.*
FROM (
SELECT b_dj_id, b_module_id, MAX(b_id) AS b_maxid
FROM dbo.sh_record
GROUP BY b_dj_id, b_module_id
) AS a
JOIN sh_record r ON a.b_maxid = r.b_id
WHERE r.b_sh = '1'
) AS rs
LEFT JOIN (
SELECT b_module_id, b_level
FROM sh_b_set
WHERE b_user_id = '${userStore.userInfo.userid}'
) AS st
ON rs.b_module_id = st.b_module_id
AND (rs.b_level = st.b_level - 1 OR rs.b_level = st.b_level)
WHERE rs.b_module_id = 'car_daily';
`,
}
// 根据传入的参数动态生成请求列表
const promises = requests.map((key) => {
if (sqlQueries[key]) {
return loaddatabysqlApi({
sql: sqlQueries[key],
orderfield: '',
soption: '',
})
}
return null
}).filter(item => item !== null)
const results = await Promise.all(promises)
// 更新 taskCounts
results.forEach((res, index) => {
const key = requests[index]
if (res.data.length > 0) {
if (key === 'fukuan') {
fukuan.v_dsh = res.data[0].v_dsh || 0
fukuan.v_ash = res.data[0].v_ash || 0
fukuan.all_cnt = res.data[0].all_cnt || 0
}
else if (key === 'baoxiao') {
baoxiao.v_dsh = res.data[0].v_dsh || 0
baoxiao.v_ash = res.data[0].v_ash || 0
baoxiao.all_cnt = res.data[0].all_cnt || 0
}
}
})
}
catch (error) {
console.error('加载任务统计失败:', error)
}
}
}
return {
fukuan,
baoxiao,
loadTaskCounts,
}
})
+1
View File
@@ -13,5 +13,6 @@ store.use(
export default store
export * from './counts'
export * from './permission'
export * from './user'
+19 -15
View File
@@ -1,9 +1,9 @@
@font-face {
font-family: 'iconfont'; /* Project id 5092914 */
font-family: 'iconfont'; /* Project id 5152268 */
src:
url('data:application/x-font-woff2;charset=utf-8;base64,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')
url('data:application/x-font-woff2;charset=utf-8;base64,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')
format('woff2'),
url('//at.alicdn.com/t/c/font_5092914_knn9qrc14j8.ttf?t=1766557052211') format('truetype');
url('//at.alicdn.com/t/c/font_5152268_zn0fwnj9psd.ttf?t=1775031927307') format('truetype');
}
.iconfont {
@@ -14,18 +14,6 @@
-moz-osx-font-smoothing: grayscale;
}
.iconfont-sijiguanli:before {
content: '\e61c';
}
.iconfont-jindu:before {
content: '\e7b0';
}
.iconfont-jihuatiaodu:before {
content: '\e7b6';
}
.iconfont-save:before {
content: '\e8c7';
}
@@ -54,6 +42,22 @@
content: '\e888';
}
.iconfont-xiuxiang:before {
content: '\e649';
}
.iconfont-system:before {
content: '\e703';
}
.iconfont-xiangxi:before {
content: '\e65b';
}
.iconfont-liucheng:before {
content: '\e638';
}
.iconfont-fujian:before {
content: '\e819';
}
+2
View File
@@ -80,6 +80,7 @@ declare global {
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useDeviceInfo: typeof import('../hooks/useDeviceInfo')['useDeviceInfo']
const useId: typeof import('vue')['useId']
const useModel: typeof import('vue')['useModel']
const useSlots: typeof import('vue')['useSlots']
@@ -175,6 +176,7 @@ declare module 'vue' {
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
readonly useDeviceInfo: UnwrapRef<typeof import('../hooks/useDeviceInfo')['useDeviceInfo']>
readonly useId: UnwrapRef<typeof import('vue')['useId']>
readonly useModel: UnwrapRef<typeof import('vue')['useModel']>
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
+3
View File
@@ -8,8 +8,11 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
DateSearch: typeof import('./../components/date-search/index.vue')['default']
EmptyPage: typeof import('./../components/empty-page/index.vue')['default']
LoadingPage: typeof import('./../components/loading-page/index.vue')['default']
OverlayLoading: typeof import('./../components/OverlayLoading.vue')['default']
PickerSelect: typeof import('./../components/picker-select/index.vue')['default']
PickerSelectInput: typeof import('./../components/picker-select-input/index.vue')['default']
ShDialog: typeof import('./../components/sh-dialog/index.vue')['default']
}
}
+109
View File
@@ -0,0 +1,109 @@
import { saveobjtApi } from '@/request/api'
import { useUserStore } from '@/store'
import { jsonToString } from './common'
import { getCurrentDateTimeWithSeconds } from './time'
const userStore = useUserStore()
const { userid } = userStore.userInfo
interface saveObjParams {
tables: Array<string>
insertValues: Array<string>
delValues: Array<string>
updateValues: Array<string>
keys: Array<string>
logValues: Array<string>
}
export function saveObjectHelper(data: saveObjParams): Promise<string> {
return saveobjtApi(data).then((res) => {
if (res.data === 'OK') {
return saveLogDatas(data).then(() => 'OK')
}
return Promise.reject('Error')
})
}
async function saveLogDatas(data: saveObjParams) {
const { tables: subtable, insertValues: subinsertvalue, delValues: subdelvalue, updateValues: subupdatevalue, keys: keyid, logValues: logvalues } = data
let log_inserts = []
let log_deletes = []
let log_updates = []
let log_datas_inserts = []
let s_Log_inserts = []
let tablearr = []
let keysarr = []
let thistime = getCurrentDateTimeWithSeconds()
for (let i in subtable) {
let tablename = subtable[i]
let insertdatas = eval(`(${subinsertvalue[i]})`)
if (insertdatas.length > 0) {
let obj: any = {}
obj.b_table = tablename
obj.b_option = 'INSERT'
obj.b_datas = subinsertvalue[i]
obj.b_inputdatetime = thistime
obj.b_inputuser_id = userid
log_datas_inserts.push(obj)
}
let deletedatas = eval(`(${subdelvalue[i]})`)
if (deletedatas.length > 0) {
let obj: any = {}
obj.b_table = tablename
obj.b_option = 'DELETE'
obj.b_datas = subdelvalue[i]
obj.b_inputdatetime = thistime
obj.b_inputuser_id = userid
log_datas_inserts.push(obj)
}
let updatedatas = eval(`(${subupdatevalue[i]})`)
if (updatedatas.length > 0) {
let obj: any = {}
obj.b_table = tablename
obj.b_option = 'UPDATE'
obj.b_datas = subupdatevalue[i]
obj.b_inputdatetime = thistime
obj.b_inputuser_id = userid
log_datas_inserts.push(obj)
}
}
if (log_datas_inserts.length > 0) {
tablearr.push('log_datas')
keysarr.push('b_id')
log_inserts.push(JSON.stringify(log_datas_inserts))
log_deletes.push('[]')
log_updates.push('[]')
}
if (logvalues !== undefined) {
let s_Log_datas = []
for (let i in logvalues) {
let logdatas = eval(`(${logvalues[i]})`)
for (let j in logdatas) {
let logdata = logdatas[j]
logdata.OpDate = thistime
logdata.UserID = userid
s_Log_datas.push(logdata)
}
}
s_Log_inserts.push(jsonToString(s_Log_datas))
if (s_Log_inserts.length > 0) {
tablearr.push('s_Log')
keysarr.push('b_id')
log_inserts.push(s_Log_inserts)
log_deletes.push('[]')
log_updates.push('[]')
}
}
if (log_inserts.length > 0) {
saveobjtApi({
tables: tablearr,
insertValues: log_inserts,
delValues: log_deletes,
updateValues: log_updates,
keys: keysarr,
})
}
}