Commit 9d019fa68211576e805117494b7362b2e1924805

Authored by wuxw
1 parent dd2c2983

测试OA相关流程

Showing 45 changed files with 4664 additions and 332 deletions
package-lock.json
... ... @@ -12,6 +12,7 @@
12 12 "axios": "^0.21.1",
13 13 "echarts": "^5.6.0",
14 14 "element-ui": "^2.15.6",
  15 + "formiojs": "^4.21.7",
15 16 "qrcodejs2": "^0.0.2",
16 17 "tinymce": "^5.10.7",
17 18 "vue": "^2.6.14",
... ... @@ -1571,6 +1572,47 @@
1571 1572 "node": ">=6.9.0"
1572 1573 }
1573 1574 },
  1575 + "node_modules/@formio/bootstrap3": {
  1576 + "version": "2.12.4-rc.1",
  1577 + "resolved": "https://registry.npmjs.org/@formio/bootstrap3/-/bootstrap3-2.12.4-rc.1.tgz",
  1578 + "integrity": "sha512-4B5rs+w9tAk5i+wbdw2/NrTxPqnDX7/W19tiTd9lfXnIGQmaj0ecMEVqDmOJg8pIlyU02g3c4ih6JnA/JVmUbA==",
  1579 + "dependencies": {
  1580 + "resize-observer-polyfill": "^1.5.1"
  1581 + }
  1582 + },
  1583 + "node_modules/@formio/choices.js": {
  1584 + "version": "10.2.1",
  1585 + "resolved": "https://registry.npmjs.org/@formio/choices.js/-/choices.js-10.2.1.tgz",
  1586 + "integrity": "sha512-NCE5u7jG3XGokJP16MyAbVSUptKu/mpJYAxd4PPIoLiO/l9Do5uoOQ0MgNb9qG9qABJiOX+qNRE8q8RybY/SwQ==",
  1587 + "dependencies": {
  1588 + "deepmerge": "^4.2.2",
  1589 + "fuse.js": "^6.6.2",
  1590 + "redux": "^4.2.0"
  1591 + }
  1592 + },
  1593 + "node_modules/@formio/choices.js/node_modules/deepmerge": {
  1594 + "version": "4.3.1",
  1595 + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
  1596 + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
  1597 + "engines": {
  1598 + "node": ">=0.10.0"
  1599 + }
  1600 + },
  1601 + "node_modules/@formio/semantic": {
  1602 + "version": "2.6.1",
  1603 + "resolved": "https://registry.npmjs.org/@formio/semantic/-/semantic-2.6.1.tgz",
  1604 + "integrity": "sha512-obp1BT5UnzD+uYBbqmnsTfO2hGxI2A2iR/cj3P5JUFLYSBpnr3TS2ShQ7Ee5GCRRtJPu0JnljuJj+YSKLCMuhg=="
  1605 + },
  1606 + "node_modules/@formio/text-mask-addons": {
  1607 + "version": "3.8.0-formio.4",
  1608 + "resolved": "https://registry.npmjs.org/@formio/text-mask-addons/-/text-mask-addons-3.8.0-formio.4.tgz",
  1609 + "integrity": "sha512-vhkeIyuL+1rtC9S4IW8O3JCwroPtvJrkrcMO4wyELNqMIgQRKbiyBAitZfUP4tY04xdB5lxAinbzdwb+NMdX6w=="
  1610 + },
  1611 + "node_modules/@formio/vanilla-text-mask": {
  1612 + "version": "5.1.1-formio.1",
  1613 + "resolved": "https://registry.npmjs.org/@formio/vanilla-text-mask/-/vanilla-text-mask-5.1.1-formio.1.tgz",
  1614 + "integrity": "sha512-rYBlvIPMNUd6sAaduOaiIwI4vfTAjHDRonko2qJn2RP1O//TQ7rcFIPYVYePJZ4OtOpwHiHAvAIh79McphZotQ=="
  1615 + },
1574 1616 "node_modules/@hapi/address": {
1575 1617 "version": "2.1.4",
1576 1618 "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
... ... @@ -2069,6 +2111,15 @@
2069 2111 "node": ">=8.0"
2070 2112 }
2071 2113 },
  2114 + "node_modules/@popperjs/core": {
  2115 + "version": "2.11.8",
  2116 + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
  2117 + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
  2118 + "funding": {
  2119 + "type": "opencollective",
  2120 + "url": "https://opencollective.com/popperjs"
  2121 + }
  2122 + },
2072 2123 "node_modules/@soda/friendly-errors-webpack-plugin": {
2073 2124 "version": "1.8.1",
2074 2125 "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.1.tgz",
... ... @@ -2093,6 +2144,11 @@
2093 2144 "integrity": "sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w==",
2094 2145 "dev": true
2095 2146 },
  2147 + "node_modules/@sphinxxxx/color-conversion": {
  2148 + "version": "2.2.2",
  2149 + "resolved": "https://registry.npmjs.org/@sphinxxxx/color-conversion/-/color-conversion-2.2.2.tgz",
  2150 + "integrity": "sha512-XExJS3cLqgrmNBIP3bBw6+1oQ1ksGjFh0+oClDKFYpCCqx/hlqwWO5KO/S63fzUo67SxI9dMrF0y5T/Ey7h8Zw=="
  2151 + },
2096 2152 "node_modules/@tinymce/tinymce-vue": {
2097 2153 "version": "3.2.8",
2098 2154 "resolved": "https://registry.npmjs.org/@tinymce/tinymce-vue/-/tinymce-vue-3.2.8.tgz",
... ... @@ -2268,6 +2324,12 @@
2268 2324 "integrity": "sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q==",
2269 2325 "dev": true
2270 2326 },
  2327 + "node_modules/@types/trusted-types": {
  2328 + "version": "2.0.7",
  2329 + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
  2330 + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
  2331 + "optional": true
  2332 + },
2271 2333 "node_modules/@types/uglify-js": {
2272 2334 "version": "3.17.5",
2273 2335 "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.17.5.tgz",
... ... @@ -3135,6 +3197,11 @@
3135 3197 "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
3136 3198 "dev": true
3137 3199 },
  3200 + "node_modules/abortcontroller-polyfill": {
  3201 + "version": "1.7.8",
  3202 + "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.8.tgz",
  3203 + "integrity": "sha512-9f1iZ2uWh92VcrU9Y8x+LdM4DLj75VE0MJB8zuF1iUnroEptStw+DQ8EQPMUdfe5k+PkB1uUfDQfWbhstH8LrQ=="
  3204 + },
3138 3205 "node_modules/accepts": {
3139 3206 "version": "1.3.8",
3140 3207 "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
... ... @@ -3227,6 +3294,11 @@
3227 3294 "integrity": "sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==",
3228 3295 "dev": true
3229 3296 },
  3297 + "node_modules/animation-frame-polyfill": {
  3298 + "version": "1.0.2",
  3299 + "resolved": "https://registry.npmjs.org/animation-frame-polyfill/-/animation-frame-polyfill-1.0.2.tgz",
  3300 + "integrity": "sha512-PvO5poSMoHhaoNNgHPo+oqs/0L9UqjsUbqv0iOXVqLh6HX85fsOVQTUrzSBvjdZz7hydARlgLELyzJJKIrPJAQ=="
  3301 + },
3230 3302 "node_modules/ansi-colors": {
3231 3303 "version": "3.2.4",
3232 3304 "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
... ... @@ -3390,6 +3462,11 @@
3390 3462 "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
3391 3463 "dev": true
3392 3464 },
  3465 + "node_modules/array-from": {
  3466 + "version": "2.1.1",
  3467 + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz",
  3468 + "integrity": "sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg=="
  3469 + },
3393 3470 "node_modules/array-union": {
3394 3471 "version": "1.0.2",
3395 3472 "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
... ... @@ -3588,6 +3665,11 @@
3588 3665 "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
3589 3666 "dev": true
3590 3667 },
  3668 + "node_modules/atoa": {
  3669 + "version": "1.0.0",
  3670 + "resolved": "https://registry.npmjs.org/atoa/-/atoa-1.0.0.tgz",
  3671 + "integrity": "sha512-VVE1H6cc4ai+ZXo/CRWoJiHXrA1qfA31DPnx6D20+kSI547hQN5Greh51LQ1baMRMfxO5K5M4ImMtZbZt2DODQ=="
  3672 + },
3591 3673 "node_modules/atob": {
3592 3674 "version": "2.1.2",
3593 3675 "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
... ... @@ -3600,6 +3682,11 @@
3600 3682 "node": ">= 4.5.0"
3601 3683 }
3602 3684 },
  3685 + "node_modules/autocompleter": {
  3686 + "version": "7.1.0",
  3687 + "resolved": "https://registry.npmjs.org/autocompleter/-/autocompleter-7.1.0.tgz",
  3688 + "integrity": "sha512-uCToOnq7eAD/GJAteDbYuQ7ksDtrYWOy5CIAq43wh0dT+5frMpPlyD9tp+y5fz8KIcsP+zR2MjzoTAdW5aJESw=="
  3689 + },
3603 3690 "node_modules/autoprefixer": {
3604 3691 "version": "9.8.8",
3605 3692 "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz",
... ... @@ -4048,6 +4135,19 @@
4048 4135 "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==",
4049 4136 "dev": true
4050 4137 },
  4138 + "node_modules/browser-cookies": {
  4139 + "version": "1.2.0",
  4140 + "resolved": "https://registry.npmjs.org/browser-cookies/-/browser-cookies-1.2.0.tgz",
  4141 + "integrity": "sha512-cg2WuoOJo+F+g2XjEaP8nmeRp1vDHjt7sqpKJMsTNXKrpyIBNVslYJeehvs6FEddj8usV2+qyRSBEX244yN5/g=="
  4142 + },
  4143 + "node_modules/browser-md5-file": {
  4144 + "version": "1.1.1",
  4145 + "resolved": "https://registry.npmjs.org/browser-md5-file/-/browser-md5-file-1.1.1.tgz",
  4146 + "integrity": "sha512-9h2UViTtZPhBa7oHvp5mb7MvJaX5OKEPUsplDwJ800OIV+In7BOR3RXOMB78obn2iQVIiS3WkVLhG7Zu1EMwbw==",
  4147 + "dependencies": {
  4148 + "spark-md5": "^2.0.2"
  4149 + }
  4150 + },
4051 4151 "node_modules/browserify-aes": {
4052 4152 "version": "1.2.0",
4053 4153 "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
... ... @@ -4987,6 +5087,11 @@
4987 5087 "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
4988 5088 "dev": true
4989 5089 },
  5090 + "node_modules/compare-versions": {
  5091 + "version": "5.0.3",
  5092 + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.3.tgz",
  5093 + "integrity": "sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A=="
  5094 + },
4990 5095 "node_modules/component-emitter": {
4991 5096 "version": "1.3.1",
4992 5097 "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
... ... @@ -5166,6 +5271,15 @@
5166 5271 "node": ">= 0.6"
5167 5272 }
5168 5273 },
  5274 + "node_modules/contra": {
  5275 + "version": "1.9.4",
  5276 + "resolved": "https://registry.npmjs.org/contra/-/contra-1.9.4.tgz",
  5277 + "integrity": "sha512-N9ArHAqwR/lhPq4OdIAwH4e1btn6EIZMAz4TazjnzCiVECcWUPTma+dRAM38ERImEJBh8NiCCpjoQruSZ+agYg==",
  5278 + "dependencies": {
  5279 + "atoa": "1.0.0",
  5280 + "ticky": "1.0.1"
  5281 + }
  5282 + },
5169 5283 "node_modules/convert-source-map": {
5170 5284 "version": "2.0.0",
5171 5285 "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
... ... @@ -5513,6 +5627,14 @@
5513 5627 "sha.js": "^2.4.8"
5514 5628 }
5515 5629 },
  5630 + "node_modules/create-point-cb": {
  5631 + "version": "1.2.0",
  5632 + "resolved": "https://registry.npmjs.org/create-point-cb/-/create-point-cb-1.2.0.tgz",
  5633 + "integrity": "sha512-r4l6IO/YGI7hIZRMLggOzwM6XO80+Fdcv4hx1fXCEdU+hKd7zZki6i+cbYfK9OliMwMYx1wPfQLU/snvS+Dygw==",
  5634 + "dependencies": {
  5635 + "type-func": "^1.0.1"
  5636 + }
  5637 + },
5516 5638 "node_modules/cross-spawn": {
5517 5639 "version": "6.0.6",
5518 5640 "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
... ... @@ -5538,6 +5660,14 @@
5538 5660 "semver": "bin/semver"
5539 5661 }
5540 5662 },
  5663 + "node_modules/crossvent": {
  5664 + "version": "1.5.5",
  5665 + "resolved": "https://registry.npmjs.org/crossvent/-/crossvent-1.5.5.tgz",
  5666 + "integrity": "sha512-MY4xhBYEnVi+pmTpHCOCsCLYczc0PVtGdPBz6NXNXxikLaUZo4HdAeUb1UqAo3t3yXAloSelTmfxJ+/oUqkW5w==",
  5667 + "dependencies": {
  5668 + "custom-event": "^1.0.0"
  5669 + }
  5670 + },
5541 5671 "node_modules/crypto-browserify": {
5542 5672 "version": "3.12.1",
5543 5673 "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.1.tgz",
... ... @@ -5833,6 +5963,16 @@
5833 5963 "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
5834 5964 "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
5835 5965 },
  5966 + "node_modules/custom-event": {
  5967 + "version": "1.0.1",
  5968 + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
  5969 + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg=="
  5970 + },
  5971 + "node_modules/custom-event-polyfill": {
  5972 + "version": "1.0.7",
  5973 + "resolved": "https://registry.npmjs.org/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz",
  5974 + "integrity": "sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w=="
  5975 + },
5836 5976 "node_modules/cyclist": {
5837 5977 "version": "1.0.2",
5838 5978 "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.2.tgz",
... ... @@ -6276,6 +6416,11 @@
6276 6416 "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
6277 6417 "dev": true
6278 6418 },
  6419 + "node_modules/dialog-polyfill": {
  6420 + "version": "0.5.6",
  6421 + "resolved": "https://registry.npmjs.org/dialog-polyfill/-/dialog-polyfill-0.5.6.tgz",
  6422 + "integrity": "sha512-ZbVDJI9uvxPAKze6z146rmfUZjBqNEwcnFTVamQzXH+svluiV7swmVIGr7miwADgfgt1G2JQIytypM9fbyhX4w=="
  6423 + },
6279 6424 "node_modules/diffie-hellman": {
6280 6425 "version": "5.0.3",
6281 6426 "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
... ... @@ -6342,6 +6487,19 @@
6342 6487 "node": ">=6.0.0"
6343 6488 }
6344 6489 },
  6490 + "node_modules/dom-autoscroller": {
  6491 + "version": "2.3.4",
  6492 + "resolved": "https://registry.npmjs.org/dom-autoscroller/-/dom-autoscroller-2.3.4.tgz",
  6493 + "integrity": "sha512-HcAdt/2Dq9x4CG6LWXc2x9Iq0MJPAu8fuzHncclq7byufqYEYVtx9sZ/dyzR+gdj4qwEC9p27Lw1G2HRRYX6jQ==",
  6494 + "dependencies": {
  6495 + "animation-frame-polyfill": "^1.0.0",
  6496 + "create-point-cb": "^1.0.0",
  6497 + "dom-mousemove-dispatcher": "^1.0.1",
  6498 + "dom-plane": "^1.0.1",
  6499 + "dom-set": "^1.0.1",
  6500 + "type-func": "^1.0.1"
  6501 + }
  6502 + },
6345 6503 "node_modules/dom-converter": {
6346 6504 "version": "0.2.0",
6347 6505 "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
... ... @@ -6351,6 +6509,19 @@
6351 6509 "utila": "~0.4"
6352 6510 }
6353 6511 },
  6512 + "node_modules/dom-mousemove-dispatcher": {
  6513 + "version": "1.0.1",
  6514 + "resolved": "https://registry.npmjs.org/dom-mousemove-dispatcher/-/dom-mousemove-dispatcher-1.0.1.tgz",
  6515 + "integrity": "sha512-NMdqqMbgW8kqOdmod2hkS+9hD/v7h4XoSvwU9qqe+wAA/O+ba0jhpbfW0Kb/fCyR0RX9jf4dwfQrl04LQX4FzQ=="
  6516 + },
  6517 + "node_modules/dom-plane": {
  6518 + "version": "1.0.2",
  6519 + "resolved": "https://registry.npmjs.org/dom-plane/-/dom-plane-1.0.2.tgz",
  6520 + "integrity": "sha512-/tR67G6ZGSciXoZLsD706yLxEXvX3mG/OWE8YNYj3A1yU/RAimtPXzklVTu5Y5xoeMoloA/Y+MaNjQm9apgAww==",
  6521 + "dependencies": {
  6522 + "create-point-cb": "^1.0.0"
  6523 + }
  6524 + },
6354 6525 "node_modules/dom-serializer": {
6355 6526 "version": "1.4.1",
6356 6527 "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
... ... @@ -6374,6 +6545,16 @@
6374 6545 "url": "https://github.com/fb55/entities?sponsor=1"
6375 6546 }
6376 6547 },
  6548 + "node_modules/dom-set": {
  6549 + "version": "1.1.1",
  6550 + "resolved": "https://registry.npmjs.org/dom-set/-/dom-set-1.1.1.tgz",
  6551 + "integrity": "sha512-sUi2aSvRsK3Ixx++gwX9cnaWk9ZxGVFry8+HnTRVmDimybU5PaiI4wX0o00mVtjFKlQNZLmtGoPTLorYbN0+Rw==",
  6552 + "dependencies": {
  6553 + "array-from": "^2.1.1",
  6554 + "is-array": "^1.0.1",
  6555 + "iselement": "^1.1.4"
  6556 + }
  6557 + },
6377 6558 "node_modules/domain-browser": {
6378 6559 "version": "1.2.0",
6379 6560 "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
... ... @@ -6411,6 +6592,14 @@
6411 6592 "url": "https://github.com/fb55/domhandler?sponsor=1"
6412 6593 }
6413 6594 },
  6595 + "node_modules/dompurify": {
  6596 + "version": "3.2.6",
  6597 + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz",
  6598 + "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==",
  6599 + "optionalDependencies": {
  6600 + "@types/trusted-types": "^2.0.7"
  6601 + }
  6602 + },
6414 6603 "node_modules/domutils": {
6415 6604 "version": "2.8.0",
6416 6605 "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
... ... @@ -6452,6 +6641,20 @@
6452 6641 "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==",
6453 6642 "dev": true
6454 6643 },
  6644 + "node_modules/downloadjs": {
  6645 + "version": "1.4.7",
  6646 + "resolved": "https://registry.npmjs.org/downloadjs/-/downloadjs-1.4.7.tgz",
  6647 + "integrity": "sha512-LN1gO7+u9xjU5oEScGFKvXhYf7Y/empUIIEAGBs1LzUq/rg5duiDrkuH5A2lQGd5jfMOb9X9usDa2oVXwJ0U/Q=="
  6648 + },
  6649 + "node_modules/dragula": {
  6650 + "version": "3.7.3",
  6651 + "resolved": "https://registry.npmjs.org/dragula/-/dragula-3.7.3.tgz",
  6652 + "integrity": "sha512-/rRg4zRhcpf81TyDhaHLtXt6sEywdfpv1cRUMeFFy7DuypH2U0WUL0GTdyAQvXegviT4PJK4KuMmOaIDpICseQ==",
  6653 + "dependencies": {
  6654 + "contra": "1.9.4",
  6655 + "crossvent": "1.5.5"
  6656 + }
  6657 + },
6455 6658 "node_modules/dunder-proto": {
6456 6659 "version": "1.0.1",
6457 6660 "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
... ... @@ -7246,8 +7449,7 @@
7246 7449 "node_modules/eventemitter3": {
7247 7450 "version": "4.0.7",
7248 7451 "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
7249   - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
7250   - "dev": true
  7452 + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
7251 7453 },
7252 7454 "node_modules/events": {
7253 7455 "version": "3.3.0",
... ... @@ -7567,8 +7769,12 @@
7567 7769 "node_modules/fast-deep-equal": {
7568 7770 "version": "3.1.3",
7569 7771 "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
7570   - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
7571   - "dev": true
  7772 + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
  7773 + },
  7774 + "node_modules/fast-diff": {
  7775 + "version": "1.3.0",
  7776 + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
  7777 + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw=="
7572 7778 },
7573 7779 "node_modules/fast-glob": {
7574 7780 "version": "2.2.7",
... ... @@ -7587,6 +7793,11 @@
7587 7793 "node": ">=4.0.0"
7588 7794 }
7589 7795 },
  7796 + "node_modules/fast-json-patch": {
  7797 + "version": "3.1.1",
  7798 + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz",
  7799 + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ=="
  7800 + },
7590 7801 "node_modules/fast-json-stable-stringify": {
7591 7802 "version": "2.1.0",
7592 7803 "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
... ... @@ -7611,6 +7822,14 @@
7611 7822 "node": ">=0.8.0"
7612 7823 }
7613 7824 },
  7825 + "node_modules/fetch-ponyfill": {
  7826 + "version": "7.1.0",
  7827 + "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-7.1.0.tgz",
  7828 + "integrity": "sha512-FhbbL55dj/qdVO3YNK7ZEkshvj3eQ7EuIGV2I6ic/2YiocvyWv+7jg2s4AyS0wdRU75s3tA8ZxI/xPigb0v5Aw==",
  7829 + "dependencies": {
  7830 + "node-fetch": "~2.6.1"
  7831 + }
  7832 + },
7614 7833 "node_modules/figgy-pudding": {
7615 7834 "version": "3.5.2",
7616 7835 "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
... ... @@ -7911,6 +8130,63 @@
7911 8130 "node": ">= 0.12"
7912 8131 }
7913 8132 },
  8133 + "node_modules/formiojs": {
  8134 + "version": "4.21.7",
  8135 + "resolved": "https://registry.npmjs.org/formiojs/-/formiojs-4.21.7.tgz",
  8136 + "integrity": "sha512-DDXPhXABxdEbpyfv0C8SAS6zt92luGFXqe0usPHxSHvlP960GQkhS//WV7TAMrRsjj1WTIqqv3XZha8qTknG3Q==",
  8137 + "dependencies": {
  8138 + "@formio/bootstrap3": "2.12.4-rc.1",
  8139 + "@formio/choices.js": "10.2.1",
  8140 + "@formio/semantic": "2.6.1",
  8141 + "@formio/text-mask-addons": "^3.8.0-formio.4",
  8142 + "@formio/vanilla-text-mask": "^5.1.1-formio.1",
  8143 + "abortcontroller-polyfill": "^1.7.5",
  8144 + "autocompleter": "^7.0.1",
  8145 + "browser-cookies": "^1.2.0",
  8146 + "browser-md5-file": "^1.1.1",
  8147 + "compare-versions": "^5.0.1",
  8148 + "core-js": "^3.26.1",
  8149 + "custom-event-polyfill": "^1.0.7",
  8150 + "dialog-polyfill": "^0.5.6",
  8151 + "dom-autoscroller": "^2.3.4",
  8152 + "dompurify": "^3.0.5",
  8153 + "downloadjs": "^1.4.7",
  8154 + "dragula": "^3.7.3",
  8155 + "eventemitter3": "^4.0.7",
  8156 + "fast-deep-equal": "^3.1.3",
  8157 + "fast-json-patch": "^3.1.1",
  8158 + "fetch-ponyfill": "^7.1.0",
  8159 + "i18next": "22.4.12",
  8160 + "idb": "^7.1.1",
  8161 + "inputmask": "^5.0.9",
  8162 + "ismobilejs": "^1.1.1",
  8163 + "json-logic-js": "^2.0.2",
  8164 + "jstimezonedetect": "^1.0.7",
  8165 + "jwt-decode": "^3.1.2",
  8166 + "lodash": "^4.17.21",
  8167 + "moment": "^2.29.4",
  8168 + "moment-timezone": "^0.5.40",
  8169 + "native-promise-only": "^0.8.1",
  8170 + "quill": "^2.0.0-dev.3",
  8171 + "signature_pad": "^4.1.4",
  8172 + "string-hash": "^1.1.3",
  8173 + "tippy.js": "^6.3.7",
  8174 + "uuid": "^9.0.0",
  8175 + "vanilla-picker": "^2.12.1"
  8176 + }
  8177 + },
  8178 + "node_modules/formiojs/node_modules/uuid": {
  8179 + "version": "9.0.1",
  8180 + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
  8181 + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
  8182 + "funding": [
  8183 + "https://github.com/sponsors/broofa",
  8184 + "https://github.com/sponsors/ctavan"
  8185 + ],
  8186 + "bin": {
  8187 + "uuid": "dist/bin/uuid"
  8188 + }
  8189 + },
7914 8190 "node_modules/forwarded": {
7915 8191 "version": "0.2.0",
7916 8192 "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
... ... @@ -8041,6 +8317,14 @@
8041 8317 "url": "https://github.com/sponsors/ljharb"
8042 8318 }
8043 8319 },
  8320 + "node_modules/fuse.js": {
  8321 + "version": "6.6.2",
  8322 + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz",
  8323 + "integrity": "sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==",
  8324 + "engines": {
  8325 + "node": ">=10"
  8326 + }
  8327 + },
8044 8328 "node_modules/gensync": {
8045 8329 "version": "1.0.0-beta.2",
8046 8330 "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
... ... @@ -8820,6 +9104,28 @@
8820 9104 "node": ">=8.12.0"
8821 9105 }
8822 9106 },
  9107 + "node_modules/i18next": {
  9108 + "version": "22.4.12",
  9109 + "resolved": "https://registry.npmjs.org/i18next/-/i18next-22.4.12.tgz",
  9110 + "integrity": "sha512-2lE+vRXxQ3lGLub1CVbwgO0IfkLHmUSDVOAVdPh22CsxttMXi+35n2qgxh2wZIkKl6t/NMzPfgFPRDiFQOmiCg==",
  9111 + "funding": [
  9112 + {
  9113 + "type": "individual",
  9114 + "url": "https://locize.com"
  9115 + },
  9116 + {
  9117 + "type": "individual",
  9118 + "url": "https://locize.com/i18next.html"
  9119 + },
  9120 + {
  9121 + "type": "individual",
  9122 + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
  9123 + }
  9124 + ],
  9125 + "dependencies": {
  9126 + "@babel/runtime": "^7.20.6"
  9127 + }
  9128 + },
8823 9129 "node_modules/iconv-lite": {
8824 9130 "version": "0.4.24",
8825 9131 "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
... ... @@ -8844,6 +9150,11 @@
8844 9150 "node": ">= 6"
8845 9151 }
8846 9152 },
  9153 + "node_modules/idb": {
  9154 + "version": "7.1.1",
  9155 + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
  9156 + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ=="
  9157 + },
8847 9158 "node_modules/ieee754": {
8848 9159 "version": "1.2.1",
8849 9160 "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
... ... @@ -9034,6 +9345,11 @@
9034 9345 "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
9035 9346 "dev": true
9036 9347 },
  9348 + "node_modules/inputmask": {
  9349 + "version": "5.0.9",
  9350 + "resolved": "https://registry.npmjs.org/inputmask/-/inputmask-5.0.9.tgz",
  9351 + "integrity": "sha512-s0lUfqcEbel+EQXtehXqwCJGShutgieOaIImFKC/r4reYNvX3foyrChl6LOEvaEgxEbesePIrw1Zi2jhZaDZbQ=="
  9352 + },
9037 9353 "node_modules/inquirer": {
9038 9354 "version": "7.3.3",
9039 9355 "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
... ... @@ -9175,6 +9491,11 @@
9175 9491 "url": "https://github.com/sponsors/ljharb"
9176 9492 }
9177 9493 },
  9494 + "node_modules/is-array": {
  9495 + "version": "1.0.1",
  9496 + "resolved": "https://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz",
  9497 + "integrity": "sha512-gxiZ+y/u67AzpeFmAmo4CbtME/bs7J2C++su5zQzvQyaxUqVzkh69DI+jN+KZuSO6JaH6TIIU6M6LhqxMjxEpw=="
  9498 + },
9178 9499 "node_modules/is-array-buffer": {
9179 9500 "version": "3.0.5",
9180 9501 "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
... ... @@ -9779,12 +10100,22 @@
9779 10100 "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
9780 10101 "dev": true
9781 10102 },
  10103 + "node_modules/iselement": {
  10104 + "version": "1.1.4",
  10105 + "resolved": "https://registry.npmjs.org/iselement/-/iselement-1.1.4.tgz",
  10106 + "integrity": "sha512-4Q519eWmbHO1pbimiz7H1iJRUHVmAmfh0viSsUD+oAwVO4ntZt7gpf8i8AShVBTyOvRTZNYNBpUxOIvwZR+ffw=="
  10107 + },
9782 10108 "node_modules/isexe": {
9783 10109 "version": "2.0.0",
9784 10110 "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
9785 10111 "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
9786 10112 "dev": true
9787 10113 },
  10114 + "node_modules/ismobilejs": {
  10115 + "version": "1.1.1",
  10116 + "resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz",
  10117 + "integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw=="
  10118 + },
9788 10119 "node_modules/isobject": {
9789 10120 "version": "3.0.1",
9790 10121 "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
... ... @@ -9852,6 +10183,11 @@
9852 10183 "node": ">=6"
9853 10184 }
9854 10185 },
  10186 + "node_modules/json-logic-js": {
  10187 + "version": "2.0.5",
  10188 + "resolved": "https://registry.npmjs.org/json-logic-js/-/json-logic-js-2.0.5.tgz",
  10189 + "integrity": "sha512-rTT2+lqcuUmj4DgWfmzupZqQDA64AdmYqizzMPWj3DxGdfFNsxPpcNVSaTj4l8W2tG/+hg7/mQhxjU3aPacO6g=="
  10190 + },
9855 10191 "node_modules/json-parse-better-errors": {
9856 10192 "version": "1.0.2",
9857 10193 "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
... ... @@ -9924,6 +10260,16 @@
9924 10260 "node": ">=0.6.0"
9925 10261 }
9926 10262 },
  10263 + "node_modules/jstimezonedetect": {
  10264 + "version": "1.0.7",
  10265 + "resolved": "https://registry.npmjs.org/jstimezonedetect/-/jstimezonedetect-1.0.7.tgz",
  10266 + "integrity": "sha512-ARADHortktl9IZ1tr4GHwGPIAzgz3mLNCbR/YjWtRtc/O0o634O3NeFlpLjv95EvuDA5dc8z6yfgbS8nUc4zcQ=="
  10267 + },
  10268 + "node_modules/jwt-decode": {
  10269 + "version": "3.1.2",
  10270 + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
  10271 + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
  10272 + },
9927 10273 "node_modules/killable": {
9928 10274 "version": "1.0.1",
9929 10275 "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
... ... @@ -10085,14 +10431,18 @@
10085 10431 "node_modules/lodash": {
10086 10432 "version": "4.17.21",
10087 10433 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
10088   - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
10089   - "dev": true
  10434 + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
10090 10435 },
10091 10436 "node_modules/lodash-es": {
10092 10437 "version": "4.17.21",
10093 10438 "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
10094 10439 "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
10095 10440 },
  10441 + "node_modules/lodash.clonedeep": {
  10442 + "version": "4.5.0",
  10443 + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
  10444 + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
  10445 + },
10096 10446 "node_modules/lodash.debounce": {
10097 10447 "version": "4.0.8",
10098 10448 "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
... ... @@ -10105,6 +10455,12 @@
10105 10455 "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
10106 10456 "dev": true
10107 10457 },
  10458 + "node_modules/lodash.isequal": {
  10459 + "version": "4.5.0",
  10460 + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
  10461 + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
  10462 + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead."
  10463 + },
10108 10464 "node_modules/lodash.kebabcase": {
10109 10465 "version": "4.1.1",
10110 10466 "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
... ... @@ -10607,6 +10963,25 @@
10607 10963 "mkdirp": "bin/cmd.js"
10608 10964 }
10609 10965 },
  10966 + "node_modules/moment": {
  10967 + "version": "2.30.1",
  10968 + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
  10969 + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
  10970 + "engines": {
  10971 + "node": "*"
  10972 + }
  10973 + },
  10974 + "node_modules/moment-timezone": {
  10975 + "version": "0.5.48",
  10976 + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz",
  10977 + "integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==",
  10978 + "dependencies": {
  10979 + "moment": "^2.29.4"
  10980 + },
  10981 + "engines": {
  10982 + "node": "*"
  10983 + }
  10984 + },
10610 10985 "node_modules/move-concurrently": {
10611 10986 "version": "1.0.1",
10612 10987 "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
... ... @@ -10710,6 +11085,11 @@
10710 11085 "node": ">=0.10.0"
10711 11086 }
10712 11087 },
  11088 + "node_modules/native-promise-only": {
  11089 + "version": "0.8.1",
  11090 + "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz",
  11091 + "integrity": "sha512-zkVhZUA3y8mbz652WrL5x0fB0ehrBkulWT3TomAQ9iDtyXZvzKeEA6GPxAItBYeNYl5yngKRX612qHOhvMkDeg=="
  11092 + },
10713 11093 "node_modules/natural-compare": {
10714 11094 "version": "1.4.0",
10715 11095 "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
... ... @@ -10753,6 +11133,25 @@
10753 11133 "dev": true,
10754 11134 "optional": true
10755 11135 },
  11136 + "node_modules/node-fetch": {
  11137 + "version": "2.6.13",
  11138 + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz",
  11139 + "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==",
  11140 + "dependencies": {
  11141 + "whatwg-url": "^5.0.0"
  11142 + },
  11143 + "engines": {
  11144 + "node": "4.x || >=6.0.0"
  11145 + },
  11146 + "peerDependencies": {
  11147 + "encoding": "^0.1.0"
  11148 + },
  11149 + "peerDependenciesMeta": {
  11150 + "encoding": {
  11151 + "optional": true
  11152 + }
  11153 + }
  11154 + },
10756 11155 "node_modules/node-forge": {
10757 11156 "version": "0.10.0",
10758 11157 "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
... ... @@ -11480,6 +11879,11 @@
11480 11879 "no-case": "^2.2.0"
11481 11880 }
11482 11881 },
  11882 + "node_modules/parchment": {
  11883 + "version": "3.0.0",
  11884 + "resolved": "https://registry.npmjs.org/parchment/-/parchment-3.0.0.tgz",
  11885 + "integrity": "sha512-HUrJFQ/StvgmXRcQ1ftY6VEZUq3jA2t9ncFN4F84J/vN0/FPpQF+8FKXb3l6fLces6q0uOHj6NJn+2xvZnxO6A=="
  11886 + },
11483 11887 "node_modules/parent-module": {
11484 11888 "version": "1.0.1",
11485 11889 "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
... ... @@ -12696,6 +13100,38 @@
12696 13100 "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
12697 13101 "dev": true
12698 13102 },
  13103 + "node_modules/quill": {
  13104 + "version": "2.0.3",
  13105 + "resolved": "https://registry.npmjs.org/quill/-/quill-2.0.3.tgz",
  13106 + "integrity": "sha512-xEYQBqfYx/sfb33VJiKnSJp8ehloavImQ2A6564GAbqG55PGw1dAWUn1MUbQB62t0azawUS2CZZhWCjO8gRvTw==",
  13107 + "dependencies": {
  13108 + "eventemitter3": "^5.0.1",
  13109 + "lodash-es": "^4.17.21",
  13110 + "parchment": "^3.0.0",
  13111 + "quill-delta": "^5.1.0"
  13112 + },
  13113 + "engines": {
  13114 + "npm": ">=8.2.3"
  13115 + }
  13116 + },
  13117 + "node_modules/quill-delta": {
  13118 + "version": "5.1.0",
  13119 + "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz",
  13120 + "integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==",
  13121 + "dependencies": {
  13122 + "fast-diff": "^1.3.0",
  13123 + "lodash.clonedeep": "^4.5.0",
  13124 + "lodash.isequal": "^4.5.0"
  13125 + },
  13126 + "engines": {
  13127 + "node": ">= 12.0.0"
  13128 + }
  13129 + },
  13130 + "node_modules/quill/node_modules/eventemitter3": {
  13131 + "version": "5.0.1",
  13132 + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
  13133 + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="
  13134 + },
12699 13135 "node_modules/randombytes": {
12700 13136 "version": "2.1.0",
12701 13137 "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
... ... @@ -12809,6 +13245,14 @@
12809 13245 "node": ">=8.10.0"
12810 13246 }
12811 13247 },
  13248 + "node_modules/redux": {
  13249 + "version": "4.2.1",
  13250 + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
  13251 + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
  13252 + "dependencies": {
  13253 + "@babel/runtime": "^7.9.2"
  13254 + }
  13255 + },
12812 13256 "node_modules/reflect.getprototypeof": {
12813 13257 "version": "1.0.10",
12814 13258 "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
... ... @@ -13851,6 +14295,11 @@
13851 14295 "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
13852 14296 "dev": true
13853 14297 },
  14298 + "node_modules/signature_pad": {
  14299 + "version": "4.2.0",
  14300 + "resolved": "https://registry.npmjs.org/signature_pad/-/signature_pad-4.2.0.tgz",
  14301 + "integrity": "sha512-YLWysmaUBaC5wosAKkgbX7XI+LBv2w5L0QUcI6Jc4moHYzv9BUBJtAyNLpWzHjtjKTeWOH6bfP4a4pzf0UinfQ=="
  14302 + },
13854 14303 "node_modules/simple-swizzle": {
13855 14304 "version": "0.2.2",
13856 14305 "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
... ... @@ -14186,6 +14635,11 @@
14186 14635 "deprecated": "See https://github.com/lydell/source-map-url#deprecated",
14187 14636 "dev": true
14188 14637 },
  14638 + "node_modules/spark-md5": {
  14639 + "version": "2.0.2",
  14640 + "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-2.0.2.tgz",
  14641 + "integrity": "sha512-9WfT+FYBEvlrOOBEs484/zmbtSX4BlGjzXih1qIEWA1yhHbcqgcMHkiwXoWk2Sq1aJjLpcs6ZKV7JxrDNjIlNg=="
  14642 + },
14189 14643 "node_modules/spdx-correct": {
14190 14644 "version": "3.2.0",
14191 14645 "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
... ... @@ -14434,6 +14888,11 @@
14434 14888 "safe-buffer": "~5.1.0"
14435 14889 }
14436 14890 },
  14891 + "node_modules/string-hash": {
  14892 + "version": "1.1.3",
  14893 + "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz",
  14894 + "integrity": "sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A=="
  14895 + },
14437 14896 "node_modules/string-width": {
14438 14897 "version": "4.2.3",
14439 14898 "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
... ... @@ -15108,6 +15567,11 @@
15108 15567 "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
15109 15568 "dev": true
15110 15569 },
  15570 + "node_modules/ticky": {
  15571 + "version": "1.0.1",
  15572 + "resolved": "https://registry.npmjs.org/ticky/-/ticky-1.0.1.tgz",
  15573 + "integrity": "sha512-RX35iq/D+lrsqhcPWIazM9ELkjOe30MSeoBHQHSsRwd1YuhJO5ui1K1/R0r7N3mFvbLBs33idw+eR6j+w6i/DA=="
  15574 + },
15111 15575 "node_modules/timers-browserify": {
15112 15576 "version": "2.0.12",
15113 15577 "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
... ... @@ -15131,6 +15595,14 @@
15131 15595 "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-5.10.7.tgz",
15132 15596 "integrity": "sha512-9UUjaO0R7FxcFo0oxnd1lMs7H+D0Eh+dDVo5hKbVe1a+VB0nit97vOqlinj+YwgoBDt6/DSCUoWqAYlLI8BLYA=="
15133 15597 },
  15598 + "node_modules/tippy.js": {
  15599 + "version": "6.3.7",
  15600 + "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
  15601 + "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
  15602 + "dependencies": {
  15603 + "@popperjs/core": "^2.9.0"
  15604 + }
  15605 + },
15134 15606 "node_modules/tmp": {
15135 15607 "version": "0.0.33",
15136 15608 "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
... ... @@ -15229,6 +15701,11 @@
15229 15701 "node": ">=0.8"
15230 15702 }
15231 15703 },
  15704 + "node_modules/tr46": {
  15705 + "version": "0.0.3",
  15706 + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
  15707 + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
  15708 + },
15232 15709 "node_modules/tryer": {
15233 15710 "version": "1.0.1",
15234 15711 "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz",
... ... @@ -15303,6 +15780,11 @@
15303 15780 "url": "https://github.com/sponsors/sindresorhus"
15304 15781 }
15305 15782 },
  15783 + "node_modules/type-func": {
  15784 + "version": "1.0.3",
  15785 + "resolved": "https://registry.npmjs.org/type-func/-/type-func-1.0.3.tgz",
  15786 + "integrity": "sha512-YA90CUk+i00tWESPNRMahywXhAz+12NLJLKlOWrgHIbqaFXjdZrWstRghaibOW/IxhPjui4SmXxO/03XSGRIjA=="
  15787 + },
15306 15788 "node_modules/type-is": {
15307 15789 "version": "1.6.18",
15308 15790 "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
... ... @@ -15856,6 +16338,14 @@
15856 16338 "spdx-expression-parse": "^3.0.0"
15857 16339 }
15858 16340 },
  16341 + "node_modules/vanilla-picker": {
  16342 + "version": "2.12.3",
  16343 + "resolved": "https://registry.npmjs.org/vanilla-picker/-/vanilla-picker-2.12.3.tgz",
  16344 + "integrity": "sha512-qVkT1E7yMbUsB2mmJNFmaXMWE2hF8ffqzMMwe9zdAikd8u2VfnsVY2HQcOUi2F38bgbxzlJBEdS1UUhOXdF9GQ==",
  16345 + "dependencies": {
  16346 + "@sphinxxxx/color-conversion": "^2.2.2"
  16347 + }
  16348 + },
15859 16349 "node_modules/vary": {
15860 16350 "version": "1.1.2",
15861 16351 "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
... ... @@ -16413,6 +16903,11 @@
16413 16903 "defaults": "^1.0.3"
16414 16904 }
16415 16905 },
  16906 + "node_modules/webidl-conversions": {
  16907 + "version": "3.0.1",
  16908 + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
  16909 + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
  16910 + },
16416 16911 "node_modules/webpack": {
16417 16912 "version": "4.47.0",
16418 16913 "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.47.0.tgz",
... ... @@ -17161,6 +17656,15 @@
17161 17656 "node": ">=0.8.0"
17162 17657 }
17163 17658 },
  17659 + "node_modules/whatwg-url": {
  17660 + "version": "5.0.0",
  17661 + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
  17662 + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
  17663 + "dependencies": {
  17664 + "tr46": "~0.0.3",
  17665 + "webidl-conversions": "^3.0.0"
  17666 + }
  17667 + },
17164 17668 "node_modules/which": {
17165 17669 "version": "1.3.1",
17166 17670 "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
... ...
package.json
... ... @@ -12,6 +12,7 @@
12 12 "axios": "^0.21.1",
13 13 "echarts": "^5.6.0",
14 14 "element-ui": "^2.15.6",
  15 + "formiojs": "^4.21.7",
15 16 "qrcodejs2": "^0.0.2",
16 17 "tinymce": "^5.10.7",
17 18 "vue": "^2.6.14",
... ...
public/index.html
... ... @@ -5,6 +5,8 @@
5 5 <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 6 <meta name="viewport" content="width=device-width,initial-scale=1.0">
7 7 <link rel="icon" href="<%= BASE_URL %>favicon.ico">
  8 + <link rel="stylesheet" href="/formjs/css/form-js.css">
  9 +
8 10 <title><%= htmlWebpackPlugin.options.title %></title>
9 11 <!-- 全局脚本引入 -->
10 12 <script>
... ... @@ -20,6 +22,7 @@
20 22  
21 23 <!-- Qs 库 - 主 CDN -->
22 24 <script src="/js/jessibuca/jessibuca.js"></script>
  25 + <script src="/formjs/js/form-viewer.umd.js"></script>
23 26  
24 27  
25 28  
... ...
src/api/fee/createFeeByComboApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +// 获取费用套餐列表
  5 +export function listFeeCombo(params) {
  6 + return new Promise((resolve, reject) => {
  7 + const communityId = getCommunityId()
  8 + request({
  9 + url: '/feeCombo.listFeeCombo',
  10 + method: 'get',
  11 + params: {
  12 + ...params,
  13 + communityId
  14 + }
  15 + }).then(response => {
  16 + const res = response.data
  17 + resolve(res)
  18 + }).catch(error => {
  19 + reject(error)
  20 + })
  21 + })
  22 +}
  23 +
  24 +// 获取费用套餐成员列表
  25 +export function listFeeComboMember(params) {
  26 + return new Promise((resolve, reject) => {
  27 + request({
  28 + url: '/feeComboMember.listFeeComboMember',
  29 + method: 'get',
  30 + params
  31 + }).then(response => {
  32 + const res = response.data
  33 + resolve(res)
  34 + }).catch(error => {
  35 + reject(error)
  36 + })
  37 + })
  38 +}
  39 +
  40 +// 根据费用套餐创建费用
  41 +export function createFeeByCombo(data) {
  42 + return new Promise((resolve, reject) => {
  43 + const communityId = getCommunityId()
  44 + request({
  45 + url: '/fee.createFeeByCombo',
  46 + method: 'post',
  47 + data: {
  48 + ...data,
  49 + communityId
  50 + }
  51 + }).then(response => {
  52 + const res = response.data
  53 + resolve(res)
  54 + }).catch(error => {
  55 + reject(error)
  56 + })
  57 + })
  58 +}
0 59 \ No newline at end of file
... ...
src/api/fee/owePayFeeOrderApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +/**
  4 + * 获取欠费列表
  5 + * @param {Object} params 查询参数
  6 + * @returns {Promise}
  7 + */
  8 +export function listOweFees(params) {
  9 + return new Promise((resolve, reject) => {
  10 + request({
  11 + url: '/feeApi/listOweFees',
  12 + method: 'get',
  13 + params
  14 + }).then(response => {
  15 + const res = response.data
  16 + resolve(res)
  17 + }).catch(error => {
  18 + reject(error)
  19 + })
  20 + })
  21 +}
  22 +
  23 +/**
  24 + * 缴费
  25 + * @param {Object} data 缴费数据
  26 + * @returns {Promise}
  27 + */
  28 +export function payOweFee(data) {
  29 + return new Promise((resolve, reject) => {
  30 + request({
  31 + url: '/fee.payOweFee',
  32 + method: 'post',
  33 + data
  34 + }).then(response => {
  35 + const res = response.data
  36 + resolve(res)
  37 + }).catch(error => {
  38 + reject(error)
  39 + })
  40 + })
  41 +}
  42 +
  43 +/**
  44 + * 扫码支付
  45 + * @param {Object} data 支付数据
  46 + * @returns {Promise}
  47 + */
  48 +export function qrCodePayment(data) {
  49 + return new Promise((resolve, reject) => {
  50 + request({
  51 + url: '/payment.qrCodePayment',
  52 + method: 'post',
  53 + data
  54 + }).then(response => {
  55 + const res = response.data
  56 + resolve(res)
  57 + }).catch(error => {
  58 + reject(error)
  59 + })
  60 + })
  61 +}
  62 +
  63 +/**
  64 + * 检查支付状态
  65 + * @param {Object} data 检查参数
  66 + * @returns {Promise}
  67 + */
  68 +export function checkPayFinish(data) {
  69 + return new Promise((resolve, reject) => {
  70 + request({
  71 + url: '/payment.checkPayFinish',
  72 + method: 'post',
  73 + data
  74 + }).then(response => {
  75 + const res = response.data
  76 + resolve(res)
  77 + }).catch(error => {
  78 + reject(error)
  79 + })
  80 + })
  81 +}
  82 +
  83 +/**
  84 + * 获取打印页面列表
  85 + * @param {Object} params 查询参数
  86 + * @returns {Promise}
  87 + */
  88 +export function listFeePrintPages(params) {
  89 + return new Promise((resolve, reject) => {
  90 + request({
  91 + url: '/feePrintPage.listFeePrintPage',
  92 + method: 'get',
  93 + params
  94 + }).then(response => {
  95 + const res = response.data
  96 + resolve(res)
  97 + }).catch(error => {
  98 + reject(error)
  99 + })
  100 + })
  101 +}
0 102 \ No newline at end of file
... ...
src/api/fee/refundDepositFeeApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +/**
  5 + * 查询押金费用列表
  6 + * @param {Object} params 查询参数
  7 + * @returns {Promise}
  8 + */
  9 +export function queryFeeDeposit(params) {
  10 + return new Promise((resolve, reject) => {
  11 + // 确保社区ID存在
  12 + const communityId = params.communityId || getCommunityId()
  13 + if (!communityId) {
  14 + reject(new Error('Community ID is required'))
  15 + return
  16 + }
  17 +
  18 + request({
  19 + url: '/fee.queryFeeDeposit',
  20 + method: 'get',
  21 + params: {
  22 + ...params,
  23 + communityId
  24 + }
  25 + }).then(response => {
  26 + const res = response.data
  27 + if (res.code === 0) {
  28 + resolve({
  29 + data: res.data,
  30 + total: res.total,
  31 + records: res.records
  32 + })
  33 + } else {
  34 + reject(new Error(res.msg || 'Failed to fetch deposit fees'))
  35 + }
  36 + }).catch(error => {
  37 + reject(error)
  38 + })
  39 + })
  40 +}
  41 +
  42 +/**
  43 + * 保存退费申请
  44 + * @param {Object} data 退费数据
  45 + * @returns {Promise}
  46 + */
  47 +export function saveReturnPayFee(data) {
  48 + return new Promise((resolve, reject) => {
  49 + // 确保社区ID存在
  50 + const communityId = data.communityId || getCommunityId()
  51 + if (!communityId) {
  52 + reject(new Error('Community ID is required'))
  53 + return
  54 + }
  55 +
  56 + request({
  57 + url: '/returnPayFee.saveReturnPayFee',
  58 + method: 'post',
  59 + data: {
  60 + ...data,
  61 + communityId
  62 + }
  63 + }).then(response => {
  64 + const res = response.data
  65 + if (res.code === 0) {
  66 + resolve(res)
  67 + } else {
  68 + reject(new Error(res.msg || 'Failed to save refund application'))
  69 + }
  70 + }).catch(error => {
  71 + reject(error)
  72 + })
  73 + })
  74 +}
  75 +
  76 +/**
  77 + * 获取押金状态字典
  78 + * @returns {Promise}
  79 + */
  80 +export function getDepositStates() {
  81 + return new Promise((resolve, reject) => {
  82 + request({
  83 + url: '/dict/getDict',
  84 + method: 'get',
  85 + params: {
  86 + dictType: 'fee_state',
  87 + dictCode: 'deposit'
  88 + }
  89 + }).then(response => {
  90 + const res = response.data
  91 + if (res.code === 0) {
  92 + resolve(res.data)
  93 + } else {
  94 + reject(new Error(res.msg || 'Failed to get deposit states'))
  95 + }
  96 + }).catch(error => {
  97 + reject(error)
  98 + })
  99 + })
  100 +}
0 101 \ No newline at end of file
... ...
src/api/oa/newOaWorkflowApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 查询OA工作流表单配置
  4 +export function queryOaWorkflowForm(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/oaWorkflow/queryOaWorkflowForm',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 + resolve(res)
  13 + }).catch(error => {
  14 + reject(error)
  15 + })
  16 + })
  17 +}
  18 +
  19 +// 查询OA工作流表单数据
  20 +export function queryOaWorkflowFormData(params) {
  21 + return new Promise((resolve, reject) => {
  22 + request({
  23 + url: '/oaWorkflow/queryOaWorkflowFormData',
  24 + method: 'get',
  25 + params
  26 + }).then(response => {
  27 + const res = response.data
  28 + resolve(res)
  29 + }).catch(error => {
  30 + reject(error)
  31 + })
  32 + })
  33 +}
  34 +
  35 +// 保存OA工作流表单数据
  36 +export function saveOaWorkflowFormData(data) {
  37 + return new Promise((resolve, reject) => {
  38 + request({
  39 + url: '/oaWorkflow/saveOaWorkflowFormData',
  40 + method: 'post',
  41 + data
  42 + }).then(response => {
  43 + const res = response.data
  44 + resolve(res)
  45 + }).catch(error => {
  46 + reject(error)
  47 + })
  48 + })
  49 +}
  50 +
  51 +// 查询OA工作流用户任务表单数据
  52 +export function queryOaWorkflowUserTaskFormData(params) {
  53 + return new Promise((resolve, reject) => {
  54 + request({
  55 + url: '/oaWorkflow/queryOaWorkflowUserTaskFormData',
  56 + method: 'get',
  57 + params
  58 + }).then(response => {
  59 + const res = response.data
  60 + resolve(res)
  61 + }).catch(error => {
  62 + reject(error)
  63 + })
  64 + })
  65 +}
  66 +
  67 +// 查询OA工作流用户历史任务表单数据
  68 +export function queryOaWorkflowUserHisTaskFormData(params) {
  69 + return new Promise((resolve, reject) => {
  70 + request({
  71 + url: '/oaWorkflow/queryOaWorkflowUserHisTaskFormData',
  72 + method: 'get',
  73 + params
  74 + }).then(response => {
  75 + const res = response.data
  76 + resolve(res)
  77 + }).catch(error => {
  78 + reject(error)
  79 + })
  80 + })
  81 +}
  82 +
  83 +// 上传文件
  84 +export function uploadVedio(data, config) {
  85 + return new Promise((resolve, reject) => {
  86 + request({
  87 + url: '/uploadVedio/upload',
  88 + method: 'post',
  89 + data,
  90 + ...config
  91 + }).then(response => {
  92 + const res = response.data
  93 + resolve(res)
  94 + }).catch(error => {
  95 + reject(error)
  96 + })
  97 + })
  98 +}
  99 +
  100 +// 获取工作流图片
  101 +export function listRunWorkflowImage(params) {
  102 + return new Promise((resolve, reject) => {
  103 + request({
  104 + url: '/workflow/listRunWorkflowImage',
  105 + method: 'get',
  106 + params
  107 + }).then(response => {
  108 + const res = response.data
  109 + resolve(res)
  110 + }).catch(error => {
  111 + reject(error)
  112 + })
  113 + })
  114 +}
0 115 \ No newline at end of file
... ...
src/api/oa/newOaWorkflowDetailApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 查询工单表单
  4 +export function queryOaWorkflowForm(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/oaWorkflow/queryOaWorkflowForm',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + resolve(response.data)
  12 + }).catch(error => {
  13 + reject(error)
  14 + })
  15 + })
  16 +}
  17 +
  18 +// 查询工单表单数据
  19 +export function queryOaWorkflowFormData(params) {
  20 + return new Promise((resolve, reject) => {
  21 + request({
  22 + url: '/oaWorkflow/queryOaWorkflowFormData',
  23 + method: 'get',
  24 + params
  25 + }).then(response => {
  26 + resolve(response.data)
  27 + }).catch(error => {
  28 + reject(error)
  29 + })
  30 + })
  31 +}
  32 +
  33 +// 查询工单用户
  34 +export function queryOaWorkflowUser(params) {
  35 + return new Promise((resolve, reject) => {
  36 + request({
  37 + url: '/oaWorkflow/queryOaWorkflowUser',
  38 + method: 'get',
  39 + params
  40 + }).then(response => {
  41 + resolve(response.data)
  42 + }).catch(error => {
  43 + reject(error)
  44 + })
  45 + })
  46 +}
  47 +
  48 +// 获取下一个任务
  49 +export function getNextTask(params) {
  50 + return new Promise((resolve, reject) => {
  51 + request({
  52 + url: '/oaWorkflow/getNextTask',
  53 + method: 'get',
  54 + params
  55 + }).then(response => {
  56 + resolve(response.data)
  57 + }).catch(error => {
  58 + reject(error)
  59 + })
  60 + })
  61 +}
  62 +
  63 +// 审核工单
  64 +export function auditOaWorkflow(data) {
  65 + return new Promise((resolve, reject) => {
  66 + request({
  67 + url: '/oaWorkflow/auditOaWorkflow',
  68 + method: 'post',
  69 + data
  70 + }).then(response => {
  71 + resolve(response.data)
  72 + }).catch(error => {
  73 + reject(error)
  74 + })
  75 + })
  76 +}
  77 +
  78 +// 获取流程图
  79 +export function listRunWorkflowImage(params) {
  80 + return new Promise((resolve, reject) => {
  81 + request({
  82 + url: '/workflow.listRunWorkflowImage',
  83 + method: 'get',
  84 + params
  85 + }).then(response => {
  86 + resolve(response.data)
  87 + }).catch(error => {
  88 + reject(error)
  89 + })
  90 + })
  91 +}
  92 +
  93 +// 查询组织树
  94 +export function listOrgTree(params) {
  95 + return new Promise((resolve, reject) => {
  96 + request({
  97 + url: '/org.listOrgTree',
  98 + method: 'get',
  99 + params
  100 + }).then(response => {
  101 + resolve(response.data)
  102 + }).catch(error => {
  103 + reject(error)
  104 + })
  105 + })
  106 +}
  107 +
  108 +// 查询员工信息
  109 +export function queryStaffInfos(params) {
  110 + return new Promise((resolve, reject) => {
  111 + request({
  112 + url: '/query.staff.infos',
  113 + method: 'get',
  114 + params
  115 + }).then(response => {
  116 + resolve(response.data)
  117 + }).catch(error => {
  118 + reject(error)
  119 + })
  120 + })
  121 +}
0 122 \ No newline at end of file
... ...
src/api/oa/newOaWorkflowFormEditApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +/**
  4 + * 查询OA工作流表单
  5 + * @param {Object} params 查询参数
  6 + * @returns {Promise} Promise对象
  7 + */
  8 +export function queryOaWorkflowForm(params) {
  9 + return new Promise((resolve, reject) => {
  10 + request({
  11 + url: '/oaWorkflow/queryOaWorkflowForm',
  12 + method: 'get',
  13 + params
  14 + }).then(response => {
  15 + const res = response.data
  16 + resolve(res)
  17 + }).catch(error => {
  18 + reject(error)
  19 + })
  20 + })
  21 +}
  22 +
  23 +/**
  24 + * 查询OA工作流表单数据
  25 + * @param {Object} params 查询参数
  26 + * @returns {Promise} Promise对象
  27 + */
  28 +export function queryOaWorkflowFormData(params) {
  29 + return new Promise((resolve, reject) => {
  30 + request({
  31 + url: '/oaWorkflow/queryOaWorkflowFormData',
  32 + method: 'get',
  33 + params
  34 + }).then(response => {
  35 + const res = response.data
  36 + resolve(res)
  37 + }).catch(error => {
  38 + reject(error)
  39 + })
  40 + })
  41 +}
  42 +
  43 +/**
  44 + * 更新OA工作流表单数据
  45 + * @param {Object} data 表单数据
  46 + * @returns {Promise} Promise对象
  47 + */
  48 +export function updateOaWorkflowFormData(data) {
  49 + return new Promise((resolve, reject) => {
  50 + request({
  51 + url: '/oaWorkflow.updateOaWorkflowFormData',
  52 + method: 'post',
  53 + data,
  54 + headers: {
  55 + 'Content-Type': 'application/json'
  56 + }
  57 + }).then(response => {
  58 + const res = response.data
  59 + resolve(res)
  60 + }).catch(error => {
  61 + reject(error)
  62 + })
  63 + })
  64 +}
  65 +
  66 +/**
  67 + * 上传视频文件
  68 + * @param {FormData} formData 表单数据
  69 + * @param {Object} config 配置项
  70 + * @returns {Promise} Promise对象
  71 + */
  72 +export function uploadVedio(formData, config) {
  73 + return new Promise((resolve, reject) => {
  74 + request({
  75 + url: '/uploadVedio/upload',
  76 + method: 'post',
  77 + data: formData,
  78 + onUploadProgress: config.onUploadProgress,
  79 + headers: {
  80 + 'Content-Type': 'multipart/form-data'
  81 + }
  82 + }).then(response => {
  83 + const res = response.data
  84 + resolve(res)
  85 + }).catch(error => {
  86 + reject(error)
  87 + })
  88 + })
  89 +}
0 90 \ No newline at end of file
... ...
src/components/fee/carDetailOwner.vue
... ... @@ -146,7 +146,7 @@ export default {
146 146 }
147 147 },
148 148 _toCarDetailOwnerDetail(owner) {
149   - window.open(`/#/pages/owner/ownerDetail?ownerId=${owner.ownerId}`)
  149 + window.open(`/#/views/owner/ownerDetail?ownerId=${owner.ownerId}`)
150 150 },
151 151 open(params) {
152 152 this.handleSwitch(params)
... ...
src/components/fee/chooseFeeCombo.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('chooseFeeCombo.title')"
  4 + :visible.sync="dialogVisible"
  5 + width="70%"
  6 + @close="handleClose"
  7 + >
  8 +
  9 + <div class="filter-container">
  10 + <el-input
  11 + v-model="currentFeeComboName"
  12 + :placeholder="$t('chooseFeeCombo.searchPlaceholder')"
  13 + class="filter-item"
  14 + style="width: 300px; margin-right: 10px;"
  15 + @keyup.enter.native="handleFilter"
  16 + />
  17 + <el-button
  18 + type="primary"
  19 + class="filter-item"
  20 + @click="handleFilter"
  21 + >
  22 + {{ $t('common.search') }}
  23 + </el-button>
  24 + </div>
  25 +
  26 + <el-table
  27 + v-loading="loading"
  28 + :data="feeCombos"
  29 + border
  30 + fit
  31 + highlight-current-row
  32 + style="width: 100%; margin-top: 20px;"
  33 + >
  34 + <el-table-column
  35 + :label="$t('chooseFeeCombo.comboName')"
  36 + prop="comboName"
  37 + align="center"
  38 + />
  39 + <el-table-column
  40 + :label="$t('chooseFeeCombo.createTime')"
  41 + prop="createTime"
  42 + align="center"
  43 + />
  44 + <el-table-column
  45 + :label="$t('chooseFeeCombo.remark')"
  46 + prop="remark"
  47 + align="center"
  48 + />
  49 + <el-table-column
  50 + :label="$t('common.operation')"
  51 + align="center"
  52 + width="120"
  53 + >
  54 + <template slot-scope="scope">
  55 + <el-button
  56 + type="primary"
  57 + size="mini"
  58 + @click="handleChoose(scope.row)"
  59 + >
  60 + {{ $t('common.choose') }}
  61 + </el-button>
  62 + </template>
  63 + </el-table-column>
  64 + </el-table>
  65 +
  66 + <el-pagination
  67 + :current-page="pagination.current"
  68 + :page-sizes="[10, 20, 30, 50]"
  69 + :page-size="pagination.size"
  70 + :total="pagination.total"
  71 + layout="total, sizes, prev, pager, next, jumper"
  72 + @size-change="handleSizeChange"
  73 + @current-change="handleCurrentChange"
  74 + />
  75 + </el-dialog>
  76 +</template>
  77 +
  78 +<script>
  79 +import { getCommunityId } from '@/api/community/communityApi'
  80 +import { listFeeCombo } from '@/api/fee/createFeeByComboApi'
  81 +
  82 +export default {
  83 + name: 'ChooseFeeCombo',
  84 + data() {
  85 + return {
  86 + dialogVisible: false,
  87 + loading: false,
  88 + feeCombos: [],
  89 + currentFeeComboName: '',
  90 + pagination: {
  91 + current: 1,
  92 + size: 10,
  93 + total: 0
  94 + },
  95 + communityId: ''
  96 + }
  97 + },
  98 + created() {
  99 + this.communityId = getCommunityId()
  100 + },
  101 + methods: {
  102 + open() {
  103 + this.dialogVisible = true
  104 + this.resetSearch()
  105 + this.getList()
  106 + },
  107 + handleClose() {
  108 + this.dialogVisible = false
  109 + },
  110 + resetSearch() {
  111 + this.currentFeeComboName = ''
  112 + this.pagination.current = 1
  113 + },
  114 + handleFilter() {
  115 + this.pagination.current = 1
  116 + this.getList()
  117 + },
  118 + async getList() {
  119 + try {
  120 + this.loading = true
  121 + const params = {
  122 + page: this.pagination.current,
  123 + row: this.pagination.size,
  124 + communityId: this.communityId,
  125 + name: this.currentFeeComboName
  126 + }
  127 + const { data, total } = await listFeeCombo(params)
  128 + this.feeCombos = data
  129 + this.pagination.total = total
  130 + } catch (error) {
  131 + console.error('Failed to load fee combos:', error)
  132 + } finally {
  133 + this.loading = false
  134 + }
  135 + },
  136 + handleSizeChange(val) {
  137 + this.pagination.size = val
  138 + this.getList()
  139 + },
  140 + handleCurrentChange(val) {
  141 + this.pagination.current = val
  142 + this.getList()
  143 + },
  144 + handleChoose(row) {
  145 + this.$emit('chooseFeeCombo', row)
  146 + this.$emit('loadData', { feeComboId: row.feeComboId })
  147 + this.dialogVisible = false
  148 + }
  149 + }
  150 +}
  151 +</script>
  152 +
  153 +<style lang="scss" scoped>
  154 +.filter-container {
  155 + margin-bottom: 20px;
  156 + display: flex;
  157 + align-items: center;
  158 +}
  159 +
  160 +.el-pagination {
  161 + margin-top: 20px;
  162 + text-align: right;
  163 +}
  164 +</style>
0 165 \ No newline at end of file
... ...
src/components/fee/payFeeUserAccount.vue
... ... @@ -123,7 +123,7 @@ export default {
123 123 this.listUserAccount()
124 124 },
125 125 openAddUserAmountModal(userAccount) {
126   - window.open(`/#/pages/owner/ownerDetail?ownerId=${userAccount.objId}&currentTab=ownerDetailAccount`)
  126 + window.open(`/#/views/owner/ownerDetail?ownerId=${userAccount.objId}&currentTab=ownerDetailAccount`)
127 127 },
128 128 computeFeeUserAmount(acctId) {
129 129 let totalUserAmount = 0.0
... ...
src/components/fee/printOwnFee.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('printOwnFee.printTitle')"
  4 + :visible.sync="visible"
  5 + width="50%"
  6 + @close="handleClose">
  7 + <div class="print-own-fee-container">
  8 + <el-form label-width="120px">
  9 + <el-form-item :label="$t('printOwnFee.validityDate')" required>
  10 + <el-date-picker
  11 + v-model="printOwnFeeInfo.targetEndTime"
  12 + type="date"
  13 + :placeholder="$t('printOwnFee.selectEndTime')"
  14 + style="width:100%"
  15 + value-format="yyyy-MM-dd">
  16 + </el-date-picker>
  17 + </el-form-item>
  18 + </el-form>
  19 + </div>
  20 + <span slot="footer" class="dialog-footer">
  21 + <el-button @click="handleCancel">{{ $t('common.cancel') }}</el-button>
  22 + <el-button type="primary" @click="handleConfirm">{{ $t('common.confirm') }}</el-button>
  23 + </span>
  24 + </el-dialog>
  25 +</template>
  26 +
  27 +<script>
  28 +export default {
  29 + name: 'PrintOwnFee',
  30 + data() {
  31 + return {
  32 + visible: false,
  33 + printOwnFeeInfo: {
  34 + payObjId: '',
  35 + payObjType: '',
  36 + payObjName: '',
  37 + targetEndTime: ''
  38 + }
  39 + }
  40 + },
  41 + methods: {
  42 + open(params) {
  43 + this.clearPrintOwnFeeInfo()
  44 + Object.assign(this.printOwnFeeInfo, params)
  45 + this.visible = true
  46 + },
  47 + handleClose() {
  48 + this.clearPrintOwnFeeInfo()
  49 + },
  50 + handleCancel() {
  51 + this.visible = false
  52 + this.clearPrintOwnFeeInfo()
  53 + },
  54 + handleConfirm() {
  55 + if (!this.printOwnFeeInfo.targetEndTime) {
  56 + this.$message.warning(this.$t('printOwnFee.selectEndTimeTip'))
  57 + return
  58 + }
  59 + this._openPrintOweFeePage()
  60 + this.visible = false
  61 + },
  62 + _openPrintOweFeePage() {
  63 + window.open(`/print.html#/pages/property/printOweFee?payObjId=${this.printOwnFeeInfo.payObjId
  64 + }&payObjType=${this.printOwnFeeInfo.payObjType
  65 + }&payObjName=${encodeURIComponent(this.printOwnFeeInfo.payObjName)
  66 + }&targetEndTime=${this.printOwnFeeInfo.targetEndTime}`)
  67 + },
  68 + clearPrintOwnFeeInfo() {
  69 + this.printOwnFeeInfo = {
  70 + payObjId: '',
  71 + payObjType: '',
  72 + payObjName: '',
  73 + targetEndTime: ''
  74 + }
  75 + }
  76 + }
  77 +}
  78 +</script>
  79 +
  80 +<style lang="scss" scoped>
  81 +.print-own-fee-container {
  82 + padding: 20px;
  83 +}
  84 +</style>
0 85 \ No newline at end of file
... ...
src/components/fee/returnPayFee.vue
1 1 <template>
2   - <el-dialog
3   - :title="$t('returnPayFee.fillRefundReason')"
  2 + <el-dialog
  3 + :title="$t('returnPayFee.fillRefundReason')"
4 4 :visible.sync="visible"
5 5 width="50%"
6   - center
  6 + @close="handleClose"
7 7 >
8   - <el-form :model="returnFeeDetailInfo" label-width="120px">
9   - <el-form-item :label="$t('returnPayFee.paymentId')">
10   - <el-input v-model="returnFeeDetailInfo.detailId" readonly />
  8 + <el-form
  9 + ref="form"
  10 + :model="formData"
  11 + label-width="120px"
  12 + label-position="left"
  13 + >
  14 + <el-form-item :label="$t('returnPayFee.payment') + 'ID'">
  15 + <el-input v-model="formData.detailId" readonly />
11 16 </el-form-item>
12 17  
13   - <el-form-item :label="`${$t('returnPayFee.cycle')}(单位月)`">
14   - <el-input v-model="returnFeeDetailInfo.cycles" readonly />
  18 + <el-form-item :label="$t('returnPayFee.cycle') + $t('returnPayFee.monthUnit')">
  19 + <el-input v-model="formData.cycles" readonly />
15 20 </el-form-item>
16 21  
17 22 <el-form-item :label="$t('returnPayFee.receivableAmount')">
18   - <el-input v-model="returnFeeDetailInfo.receivableAmount" readonly />
  23 + <el-input v-model="formData.receivableAmount" readonly />
19 24 </el-form-item>
20 25  
21 26 <el-form-item :label="$t('returnPayFee.receivedAmount')">
22   - <el-input v-model="returnFeeDetailInfo.receivedAmount" readonly />
  27 + <el-input v-model="formData.receivedAmount" readonly />
23 28 </el-form-item>
24 29  
25 30 <el-form-item :label="$t('returnPayFee.paymentTime')">
26   - <el-input v-model="returnFeeDetailInfo.payTime" readonly />
  31 + <el-input v-model="formData.payTime" readonly />
27 32 </el-form-item>
28 33  
29   - <el-form-item :label="$t('returnPayFee.refundReason')" required>
  34 + <el-form-item
  35 + :label="$t('returnPayFee.refundReason')"
  36 + prop="reason"
  37 + :rules="[
  38 + { required: true, message: $t('returnPayFee.reasonRequired'), trigger: 'blur' },
  39 + { max: 200, message: $t('returnPayFee.reasonMaxLength'), trigger: 'blur' }
  40 + ]"
  41 + >
30 42 <el-input
  43 + v-model="formData.reason"
31 44 type="textarea"
32 45 :rows="3"
33   - v-model="returnFeeDetailInfo.reason"
34   - :placeholder="$t('returnPayFee.enterRefundReason')"
35   - ></el-input>
  46 + :placeholder="$t('returnPayFee.reasonPlaceholder')"
  47 + />
36 48 </el-form-item>
37 49 </el-form>
38 50  
39 51 <span slot="footer" class="dialog-footer">
40 52 <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button>
41   - <el-button type="primary" @click="submitReturnPayFee">{{ $t('returnPayFee.submitRefund') }}</el-button>
  53 + <el-button
  54 + type="primary"
  55 + @click="submitReturnPayFee"
  56 + :loading="loading"
  57 + >
  58 + {{ $t('returnPayFee.submitRefund') }}
  59 + </el-button>
42 60 </span>
43 61 </el-dialog>
44 62 </template>
45 63  
46 64 <script>
47   -import { getCommunityId } from '@/api/community/communityApi'
48   -import { saveReturnPayFee } from '@/api/fee/propertyFeeApi'
  65 +import { saveReturnPayFee } from '@/api/fee/refundDepositFeeApi'
49 66  
50 67 export default {
51 68 name: 'ReturnPayFee',
52 69 data() {
53 70 return {
54 71 visible: false,
55   - returnFeeDetailInfo: {
  72 + loading: false,
  73 + formData: {
56 74 detailId: '',
57 75 cycles: '',
58 76 receivableAmount: '',
... ... @@ -63,64 +81,50 @@ export default {
63 81 feeId: '',
64 82 feeTypeCd: '',
65 83 configId: ''
66   - },
67   - communityId: ''
  84 + }
68 85 }
69 86 },
70   - created() {
71   - this.communityId = getCommunityId()
72   - },
73 87 methods: {
74   - open(params) {
75   - this.returnFeeDetailInfo = {
76   - ...this.returnFeeDetailInfo,
77   - communityId: params.communityId || this.communityId,
78   - payTime: params.createTime,
79   - detailId: params.detailId,
80   - cycles: params.cycles,
81   - receivableAmount: params.receivableAmount,
82   - receivedAmount: params.receivedAmount,
83   - feeId: params.mainFeeInfo.feeId || '',
84   - feeTypeCd: params.mainFeeInfo.feeTypeCd || '',
85   - configId: params.mainFeeInfo.configId || '',
86   - remark: params.remark || ''
87   - }
  88 + open(data) {
  89 + this.resetForm()
  90 + Object.assign(this.formData, data)
88 91 this.visible = true
89 92 },
90   - returnPayFeeValidate() {
91   - if (!this.returnFeeDetailInfo.reason) {
92   - this.$message.error(this.$t('returnPayFee.refundReasonRequired'))
93   - return false
94   - }
95   - if (this.returnFeeDetailInfo.reason.length > 200) {
96   - this.$message.error(this.$t('returnPayFee.refundReasonTooLong'))
97   - return false
  93 + resetForm() {
  94 + this.$refs.form && this.$refs.form.resetFields()
  95 + this.formData = {
  96 + detailId: '',
  97 + cycles: '',
  98 + receivableAmount: '',
  99 + receivedAmount: '',
  100 + payTime: '',
  101 + reason: '',
  102 + communityId: '',
  103 + feeId: '',
  104 + feeTypeCd: '',
  105 + configId: ''
98 106 }
99   - return true
  107 + },
  108 + handleClose() {
  109 + this.resetForm()
100 110 },
101 111 async submitReturnPayFee() {
102   - if (!this.returnPayFeeValidate()) return
103   -
104 112 try {
105   - const res = await saveReturnPayFee(this.returnFeeDetailInfo)
106   - if (res.code === 0) {
107   - this.$message.success(this.$t('common.operateSuccess'))
108   - this.visible = false
109   - this.$emit('success')
110   - } else {
111   - this.$message.error(res.msg || this.$t('common.operateFailed'))
112   - }
  113 + const valid = await this.$refs.form.validate()
  114 + if (!valid) return
  115 +
  116 + this.loading = true
  117 + await saveReturnPayFee(this.formData)
  118 +
  119 + this.$message.success(this.$t('common.operateSuccess'))
  120 + this.visible = false
  121 + this.$emit('success')
113 122 } catch (error) {
114   - console.error('提交退费申请失败:', error)
115   - this.$message.error(this.$t('common.operateFailed'))
  123 + console.error(error)
  124 + } finally {
  125 + this.loading = false
116 126 }
117 127 }
118 128 }
119 129 }
120   -</script>
121   -
122   -<style scoped>
123   -.el-input, .el-textarea {
124   - width: 100%;
125   -}
126   -</style>
127 130 \ No newline at end of file
  131 +</script>
128 132 \ No newline at end of file
... ...
src/components/fee/simplifyRoomFee.vue
... ... @@ -385,7 +385,7 @@ export default {
385 385 },
386 386 toOwnerPayFee() {
387 387 this.$router.push({
388   - path: '/property/owePayFeeOrder',
  388 + path: '/views/fee/owePayFeeOrder',
389 389 query: {
390 390 payObjId: this.simplifyRoomFeeInfo.roomId,
391 391 payObjType: '3333',
... ... @@ -544,7 +544,7 @@ export default {
544 544 },
545 545 openRoomCreateFeeComboModal() {
546 546 this.$router.push({
547   - path: '/property/createFeeByCombo',
  547 + path: '/views/fee/createFeeByCombo',
548 548 query: {
549 549 payerObjId: this.simplifyRoomFeeInfo.roomId,
550 550 payerObjName: this.simplifyRoomFeeInfo.roomName,
... ...
src/components/inspection/selectMapPos.vue
... ... @@ -50,6 +50,8 @@ export default {
50 50 center = new TMap.LatLng(data.lat, data.lng)
51 51 zoom = 16
52 52 }
  53 +
  54 + let TMap = window.TMap
53 55  
54 56 // 创建地图实例
55 57 this.map = new TMap.Map(document.getElementById(this.elementId), {
... ... @@ -88,6 +90,8 @@ export default {
88 90 }
89 91  
90 92 // 创建新标记
  93 + let TMap = window.TMap
  94 +
91 95 this.marker = new TMap.MultiMarker({
92 96 map: this.map,
93 97 styles: {
... ... @@ -112,7 +116,8 @@ export default {
112 116  
113 117 updatePosition(lat, lng) {
114 118 if (!this.map) return
115   -
  119 + let TMap = window.TMap
  120 +
116 121 const position = new TMap.LatLng(lat, lng)
117 122 this.addMarker(position)
118 123 }
... ...
src/components/oa/newOaWorkflowFinish.vue 0 → 100644
  1 +<template>
  2 + <div class="new-oa-workflow-finish">
  3 + <el-card class="search-card">
  4 + <div slot="header" class="flex justify-between">
  5 + <span>{{ $t('newOaWorkflowFinish.searchTitle') }}</span>
  6 + </div>
  7 + <el-form :inline="true" :model="conditions" class="search-form">
  8 + <el-form-item>
  9 + <el-input v-model="conditions.createUserName" :placeholder="$t('newOaWorkflowFinish.enterApplicant')"
  10 + clearable />
  11 + </el-form-item>
  12 + <el-form-item>
  13 + <el-date-picker v-model="conditions.startTime" type="datetime"
  14 + :placeholder="$t('newOaWorkflowFinish.enterStartTime')" value-format="yyyy-MM-dd HH:mm:ss" />
  15 + </el-form-item>
  16 + <el-form-item>
  17 + <el-date-picker v-model="conditions.endTime" type="datetime"
  18 + :placeholder="$t('newOaWorkflowFinish.enterEndTime')" value-format="yyyy-MM-dd HH:mm:ss" />
  19 + </el-form-item>
  20 + <el-form-item>
  21 + <el-button type="primary" @click="queryOaWorkflowFinish">
  22 + <i class="el-icon-search"></i>
  23 + {{ $t('common.search') }}
  24 + </el-button>
  25 + </el-form-item>
  26 + </el-form>
  27 + </el-card>
  28 +
  29 + <el-card class="table-card">
  30 + <div slot="header" class="flex justify-between">
  31 + <span>{{ $t('newOaWorkflowFinish.doneProcess') }}</span>
  32 + </div>
  33 + <el-table :data="finishs" border style="width: 100%" v-loading="loading">
  34 + <el-table-column prop="create_user_name" :label="$t('newOaWorkflowFinish.applicant')" align="center" />
  35 + <template v-for="(item, index) in formJson">
  36 + <el-table-column v-if="item.type === 'text' || item.type === 'textarea'" :key="index" :label="item.label"
  37 + align="center">
  38 + <template slot-scope="scope">
  39 + {{ scope.row[item.key] }}
  40 + </template>
  41 + </el-table-column>
  42 + </template>
  43 + <el-table-column :label="$t('newOaWorkflowFinish.status')" align="center">
  44 + <template slot-scope="scope">
  45 + {{ getNewOaWorkflowFinishState(scope.row) }}
  46 + </template>
  47 + </el-table-column>
  48 + <el-table-column prop="create_time" :label="$t('newOaWorkflowFinish.createTime')" align="center" />
  49 + <el-table-column :label="$t('common.operation')" align="center" width="150">
  50 + <template slot-scope="scope">
  51 + <el-button size="mini" @click="openNewOaWorkflowFinishDetail(scope.row)">
  52 + {{ $t('common.detail') }}
  53 + </el-button>
  54 + </template>
  55 + </el-table-column>
  56 + </el-table>
  57 +
  58 + <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page.current"
  59 + :page-sizes="[10, 20, 30, 50]" :page-size="page.size" layout="total, sizes, prev, pager, next, jumper"
  60 + :total="total" class="pagination" />
  61 + </el-card>
  62 + </div>
  63 +</template>
  64 +
  65 +<script>
  66 +import { queryOaWorkflowForm, queryOaWorkflowUserHisTaskFormData } from '@/api/oa/newOaWorkflowApi'
  67 +
  68 +export default {
  69 + name: 'NewOaWorkflowFinish',
  70 + data() {
  71 + return {
  72 + loading: false,
  73 + finishs: [],
  74 + formJson: [],
  75 + total: 0,
  76 + page: {
  77 + current: 1,
  78 + size: 10
  79 + },
  80 + conditions: {
  81 + createUserName: '',
  82 + startTime: '',
  83 + endTime: '',
  84 + flowId: this.flowId
  85 + }
  86 + }
  87 + },
  88 + created() {
  89 + },
  90 + methods: {
  91 + open(params) {
  92 + this.conditions.flowId = params.flowId
  93 + this.listOaWorkFlowFinishForm()
  94 + this.listOaWorkflowFinishs()
  95 + },
  96 + async listOaWorkFlowFinishForm() {
  97 + try {
  98 + const res = await queryOaWorkflowForm({
  99 + page: 1,
  100 + row: 1,
  101 + flowId: this.conditions.flowId
  102 + })
  103 + this.formJson = JSON.parse(res.data[0].formJson).components
  104 + } catch (error) {
  105 + console.error('获取表单配置失败:', error)
  106 + }
  107 + },
  108 + async listOaWorkflowFinishs() {
  109 + this.loading = true
  110 + try {
  111 + const params = {
  112 + ...this.conditions,
  113 + page: this.page.current,
  114 + row: this.page.size
  115 + }
  116 + const { data, total } = await queryOaWorkflowUserHisTaskFormData(params)
  117 + this.finishs = data
  118 + this.total = total
  119 + } catch (error) {
  120 + console.error('获取已办流程数据失败:', error)
  121 + } finally {
  122 + this.loading = false
  123 + }
  124 + },
  125 + queryOaWorkflowFinish() {
  126 + this.page.current = 1
  127 + this.listOaWorkflowFinishs()
  128 + },
  129 + handleSizeChange(val) {
  130 + this.page.size = val
  131 + this.listOaWorkflowFinishs()
  132 + },
  133 + handleCurrentChange(val) {
  134 + this.page.current = val
  135 + this.listOaWorkflowFinishs()
  136 + },
  137 + openNewOaWorkflowFinishDetail(finish) {
  138 + this.$router.push({
  139 + path: '/views/oa/newOaWorkflowDetail',
  140 + query: {
  141 + id: finish.id,
  142 + flowId: this.conditions.flowId
  143 + }
  144 + })
  145 + },
  146 + getNewOaWorkflowFinishState(finish) {
  147 + if (!Object.prototype.hasOwnProperty.call(finish, 'state')) return this.$t('common.unknown')
  148 +
  149 + const stateMap = {
  150 + '1001': this.$t('newOaWorkflowFinish.stateApply'),
  151 + '1002': this.$t('newOaWorkflowFinish.statePending'),
  152 + '1003': this.$t('newOaWorkflowFinish.stateReturned'),
  153 + '1004': this.$t('newOaWorkflowFinish.stateDelegate'),
  154 + '1005': this.$t('newOaWorkflowFinish.stateCompleted')
  155 + }
  156 +
  157 + return stateMap[finish.state] || this.$t('common.unknown')
  158 + }
  159 + }
  160 +}
  161 +</script>
  162 +
  163 +<style lang="scss" scoped>
  164 +.new-oa-workflow-finish {
  165 + .search-card {
  166 + margin-bottom: 20px;
  167 +
  168 + .search-form {
  169 + .el-form-item {
  170 + margin-bottom: 0;
  171 + }
  172 + }
  173 + }
  174 +
  175 + .pagination {
  176 + margin-top: 20px;
  177 + text-align: right;
  178 + }
  179 +}
  180 +</style>
0 181 \ No newline at end of file
... ...
src/components/oa/newOaWorkflowForm.vue 0 → 100644
  1 +<template>
  2 + <div class="new-oa-workflow-form">
  3 + <el-card class="form-card">
  4 + <div class="form-container" id="form-container">
  5 +
  6 + <div class="upload-wrapper">
  7 + <upload-file ref="uploadFile" :call-back-listener="callBackListener" :call-back-function="callBackFunction" />
  8 + </div>
  9 + </div>
  10 +
  11 + </el-card>
  12 + </div>
  13 +</template>
  14 +
  15 +<script>
  16 +import UploadFile from '@/components/upload/uploadFile'
  17 +import { queryOaWorkflowForm, saveOaWorkflowFormData } from '@/api/oa/newOaWorkflowApi'
  18 +//import { Formio } from 'formiojs'
  19 +
  20 +export default {
  21 + name: 'NewOaWorkflowForm',
  22 + components: { UploadFile },
  23 +
  24 + data() {
  25 + return {
  26 + formJson: {},
  27 + fileName: '',
  28 + realFileName: '',
  29 + callBackListener: 'newOaWorkflowForm',
  30 + callBackFunction: 'fileName',
  31 + formViewer: null
  32 + }
  33 + },
  34 + mounted() {
  35 + },
  36 + methods: {
  37 + open(params) {
  38 + this.flowId = params.flowId
  39 + this.listOaWorkflowForm()
  40 + },
  41 + async listOaWorkflowForm() {
  42 + try {
  43 + const res = await queryOaWorkflowForm({
  44 + page: 1,
  45 + row: 1,
  46 + flowId: this.flowId
  47 + })
  48 + console.log(res)
  49 + this.formJson = JSON.parse(res.data[0].formJson)
  50 + this.initForm()
  51 + } catch (error) {
  52 + console.error('获取表单配置失败:', error)
  53 + }
  54 + },
  55 + initForm() {
  56 + const container = document.getElementById('form-container')
  57 +
  58 + const form = window.FormViewer.createForm({
  59 + container,
  60 + schema: this.formJson
  61 + });
  62 + console.log(form);
  63 + form.then((_from) => {
  64 + _from.on('submit', (event) => {
  65 + this.submitFormData(event.data, event.errors);
  66 + })
  67 + }).then((_from) => {
  68 + console.log(_from);
  69 + let node = document.querySelector('.fjs-form .uploadFile');
  70 + const submitBtn = document.querySelector('.fjs-form .fjs-form-field-button');
  71 + submitBtn.parentNode.insertBefore(node, submitBtn);
  72 + });
  73 + },
  74 + async submitFormData(data, errors) {
  75 + if (Object.keys(errors).length !== 0) return
  76 +
  77 + const formData = {
  78 + ...data,
  79 + flowId: this.flowId,
  80 + fileName: this.fileName,
  81 + realFileName: this.realFileName
  82 + }
  83 +
  84 + try {
  85 + const res = await saveOaWorkflowFormData(formData)
  86 + if (res.code === 0) {
  87 + this.$message.success(this.$t('common.submitSuccess'))
  88 + this.resetForm()
  89 + this.$emit('switch-tab', 'newOaWorkflowPool')
  90 + } else {
  91 + this.$message.error(res.msg)
  92 + }
  93 + } catch (error) {
  94 + console.error('提交表单失败:', error)
  95 + this.$message.error(this.$t('common.submitFailed'))
  96 + }
  97 + },
  98 + resetForm() {
  99 + if (this.formViewer) {
  100 + this.formViewer.destroy()
  101 + }
  102 + this.$refs.uploadFile.clear()
  103 + this.fileName = ''
  104 + this.realFileName = ''
  105 + this.formJson = {}
  106 + },
  107 + handleFileUpload(fileInfo) {
  108 + this.fileName = fileInfo.fileName
  109 + this.realFileName = fileInfo.realFileName
  110 + }
  111 + }
  112 +}
  113 +</script>
  114 +
  115 +<style lang="scss">
  116 +.new-oa-workflow-form {
  117 + .form-card {
  118 + padding: 20px;
  119 + border-radius: 4px;
  120 + border: 1px solid #ebeef5;
  121 + background-color: #fff;
  122 + box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  123 +
  124 + .form-container {
  125 +
  126 + .upload-wrapper {
  127 + margin-bottom: 20px;
  128 + padding: 20px;
  129 + background-color: #fafafa;
  130 + border: 1px solid #e4e7ed;
  131 + border-radius: 4px;
  132 + }
  133 + }
  134 + }
  135 +}
  136 +
  137 +// 全局Formio样式覆盖(不使用scoped)
  138 +
  139 +// Formio Element UI 风格样式
  140 +.formio-form {
  141 + font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif !important;
  142 +
  143 + .form-group {
  144 + margin-bottom: 22px !important;
  145 + text-align: left !important;
  146 + }
  147 +
  148 + .form-control {
  149 + border: 1px solid #dcdfe6 !important;
  150 + border-radius: 4px !important;
  151 + padding: 0 15px !important;
  152 + height: 40px !important;
  153 + line-height: 40px !important;
  154 + font-size: 14px !important;
  155 + background: #fff !important;
  156 + color: #606266 !important;
  157 + box-sizing: border-box !important;
  158 + width: 100% !important;
  159 + transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) !important;
  160 + }
  161 +
  162 + .form-control:focus {
  163 + border-color: #409eff !important;
  164 + outline: none !important;
  165 + }
  166 +
  167 + .form-control:disabled {
  168 + background: #f5f7fa !important;
  169 + color: #c0c4cc !important;
  170 + }
  171 +
  172 + .col-form-label {
  173 + font-weight: 500 !important;
  174 + color: #606266 !important;
  175 + font-size: 14px !important;
  176 + margin-bottom: 8px !important;
  177 + }
  178 +
  179 + .formio-errors {
  180 + color: #f56c6c !important;
  181 + font-size: 12px !important;
  182 + margin-top: 4px !important;
  183 + }
  184 +
  185 + button.btn {
  186 + background-color: #409eff !important;
  187 + border: 1px solid #409eff !important;
  188 + border-radius: 4px !important;
  189 + padding: 12px 20px !important;
  190 + font-size: 14px !important;
  191 + font-weight: 500 !important;
  192 + color: #fff !important;
  193 + cursor: pointer !important;
  194 + transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1) !important;
  195 + }
  196 +
  197 + button.btn:hover {
  198 + background-color: #66b1ff !important;
  199 + border-color: #66b1ff !important;
  200 + }
  201 +
  202 + button.btn:active {
  203 + background-color: #3a8ee6 !important;
  204 + border-color: #3a8ee6 !important;
  205 + }
  206 +
  207 + button.btn:disabled {
  208 + background-color: #c0c4cc !important;
  209 + border-color: #c0c4cc !important;
  210 + color: #fff !important;
  211 + cursor: not-allowed !important;
  212 + }
  213 +}
  214 +</style>
0 215 \ No newline at end of file
... ...
src/components/oa/newOaWorkflowPool.vue 0 → 100644
  1 +<template>
  2 + <div class="new-oa-workflow-pool">
  3 + <el-card class="search-card">
  4 + <div slot="header" class="flex justify-between">
  5 + <span>{{ $t('newOaWorkflowPool.searchTitle') }}</span>
  6 + </div>
  7 + <el-form :inline="true" :model="conditions" class="search-form text-left">
  8 + <el-form-item>
  9 + <el-input v-model="conditions.createUserName" :placeholder="$t('newOaWorkflowPool.enterApplicant')"
  10 + clearable />
  11 + </el-form-item>
  12 + <el-form-item>
  13 + <el-date-picker v-model="conditions.startTime" type="datetime"
  14 + :placeholder="$t('newOaWorkflowPool.enterStartTime')" value-format="yyyy-MM-dd HH:mm:ss" />
  15 + </el-form-item>
  16 + <el-form-item>
  17 + <el-date-picker v-model="conditions.endTime" type="datetime"
  18 + :placeholder="$t('newOaWorkflowPool.enterEndTime')" value-format="yyyy-MM-dd HH:mm:ss" />
  19 + </el-form-item>
  20 + <el-form-item>
  21 + <el-button type="primary" @click="queryOaWorkflowPool">
  22 + <i class="el-icon-search"></i>
  23 + {{ $t('common.search') }}
  24 + </el-button>
  25 + </el-form-item>
  26 + </el-form>
  27 + </el-card>
  28 +
  29 + <el-card class="table-card">
  30 + <div slot="header" class="flex justify-between">
  31 + <span>{{ $t('newOaWorkflowPool.processWorkOrder') }}</span>
  32 + </div>
  33 + <el-table :data="pools" border style="width: 100%" v-loading="loading">
  34 + <el-table-column prop="create_user_name" :label="$t('newOaWorkflowPool.applicant')" align="center" />
  35 + <template v-for="(item, index) in formJson">
  36 + <el-table-column
  37 + v-if="item.type !== 'text' && item.type !== 'button' && item.type !== 'textarea'" :key="index"
  38 + :label="item.label" align="center">
  39 + <template slot-scope="scope">
  40 + {{ scope.row[item.key] }}
  41 + </template>
  42 + </el-table-column>
  43 + </template>
  44 + <el-table-column :label="$t('newOaWorkflowPool.status')" align="center">
  45 + <template slot-scope="scope">
  46 + {{ getNewOaWorkflowPoolState(scope.row) }}
  47 + </template>
  48 + </el-table-column>
  49 + <el-table-column prop="create_time" :label="$t('newOaWorkflowPool.createTime')" align="center" />
  50 + <el-table-column :label="$t('common.operation')" align="center" width="200">
  51 + <template slot-scope="scope">
  52 + <el-button size="mini" @click="openNewOaWorkflowPoolDetail(scope.row)">
  53 + {{ $t('common.detail') }}
  54 + </el-button>
  55 + <el-button size="mini" @click="openNewOaWorkflowPoolImg(scope.row)">
  56 + {{ $t('newOaWorkflowPool.flowChart') }}
  57 + </el-button>
  58 + </template>
  59 + </el-table-column>
  60 + </el-table>
  61 +
  62 + <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page.current"
  63 + :page-sizes="[10, 20, 30, 50]" :page-size="page.size" layout="total, sizes, prev, pager, next, jumper"
  64 + :total="total" class="pagination" />
  65 + </el-card>
  66 +
  67 + <view-image ref="viewImage" />
  68 + </div>
  69 +</template>
  70 +
  71 +<script>
  72 +import { queryOaWorkflowForm, queryOaWorkflowFormData } from '@/api/oa/newOaWorkflowApi'
  73 +import ViewImage from '@/components/system/viewImage'
  74 +
  75 +export default {
  76 + name: 'NewOaWorkflowPool',
  77 + components: { ViewImage },
  78 +
  79 + data() {
  80 + return {
  81 + loading: false,
  82 + pools: [],
  83 + formJson: [],
  84 + total: 0,
  85 + page: {
  86 + current: 1,
  87 + size: 10
  88 + },
  89 + conditions: {
  90 + createUserName: '',
  91 + startTime: '',
  92 + endTime: '',
  93 + flowId: this.flowId
  94 + }
  95 + }
  96 + },
  97 + created() {
  98 + },
  99 + methods: {
  100 + open(params) {
  101 + this.conditions.flowId = params.flowId
  102 + this.listOaWorkFlowPoolForm()
  103 + this.listOaWorkflowPools()
  104 + },
  105 + async listOaWorkFlowPoolForm() {
  106 + try {
  107 + const res = await queryOaWorkflowForm({
  108 + page: 1,
  109 + row: 1,
  110 + flowId: this.conditions.flowId
  111 + })
  112 + this.formJson = JSON.parse(res.data[0].formJson).components
  113 + } catch (error) {
  114 + console.error('获取表单配置失败:', error)
  115 + }
  116 + },
  117 + async listOaWorkflowPools() {
  118 + this.loading = true
  119 + try {
  120 + const params = {
  121 + ...this.conditions,
  122 + page: this.page.current,
  123 + row: this.page.size
  124 + }
  125 + const { data, total } = await queryOaWorkflowFormData(params)
  126 + this.pools = data
  127 + this.total = total
  128 + } catch (error) {
  129 + console.error('获取工单池数据失败:', error)
  130 + } finally {
  131 + this.loading = false
  132 + }
  133 + },
  134 + queryOaWorkflowPool() {
  135 + this.page.current = 1
  136 + this.listOaWorkflowPools()
  137 + },
  138 + handleSizeChange(val) {
  139 + this.page.size = val
  140 + this.listOaWorkflowPools()
  141 + },
  142 + handleCurrentChange(val) {
  143 + this.page.current = val
  144 + this.listOaWorkflowPools()
  145 + },
  146 + openNewOaWorkflowPoolDetail(pool) {
  147 + this.$router.push({
  148 + path: '/views/oa/newOaWorkflowDetail',
  149 + query: {
  150 + id: pool.id,
  151 + flowId: this.conditions.flowId
  152 + }
  153 + })
  154 + },
  155 + async openNewOaWorkflowPoolImg(pool) {
  156 + try {
  157 + const res = await this.$api.workflow.listRunWorkflowImage({
  158 + communityId: this.$store.getters.communityId,
  159 + businessKey: pool.id
  160 + })
  161 + if (res.code !== '0') {
  162 + this.$message.error(res.msg)
  163 + return
  164 + }
  165 + this.$refs.viewImage.open(`data:image/png;base64,${res.data}`)
  166 + } catch (error) {
  167 + console.error('获取流程图失败:', error)
  168 + }
  169 + },
  170 + getNewOaWorkflowPoolState(pool) {
  171 + if (!Object.prototype.hasOwnProperty.call(pool, 'state')) return this.$t('common.unknown')
  172 +
  173 + const stateMap = {
  174 + '1001': this.$t('newOaWorkflowPool.stateApply'),
  175 + '1002': this.$t('newOaWorkflowPool.statePending'),
  176 + '1003': this.$t('newOaWorkflowPool.stateReturned'),
  177 + '1004': this.$t('newOaWorkflowPool.stateDelegate'),
  178 + '1005': this.$t('newOaWorkflowPool.stateCompleted')
  179 + }
  180 +
  181 + return stateMap[pool.state] || this.$t('common.unknown')
  182 + }
  183 + }
  184 +}
  185 +</script>
  186 +
  187 +<style lang="scss" scoped>
  188 +.new-oa-workflow-pool {
  189 + .search-card {
  190 + margin-bottom: 20px;
  191 +
  192 + .search-form {
  193 + .el-form-item {
  194 + margin-bottom: 0;
  195 + }
  196 + }
  197 + }
  198 +
  199 + .pagination {
  200 + margin-top: 20px;
  201 + text-align: right;
  202 + }
  203 +}
  204 +</style>
0 205 \ No newline at end of file
... ...
src/components/oa/newOaWorkflowUndo.vue 0 → 100644
  1 +<template>
  2 + <div class="new-oa-workflow-undo">
  3 + <el-card class="search-card">
  4 + <div slot="header" class="flex justify-between">
  5 + <span>{{ $t('newOaWorkflowUndo.searchTitle') }}</span>
  6 + </div>
  7 + <el-form :inline="true" :model="conditions" class="search-form">
  8 + <el-form-item>
  9 + <el-input v-model="conditions.createUserName" :placeholder="$t('newOaWorkflowUndo.enterApplicant')"
  10 + clearable />
  11 + </el-form-item>
  12 + <el-form-item>
  13 + <el-date-picker v-model="conditions.startTime" type="datetime"
  14 + :placeholder="$t('newOaWorkflowUndo.enterStartTime')" value-format="yyyy-MM-dd HH:mm:ss" />
  15 + </el-form-item>
  16 + <el-form-item>
  17 + <el-date-picker v-model="conditions.endTime" type="datetime"
  18 + :placeholder="$t('newOaWorkflowUndo.enterEndTime')" value-format="yyyy-MM-dd HH:mm:ss" />
  19 + </el-form-item>
  20 + <el-form-item>
  21 + <el-button type="primary" @click="queryOaWorkflowUndo">
  22 + <i class="el-icon-search"></i>
  23 + {{ $t('common.search') }}
  24 + </el-button>
  25 + </el-form-item>
  26 + </el-form>
  27 + </el-card>
  28 +
  29 + <el-card class="table-card">
  30 + <div slot="header" class="flex justify-between">
  31 + <span>{{ $t('newOaWorkflowUndo.todoProcess') }}</span>
  32 + </div>
  33 + <el-table :data="undos" border style="width: 100%" v-loading="loading">
  34 + <el-table-column prop="create_user_name" :label="$t('newOaWorkflowUndo.applicant')" align="center" />
  35 + <template v-for="(item, index) in formJson">
  36 + <el-table-column v-if="item.type === 'text' || item.type === 'textarea'" :key="index" :label="item.label"
  37 + align="center">
  38 + <template slot-scope="scope">
  39 + {{ scope.row[item.key] }}
  40 + </template>
  41 + </el-table-column>
  42 + </template>
  43 + <el-table-column :label="$t('newOaWorkflowUndo.status')" align="center">
  44 + <template slot-scope="scope">
  45 + {{ getNewOaWorkflowUndoState(scope.row) }}
  46 + </template>
  47 + </el-table-column>
  48 + <el-table-column prop="create_time" :label="$t('newOaWorkflowUndo.createTime')" align="center" />
  49 + <el-table-column :label="$t('common.operation')" align="center" width="300">
  50 + <template slot-scope="scope">
  51 + <el-button size="mini" type="primary" @click="openAuditNewOaWorkflowUndoDetail(scope.row)">
  52 + {{ $t('newOaWorkflowUndo.process') }}
  53 + </el-button>
  54 + <el-button size="mini" @click="openNewOaWorkflowUndoDetail(scope.row)">
  55 + {{ $t('common.detail') }}
  56 + </el-button>
  57 + <el-button size="mini" type="warning" v-if="isMe(scope.row)" @click="openEditNewOaWorkflow(scope.row)">
  58 + {{ $t('common.edit') }}
  59 + </el-button>
  60 + </template>
  61 + </el-table-column>
  62 + </el-table>
  63 +
  64 + <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page.current"
  65 + :page-sizes="[10, 20, 30, 50]" :page-size="page.size" layout="total, sizes, prev, pager, next, jumper"
  66 + :total="total" class="pagination" />
  67 + </el-card>
  68 + </div>
  69 +</template>
  70 +
  71 +<script>
  72 +import { queryOaWorkflowForm, queryOaWorkflowUserTaskFormData } from '@/api/oa/newOaWorkflowApi'
  73 +// import { getCommunityId } from '@/api/community/communityApi'
  74 +import { getUserId } from '@/api/user/userApi'
  75 +
  76 +export default {
  77 + name: 'NewOaWorkflowUndo',
  78 +
  79 + data() {
  80 + return {
  81 + loading: false,
  82 + undos: [],
  83 + formJson: [],
  84 + total: 0,
  85 + page: {
  86 + current: 1,
  87 + size: 10
  88 + },
  89 + conditions: {
  90 + createUserName: '',
  91 + startTime: '',
  92 + endTime: '',
  93 + flowId: this.flowId,
  94 + userId: getUserId()
  95 + }
  96 + }
  97 + },
  98 + created() {
  99 + },
  100 + methods: {
  101 + open(params) {
  102 + this.conditions.flowId = params.flowId
  103 + this.listOaWorkFlowUndoForm()
  104 + this.listOaWorkflowUndos()
  105 + },
  106 + async listOaWorkFlowUndoForm() {
  107 + try {
  108 + const res = await queryOaWorkflowForm({
  109 + page: 1,
  110 + row: 1,
  111 + flowId: this.conditions.flowId
  112 + })
  113 + this.formJson = JSON.parse(res.data[0].formJson).components
  114 + } catch (error) {
  115 + console.error('获取表单配置失败:', error)
  116 + }
  117 + },
  118 + async listOaWorkflowUndos() {
  119 + this.loading = true
  120 + try {
  121 + const params = {
  122 + ...this.conditions,
  123 + page: this.page.current,
  124 + row: this.page.size
  125 + }
  126 + const { data, total } = await queryOaWorkflowUserTaskFormData(params)
  127 + this.undos = data
  128 + this.total = total
  129 + } catch (error) {
  130 + console.error('获取待办流程数据失败:', error)
  131 + } finally {
  132 + this.loading = false
  133 + }
  134 + },
  135 + queryOaWorkflowUndo() {
  136 + this.page.current = 1
  137 + this.listOaWorkflowUndos()
  138 + },
  139 + handleSizeChange(val) {
  140 + this.page.size = val
  141 + this.listOaWorkflowUndos()
  142 + },
  143 + handleCurrentChange(val) {
  144 + this.page.current = val
  145 + this.listOaWorkflowUndos()
  146 + },
  147 + openNewOaWorkflowUndoDetail(undo) {
  148 + this.$router.push({
  149 + path: '/views/oa/newOaWorkflowDetail',
  150 + query: {
  151 + id: undo.id,
  152 + flowId: this.conditions.flowId
  153 + }
  154 + })
  155 + },
  156 + openAuditNewOaWorkflowUndoDetail(undo) {
  157 + this.$router.push({
  158 + path: '/views/oa/newOaWorkflowDetail',
  159 + query: {
  160 + id: undo.id,
  161 + flowId: this.conditions.flowId,
  162 + action: 'Audit',
  163 + taskId: undo.taskId
  164 + }
  165 + })
  166 + },
  167 + openEditNewOaWorkflow(undo) {
  168 + this.$router.push({
  169 + path: '/views/oa/newOaWorkflowFormEdit',
  170 + query: {
  171 + id: undo.id,
  172 + flowId: this.conditions.flowId
  173 + }
  174 + })
  175 + },
  176 + getNewOaWorkflowUndoState(undo) {
  177 + if (!Object.prototype.hasOwnProperty.call(undo, 'state')) return this.$t('common.unknown')
  178 +
  179 + const stateMap = {
  180 + '1001': this.$t('newOaWorkflowUndo.stateApply'),
  181 + '1002': this.$t('newOaWorkflowUndo.statePending'),
  182 + '1003': this.$t('newOaWorkflowUndo.stateReturned'),
  183 + '1004': this.$t('newOaWorkflowUndo.stateDelegate'),
  184 + '1005': this.$t('newOaWorkflowUndo.stateCompleted')
  185 + }
  186 +
  187 + return stateMap[undo.state] || this.$t('common.unknown')
  188 + },
  189 + isMe(undo) {
  190 + return undo.create_user_id === getUserId()
  191 + }
  192 + }
  193 +}
  194 +</script>
  195 +
  196 +<style lang="scss" scoped>
  197 +.new-oa-workflow-undo {
  198 + .search-card {
  199 + margin-bottom: 20px;
  200 +
  201 + .search-form {
  202 + .el-form-item {
  203 + margin-bottom: 0;
  204 + }
  205 + }
  206 + }
  207 +
  208 + .pagination {
  209 + margin-top: 20px;
  210 + text-align: right;
  211 + }
  212 +}
  213 +</style>
0 214 \ No newline at end of file
... ...
src/components/oa/orgTreeShow.vue
1 1 <template>
2   - <div class="org-tree-show">
  2 + <div class="org-tree-container">
3 3 <el-tree
4 4 ref="orgTree"
5 5 :data="orgTreeShowInfo.orgs"
6   - node-key="id"
7 6 :props="defaultProps"
8   - :default-expand-all="true"
9   - :highlight-current="true"
  7 + node-key="id"
  8 + default-expand-all
  9 + highlight-current
10 10 @node-click="handleNodeClick"
11 11 />
12 12 </div>
13 13 </template>
14 14  
15 15 <script>
16   -import { listOrgTree } from '@/api/oa/editWorkApi'
  16 +import { listOrgTree } from '@/api/oa/newOaWorkflowDetailApi'
17 17 import { getCommunityId } from '@/api/community/communityApi'
18 18  
19 19 export default {
20 20 name: 'OrgTreeShow',
21   - props: {
22   - callBackListener: {
23   - type: String,
24   - required: true
25   - }
26   - },
27 21 data() {
28 22 return {
29 23 orgTreeShowInfo: {
... ... @@ -34,31 +28,32 @@ export default {
34 28 defaultProps: {
35 29 children: 'children',
36 30 label: 'text'
37   - }
  31 + },
  32 + communityId: ''
38 33 }
39 34 },
40   - mounted() {
41   - this._loadOrgsShow()
  35 + created() {
  36 + this.communityId = getCommunityId()
42 37 },
43 38 methods: {
44   - refreshTree() {
  39 + refresh() {
45 40 this._loadOrgsShow()
46 41 },
47 42 async _loadOrgsShow() {
48 43 try {
49 44 const params = {
50   - communityId: getCommunityId()
  45 + communityId: this.communityId
51 46 }
52   - const { data } = await listOrgTree(params)
53   - this.orgTreeShowInfo.orgs = data
  47 + const response = await listOrgTree(params)
  48 + this.orgTreeShowInfo.orgs = response.data
54 49 } catch (error) {
55 50 console.error('加载组织树失败:', error)
56 51 }
57 52 },
58   - handleNodeClick(data) {
  53 + handleNodeClick(data, node) {
59 54 this.orgTreeShowInfo.curOrg = data
60 55 this.orgTreeShowInfo.curOrg.orgId = data.id
61   - this.$emit(this.callBackListener, 'switchOrg', {
  56 + this.$emit('switchOrg', {
62 57 orgId: data.id,
63 58 orgName: data.text
64 59 })
... ... @@ -68,18 +63,15 @@ export default {
68 63 </script>
69 64  
70 65 <style lang="scss" scoped>
71   -.org-tree-show {
72   - ::v-deep .el-tree {
73   - background: transparent;
  66 +.org-tree-container {
  67 + height: 100%;
  68 +
  69 + /deep/ .el-tree {
  70 + height: 100%;
  71 + overflow-y: auto;
  72 +
74 73 .el-tree-node__content {
75 74 height: 36px;
76   - &:hover {
77   - background-color: #f5f7fa;
78   - }
79   - }
80   - .is-current > .el-tree-node__content {
81   - background-color: #ecf5ff;
82   - color: #409eff;
83 75 }
84 76 }
85 77 }
... ...
src/components/oa/selectStaff.vue
1 1 <template>
2   - <el-dialog
  2 + <el-dialog
  3 + :visible.sync="visible"
3 4 :title="$t('selectStaff.title')"
4   - :visible.sync="visible"
5   - width="70%"
6   - top="5vh"
  5 + width="80%"
  6 + @close="handleClose"
7 7 >
8 8 <el-row :gutter="20">
9 9 <el-col :span="12" class="border-right">
10   - <div class="text-center section-title">
11   - {{ $t('selectStaff.orgInfo') }}
  10 + <div class="text-center mb-20">
  11 + <h4>{{ $t('selectStaff.orgInfo') }}</h4>
12 12 </div>
13   - <div class="org-tree-container">
14   - <org-tree-show
15   - ref="orgTree"
16   - :call-back-listener="'selectStaff'"
17   - />
  13 + <div class="staff-container">
  14 + <org-tree-show ref="orgTree" @switchOrg="handleSwitchOrg" />
18 15 </div>
19 16 </el-col>
20 17 <el-col :span="12">
21   - <div class="text-center section-title">
22   - {{ $t('selectStaff.staffInfo') }}
  18 + <div class="text-center mb-20">
  19 + <h4>{{ $t('selectStaff.staffInfo') }}</h4>
23 20 </div>
24   - <div class="staff-list">
25   - <div
26   - v-for="(item, index) in selectStaffInfo.staffs"
  21 + <div class="staff-container">
  22 + <div
  23 + v-for="(item,index) in selectStaffInfo.staffs"
27 24 :key="index"
28 25 class="staff-item"
29 26 :class="{ 'selected': selectStaffInfo.curStaffId === item.staffId }"
30   - @click="_changeStaff(item)"
  27 + @click="handleChangeStaff(item)"
31 28 >
32 29 <div>
33 30 <i class="el-icon-user"></i>
... ... @@ -38,25 +35,26 @@
38 35 </div>
39 36 </el-col>
40 37 </el-row>
41   - <div
  38 +
  39 + <div
42 40 v-if="selectStaffInfo.staff.from === 'bpmn' ||
43 41 selectStaffInfo.staff.from === 'purchase' ||
44 42 selectStaffInfo.staff.from === 'contract'"
45 43 slot="footer"
46 44 class="dialog-footer"
47 45 >
48   - <el-button @click="_firstUser">
  46 + <el-button @click="handleFirstUser">
49 47 {{ $t('selectStaff.submitter') }}
50 48 </el-button>
51   - <el-button @click="_customUser">
52   - {{ $t('selectStaff.dynamicAssign') }}
  49 + <el-button @click="handleCustomUser">
  50 + {{ $t('selectStaff.customAssign') }}
53 51 </el-button>
54 52 </div>
55 53 </el-dialog>
56 54 </template>
57 55  
58 56 <script>
59   -import { queryStaffInfos } from '@/api/oa/editWorkApi'
  57 +import { queryStaffInfos } from '@/api/oa/newOaWorkflowDetailApi'
60 58 import OrgTreeShow from './OrgTreeShow'
61 59  
62 60 export default {
... ... @@ -77,57 +75,61 @@ export default {
77 75 },
78 76 methods: {
79 77 open(staff) {
80   - this.selectStaffInfo.staff = staff || {}
  78 + this.selectStaffInfo.staff = staff
81 79 this.visible = true
82 80 this.$nextTick(() => {
83   - this.$refs.orgTree.refreshTree()
  81 + this.$refs.orgTree.refresh()
84 82 })
85 83 },
86   - _changeStaff(item) {
87   - this.selectStaffInfo.staff.staffId = item.userId
88   - this.selectStaffInfo.staff.staffName = item.userName
89   - this.selectStaffInfo.staff.staffTel = item.tel
90   - this.visible = false
91   - if (typeof this.selectStaffInfo.staff.call === 'function') {
92   - this.selectStaffInfo.staff.call(this.selectStaffInfo.staff)
93   - }
  84 + handleClose() {
  85 + this.selectStaffInfo.staffs = []
  86 + this.selectStaffInfo.curStaffId = ''
94 87 },
95   - async loadStaff(org) {
  88 + handleSwitchOrg({ orgId, orgName }) {
  89 + this.loadStaff(orgId)
  90 + },
  91 + async loadStaff(orgId) {
96 92 try {
97 93 const params = {
98 94 page: 1,
99 95 rows: 50,
100 96 row: 50,
101   - orgId: org.orgId
  97 + orgId
102 98 }
103   - const { data } = await queryStaffInfos(params)
104   - this.selectStaffInfo.staffs = data.staffs
105   - if (data.staffs.length > 0) {
106   - this.selectStaffInfo.curStaffId = data.staffs[0].orgId
  99 + const response = await queryStaffInfos(params)
  100 + this.selectStaffInfo.staffs = response.staffs
  101 + if (response.staffs.length > 0) {
  102 + this.selectStaffInfo.curStaffId = response.staffs[0].orgId
107 103 }
108 104 } catch (error) {
109 105 console.error('加载员工失败:', error)
110 106 }
111 107 },
112   - _firstUser() {
  108 + handleChangeStaff(item) {
  109 + this.selectStaffInfo.staff.staffId = item.userId
  110 + this.selectStaffInfo.staff.staffName = item.userName
  111 + this.selectStaffInfo.staff.staffTel = item.tel
  112 + this.visible = false
  113 + if (this.selectStaffInfo.staff.call) {
  114 + this.selectStaffInfo.staff.call(this.selectStaffInfo.staff)
  115 + }
  116 + },
  117 + handleFirstUser() {
113 118 this.selectStaffInfo.staff.staffId = '${startUserId}'
114 119 this.selectStaffInfo.staff.staffName = this.$t('selectStaff.submitter')
115 120 this.visible = false
116   - if (typeof this.selectStaffInfo.staff.call === 'function') {
  121 + if (this.selectStaffInfo.staff.call) {
117 122 this.selectStaffInfo.staff.call(this.selectStaffInfo.staff)
118 123 }
119 124 },
120   - _customUser() {
  125 + handleCustomUser() {
121 126 this.selectStaffInfo.staff.staffId = '${nextUserId}'
122   - this.selectStaffInfo.staff.staffName = this.$t('selectStaff.dynamicAssign')
  127 + this.selectStaffInfo.staff.staffName = this.$t('selectStaff.customAssign')
123 128 this.visible = false
124   - if (typeof this.selectStaffInfo.staff.call === 'function') {
  129 + if (this.selectStaffInfo.staff.call) {
125 130 this.selectStaffInfo.staff.call(this.selectStaffInfo.staff)
126 131 }
127 132 }
128   - },
129   - created() {
130   - this.$on('selectStaff', 'switchOrg', this.loadStaff)
131 133 }
132 134 }
133 135 </script>
... ... @@ -137,38 +139,34 @@ export default {
137 139 border-right: 1px solid #eee;
138 140 }
139 141  
140   -.section-title {
141   - font-weight: bold;
142   - margin-bottom: 15px;
143   -}
144   -
145   -.org-tree-container {
146   - padding: 10px;
147   - height: 500px;
  142 +.staff-container {
  143 + height: 400px;
148 144 overflow-y: auto;
149   -}
150   -
151   -.staff-list {
152 145 padding: 10px;
153   - height: 500px;
154   - overflow-y: auto;
155 146 }
156 147  
157 148 .staff-item {
158 149 padding: 10px;
159   - margin-bottom: 5px;
  150 + margin-bottom: 10px;
  151 + border: 1px solid #eee;
160 152 border-radius: 4px;
161 153 cursor: pointer;
  154 +
162 155 &:hover {
163 156 background-color: #f5f7fa;
164 157 }
  158 +
165 159 &.selected {
166 160 background-color: #ecf5ff;
167   - color: #409eff;
  161 + border-color: #c6e2ff;
168 162 }
169 163 }
170 164  
171   -.dialog-footer {
172   - text-align: right;
  165 +.text-center {
  166 + text-align: center;
  167 +}
  168 +
  169 +.mb-20 {
  170 + margin-bottom: 20px;
173 171 }
174 172 </style>
175 173 \ No newline at end of file
... ...
src/components/oa/uploadFile.vue
1 1 <template>
2 2 <div class="upload-file-container">
3   - <el-progress
4   - v-if="uploadFileInfo.progress > 0"
5   - :percentage="uploadFileInfo.progress"
6   - :stroke-width="2"
7   - />
8   - <div v-if="uploadFileInfo.progress > 0" class="file-name">
9   - {{ uploadFileInfo.fileName }}
  3 + <div class="progress" v-if="uploadFileInfo.progress > 0">
  4 + <el-progress
  5 + :percentage="uploadFileInfo.progress"
  6 + :stroke-width="2"
  7 + :show-text="false" />
10 8 </div>
11   - <div>
12   - <el-button
13   - type="primary"
14   - size="small"
15   - @click="_uploadFile"
16   - >
17   - {{ $t('uploadFile.upload') }}
  9 + <div class="file-info" v-if="uploadFileInfo.progress > 0">
  10 + <span>{{ uploadFileInfo.fileName }}</span>
  11 + </div>
  12 + <div class="upload-btn">
  13 + <el-button
  14 + type="primary"
  15 + @click="_uploadFile">
  16 + {{ $t('uploadFile.uploadBtn') }}
18 17 </el-button>
19   - <input
20   - ref="fileInput"
21   - type="file"
22   - class="file-input"
23   - accept="*"
24   - capture="camcorder"
25   - @change="_chooseFile"
26   - >
  18 + <input
  19 + type="file"
  20 + class="file-input"
  21 + accept="*"
  22 + id="uploadFile"
  23 + hidden
  24 + @change="_chooseFile($event)" />
27 25 </div>
28 26 </div>
29 27 </template>
30 28  
31 29 <script>
32   -import { uploadFile } from '@/api/oa/editWorkApi'
  30 +import { uploadVedio } from '@/api/oa/newOaWorkflowFormEditApi'
33 31  
34 32 export default {
35 33 name: 'UploadFile',
36 34 props: {
37 35 callBackListener: {
38 36 type: String,
39   - default: ''
  37 + required: true
40 38 },
41 39 callBackFunction: {
42 40 type: String,
43   - default: ''
  41 + required: true
44 42 }
45 43 },
46 44 data() {
... ... @@ -61,25 +59,13 @@ export default {
61 59 }
62 60 }
63 61 },
  62 + created() {
  63 + this.$on('clearVedio', this.clearVedio)
  64 + this.$on('notifyVedio', this.notifyVedio)
  65 + },
64 66 methods: {
65   - notifyVedio(fileName) {
66   - this.uploadFileInfo = {
67   - vedio: {},
68   - fileName: fileName,
69   - realFileName: fileName,
70   - progress: 100
71   - }
72   - },
73   - clearVedio() {
74   - this.uploadFileInfo = {
75   - vedio: {},
76   - fileName: '',
77   - realFileName: '',
78   - progress: 0
79   - }
80   - },
81 67 _uploadFile() {
82   - this.$refs.fileInput.click()
  68 + document.getElementById('uploadFile').click()
83 69 },
84 70 _chooseFile(event) {
85 71 const files = event.target.files
... ... @@ -98,8 +84,8 @@ export default {
98 84 formData.append('uploadFile', file)
99 85  
100 86 try {
101   - const res = await uploadFile(formData, {
102   - onUploadProgress: (progressEvent) => {
  87 + const res = await uploadVedio(formData, {
  88 + onUploadProgress: progressEvent => {
103 89 const rate = progressEvent.loaded / progressEvent.total
104 90 if (rate < 0.9) {
105 91 this.uploadFileInfo.progress = Math.floor(rate * 100)
... ... @@ -108,14 +94,27 @@ export default {
108 94 })
109 95  
110 96 this.uploadFileInfo.progress = 100
111   - this.$message.success(this.$t('uploadFile.success'))
  97 + this.$message.success(this.$t('uploadFile.uploadSuccess'))
112 98 this.uploadFileInfo.fileName = res.fileName
113 99 this.uploadFileInfo.realFileName = res.realFileName
114 100 this.$emit(this.callBackListener, this.callBackFunction, res)
115 101 } catch (error) {
116   - console.error('上传失败:', error)
117   - this.$message.error(this.$t('uploadFile.failed'))
  102 + console.error('上传文件失败:', error)
  103 + this.$message.error(this.$t('uploadFile.uploadError'))
  104 + }
  105 + },
  106 + clearVedio() {
  107 + this.uploadFileInfo = {
  108 + vedio: {},
  109 + fileName: '',
  110 + realFileName: '',
  111 + progress: 0
118 112 }
  113 + },
  114 + notifyVedio(fileName) {
  115 + this.uploadFileInfo.fileName = fileName
  116 + this.uploadFileInfo.realFileName = fileName
  117 + this.uploadFileInfo.progress = 100
119 118 }
120 119 }
121 120 }
... ... @@ -123,8 +122,16 @@ export default {
123 122  
124 123 <style lang="scss" scoped>
125 124 .upload-file-container {
126   - .file-name {
127   - margin-bottom: 5px;
  125 + margin-bottom: 20px;
  126 +
  127 + .progress {
  128 + margin-bottom: 10px;
  129 + }
  130 +
  131 + .file-info {
  132 + margin-bottom: 10px;
  133 + font-size: 14px;
  134 + color: #606266;
128 135 }
129 136  
130 137 .file-input {
... ...
src/components/oa/viewImage.vue
1 1 <template>
2   - <div class="view-image-wrapper" v-show="visible">
3   - <div class="image-container">
4   - <img
5   - :src="imageUrl"
6   - :style="{
7   - width: imgWidth + 'px',
8   - height: imgHeight + 'px'
9   - }"
10   - @error="handleImageError"
11   - />
12   - <i class="el-icon-close close-icon" @click="close"></i>
13   - </div>
  2 + <div class="view-image-container">
  3 + <el-dialog
  4 + :visible.sync="dialogVisible"
  5 + fullscreen
  6 + :show-close="false"
  7 + custom-class="image-viewer-dialog"
  8 + >
  9 + <div class="image-wrapper">
  10 + <img
  11 + :src="imageUrl"
  12 + :style="imageStyle"
  13 + @error="handleImageError"
  14 + />
  15 + <i
  16 + class="el-icon-close close-icon"
  17 + @click="close"
  18 + />
  19 + </div>
  20 + </el-dialog>
14 21 </div>
15 22 </template>
16 23  
... ... @@ -19,103 +26,65 @@ export default {
19 26 name: 'ViewImage',
20 27 data() {
21 28 return {
22   - visible: false,
  29 + dialogVisible: false,
23 30 imageUrl: '',
24   - imgWidth: 800,
25   - imgHeight: 800
  31 + imageStyle: {
  32 + width: '800px',
  33 + height: 'auto',
  34 + display: 'block',
  35 + margin: '0 auto'
  36 + }
26 37 }
27 38 },
28 39 methods: {
29 40 open(url) {
30 41 this.imageUrl = url
31   - this.visible = true
32   - this.calculateImageSize(url)
33   - this.enterFullscreen()
34   - },
35   - close() {
36   - this.visible = false
37   - this.exitFullscreen()
38   - },
39   - handleImageError() {
40   - this.imageUrl = '/img/noPhoto.jpg'
41   - },
42   - calculateImageSize(url) {
  42 + this.dialogVisible = true
  43 +
  44 + // 预加载图片获取实际尺寸
43 45 const img = new Image()
44 46 img.src = url
45 47 img.onload = () => {
46 48 const imgScale = img.width / img.height
47   - this.imgWidth = 800
48   - this.imgHeight = 800 / imgScale
  49 + this.imageStyle.width = '800px'
  50 + this.imageStyle.height = `${800 / imgScale}px`
49 51 }
50 52 },
51   - enterFullscreen() {
52   - const element = document.querySelector('.view-image-wrapper')
53   - if (element.requestFullscreen) {
54   - element.requestFullscreen()
55   - } else if (element.mozRequestFullScreen) {
56   - element.mozRequestFullScreen()
57   - } else if (element.webkitRequestFullscreen) {
58   - element.webkitRequestFullscreen()
59   - } else if (element.msRequestFullscreen) {
60   - element.msRequestFullscreen()
61   - }
  53 + close() {
  54 + this.dialogVisible = false
  55 + this.imageUrl = ''
62 56 },
63   - exitFullscreen() {
64   - if (document.exitFullscreen) {
65   - document.exitFullscreen()
66   - } else if (document.mozCancelFullScreen) {
67   - document.mozCancelFullScreen()
68   - } else if (document.webkitExitFullscreen) {
69   - document.webkitExitFullscreen()
70   - }
  57 + handleImageError(e) {
  58 + e.target.src = '/img/noPhoto.jpg'
71 59 }
72   - },
73   - mounted() {
74   - document.addEventListener('fullscreenchange', () => {
75   - if (!document.fullscreenElement) {
76   - this.close()
77   - }
78   - })
79 60 }
80 61 }
81 62 </script>
82 63  
83 64 <style lang="scss" scoped>
84   -.view-image-wrapper {
85   - position: fixed;
86   - top: 0;
87   - left: 0;
88   - width: 100%;
89   - height: 100%;
90   - background-color: rgba(0, 0, 0, 0.8);
91   - z-index: 9999;
92   - display: flex;
93   - justify-content: center;
94   - align-items: center;
95   -
96   - .image-container {
97   - position: relative;
98   - background-color: #fff;
99   - padding: 20px;
100   - border-radius: 4px;
101   -
102   - img {
103   - max-width: 90vw;
104   - max-height: 90vh;
105   - object-fit: contain;
106   - }
107   -
108   - .close-icon {
109   - position: absolute;
110   - top: 10px;
111   - right: 10px;
112   - font-size: 24px;
113   - color: #f56c6c;
114   - cursor: pointer;
115   - z-index: 1;
116   -
117   - &:hover {
118   - color: #f78989;
  65 +.view-image-container {
  66 + .image-viewer-dialog {
  67 + background-color: rgba(0, 0, 0, 0.8);
  68 +
  69 + .image-wrapper {
  70 + position: relative;
  71 + height: 100%;
  72 + display: flex;
  73 + align-items: center;
  74 + justify-content: center;
  75 +
  76 + .close-icon {
  77 + position: absolute;
  78 + top: 20px;
  79 + right: 20px;
  80 + font-size: 24px;
  81 + color: #fff;
  82 + cursor: pointer;
  83 + z-index: 2001;
  84 +
  85 + &:hover {
  86 + color: #f56c6c;
  87 + }
119 88 }
120 89 }
121 90 }
... ...
src/i18n/commonLang.js
... ... @@ -53,6 +53,7 @@ export const messages = {
53 53 month:'Month',
54 54 examine:'Examine',
55 55 audit:'Audit',
  56 + choose:'Choose',
56 57 }
57 58 },
58 59 zh: {
... ... @@ -109,6 +110,7 @@ export const messages = {
109 110 month:'月',
110 111 examine:'审核',
111 112 audit:'审核',
  113 + choose:'选择',
112 114 }
113 115 }
114 116 }
115 117 \ No newline at end of file
... ...
src/i18n/feeI18n.js
... ... @@ -28,6 +28,9 @@ import { messages as propertyFeeMessages } from &#39;../views/fee/propertyFeeLang&#39;
28 28 import { messages as batchPayFeeOrderMessages } from '../views/fee/batchPayFeeOrderLang'
29 29 import { messages as simplifyAcceptanceMessages } from '../views/simplify/simplifyAcceptanceLang.js'
30 30 import { messages as payFeeOrderMessages } from '../views/fee/payFeeOrderLang'
  31 +import { messages as refundDepositFeeMessages } from '../views/fee/refundDepositFeeLang'
  32 +import { messages as createFeeByComboMessages } from '../views/fee/createFeeByComboLang'
  33 +import { messages as owePayFeeOrderMessages } from '../views/fee/owePayFeeOrderLang'
31 34  
32 35 export const messages = {
33 36 en: {
... ... @@ -61,6 +64,9 @@ export const messages = {
61 64 ...batchPayFeeOrderMessages.en,
62 65 ...simplifyAcceptanceMessages.en,
63 66 ...payFeeOrderMessages.en,
  67 + ...refundDepositFeeMessages.en,
  68 + ...createFeeByComboMessages.en,
  69 + ...owePayFeeOrderMessages.en,
64 70 },
65 71 zh: {
66 72 ...contractCreateFeeMessages.zh,
... ... @@ -93,5 +99,8 @@ export const messages = {
93 99 ...batchPayFeeOrderMessages.zh,
94 100 ...simplifyAcceptanceMessages.zh,
95 101 ...payFeeOrderMessages.zh,
  102 + ...refundDepositFeeMessages.zh,
  103 + ...createFeeByComboMessages.zh,
  104 + ...owePayFeeOrderMessages.zh,
96 105 }
97 106 }
98 107 \ No newline at end of file
... ...
src/i18n/oaI18n.js
... ... @@ -46,6 +46,11 @@ import { messages as doWorkMessages } from &#39;../views/oa/doWorkLang&#39;
46 46 import { messages as copyWorkMessages } from '../views/oa/copyWorkLang'
47 47 import { messages as workPoolMessages } from '../views/oa/workPoolLang'
48 48 import { messages as workDeductionMessages } from '../views/oa/workDeductionLang'
  49 +import { messages as newOaWorkflowMessages } from '../views/oa/newOaWorkflowLang'
  50 +import { messages as newOaWorkflowDetailMessages } from '../views/oa/newOaWorkflowDetailLang'
  51 +import { messages as newOaWorkflowFormEditMessages } from '../views/oa/newOaWorkflowFormEditLang'
  52 +
  53 +
49 54 export const messages ={
50 55 en:{
51 56 ...activitiesTypeManageMessages.en,
... ... @@ -95,6 +100,9 @@ export const messages ={
95 100 ...copyWorkMessages.en,
96 101 ...workPoolMessages.en,
97 102 ...workDeductionMessages.en,
  103 + ...newOaWorkflowMessages.en,
  104 + ...newOaWorkflowDetailMessages.en,
  105 + ...newOaWorkflowFormEditMessages.en,
98 106 },
99 107 zh:{
100 108 ...activitiesTypeManageMessages.zh,
... ... @@ -144,5 +152,8 @@ export const messages ={
144 152 ...copyWorkMessages.zh,
145 153 ...workPoolMessages.zh,
146 154 ...workDeductionMessages.zh,
  155 + ...newOaWorkflowMessages.zh,
  156 + ...newOaWorkflowDetailMessages.zh,
  157 + ...newOaWorkflowFormEditMessages.zh,
147 158 }
148 159 }
149 160 \ No newline at end of file
... ...
src/main.js
... ... @@ -3,6 +3,7 @@ import App from &#39;./App.vue&#39;
3 3 import router from './router'
4 4 import ElementUI from 'element-ui'
5 5 import 'element-ui/lib/theme-chalk/index.css'
  6 +import 'formiojs/dist/formio.full.min.css'
6 7 import i18n from './i18n'
7 8 import {getCommunityName,getCommunityId} from '@/api/community/communityApi'
8 9  
... ...
src/router/feeRouter.js
... ... @@ -130,8 +130,24 @@ export default [
130 130 component: () => import('@/views/simplify/simplifyAcceptanceList.vue')
131 131 },
132 132 {
133   - path:'/views/fee/payFeeOrder',
134   - name:'/views/fee/payFeeOrder',
  133 + path: '/views/fee/payFeeOrder',
  134 + name: '/views/fee/payFeeOrder',
135 135 component: () => import('@/views/fee/payFeeOrderList.vue')
136   - },
  136 + },
  137 + {
  138 + path: '/views/fee/refundDepositFee',
  139 + name: '/views/fee/refundDepositFee',
  140 + component: () => import('@/views/fee/refundDepositFeeList.vue')
  141 + },
  142 + {
  143 + path: '/views/fee/createFeeByCombo',
  144 + name: '/views/fee/createFeeByCombo',
  145 + component: () => import('@/views/fee/createFeeByComboList.vue')
  146 + },
  147 + {
  148 + path: '/views/fee/owePayFeeOrder',
  149 + name: '/views/fee/owePayFeeOrder',
  150 + component: () => import('@/views/fee/owePayFeeOrderList.vue')
  151 + },
  152 +
137 153 ]
138 154 \ No newline at end of file
... ...
src/router/oaRouter.js
... ... @@ -219,4 +219,19 @@ export default [
219 219 name: '/pages/oa/workDeduction',
220 220 component: () => import('@/views/oa/workDeductionList.vue')
221 221 },
  222 + {
  223 + path: '/views/oa/newOaWorkflow',
  224 + name: '/views/oa/newOaWorkflow',
  225 + component: () => import('@/views/oa/newOaWorkflowList.vue')
  226 + },
  227 + {
  228 + path: '/views/oa/newOaWorkflowDetail',
  229 + name: '/views/oa/newOaWorkflowDetail',
  230 + component: () => import('@/views/oa/newOaWorkflowDetailList.vue')
  231 + },
  232 + {
  233 + path: '/views/oa/newOaWorkflowFormEdit',
  234 + name: '/views/oa/newOaWorkflowFormEdit',
  235 + component: () => import('@/views/oa/newOaWorkflowFormEditList.vue')
  236 + },
222 237 ]
223 238 \ No newline at end of file
... ...
src/views/fee/createFeeByComboLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + createFeeByCombo: {
  4 + title: 'Create Fee (Create by Fee Combo)',
  5 + chooseFeeCombo: 'Choose Fee Combo',
  6 + feeType: 'Fee Type',
  7 + feeItem: 'Fee Item',
  8 + feeFlag: 'Fee Flag',
  9 + startTime: 'Billing Start Time',
  10 + endTime: 'Billing End Time',
  11 + requiredStartTime: 'Required, please enter start time',
  12 + requiredEndTime: 'Required, please enter end time',
  13 + feeItemEndTime: 'Fee Item End Time',
  14 + endTimeMustGreater: 'End time must be greater than start time',
  15 + noFeeSelected: 'No fee combo selected',
  16 + startTimeRequired: ' start time is required',
  17 + endTimeRequired: ' end time is required'
  18 + },
  19 + chooseFeeCombo: {
  20 + title: 'Choose Fee Combo',
  21 + searchPlaceholder: 'Enter fee combo name',
  22 + comboName: 'Combo Name',
  23 + createTime: 'Create Time',
  24 + remark: 'Remark'
  25 + }
  26 + },
  27 + zh: {
  28 + createFeeByCombo: {
  29 + title: '创建费用(根据费用套餐创建)',
  30 + chooseFeeCombo: '选择费用套餐',
  31 + feeType: '费用类型',
  32 + feeItem: '费用项目',
  33 + feeFlag: '费用标识',
  34 + startTime: '计费起始时间',
  35 + endTime: '计费结束时间',
  36 + requiredStartTime: '必填,请填写开始时间',
  37 + requiredEndTime: '必填,请填写结束时间',
  38 + feeItemEndTime: '费用项结束时间',
  39 + endTimeMustGreater: '结束时间必须大于开始时间',
  40 + noFeeSelected: '未选中要创建的费用套餐',
  41 + startTimeRequired: '开始时间不能为空',
  42 + endTimeRequired: '结束时间不能为空'
  43 + },
  44 + chooseFeeCombo: {
  45 + title: '选择费用套餐',
  46 + searchPlaceholder: '输入费用套餐名称',
  47 + comboName: '套餐名称',
  48 + createTime: '创建时间',
  49 + remark: '说明'
  50 + }
  51 + }
  52 +}
0 53 \ No newline at end of file
... ...
src/views/fee/createFeeByComboList.vue 0 → 100644
  1 +<template>
  2 + <div class="create-fee-by-combo-container">
  3 + <el-card class="box-card">
  4 + <div slot="header" class="clearfix">
  5 + <span>{{ createFeeByComboInfo.payerObjName }}</span>
  6 + <span>{{ $t('createFeeByCombo.title') }}</span>
  7 + <div class="header-tools">
  8 + <el-button type="primary" size="small" @click="_chooseFeeCombo()">
  9 + <i class="el-icon-search"></i>{{ $t('createFeeByCombo.chooseFeeCombo') }}
  10 + </el-button>
  11 + <el-button type="info" size="small" @click="_goBack()">
  12 + <i class="el-icon-close"></i>{{ $t('common.back') }}
  13 + </el-button>
  14 + </div>
  15 + </div>
  16 +
  17 + <el-table :data="createFeeByComboInfo.feeConfigs" border style="width: 100%" class="fee-config-table">
  18 + <el-table-column type="selection" width="55" align="center" @selection-change="handleSelectionChange">
  19 + </el-table-column>
  20 + <el-table-column prop="feeTypeCdName" :label="$t('createFeeByCombo.feeType')" align="center"></el-table-column>
  21 + <el-table-column prop="feeName" :label="$t('createFeeByCombo.feeItem')" align="center"></el-table-column>
  22 + <el-table-column prop="feeFlagName" :label="$t('createFeeByCombo.feeFlag')" align="center"></el-table-column>
  23 + <el-table-column :label="$t('createFeeByCombo.startTime')" align="center">
  24 + <template slot-scope="scope">
  25 + <el-date-picker v-model="scope.row.startTime" type="datetime"
  26 + :placeholder="$t('createFeeByCombo.requiredStartTime')" value-format="yyyy-MM-dd HH:mm:ss"
  27 + style="width: 100%"></el-date-picker>
  28 + </template>
  29 + </el-table-column>
  30 + <el-table-column :label="$t('createFeeByCombo.endTime')" align="center">
  31 + <template slot-scope="scope">
  32 + <el-date-picker v-if="scope.row.feeFlag != '1003006'" v-model="scope.row.endTime" type="datetime"
  33 + :placeholder="$t('createFeeByCombo.requiredEndTime')" value-format="yyyy-MM-dd HH:mm:ss"
  34 + style="width: 100%" @change="validateTime(scope.row)"></el-date-picker>
  35 + <span v-else>{{ $t('createFeeByCombo.feeItemEndTime') }}</span>
  36 + </template>
  37 + </el-table-column>
  38 + </el-table>
  39 +
  40 + <div class="footer-buttons">
  41 + <el-button type="primary" size="large" @click="_createFee()">
  42 + {{ $t('common.submit') }}
  43 + </el-button>
  44 + </div>
  45 + </el-card>
  46 +
  47 + <choose-fee-combo ref="chooseFeeCombo" @chooseFeeCombo="handleChooseFeeCombo"
  48 + @loadData="handleLoadData"></choose-fee-combo>
  49 + </div>
  50 +</template>
  51 +
  52 +<script>
  53 +import { getCommunityId } from '@/api/community/communityApi'
  54 +import ChooseFeeCombo from '@/components/fee/chooseFeeCombo'
  55 +import { createFeeByCombo, listFeeComboMember } from '@/api/fee/createFeeByComboApi'
  56 +
  57 +export default {
  58 + name: 'CreateFeeByComboList',
  59 + components: {
  60 + ChooseFeeCombo
  61 + },
  62 + data() {
  63 + return {
  64 + createFeeByComboInfo: {
  65 + feeConfigs: [],
  66 + selectConfigIds: [],
  67 + communityId: '',
  68 + payerObjId: '',
  69 + payerObjName: '',
  70 + payerObjType: '',
  71 + comboId: ''
  72 + }
  73 + }
  74 + },
  75 + created() {
  76 + this.communityId = getCommunityId()
  77 + this._initData()
  78 + },
  79 + methods: {
  80 + _initData() {
  81 + this.createFeeByComboInfo.payerObjId = this.$route.query.payerObjId
  82 + this.createFeeByComboInfo.payerObjType = this.$route.query.payerObjType
  83 + this.createFeeByComboInfo.payerObjName = this.$route.query.payerObjName
  84 + },
  85 + _chooseFeeCombo() {
  86 + this.$refs.chooseFeeCombo.open()
  87 + },
  88 + handleChooseFeeCombo(feeCombo) {
  89 + this.createFeeByComboInfo.comboId = feeCombo.comboId
  90 + this._listFeeComboMembers(feeCombo)
  91 + },
  92 + handleLoadData(params) {
  93 + this._listFeeComboMembers(params)
  94 + },
  95 + async _listFeeComboMembers(feeCombo) {
  96 + try {
  97 + const params = {
  98 + page: 1,
  99 + row: 100,
  100 + comboId: feeCombo.comboId
  101 + }
  102 + const { data } = await listFeeComboMember(params)
  103 + this.createFeeByComboInfo.selectConfigIds = []
  104 + data.forEach(config => {
  105 + config.startTime = ''
  106 + config.endTime = ''
  107 + this.createFeeByComboInfo.selectConfigIds.push(config.configId)
  108 + })
  109 + this.createFeeByComboInfo.feeConfigs = data
  110 + } catch (error) {
  111 + console.error('Failed to load fee combo members:', error)
  112 + }
  113 + },
  114 + validateTime(row) {
  115 + if (row.startTime && row.endTime) {
  116 + const start = new Date(row.startTime).getTime()
  117 + const end = new Date(row.endTime).getTime()
  118 + if (start >= end) {
  119 + this.$message.error(this.$t('createFeeByCombo.endTimeMustGreater'))
  120 + row.endTime = ''
  121 + }
  122 + }
  123 + },
  124 + handleSelectionChange(val) {
  125 + this.createFeeByComboInfo.selectConfigIds = val.map(item => item.configId)
  126 + },
  127 + async _createFee() {
  128 + const selectedFees = this.createFeeByComboInfo.feeConfigs.filter(item =>
  129 + this.createFeeByComboInfo.selectConfigIds.includes(item.configId)
  130 + )
  131 +
  132 + if (selectedFees.length === 0) {
  133 + this.$message.warning(this.$t('createFeeByCombo.noFeeSelected'))
  134 + return
  135 + }
  136 +
  137 + for (const fee of selectedFees) {
  138 + if (!fee.startTime) {
  139 + this.$message.warning(fee.feeName + this.$t('createFeeByCombo.startTimeRequired'))
  140 + return
  141 + }
  142 + if (fee.feeFlag !== '1003006' && !fee.endTime) {
  143 + this.$message.warning(fee.feeName + this.$t('createFeeByCombo.endTimeRequired'))
  144 + return
  145 + }
  146 + }
  147 +
  148 + const postData = {
  149 + communityId: this.communityId,
  150 + configs: selectedFees,
  151 + payerObjId: this.createFeeByComboInfo.payerObjId,
  152 + payerObjName: this.createFeeByComboInfo.payerObjName,
  153 + payerObjType: this.createFeeByComboInfo.payerObjType,
  154 + comboId: this.createFeeByComboInfo.comboId
  155 + }
  156 +
  157 + try {
  158 + const response = await createFeeByCombo(postData)
  159 + this.$message.success(response.msg)
  160 + if (response.code === 0) {
  161 + this.$router.go(-1)
  162 + }
  163 + } catch (error) {
  164 + console.error('Failed to create fee:', error)
  165 + this.$message.error(error.message || this.$t('common.operationFailed'))
  166 + }
  167 + },
  168 + _goBack() {
  169 + this.$router.go(-1)
  170 + }
  171 + }
  172 +}
  173 +</script>
  174 +
  175 +<style lang="scss" scoped>
  176 +.create-fee-by-combo-container {
  177 + padding: 20px;
  178 +
  179 + .box-card {
  180 + margin-bottom: 20px;
  181 +
  182 + .clearfix {
  183 + display: flex;
  184 + justify-content: space-between;
  185 + align-items: center;
  186 +
  187 + .header-tools {
  188 + display: flex;
  189 + gap: 10px;
  190 + }
  191 + }
  192 + }
  193 +
  194 + .fee-config-table {
  195 + margin-top: 20px;
  196 + }
  197 +
  198 + .footer-buttons {
  199 + margin-top: 20px;
  200 + display: flex;
  201 + justify-content: flex-end;
  202 + }
  203 +}
  204 +</style>
0 205 \ No newline at end of file
... ...
src/views/fee/owePayFeeOrderLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + owePayFeeOrder: {
  4 + printNotice1: 'Notice 1',
  5 + printNotice2: 'Notice 2',
  6 + payerObj: 'Payer',
  7 + feeType: 'Fee Type',
  8 + feeItem: 'Fee Item',
  9 + feeFlag: 'Fee Flag',
  10 + feeId: 'Fee ID',
  11 + startTime: 'Start Time',
  12 + endTime: 'End Time',
  13 + oweAmount: 'Owe Amount',
  14 + paymentAmount: 'Payment Amount',
  15 + yuan: 'Yuan',
  16 + scanPay: 'Scan Payment',
  17 + pay: 'Pay',
  18 + paymentConfirm: 'Payment Confirmation',
  19 + room: 'Room:',
  20 + amount: 'Amount:',
  21 + paymentMethod: 'Payment Method:',
  22 + selectPaymentMethod: 'Required, please select payment method',
  23 + remark: 'Remark:',
  24 + inputRemark: 'Optional, please enter remark',
  25 + authCode: 'Auth Code:',
  26 + scanCodeTip: 'Please scan with scanner',
  27 + confirmPayment: 'Confirm Payment',
  28 + paymentTip: 'Payment Notice',
  29 + paymentSuccess: 'Payment successful',
  30 + mergePrint: 'Merge Print',
  31 + printReceipt: 'Print Receipt',
  32 + illegalOperation: 'Illegal operation',
  33 + noOweData: 'No owe data currently',
  34 + noSelectedFee: 'No fee selected',
  35 + noSelectedFeeItem: 'No fee item selected',
  36 + selectPaymentMethodTip: 'Please select payment method'
  37 + },
  38 + printOwnFee: {
  39 + printTitle: 'Print Notice',
  40 + validityDate: 'Validity Date:',
  41 + selectEndTime: 'Required, please select end time',
  42 + selectEndTimeTip: 'Please select end time'
  43 + }
  44 + },
  45 + zh: {
  46 + owePayFeeOrder: {
  47 + printNotice1: '催缴单1',
  48 + printNotice2: '催缴单2',
  49 + payerObj: '收费对象',
  50 + feeType: '费用类型',
  51 + feeItem: '费用项目',
  52 + feeFlag: '费用标识',
  53 + feeId: '费用ID',
  54 + startTime: '计费起始时间',
  55 + endTime: '计费结束时间',
  56 + oweAmount: '欠费金额',
  57 + paymentAmount: '缴费金额',
  58 + yuan: '元',
  59 + scanPay: '扫码收费',
  60 + pay: '缴费',
  61 + paymentConfirm: '收费确认',
  62 + room: '房屋:',
  63 + amount: '金额:',
  64 + paymentMethod: '支付方式:',
  65 + selectPaymentMethod: '必填,请选择支付方式',
  66 + remark: '备注:',
  67 + inputRemark: '可填,请填写备注',
  68 + authCode: '授权码:',
  69 + scanCodeTip: '请用扫码枪扫码',
  70 + confirmPayment: '确定收费',
  71 + paymentTip: '缴费提示',
  72 + paymentSuccess: '缴费成功',
  73 + mergePrint: '合并打印',
  74 + printReceipt: '打印收据',
  75 + illegalOperation: '非法操作',
  76 + noOweData: '当前没有欠费数据',
  77 + noSelectedFee: '未选择费用',
  78 + noSelectedFeeItem: '未选中要缴费的项目',
  79 + selectPaymentMethodTip: '请选择支付方式'
  80 + },
  81 + printOwnFee: {
  82 + printTitle: '打印催缴单',
  83 + validityDate: '有效期至:',
  84 + selectEndTime: '必填,请填写截止时间',
  85 + selectEndTimeTip: '请选择截止时间'
  86 + }
  87 + }
  88 +}
0 89 \ No newline at end of file
... ...
src/views/fee/owePayFeeOrderList.vue 0 → 100644
  1 +<template>
  2 + <div class="owe-pay-fee-order-container">
  3 + <el-card class="box-card">
  4 + <div slot="header" class="clearfix">
  5 + <span>{{ owePayFeeOrderInfo.roomName }}</span>
  6 + <div class="card-header-actions">
  7 + <el-button
  8 + type="primary"
  9 + size="small"
  10 + @click="_printOwnOrder()"
  11 + v-if="owePayFeeOrderInfo.oweFees.length > 0">
  12 + {{ $t('owePayFeeOrder.printNotice1') }}
  13 + </el-button>
  14 + <el-button
  15 + type="primary"
  16 + size="small"
  17 + @click="_printOwnOrder2()"
  18 + v-if="owePayFeeOrderInfo.oweFees.length > 0">
  19 + {{ $t('owePayFeeOrder.printNotice2') }}
  20 + </el-button>
  21 + <el-button
  22 + type="primary"
  23 + size="small"
  24 + @click="_goBack()">
  25 + <i class="el-icon-close"></i>
  26 + {{ $t('common.back') }}
  27 + </el-button>
  28 + </div>
  29 + </div>
  30 +
  31 + <el-table
  32 + :data="owePayFeeOrderInfo.oweFees"
  33 + border
  34 + style="width: 100%">
  35 + <el-table-column type="selection" width="55" @selection-change="handleSelectionChange"></el-table-column>
  36 + <el-table-column prop="payerObjName" :label="$t('owePayFeeOrder.payerObj')" align="center"></el-table-column>
  37 + <el-table-column prop="feeTypeCdName" :label="$t('owePayFeeOrder.feeType')" align="center"></el-table-column>
  38 + <el-table-column prop="feeName" :label="$t('owePayFeeOrder.feeItem')" align="center"></el-table-column>
  39 + <el-table-column prop="feeFlagName" :label="$t('owePayFeeOrder.feeFlag')" align="center"></el-table-column>
  40 + <el-table-column prop="feeId" :label="$t('owePayFeeOrder.feeId')" align="center"></el-table-column>
  41 + <el-table-column :label="$t('owePayFeeOrder.startTime')" align="center">
  42 + <template slot-scope="scope">
  43 + {{ _getEndTime(scope.row) }}
  44 + </template>
  45 + </el-table-column>
  46 + <el-table-column :label="$t('owePayFeeOrder.endTime')" align="center">
  47 + <template slot-scope="scope">
  48 + {{ _getDeadlineTime(scope.row) }}
  49 + </template>
  50 + </el-table-column>
  51 + <el-table-column prop="feeTotalPrice" :label="$t('owePayFeeOrder.oweAmount')" align="center"></el-table-column>
  52 + </el-table>
  53 +
  54 + <el-row class="footer-row">
  55 + <el-col :span="16"></el-col>
  56 + <el-col :span="4" class="amount-col">
  57 + {{ $t('owePayFeeOrder.paymentAmount') }}:
  58 + <span class="amount-text">{{ owePayFeeOrderInfo.feePrices }}</span>
  59 + <span>{{ $t('owePayFeeOrder.yuan') }}</span>
  60 + </el-col>
  61 + <el-col :span="2">
  62 + <el-button
  63 + type="success"
  64 + size="medium"
  65 + @click="_openPayFee('qrCode')"
  66 + class="pay-btn">
  67 + {{ $t('owePayFeeOrder.scanPay') }}
  68 + </el-button>
  69 + </el-col>
  70 + <el-col :span="2">
  71 + <el-button
  72 + type="primary"
  73 + size="medium"
  74 + @click="_payFee()"
  75 + class="pay-btn">
  76 + {{ $t('owePayFeeOrder.pay') }}
  77 + </el-button>
  78 + </el-col>
  79 + </el-row>
  80 + </el-card>
  81 +
  82 + <!-- 缴费确认弹窗 -->
  83 + <el-dialog
  84 + :title="$t('owePayFeeOrder.paymentConfirm')"
  85 + :visible.sync="showPayModal"
  86 + width="50%">
  87 + <el-form label-width="120px">
  88 + <el-form-item :label="$t('owePayFeeOrder.room')">
  89 + <span>{{ owePayFeeOrderInfo.roomName }}</span>
  90 + </el-form-item>
  91 + <el-form-item :label="$t('owePayFeeOrder.amount')">
  92 + <span>{{ owePayFeeOrderInfo.feePrices }}</span>
  93 + <span>{{ $t('owePayFeeOrder.yuan') }}</span>
  94 + </el-form-item>
  95 + <el-form-item :label="$t('owePayFeeOrder.paymentMethod')" required>
  96 + <el-select
  97 + v-model="owePayFeeOrderInfo.primeRate"
  98 + style="width:100%"
  99 + :placeholder="$t('owePayFeeOrder.selectPaymentMethod')">
  100 + <el-option
  101 + v-for="item in filteredPrimeRates"
  102 + :key="item.statusCd"
  103 + :label="item.name"
  104 + :value="item.statusCd">
  105 + </el-option>
  106 + </el-select>
  107 + </el-form-item>
  108 + <el-form-item :label="$t('owePayFeeOrder.remark')">
  109 + <el-input
  110 + type="textarea"
  111 + :placeholder="$t('owePayFeeOrder.inputRemark')"
  112 + v-model="owePayFeeOrderInfo.remark">
  113 + </el-input>
  114 + </el-form-item>
  115 + <el-form-item
  116 + v-if="owePayFeeOrderInfo.payType === 'qrCode'"
  117 + :label="$t('owePayFeeOrder.authCode')">
  118 + <el-input
  119 + v-model="owePayFeeOrderInfo.authCode"
  120 + :placeholder="$t('owePayFeeOrder.scanCodeTip')"
  121 + @keyup.enter.native="_qrCodePayFee">
  122 + </el-input>
  123 + </el-form-item>
  124 + </el-form>
  125 + <span slot="footer" class="dialog-footer">
  126 + <el-button @click="_closeDoOwePayFeeModal()">{{ $t('common.close') }}</el-button>
  127 + <el-button
  128 + type="primary"
  129 + @click="_doPayFee()"
  130 + v-if="owePayFeeOrderInfo.payType === 'common'">
  131 + {{ $t('owePayFeeOrder.confirmPayment') }}
  132 + </el-button>
  133 + </span>
  134 + </el-dialog>
  135 +
  136 + <!-- 缴费结果弹窗 -->
  137 + <el-dialog
  138 + :title="$t('owePayFeeOrder.paymentTip')"
  139 + :visible.sync="showResultModal"
  140 + width="30%">
  141 + <p>{{ $t('owePayFeeOrder.paymentSuccess') }}</p>
  142 + <span slot="footer" class="dialog-footer">
  143 + <el-button @click="_back()">{{ $t('common.back') }}</el-button>
  144 + <el-button
  145 + type="primary"
  146 + @click="_printAndBack('ON')">
  147 + {{ $t('owePayFeeOrder.mergePrint') }}
  148 + </el-button>
  149 + <el-button
  150 + type="primary"
  151 + @click="_printAndBack('OFF')">
  152 + {{ $t('owePayFeeOrder.printReceipt') }}
  153 + </el-button>
  154 + </span>
  155 + </el-dialog>
  156 +
  157 + <print-own-fee ref="printOwnFee"></print-own-fee>
  158 + </div>
  159 +</template>
  160 +
  161 +<script>
  162 +import { getDict } from '@/api/community/communityApi'
  163 +import { getCommunityId } from '@/api/community/communityApi'
  164 +import { dateFormat } from '@/utils/dateUtil'
  165 +import {
  166 + listOweFees,
  167 + payOweFee,
  168 + qrCodePayment,
  169 + checkPayFinish,
  170 + listFeePrintPages
  171 +} from '@/api/fee/owePayFeeOrderApi'
  172 +import PrintOwnFee from '@/components/fee/printOwnFee'
  173 +
  174 +export default {
  175 + name: 'OwePayFeeOrderList',
  176 + components: {
  177 + PrintOwnFee
  178 + },
  179 + data() {
  180 + return {
  181 + owePayFeeOrderInfo: {
  182 + oweFees: [],
  183 + selectPayFeeIds: [],
  184 + feePrices: 0.00,
  185 + communityId: '',
  186 + payObjId: '',
  187 + payObjType: '',
  188 + roomName: '',
  189 + receiptIds: '',
  190 + remark: '',
  191 + primeRate: '',
  192 + primeRates: [],
  193 + toFixedSign: 1,
  194 + payType: 'common',
  195 + authCode: '',
  196 + orderId: '',
  197 + printUrl: '/print.html#/pages/property/printPayFee',
  198 + detailIds: '',
  199 + paymentPoolId: ''
  200 + },
  201 + showPayModal: false,
  202 + showResultModal: false
  203 + }
  204 + },
  205 + computed: {
  206 + filteredPrimeRates() {
  207 + return this.owePayFeeOrderInfo.primeRates.filter(item => {
  208 + if (this.owePayFeeOrderInfo.payType === 'common') {
  209 + return item.statusCd !== '5' && item.statusCd !== '6'
  210 + } else {
  211 + return item.statusCd === '3' || item.statusCd === '4'
  212 + }
  213 + })
  214 + }
  215 + },
  216 + created() {
  217 + this.communityId = getCommunityId()
  218 + this._initData()
  219 + },
  220 + methods: {
  221 + async _initData() {
  222 + const _payObjId = this.$route.query.payObjId
  223 + const _payObjType = this.$route.query.payObjType
  224 +
  225 + if (!_payObjId) {
  226 + this.$message.error(this.$t('owePayFeeOrder.illegalOperation'))
  227 + this.$router.go(-1)
  228 + return
  229 + }
  230 +
  231 + this.owePayFeeOrderInfo.payObjId = _payObjId
  232 + this.owePayFeeOrderInfo.payObjType = _payObjType
  233 + this.owePayFeeOrderInfo.roomName = this.$route.query.roomName
  234 + this.owePayFeeOrderInfo.communityId = this.communityId
  235 +
  236 + await this._loadOweFees()
  237 + await this._loadPrimeRates()
  238 + await this._listFeePrintPages()
  239 + },
  240 +
  241 + handleSelectionChange(val) {
  242 + this.owePayFeeOrderInfo.selectPayFeeIds = val.map(item => item.feeId)
  243 + },
  244 +
  245 + async _loadOweFees() {
  246 + try {
  247 + const params = {
  248 + page: 1,
  249 + row: 50,
  250 + communityId: this.communityId,
  251 + payObjId: this.owePayFeeOrderInfo.payObjId,
  252 + payObjType: this.owePayFeeOrderInfo.payObjType,
  253 + }
  254 +
  255 + const { data } = await listOweFees(params)
  256 +
  257 + if (data.length < 1) {
  258 + this.owePayFeeOrderInfo.oweFees = []
  259 + this.$message.warning(this.$t('owePayFeeOrder.noOweData'))
  260 + return
  261 + }
  262 +
  263 + this.owePayFeeOrderInfo.oweFees = data
  264 + this.owePayFeeOrderInfo.selectPayFeeIds = data.map(item => item.feeId)
  265 + this.owePayFeeOrderInfo.toFixedSign = data[0].val
  266 +
  267 + this.owePayFeeOrderInfo.oweFees.forEach(item => {
  268 + item.receivableAmount = item.feeTotalPrice
  269 + item.feePrice = item.feeTotalPrice
  270 + })
  271 +
  272 + this._dealSelectFee()
  273 + } catch (error) {
  274 + console.error('获取欠费数据失败:', error)
  275 + }
  276 + },
  277 +
  278 + async _loadPrimeRates() {
  279 + try {
  280 + const data = await getDict('pay_fee_detail', 'prime_rate')
  281 + this.owePayFeeOrderInfo.primeRates = data
  282 + } catch (error) {
  283 + console.error('获取支付方式失败:', error)
  284 + }
  285 + },
  286 +
  287 + async _listFeePrintPages() {
  288 + try {
  289 + const params = {
  290 + page: 1,
  291 + row: 1,
  292 + state: 'T',
  293 + communityId: this.communityId
  294 + }
  295 +
  296 + const { data } = await listFeePrintPages(params)
  297 + if (data && data.length > 0) {
  298 + this.owePayFeeOrderInfo.printUrl = data[0].url
  299 + }
  300 + } catch (error) {
  301 + console.error('获取打印页面失败:', error)
  302 + }
  303 + },
  304 +
  305 + _payFee() {
  306 + if (this.owePayFeeOrderInfo.selectPayFeeIds.length <= 0) {
  307 + this.$message.warning(this.$t('owePayFeeOrder.noSelectedFee'))
  308 + return
  309 + }
  310 + this.showPayModal = true
  311 + this.owePayFeeOrderInfo.payType = 'common'
  312 + },
  313 +
  314 + _openPayFee() {
  315 + if (this.owePayFeeOrderInfo.selectPayFeeIds.length <= 0) {
  316 + this.$message.warning(this.$t('owePayFeeOrder.noSelectedFee'))
  317 + return
  318 + }
  319 + this.showPayModal = true
  320 + this.owePayFeeOrderInfo.payType = 'qrCode'
  321 + },
  322 +
  323 + _closeDoOwePayFeeModal() {
  324 + this.showPayModal = false
  325 + },
  326 +
  327 + _getPayFees() {
  328 + const _fees = []
  329 + this.owePayFeeOrderInfo.selectPayFeeIds.forEach(_item => {
  330 + const feeItem = this.owePayFeeOrderInfo.oweFees.find(_oweFeeItem => _item === _oweFeeItem.feeId)
  331 + if (feeItem) {
  332 + _fees.push({
  333 + feeId: _item,
  334 + startTime: feeItem.endTime,
  335 + endTime: feeItem.deadlineTime,
  336 + receivableAmount: feeItem.receivableAmount,
  337 + receivedAmount: feeItem.feePrice,
  338 + primeRate: this.owePayFeeOrderInfo.primeRate
  339 + })
  340 + }
  341 + })
  342 + return _fees
  343 + },
  344 +
  345 + async _doPayFee() {
  346 + if (!this.owePayFeeOrderInfo.primeRate) {
  347 + this.$message.warning(this.$t('owePayFeeOrder.selectPaymentMethod'))
  348 + return
  349 + }
  350 +
  351 + const _fees = this._getPayFees()
  352 + if (_fees.length < 1) {
  353 + this.$message.warning(this.$t('owePayFeeOrder.noSelectedFeeItem'))
  354 + return
  355 + }
  356 +
  357 + const _data = {
  358 + communityId: this.communityId,
  359 + fees: _fees,
  360 + remark: this.owePayFeeOrderInfo.remark
  361 + }
  362 +
  363 + try {
  364 + const res = await payOweFee(_data)
  365 + if (res.code === 0) {
  366 + this._doDealPayResult(res)
  367 + } else {
  368 + this.$message.error(res.msg)
  369 + }
  370 + } catch (error) {
  371 + console.error('缴费失败:', error)
  372 + this._closeDoOwePayFeeModal()
  373 + this.$message.error(error)
  374 + }
  375 + },
  376 +
  377 + async _qrCodePayFee() {
  378 + if (!this.owePayFeeOrderInfo.primeRate) {
  379 + this.$message.warning(this.$t('owePayFeeOrder.selectPaymentMethod'))
  380 + return
  381 + }
  382 +
  383 + const _fees = this._getPayFees()
  384 + if (_fees.length < 1) {
  385 + this.$message.warning(this.$t('owePayFeeOrder.noSelectedFeeItem'))
  386 + return
  387 + }
  388 +
  389 + const _data = {
  390 + communityId: this.communityId,
  391 + fees: _fees,
  392 + remark: this.owePayFeeOrderInfo.remark,
  393 + authCode: this.owePayFeeOrderInfo.authCode,
  394 + receivedAmount: this.owePayFeeOrderInfo.feePrices,
  395 + subServiceCode: 'fee.payOweFee'
  396 + }
  397 +
  398 + try {
  399 + const res = await qrCodePayment(_data)
  400 + if (res.code === 404) {
  401 + this.$message.error(res.msg)
  402 + if (res.data && res.data.orderId) {
  403 + this.owePayFeeOrderInfo.orderId = res.data.orderId
  404 + this.owePayFeeOrderInfo.paymentPoolId = res.data.paymentPoolId
  405 + setTimeout(() => {
  406 + this._qrCodeCheckPayFinish()
  407 + }, 5000)
  408 + }
  409 + } else if (res.code === 0) {
  410 + this._doDealPayResult(res)
  411 + } else {
  412 + this.$message.error(res.msg)
  413 + }
  414 + } catch (error) {
  415 + console.error('扫码支付失败:', error)
  416 + this.$message.error(error)
  417 + }
  418 + },
  419 +
  420 + async _qrCodeCheckPayFinish() {
  421 + const _fees = this._getPayFees()
  422 + if (_fees.length < 1) {
  423 + this.$message.warning(this.$t('owePayFeeOrder.noSelectedFeeItem'))
  424 + return
  425 + }
  426 +
  427 + const _data = {
  428 + communityId: this.communityId,
  429 + fees: _fees,
  430 + remark: this.owePayFeeOrderInfo.remark,
  431 + authCode: this.owePayFeeOrderInfo.authCode,
  432 + receivedAmount: this.owePayFeeOrderInfo.feePrices,
  433 + orderId: this.owePayFeeOrderInfo.orderId,
  434 + paymentPoolId: this.owePayFeeOrderInfo.paymentPoolId,
  435 + subServiceCode: 'fee.payOweFee'
  436 + }
  437 +
  438 + try {
  439 + const res = await checkPayFinish(_data)
  440 + if (res.code === 404) {
  441 + this.$message.error(res.msg)
  442 + } else if (res.code === 41) {
  443 + setTimeout(() => {
  444 + this._qrCodeCheckPayFinish()
  445 + }, 5000)
  446 + } else {
  447 + this._doDealPayResult(res)
  448 + }
  449 + } catch (error) {
  450 + console.error('检查支付状态失败:', error)
  451 + this.$message.error(error)
  452 + }
  453 + },
  454 +
  455 + _doDealPayResult(res) {
  456 + this._closeDoOwePayFeeModal()
  457 + const _data = res.data
  458 + let _detailIds = ''
  459 + _data.details.forEach(item => {
  460 + _detailIds += (item + ',')
  461 + })
  462 + this.owePayFeeOrderInfo.detailIds = _detailIds
  463 +
  464 + setTimeout(() => {
  465 + this.showResultModal = true
  466 + }, 2000)
  467 +
  468 + this.owePayFeeOrderInfo.selectPayFeeIds = []
  469 + this._loadOweFees()
  470 + this.$message.success(res.msg)
  471 + },
  472 +
  473 + _back() {
  474 + this.showResultModal = false
  475 + this.$router.go(-1)
  476 + },
  477 +
  478 + _printAndBack(merge) {
  479 + this.showResultModal = false
  480 + window.open(`${this.owePayFeeOrderInfo.printUrl}?detailIds=${this.owePayFeeOrderInfo.detailIds}&merge=${merge}`)
  481 + },
  482 +
  483 + _dealSelectFee() {
  484 + let totalFee = 0.00
  485 + this.owePayFeeOrderInfo.selectPayFeeIds.forEach(_item => {
  486 + const feeItem = this.owePayFeeOrderInfo.oweFees.find(_oweFeeItem => _item === _oweFeeItem.feeId)
  487 + if (feeItem) {
  488 + totalFee += parseFloat(feeItem.feePrice)
  489 + }
  490 + })
  491 + this.owePayFeeOrderInfo.feePrices = Math.round(totalFee * 100, 2) / 100
  492 + },
  493 +
  494 + _goBack() {
  495 + this.$router.go(-1)
  496 + },
  497 +
  498 + _printOwnOrder() {
  499 + window.open(`/print.html#/pages/property/printOweFee?payObjId=${this.owePayFeeOrderInfo.payObjId}&payObjType=${this.owePayFeeOrderInfo.payObjType}&payObjName=${this.owePayFeeOrderInfo.roomName}`)
  500 + },
  501 +
  502 + _printOwnOrder2() {
  503 + this.$refs.printOwnFee.open({
  504 + payObjId: this.owePayFeeOrderInfo.payObjId,
  505 + payObjType: this.owePayFeeOrderInfo.payObjType,
  506 + payObjName: this.owePayFeeOrderInfo.roomName
  507 + })
  508 + },
  509 +
  510 + _getDeadlineTime(fee) {
  511 + if (fee.amountOwed === 0 && fee.endTime === fee.deadlineTime) {
  512 + return "-"
  513 + }
  514 + if (fee.state === '2009001') {
  515 + return "-"
  516 + }
  517 + return dateFormat(fee.deadlineTime)
  518 + },
  519 +
  520 + _getEndTime(fee) {
  521 + if (fee.state === '2009001') {
  522 + return "-"
  523 + }
  524 + return dateFormat(fee.endTime)
  525 + }
  526 + }
  527 +}
  528 +</script>
  529 +
  530 +<style lang="scss" scoped>
  531 +.owe-pay-fee-order-container {
  532 + padding: 20px;
  533 +
  534 + .box-card {
  535 + margin-bottom: 20px;
  536 +
  537 + .clearfix {
  538 + display: flex;
  539 + justify-content: space-between;
  540 + align-items: center;
  541 + }
  542 +
  543 + .card-header-actions {
  544 + .el-button {
  545 + margin-left: 10px;
  546 + }
  547 + }
  548 + }
  549 +
  550 + .footer-row {
  551 + margin-top: 20px;
  552 + display: flex;
  553 + align-items: center;
  554 +
  555 + .amount-col {
  556 + display: flex;
  557 + align-items: center;
  558 + justify-content: flex-end;
  559 + padding-right: 20px;
  560 +
  561 + .amount-text {
  562 + font-size: 30px;
  563 + color: red;
  564 + padding: 0 5px;
  565 + }
  566 + }
  567 +
  568 + .pay-btn {
  569 + width: 100%;
  570 + }
  571 + }
  572 +}
  573 +</style>
0 574 \ No newline at end of file
... ...
src/views/fee/refundDepositFeeLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + refundDepositFee: {
  4 + title: 'Refund Deposit',
  5 + unrefunded: 'Unrefunded',
  6 + refunded: 'Refunded',
  7 + pendingReview: 'Pending Review',
  8 + printReceipt: 'Reprint Receipt'
  9 + },
  10 + payFeeDeposit: {
  11 + payerObject: 'Payer',
  12 + feeItem: 'Fee Item',
  13 + timePeriod: 'Time Period',
  14 + amount: 'Amount',
  15 + paymentTime: 'Payment Time',
  16 + status: 'Status',
  17 + operation: 'Operation',
  18 + refundDeposit: 'Refund Deposit',
  19 + detail: 'Detail'
  20 + },
  21 + returnPayFee: {
  22 + fillRefundReason: 'Fill Refund Reason',
  23 + payment: 'Payment',
  24 + monthUnit: '(Months)',
  25 + cycle: 'Cycle',
  26 + receivableAmount: 'Receivable Amount',
  27 + receivedAmount: 'Received Amount',
  28 + paymentTime: 'Payment Time',
  29 + refundReason: 'Refund Reason',
  30 + reasonRequired: 'Refund reason is required',
  31 + reasonMaxLength: 'Refund reason cannot exceed 200 characters',
  32 + reasonPlaceholder: 'Please enter refund reason',
  33 + submitRefund: 'Submit Refund Application'
  34 + }
  35 + },
  36 + zh: {
  37 + refundDepositFee: {
  38 + title: '退押金',
  39 + unrefunded: '未退押金',
  40 + refunded: '已退押金',
  41 + pendingReview: '待审核',
  42 + printReceipt: '补打退款单'
  43 + },
  44 + payFeeDeposit: {
  45 + payerObject: '收费对象',
  46 + feeItem: '费用项',
  47 + timePeriod: '时间段',
  48 + amount: '金额',
  49 + paymentTime: '缴费时间',
  50 + status: '状态',
  51 + operation: '操作',
  52 + refundDeposit: '退押金',
  53 + detail: '详情'
  54 + },
  55 + returnPayFee: {
  56 + fillRefundReason: '填写退费原因',
  57 + payment: '缴费',
  58 + monthUnit: '(单位月)',
  59 + cycle: '周期',
  60 + receivableAmount: '应收金额',
  61 + receivedAmount: '实收金额',
  62 + paymentTime: '缴费时间',
  63 + refundReason: '退费原因',
  64 + reasonRequired: '退费原因不能为空',
  65 + reasonMaxLength: '退费原因不能超过200个字符',
  66 + reasonPlaceholder: '请输入退费原因',
  67 + submitRefund: '提交退费申请'
  68 + }
  69 + }
  70 +}
0 71 \ No newline at end of file
... ...
src/views/fee/refundDepositFeeList.vue 0 → 100644
  1 +<template>
  2 + <div class="refund-deposit-fee-container">
  3 + <el-row :gutter="20">
  4 + <el-col :span="4">
  5 + <el-card class="state-card">
  6 + <ul class="state-list">
  7 + <li v-for="(item, index) in refundDepositFeeInfo.states" :key="index" @click="switchDepositState(item)"
  8 + :class="{ 'active-state': refundDepositFeeInfo.state === item.state }">
  9 + {{ item.name }}
  10 + </li>
  11 + </ul>
  12 + </el-card>
  13 + </el-col>
  14 + <el-col :span="20">
  15 + <el-card>
  16 + <div slot="header" class="flex justify-between">
  17 + <span>{{ $t('refundDepositFee.title') }}</span>
  18 + <div class="card-header-actions">
  19 + <el-button size="small" @click="printRefundFeeReceipt">
  20 + {{ $t('refundDepositFee.printReceipt') }}
  21 + </el-button>
  22 + <el-button size="small" @click="$router.go(-1)">
  23 + {{ $t('common.back') }}
  24 + </el-button>
  25 + </div>
  26 + </div>
  27 +
  28 + <el-table :data="refundDepositFeeInfo.fees" border style="width: 100%">
  29 + <el-table-column prop="payerObjName" :label="$t('payFeeDeposit.payerObject')" align="center" />
  30 + <el-table-column prop="feeName" :label="$t('payFeeDeposit.feeItem')" align="center" />
  31 + <el-table-column :label="$t('payFeeDeposit.timePeriod')" align="center">
  32 + <template slot-scope="scope">
  33 + {{ scope.row.startTime }}~{{ scope.row.endTime }}
  34 + </template>
  35 + </el-table-column>
  36 + <el-table-column prop="receivedAmount" :label="$t('payFeeDeposit.amount')" align="center" />
  37 + <el-table-column prop="createTime" :label="$t('payFeeDeposit.paymentTime')" align="center" />
  38 + <el-table-column prop="stateName" :label="$t('payFeeDeposit.status')" align="center" />
  39 + <el-table-column :label="$t('payFeeDeposit.operation')" align="center" width="180">
  40 + <template slot-scope="scope">
  41 + <el-button v-if="scope.row.state === '1400'" size="mini" type="primary"
  42 + @click="openRefundModel(scope.row)">
  43 + {{ $t('payFeeDeposit.refundDeposit') }}
  44 + </el-button>
  45 + <el-button size="mini" @click="toFeeDetail(scope.row)">
  46 + {{ $t('payFeeDeposit.detail') }}
  47 + </el-button>
  48 + </template>
  49 + </el-table-column>
  50 + </el-table>
  51 +
  52 + <el-pagination :current-page.sync="pagination.current" :page-sizes="[10, 20, 30, 50]"
  53 + :page-size="pagination.size" :total="pagination.total" layout="total, sizes, prev, pager, next, jumper"
  54 + @size-change="handleSizeChange" @current-change="handleCurrentChange" />
  55 + </el-card>
  56 + </el-col>
  57 + </el-row>
  58 +
  59 + <return-pay-fee ref="returnPayFee" @success="handleSuccess" />
  60 + </div>
  61 +</template>
  62 +
  63 +<script>
  64 +import { getCommunityId } from '@/api/community/communityApi'
  65 +import { queryFeeDeposit } from '@/api/fee/refundDepositFeeApi'
  66 +import ReturnPayFee from '@/components/fee/returnPayFee'
  67 +
  68 +export default {
  69 + name: 'RefundDepositFeeList',
  70 + components: {
  71 + ReturnPayFee
  72 + },
  73 + data() {
  74 + return {
  75 + refundDepositFeeInfo: {
  76 + fees: [],
  77 + states: [
  78 + { name: this.$t('refundDepositFee.unrefunded'), state: '1400' },
  79 + { name: this.$t('refundDepositFee.refunded'), state: '1100' },
  80 + { name: this.$t('refundDepositFee.pendingReview'), state: '1000' }
  81 + ],
  82 + state: '1400',
  83 + roomId: '',
  84 + ownerId: ''
  85 + },
  86 + pagination: {
  87 + current: 1,
  88 + size: 10,
  89 + total: 0
  90 + },
  91 + communityId: ''
  92 + }
  93 + },
  94 + created() {
  95 + this.communityId = getCommunityId()
  96 + this.refundDepositFeeInfo.roomId = this.$route.query.roomId
  97 + this.refundDepositFeeInfo.ownerId = this.$route.query.ownerId
  98 + this.listFeeDeposit()
  99 + },
  100 + methods: {
  101 + async listFeeDeposit() {
  102 + try {
  103 + const params = {
  104 + page: this.pagination.current,
  105 + row: this.pagination.size,
  106 + payerObjId: this.refundDepositFeeInfo.roomId,
  107 + ownerId: this.refundDepositFeeInfo.ownerId,
  108 + communityId: this.communityId,
  109 + state: this.refundDepositFeeInfo.state
  110 + }
  111 + const { data, total } = await queryFeeDeposit(params)
  112 + this.refundDepositFeeInfo.fees = data
  113 + this.pagination.total = total
  114 + } catch (error) {
  115 + this.$message.error(this.$t('common.fetchError'))
  116 + }
  117 + },
  118 + switchDepositState(state) {
  119 + this.refundDepositFeeInfo.state = state.state
  120 + this.pagination.current = 1
  121 + this.listFeeDeposit()
  122 + },
  123 + toFeeDetail(fee) {
  124 + this.$router.push(`/pages/property/propertyFee?feeId=${fee.feeId}`)
  125 + },
  126 + printRefundFeeReceipt() {
  127 + window.open(`/#/views/owner/ownerDetail?ownerId=${this.refundDepositFeeInfo.ownerId}&currentTab=ownerDetailReceipt`)
  128 + },
  129 + openRefundModel(fee) {
  130 + const feeData = {
  131 + ...fee,
  132 + mainFeeInfo: {
  133 + feeId: fee.feeId,
  134 + feeTypeCd: fee.feeTypeCd,
  135 + configId: fee.configId
  136 + },
  137 + cycles: 1,
  138 + receivableAmount: fee.receivedAmount,
  139 + communityId: this.communityId
  140 + }
  141 + this.$refs.returnPayFee.open(feeData)
  142 + },
  143 + handleSuccess() {
  144 + this.listFeeDeposit()
  145 + },
  146 + handleSizeChange(val) {
  147 + this.pagination.size = val
  148 + this.listFeeDeposit()
  149 + },
  150 + handleCurrentChange(val) {
  151 + this.pagination.current = val
  152 + this.listFeeDeposit()
  153 + }
  154 + }
  155 +}
  156 +</script>
  157 +
  158 +<style lang="scss" scoped>
  159 +.refund-deposit-fee-container {
  160 + padding: 20px;
  161 +
  162 + .state-card {
  163 + height: 100%;
  164 +
  165 + .state-list {
  166 + list-style: none;
  167 + padding: 0;
  168 + margin: 0;
  169 +
  170 + li {
  171 + padding: 10px;
  172 + text-align: center;
  173 + cursor: pointer;
  174 + margin-bottom: 5px;
  175 + border-radius: 4px;
  176 +
  177 + &:hover {
  178 + background-color: #f5f7fa;
  179 + }
  180 +
  181 + &.active-state {
  182 + background-color: #409eff;
  183 + color: white;
  184 + }
  185 + }
  186 + }
  187 + }
  188 +
  189 + .card-header-actions {
  190 + float: right;
  191 + }
  192 +
  193 + .el-pagination {
  194 + margin-top: 20px;
  195 + text-align: right;
  196 + }
  197 +}
  198 +</style>
0 199 \ No newline at end of file
... ...
src/views/oa/newOaWorkflowDetailLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + newOaWorkflowDetail: {
  4 + title: 'Work Order Details',
  5 + back: 'Back',
  6 + applicant: 'Applicant',
  7 + applyTime: 'Application Time',
  8 + status: 'Status',
  9 + workflowProcess: 'Work Order Process',
  10 + serialNumber: 'No.',
  11 + department: 'Department',
  12 + handler: 'Handler',
  13 + timeConsuming: 'Time Consuming',
  14 + comment: 'Comment',
  15 + processed: 'Processed',
  16 + processing: 'Processing',
  17 + admin: 'Administrator',
  18 + workflowHandle: 'Work Order Handling',
  19 + action: 'Action',
  20 + selectAction: 'Please select',
  21 + handle: 'Handle',
  22 + return: 'Return',
  23 + returnToSubmitter: 'Return to Submitter',
  24 + end: 'End',
  25 + transfer: 'Transfer',
  26 + workflowDescription: 'Work Order Description',
  27 + descriptionRequired: 'Required, please fill in the work order description',
  28 + nextHandler: 'Next Handler',
  29 + selectNextHandler: 'Required, please select the next handler',
  30 + select: 'Select',
  31 + submit: 'Submit',
  32 + flowChart: 'Flow Chart',
  33 + illegalOperation: 'Illegal operation',
  34 + selectStatus: 'Please select status',
  35 + fillDescription: 'Please fill in the description',
  36 + submitSuccess: 'Submitted successfully',
  37 + unknown: 'Unknown',
  38 + apply: 'Apply',
  39 + pendingReview: 'Pending Review',
  40 + returned: 'Returned',
  41 + transferred: 'Transferred',
  42 + completed: 'Completed'
  43 + },
  44 + selectStaff: {
  45 + title: 'Select Staff',
  46 + orgInfo: 'Organization Information',
  47 + staffInfo: 'Staff Information',
  48 + submitter: 'Submitter',
  49 + customAssign: 'Dynamic Assignment'
  50 + }
  51 + },
  52 + zh: {
  53 + newOaWorkflowDetail: {
  54 + title: '工单详情',
  55 + back: '返回',
  56 + applicant: '申请人',
  57 + applyTime: '申请时间',
  58 + status: '状态',
  59 + workflowProcess: '工单流转',
  60 + serialNumber: '序号',
  61 + department: '部门',
  62 + handler: '处理人',
  63 + timeConsuming: '耗时',
  64 + comment: '意见',
  65 + processed: '处理完成',
  66 + processing: '正在处理',
  67 + admin: '管理员',
  68 + workflowHandle: '工单办理',
  69 + action: '动作',
  70 + selectAction: '请选择',
  71 + handle: '办理',
  72 + return: '退回',
  73 + returnToSubmitter: '退回至提交者',
  74 + end: '结束',
  75 + transfer: '转单',
  76 + workflowDescription: '工单说明',
  77 + descriptionRequired: '必填,请填写工单说明',
  78 + nextHandler: '下一处理人',
  79 + selectNextHandler: '必填,请选择下一处理人',
  80 + select: '选择',
  81 + submit: '提交',
  82 + flowChart: '流程图',
  83 + illegalOperation: '非法操作',
  84 + selectStatus: '请选择状态',
  85 + fillDescription: '请填写说明',
  86 + submitSuccess: '提交成功',
  87 + unknown: '未知',
  88 + apply: '申请',
  89 + pendingReview: '待审核',
  90 + returned: '退回',
  91 + transferred: '转单',
  92 + completed: '办结'
  93 + },
  94 + selectStaff: {
  95 + title: '选择员工',
  96 + orgInfo: '组织信息',
  97 + staffInfo: '员工信息',
  98 + submitter: '提交者',
  99 + customAssign: '动态指定'
  100 + }
  101 + }
  102 +}
0 103 \ No newline at end of file
... ...
src/views/oa/newOaWorkflowDetailList.vue 0 → 100644
  1 +<template>
  2 + <div class="new-oa-workflow-detail-container">
  3 + <el-row :gutter="20">
  4 + <el-col :span="24">
  5 + <el-card>
  6 + <div slot="header" class="flex justify-between">
  7 + <span>{{ $t('newOaWorkflowDetail.title') }}</span>
  8 + <div class="float-right">
  9 + <el-button type="primary" size="small" @click="_goBack">
  10 + {{ $t('newOaWorkflowDetail.back') }}
  11 + </el-button>
  12 + </div>
  13 + </div>
  14 +
  15 + <div v-if="newOaWorkflowDetailInfo.pools">
  16 + <el-form>
  17 + <el-row :gutter="20">
  18 + <el-col :span="8">
  19 + <el-form-item :label="$t('newOaWorkflowDetail.applicant')">
  20 + <span>{{ newOaWorkflowDetailInfo.pools.create_user_name }}</span>
  21 + </el-form-item>
  22 + </el-col>
  23 + <el-col :span="8">
  24 + <el-form-item :label="$t('newOaWorkflowDetail.applyTime')">
  25 + <span>{{ newOaWorkflowDetailInfo.pools.create_time }}</span>
  26 + </el-form-item>
  27 + </el-col>
  28 + <el-col :span="8">
  29 + <el-form-item :label="$t('newOaWorkflowDetail.status')">
  30 + <span>{{ _getNewOaWorkflowDetailState(newOaWorkflowDetailInfo.pools) }}</span>
  31 + </el-form-item>
  32 + </el-col>
  33 + </el-row>
  34 +
  35 + <el-row :gutter="20">
  36 + <template v-for="(item, index) in newOaWorkflowDetailInfo.formJson">
  37 + <el-col v-if="item.type != 'text' && item.type != 'button'" :key="index" :span="8">
  38 + <el-form-item :label="item.label">
  39 + <span>{{ newOaWorkflowDetailInfo.pools[item.key] }}</span>
  40 + </el-form-item>
  41 + </el-col>
  42 + </template>
  43 + </el-row>
  44 +
  45 + <el-row :gutter="20">
  46 + <el-col v-for="(item, index) in newOaWorkflowDetailInfo.files" :key="index" :span="8">
  47 + <el-form-item>
  48 + <el-link :href="item.realFileName" target="_blank">{{ item.fileName }}</el-link>
  49 + </el-form-item>
  50 + </el-col>
  51 + </el-row>
  52 + </el-form>
  53 + </div>
  54 + </el-card>
  55 + </el-col>
  56 + </el-row>
  57 +
  58 + <el-row :gutter="20" class="mt-20">
  59 + <el-col :span="24">
  60 + <el-card>
  61 + <div slot="header" class="flex justify-between">
  62 + <span>{{ $t('newOaWorkflowDetail.workflowProcess') }}</span>
  63 + </div>
  64 +
  65 + <el-table :data="newOaWorkflowDetailInfo.comments" border style="width: 100%">
  66 + <el-table-column prop="index" :label="$t('newOaWorkflowDetail.serialNumber')" width="80" align="center">
  67 + <template slot-scope="scope">
  68 + {{ scope.$index + 1 }}
  69 + </template>
  70 + </el-table-column>
  71 + <el-table-column prop="orgName" :label="$t('newOaWorkflowDetail.department')" align="center">
  72 + <template slot-scope="scope">
  73 + {{ scope.row.orgName || $t('newOaWorkflowDetail.admin') }}
  74 + </template>
  75 + </el-table-column>
  76 + <el-table-column prop="staffName" :label="$t('newOaWorkflowDetail.handler')" align="center" />
  77 + <el-table-column :label="$t('newOaWorkflowDetail.status')" align="center">
  78 + <template slot-scope="scope">
  79 + {{ scope.row.endTime ? $t('newOaWorkflowDetail.processed') : $t('newOaWorkflowDetail.processing') }}
  80 + </template>
  81 + </el-table-column>
  82 + <el-table-column prop="duration" :label="$t('newOaWorkflowDetail.timeConsuming')" align="center" />
  83 + <el-table-column prop="context" :label="$t('newOaWorkflowDetail.comment')" align="center" />
  84 + </el-table>
  85 + </el-card>
  86 + </el-col>
  87 + </el-row>
  88 +
  89 + <el-row v-if="newOaWorkflowDetailInfo.action" :gutter="20" class="mt-20">
  90 + <el-col :span="24">
  91 + <el-card>
  92 + <div slot="header" class="flex justify-between">
  93 + <span>{{ $t('newOaWorkflowDetail.workflowHandle') }}</span>
  94 + </div>
  95 +
  96 + <el-form label-width="120px">
  97 + <el-form-item :label="$t('newOaWorkflowDetail.action')">
  98 + <el-select v-model="newOaWorkflowDetailInfo.audit.auditCode" style="width:100%"
  99 + :placeholder="$t('newOaWorkflowDetail.selectAction')">
  100 + <el-option v-if="newOaWorkflowDetailInfo.nextAudit.next" value="1100"
  101 + :label="$t('newOaWorkflowDetail.handle')" />
  102 + <el-option v-if="newOaWorkflowDetailInfo.nextAudit.back" value="1200"
  103 + :label="$t('newOaWorkflowDetail.return')" />
  104 + <el-option v-if="newOaWorkflowDetailInfo.nextAudit.backIndex" value="1400"
  105 + :label="$t('newOaWorkflowDetail.returnToSubmitter')" />
  106 + <el-option v-if="newOaWorkflowDetailInfo.nextAudit.exit" value="1500"
  107 + :label="$t('newOaWorkflowDetail.end')" />
  108 + <el-option value="1300" :label="$t('newOaWorkflowDetail.transfer')" />
  109 + </el-select>
  110 + </el-form-item>
  111 +
  112 + <el-form-item :label="$t('newOaWorkflowDetail.workflowDescription')">
  113 + <el-input type="textarea" :rows="3" :placeholder="$t('newOaWorkflowDetail.descriptionRequired')"
  114 + v-model="newOaWorkflowDetailInfo.audit.auditMessage" />
  115 + </el-form-item>
  116 +
  117 + <!-- 办理时 判断是否指定 委托人 如果指定了 则不显示 -->
  118 + <el-form-item
  119 + v-if="newOaWorkflowDetailInfo.audit.auditCode == '1100' && newOaWorkflowDetailInfo.nextAudit.assignee == '-2'"
  120 + :label="$t('newOaWorkflowDetail.nextHandler')">
  121 + <el-input v-model="newOaWorkflowDetailInfo.audit.staffName"
  122 + :placeholder="$t('newOaWorkflowDetail.selectNextHandler')" disabled style="width:80%" />
  123 + <el-button type="primary" @click="chooseStaff" style="margin-left:10px">
  124 + {{ $t('newOaWorkflowDetail.select') }}
  125 + </el-button>
  126 + </el-form-item>
  127 +
  128 + <!-- 转单时 必须指定 委托人 -->
  129 + <el-form-item v-if="newOaWorkflowDetailInfo.audit.auditCode == '1300'"
  130 + :label="$t('newOaWorkflowDetail.nextHandler')">
  131 + <el-input v-model="newOaWorkflowDetailInfo.audit.staffName"
  132 + :placeholder="$t('newOaWorkflowDetail.selectNextHandler')" disabled style="width:80%" />
  133 + <el-button type="primary" @click="chooseStaff" style="margin-left:10px">
  134 + {{ $t('newOaWorkflowDetail.select') }}
  135 + </el-button>
  136 + </el-form-item>
  137 +
  138 + <el-form-item>
  139 + <el-button type="primary" class="float-right" @click="_auditSubmit">
  140 + {{ $t('newOaWorkflowDetail.submit') }}
  141 + </el-button>
  142 + </el-form-item>
  143 + </el-form>
  144 + </el-card>
  145 + </el-col>
  146 + </el-row>
  147 +
  148 + <el-row :gutter="20" class="mt-20">
  149 + <el-col :span="24">
  150 + <el-card>
  151 + <div slot="header" class="flex justify-between">
  152 + <span>{{ $t('newOaWorkflowDetail.flowChart') }}</span>
  153 + </div>
  154 + <div class="text-center">
  155 + <el-image :src="newOaWorkflowDetailInfo.imgData" style="height:300px" fit="contain" />
  156 + </div>
  157 + </el-card>
  158 + </el-col>
  159 + </el-row>
  160 +
  161 + <select-staff ref="selectStaff" />
  162 + </div>
  163 +</template>
  164 +
  165 +<script>
  166 +import { getCommunityId } from '@/api/community/communityApi'
  167 +import { queryOaWorkflowForm, queryOaWorkflowFormData, queryOaWorkflowUser, getNextTask, auditOaWorkflow, listRunWorkflowImage } from '@/api/oa/newOaWorkflowDetailApi'
  168 +import SelectStaff from '@/components/staff/SelectStaff'
  169 +
  170 +export default {
  171 + name: 'NewOaWorkflowDetailList',
  172 + components: {
  173 + SelectStaff
  174 + },
  175 + data() {
  176 + return {
  177 + newOaWorkflowDetailInfo: {
  178 + id: '',
  179 + flowId: '',
  180 + pools: {},
  181 + formJson: [],
  182 + comments: [],
  183 + action: '',
  184 + audit: {
  185 + auditCode: '1100',
  186 + auditMessage: '',
  187 + staffId: '',
  188 + staffName: '',
  189 + taskId: ''
  190 + },
  191 + imgData: '',
  192 + nextAudit: {},
  193 + files: []
  194 + },
  195 + communityId: ''
  196 + }
  197 + },
  198 + created() {
  199 + this.communityId = getCommunityId()
  200 + const id = this.$route.query.id
  201 + if (!id) {
  202 + this.$message.error(this.$t('newOaWorkflowDetail.illegalOperation'))
  203 + return
  204 + }
  205 + this.newOaWorkflowDetailInfo.id = id
  206 + this.newOaWorkflowDetailInfo.flowId = this.$route.query.flowId
  207 + this.newOaWorkflowDetailInfo.action = this.$route.query.action
  208 + this.newOaWorkflowDetailInfo.audit.taskId = this.$route.query.taskId
  209 + this._listOaWorkflowDetails()
  210 + this._loadComments()
  211 + if (this.newOaWorkflowDetailInfo.action) {
  212 + this._loadNextAuditPerson()
  213 + }
  214 + this._openNewOaWorkflowDetailImg()
  215 + },
  216 + methods: {
  217 + async _listOaWorkFlowDetailForm() {
  218 + try {
  219 + const params = {
  220 + page: 1,
  221 + row: 1,
  222 + flowId: this.newOaWorkflowDetailInfo.flowId
  223 + }
  224 + const response = await queryOaWorkflowForm(params)
  225 + this.newOaWorkflowDetailInfo.formJson = JSON.parse(response.data[0].formJson).components
  226 + } catch (error) {
  227 + console.error('请求失败:', error)
  228 + }
  229 + },
  230 + async _listOaWorkflowDetails() {
  231 + try {
  232 + const params = {
  233 + page: 1,
  234 + row: 1,
  235 + id: this.newOaWorkflowDetailInfo.id,
  236 + flowId: this.newOaWorkflowDetailInfo.flowId
  237 + }
  238 + const response = await queryOaWorkflowFormData(params)
  239 + this.newOaWorkflowDetailInfo.pools = response.data[0]
  240 + this.newOaWorkflowDetailInfo.files = response.data[0].files
  241 + this._listOaWorkFlowDetailForm()
  242 + } catch (error) {
  243 + console.error('请求失败:', error)
  244 + }
  245 + },
  246 + async _loadComments() {
  247 + try {
  248 + const params = {
  249 + communityId: this.communityId,
  250 + id: this.newOaWorkflowDetailInfo.id,
  251 + flowId: this.newOaWorkflowDetailInfo.flowId,
  252 + page: 1,
  253 + row: 10
  254 + }
  255 + const response = await queryOaWorkflowUser(params)
  256 + if (response.code !== '0') return
  257 + this.newOaWorkflowDetailInfo.comments = response.data
  258 + } catch (error) {
  259 + console.error('请求失败:', error)
  260 + }
  261 + },
  262 + _goBack() {
  263 + this.$router.go(-1)
  264 + },
  265 + chooseStaff() {
  266 + this.$refs.selectStaff.open(this.newOaWorkflowDetailInfo.audit)
  267 + },
  268 + async _auditSubmit() {
  269 + const audit = this.newOaWorkflowDetailInfo.audit
  270 + audit.flowId = this.newOaWorkflowDetailInfo.flowId
  271 + audit.id = this.newOaWorkflowDetailInfo.id
  272 +
  273 + if (!audit.auditCode) {
  274 + this.$message.error(this.$t('newOaWorkflowDetail.selectStatus'))
  275 + return
  276 + }
  277 + if (!audit.auditMessage) {
  278 + this.$message.error(this.$t('newOaWorkflowDetail.fillDescription'))
  279 + return
  280 + }
  281 + if (audit.auditCode !== '1200' && audit.auditCode !== '1400' && !audit.staffId) {
  282 + this.$message.error(this.$t('newOaWorkflowDetail.selectNextHandler'))
  283 + return
  284 + }
  285 +
  286 + try {
  287 + const response = await auditOaWorkflow(audit)
  288 + if (response.code === 0) {
  289 + this.$message.success(this.$t('newOaWorkflowDetail.submitSuccess'))
  290 + this._goBack()
  291 + } else {
  292 + this.$message.error(response.msg)
  293 + }
  294 + } catch (error) {
  295 + this.$message.error(error)
  296 + }
  297 + },
  298 + async _loadNextAuditPerson() {
  299 + try {
  300 + const params = {
  301 + communityId: this.communityId,
  302 + taskId: this.newOaWorkflowDetailInfo.audit.taskId,
  303 + flowId: this.newOaWorkflowDetailInfo.flowId,
  304 + id: this.newOaWorkflowDetailInfo.id
  305 + }
  306 + const response = await getNextTask(params)
  307 + if (response.code !== '0') return
  308 + this.newOaWorkflowDetailInfo.nextAudit = response.data[0]
  309 + } catch (error) {
  310 + console.error('请求失败:', error)
  311 + }
  312 + },
  313 + _getNewOaWorkflowDetailState(pool) {
  314 + if (!Object.prototype.hasOwnProperty.call(pool, 'state')) {
  315 + return this.$t('newOaWorkflowDetail.unknown')
  316 + }
  317 + switch (pool.state) {
  318 + case '1001':
  319 + return this.$t('newOaWorkflowDetail.apply')
  320 + case '1002':
  321 + return this.$t('newOaWorkflowDetail.pendingReview')
  322 + case '1003':
  323 + return this.$t('newOaWorkflowDetail.returned')
  324 + case '1004':
  325 + return this.$t('newOaWorkflowDetail.transferred')
  326 + case '1005':
  327 + return this.$t('newOaWorkflowDetail.completed')
  328 + default:
  329 + return this.$t('newOaWorkflowDetail.unknown')
  330 + }
  331 + },
  332 + async _openNewOaWorkflowDetailImg() {
  333 + try {
  334 + const params = {
  335 + communityId: this.communityId,
  336 + businessKey: this.newOaWorkflowDetailInfo.id
  337 + }
  338 + const response = await listRunWorkflowImage(params)
  339 + if (response.code !== '0') return
  340 + this.newOaWorkflowDetailInfo.imgData = 'data:image/png;base64,' + response.data
  341 + } catch (error) {
  342 + console.error('请求失败:', error)
  343 + }
  344 + }
  345 + }
  346 +}
  347 +</script>
  348 +
  349 +<style lang="scss" scoped>
  350 +.new-oa-workflow-detail-container {
  351 + padding: 20px;
  352 +
  353 + .mt-20 {
  354 + margin-top: 20px;
  355 + }
  356 +
  357 + .float-right {
  358 + float: right;
  359 + }
  360 +
  361 + .text-center {
  362 + text-align: center;
  363 + }
  364 +
  365 + .el-form-item {
  366 + margin-bottom: 0;
  367 + }
  368 +}
  369 +</style>
0 370 \ No newline at end of file
... ...
src/views/oa/newOaWorkflowFormEditLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + newOaWorkflowFormEdit: {
  4 + title: 'Edit',
  5 + submit: 'Submit',
  6 + cancel: 'Cancel',
  7 + requiredMessage: ' is required',
  8 + submitSuccess: 'Submit successfully',
  9 + submitError: 'Submit failed'
  10 + },
  11 + uploadFile: {
  12 + uploadBtn: 'Upload Attachment',
  13 + sizeLimit: 'File size cannot exceed 20MB',
  14 + uploadSuccess: 'File uploaded successfully',
  15 + uploadError: 'File upload failed'
  16 + }
  17 + },
  18 + zh: {
  19 + newOaWorkflowFormEdit: {
  20 + title: '编辑',
  21 + submit: '提交',
  22 + cancel: '取消',
  23 + requiredMessage: '不能为空',
  24 + submitSuccess: '提交成功',
  25 + submitError: '提交失败'
  26 + },
  27 + uploadFile: {
  28 + uploadBtn: '上传附件',
  29 + sizeLimit: '文件大小不能超过20MB',
  30 + uploadSuccess: '文件上传成功',
  31 + uploadError: '文件上传失败'
  32 + }
  33 + }
  34 +}
0 35 \ No newline at end of file
... ...
src/views/oa/newOaWorkflowFormEditList.vue 0 → 100644
  1 +<template>
  2 + <div class="new-oa-workflow-form-edit-container">
  3 + <el-card class="box-card">
  4 + <div slot="header" class="flex justify-between">
  5 + <span>{{ $t('newOaWorkflowFormEdit.title') }}</span>
  6 + </div>
  7 + <el-form>
  8 + <el-row :gutter="20">
  9 + <el-col :span="24">
  10 + <div v-for="(item, index) in newOaWorkflowFormEditInfo.components" :key="index">
  11 + <el-form-item v-if="item.type === 'textfield'" :label="item.label"
  12 + :prop="'components.' + index + '.value'"
  13 + :rules="[{ required: item.validate && item.validate.required, message: $t('newOaWorkflowFormEdit.requiredMessage') }]">
  14 + <el-input v-model="item.value" :placeholder="item.description" clearable />
  15 + </el-form-item>
  16 +
  17 + <el-form-item v-if="item.type === 'number'" :label="item.label" :prop="'components.' + index + '.value'">
  18 + <el-input-number v-model="item.value" :placeholder="item.description" controls-position="right" />
  19 + </el-form-item>
  20 +
  21 + <el-form-item v-if="item.type === 'textarea'" :label="item.label"
  22 + :prop="'components.' + index + '.value'">
  23 + <el-input v-model="item.value" type="textarea" :placeholder="item.description" :rows="4" />
  24 + </el-form-item>
  25 +
  26 + <el-form-item v-if="item.type === 'textdate'" :label="item.label"
  27 + :prop="'components.' + index + '.value'">
  28 + <el-date-picker v-model="item.value" type="date" :placeholder="item.description"
  29 + value-format="yyyy-MM-dd" />
  30 + </el-form-item>
  31 +
  32 + <el-form-item v-if="item.type === 'textdatetime'" :label="item.label"
  33 + :prop="'components.' + index + '.value'">
  34 + <el-date-picker v-model="item.value" type="datetime" :placeholder="item.description"
  35 + value-format="yyyy-MM-dd HH:mm:ss" />
  36 + </el-form-item>
  37 +
  38 + <el-form-item v-if="item.type === 'checkbox'" :label="item.label"
  39 + :prop="'components.' + index + '.value'">
  40 + <el-checkbox-group v-model="item.value">
  41 + <el-checkbox :label="item.value">{{ item.label }}</el-checkbox>
  42 + </el-checkbox-group>
  43 + </el-form-item>
  44 + </div>
  45 +
  46 + <upload-file ref="uploadFile" :call-back-listener="'newOaWorkflowFormEdit'"
  47 + :call-back-function="'fileName'" />
  48 +
  49 + <div class="form-footer">
  50 + <el-button type="primary" @click="_submitFormData">
  51 + <i class="el-icon-check"></i>
  52 + {{ $t('newOaWorkflowFormEdit.submit') }}
  53 + </el-button>
  54 + <el-button type="warning" @click="closeEditInfo">
  55 + {{ $t('newOaWorkflowFormEdit.cancel') }}
  56 + </el-button>
  57 + </div>
  58 + </el-col>
  59 + </el-row>
  60 + </el-form>
  61 + </el-card>
  62 + </div>
  63 +</template>
  64 +
  65 +<script>
  66 +import { queryOaWorkflowForm, queryOaWorkflowFormData, updateOaWorkflowFormData } from '@/api/oa/newOaWorkflowFormEditApi'
  67 +import UploadFile from '@/components/oa/uploadFile'
  68 +
  69 +export default {
  70 + name: 'NewOaWorkflowFormEditList',
  71 + components: {
  72 + UploadFile
  73 + },
  74 + data() {
  75 + return {
  76 + newOaWorkflowFormEditInfo: {
  77 + formJson: {},
  78 + components: [],
  79 + conditions: {},
  80 + flowId: '',
  81 + id: '',
  82 + fileName: '',
  83 + realFileName: ''
  84 + }
  85 + }
  86 + },
  87 + created() {
  88 + this.newOaWorkflowFormEditInfo.flowId = this.$route.query.flowId
  89 + this.newOaWorkflowFormEditInfo.id = this.$route.query.id
  90 + this._listOaWorkflowFormEdit(1, 100)
  91 + },
  92 + methods: {
  93 + async _listOaWorkflowFormEdit(page, rows) {
  94 + try {
  95 + const params = {
  96 + page,
  97 + row: rows,
  98 + flowId: this.newOaWorkflowFormEditInfo.flowId
  99 + }
  100 +
  101 + const { data } = await queryOaWorkflowForm(params)
  102 + const formData = JSON.parse(data[0].formJson)
  103 + this.newOaWorkflowFormEditInfo.formJson = formData
  104 + this.newOaWorkflowFormEditInfo.components = formData.components
  105 + this._listOaWorkflowDetails()
  106 + } catch (error) {
  107 + console.error('获取表单数据失败:', error)
  108 + }
  109 + },
  110 + async _listOaWorkflowDetails() {
  111 + try {
  112 + const params = {
  113 + page: 1,
  114 + row: 1,
  115 + id: this.newOaWorkflowFormEditInfo.id,
  116 + flowId: this.newOaWorkflowFormEditInfo.flowId
  117 + }
  118 +
  119 + const { data } = await queryOaWorkflowFormData(params)
  120 + const detailData = data[0]
  121 +
  122 + this.newOaWorkflowFormEditInfo.components.forEach(item => {
  123 + item.value = detailData[item.key]
  124 + })
  125 +
  126 + if (detailData.files) {
  127 + this.newOaWorkflowFormEditInfo.fileName = detailData.files[0].fileName
  128 + this.newOaWorkflowFormEditInfo.realFileName = detailData.files[0].realFileName
  129 + this.$refs.uploadFile.notifyVedio(detailData.files[0].fileName)
  130 + }
  131 + } catch (error) {
  132 + console.error('获取表单详情失败:', error)
  133 + }
  134 + },
  135 + async _submitFormData() {
  136 + try {
  137 + const components = this.newOaWorkflowFormEditInfo.components
  138 + const formData = {
  139 + id: this.newOaWorkflowFormEditInfo.id,
  140 + flowId: this.newOaWorkflowFormEditInfo.flowId,
  141 + fileName: this.newOaWorkflowFormEditInfo.fileName,
  142 + realFileName: this.newOaWorkflowFormEditInfo.realFileName
  143 + }
  144 +
  145 + components.forEach(item => {
  146 + if (item.validate && item.validate.required && !item.value) {
  147 + this.$message.error(item.label + this.$t('newOaWorkflowFormEdit.requiredMessage'))
  148 + throw new Error(item.label + this.$t('newOaWorkflowFormEdit.requiredMessage'))
  149 + }
  150 +
  151 + if (item.type !== 'button' && item.type !== 'text') {
  152 + formData[item.key] = item.value
  153 + if (item.type === 'checkbox') {
  154 + formData[item.key] = item.value.length > 0 ? item.value[0] : ''
  155 + }
  156 + }
  157 + })
  158 +
  159 + const res = await updateOaWorkflowFormData(formData)
  160 + if (res.code === 0) {
  161 + this.$message.success(this.$t('newOaWorkflowFormEdit.submitSuccess'))
  162 + this.closeEditInfo()
  163 + } else {
  164 + this.$message.error(res.msg)
  165 + }
  166 + } catch (error) {
  167 + console.error('提交表单失败:', error)
  168 + this.$message.error(this.$t('newOaWorkflowFormEdit.submitError'))
  169 + }
  170 + },
  171 + closeEditInfo() {
  172 + this.$router.go(-1)
  173 + }
  174 + }
  175 +}
  176 +</script>
  177 +
  178 +<style lang="scss" scoped>
  179 +.new-oa-workflow-form-edit-container {
  180 + padding: 20px;
  181 +
  182 + .box-card {
  183 + margin-bottom: 20px;
  184 + }
  185 +
  186 + .form-footer {
  187 + margin-top: 20px;
  188 + text-align: right;
  189 + }
  190 +
  191 + .el-form-item {
  192 + margin-bottom: 22px;
  193 + }
  194 +}
  195 +</style>
0 196 \ No newline at end of file
... ...
src/views/oa/newOaWorkflowLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + newOaWorkflow: {
  4 + processWorkOrder: 'Process Work Order',
  5 + draftProcess: 'Draft Process',
  6 + processTodo: 'Process Todo',
  7 + processDone: 'Process Done'
  8 + },
  9 + newOaWorkflowPool: {
  10 + searchTitle: 'Search Conditions',
  11 + enterApplicant: 'Please enter applicant',
  12 + enterStartTime: 'Please enter start time',
  13 + enterEndTime: 'Please enter end time',
  14 + processWorkOrder: 'Process Work Order',
  15 + applicant: 'Applicant',
  16 + status: 'Status',
  17 + createTime: 'Create Time',
  18 + operation: 'Operation',
  19 + detail: 'Detail',
  20 + flowChart: 'Flow Chart',
  21 + stateApply: 'Apply',
  22 + statePending: 'Pending',
  23 + stateReturned: 'Returned',
  24 + stateDelegate: 'Delegate',
  25 + stateCompleted: 'Completed'
  26 + },
  27 + newOaWorkflowUndo: {
  28 + searchTitle: 'Search Conditions',
  29 + enterApplicant: 'Please enter applicant',
  30 + enterStartTime: 'Please enter start time',
  31 + enterEndTime: 'Please enter end time',
  32 + todoProcess: 'Todo Process',
  33 + applicant: 'Applicant',
  34 + status: 'Status',
  35 + createTime: 'Create Time',
  36 + operation: 'Operation',
  37 + process: 'Process',
  38 + detail: 'Detail',
  39 + edit: 'Edit',
  40 + stateApply: 'Apply',
  41 + statePending: 'Pending',
  42 + stateReturned: 'Returned',
  43 + stateDelegate: 'Delegate',
  44 + stateCompleted: 'Completed'
  45 + },
  46 + newOaWorkflowFinish: {
  47 + searchTitle: 'Search Conditions',
  48 + enterApplicant: 'Please enter applicant',
  49 + enterStartTime: 'Please enter start time',
  50 + enterEndTime: 'Please enter end time',
  51 + doneProcess: 'Done Process',
  52 + applicant: 'Applicant',
  53 + status: 'Status',
  54 + createTime: 'Create Time',
  55 + operation: 'Operation',
  56 + detail: 'Detail',
  57 + stateApply: 'Apply',
  58 + statePending: 'Pending',
  59 + stateReturned: 'Returned',
  60 + stateDelegate: 'Delegate',
  61 + stateCompleted: 'Completed'
  62 + },
  63 + uploadFile: {
  64 + uploadAttachment: 'Upload Attachment',
  65 + fileSizeLimit: 'File size cannot exceed 20MB',
  66 + uploadSuccess: 'File uploaded successfully',
  67 + uploadFailed: 'File upload failed'
  68 + }
  69 + },
  70 + zh: {
  71 + newOaWorkflow: {
  72 + processWorkOrder: '流程工单',
  73 + draftProcess: '起草流程',
  74 + processTodo: '流程待办',
  75 + processDone: '流程已办'
  76 + },
  77 + newOaWorkflowPool: {
  78 + searchTitle: '查询条件',
  79 + enterApplicant: '请输入申请人',
  80 + enterStartTime: '请输入开始时间',
  81 + enterEndTime: '请输入结束时间',
  82 + processWorkOrder: '流程工单',
  83 + applicant: '申请人',
  84 + status: '状态',
  85 + createTime: '创建时间',
  86 + operation: '操作',
  87 + detail: '详情',
  88 + flowChart: '流程图',
  89 + stateApply: '申请',
  90 + statePending: '待审核',
  91 + stateReturned: '退回',
  92 + stateDelegate: '委托',
  93 + stateCompleted: '办结'
  94 + },
  95 + newOaWorkflowUndo: {
  96 + searchTitle: '查询条件',
  97 + enterApplicant: '请输入申请人',
  98 + enterStartTime: '请输入开始时间',
  99 + enterEndTime: '请输入结束时间',
  100 + todoProcess: '待办流程',
  101 + applicant: '申请人',
  102 + status: '状态',
  103 + createTime: '创建时间',
  104 + operation: '操作',
  105 + process: '办理',
  106 + detail: '详情',
  107 + edit: '编辑',
  108 + stateApply: '申请',
  109 + statePending: '待审核',
  110 + stateReturned: '退回',
  111 + stateDelegate: '委托',
  112 + stateCompleted: '办结'
  113 + },
  114 + newOaWorkflowFinish: {
  115 + searchTitle: '查询条件',
  116 + enterApplicant: '请输入申请人',
  117 + enterStartTime: '请输入开始时间',
  118 + enterEndTime: '请输入结束时间',
  119 + doneProcess: '已办流程',
  120 + applicant: '申请人',
  121 + status: '状态',
  122 + createTime: '创建时间',
  123 + operation: '操作',
  124 + detail: '详情',
  125 + stateApply: '申请',
  126 + statePending: '待审核',
  127 + stateReturned: '退回',
  128 + stateDelegate: '委托',
  129 + stateCompleted: '办结'
  130 + },
  131 + uploadFile: {
  132 + uploadAttachment: '上传附件',
  133 + fileSizeLimit: '文件大小不能超过20MB',
  134 + uploadSuccess: '文件上传成功',
  135 + uploadFailed: '文件上传失败'
  136 + }
  137 + }
  138 +}
0 139 \ No newline at end of file
... ...
src/views/oa/newOaWorkflowList.vue 0 → 100644
  1 +<template>
  2 + <div class="new-oa-workflow-container">
  3 + <el-row :gutter="20">
  4 + <el-col :span="4">
  5 + <div class="menu-wrapper bg-white">
  6 + <ul class="menu-list">
  7 + <li v-if="hasPrivilege('502023041839740294')" :class="{ 'active': activeTab === 'newOaWorkflowPool' }"
  8 + @click="switchTab('newOaWorkflowPool')">
  9 + {{ $t('newOaWorkflow.processWorkOrder') }}
  10 + </li>
  11 + <li :class="{ 'active': activeTab === 'newOaWorkflowForm' }" @click="switchTab('newOaWorkflowForm')">
  12 + {{ $t('newOaWorkflow.draftProcess') }}
  13 + </li>
  14 + <li :class="{ 'active': activeTab === 'newOaWorkflowUndo' }" @click="switchTab('newOaWorkflowUndo')">
  15 + {{ $t('newOaWorkflow.processTodo') }}
  16 + </li>
  17 + <li :class="{ 'active': activeTab === 'newOaWorkflowFinish' }" @click="switchTab('newOaWorkflowFinish')">
  18 + {{ $t('newOaWorkflow.processDone') }}
  19 + </li>
  20 + </ul>
  21 + </div>
  22 + </el-col>
  23 + <el-col :span="20">
  24 + <div class="content-wrapper">
  25 + <new-oa-workflow-pool v-show="activeTab === 'newOaWorkflowPool'" ref="newOaWorkflowPool" />
  26 + <new-oa-workflow-form v-if="activeTab === 'newOaWorkflowForm'" ref="newOaWorkflowForm" />
  27 + <new-oa-workflow-undo v-show="activeTab === 'newOaWorkflowUndo'" ref="newOaWorkflowUndo" />
  28 + <new-oa-workflow-finish v-show="activeTab === 'newOaWorkflowFinish'" ref="newOaWorkflowFinish" />
  29 + </div>
  30 + </el-col>
  31 + </el-row>
  32 + </div>
  33 +</template>
  34 +
  35 +<script>
  36 +import NewOaWorkflowPool from '@/components/oa/newOaWorkflowPool'
  37 +import NewOaWorkflowForm from '@/components/oa/newOaWorkflowForm'
  38 +import NewOaWorkflowUndo from '@/components/oa/newOaWorkflowUndo'
  39 +import NewOaWorkflowFinish from '@/components/oa/newOaWorkflowFinish'
  40 +
  41 +export default {
  42 + name: 'NewOaWorkflowList',
  43 + components: {
  44 + NewOaWorkflowPool,
  45 + NewOaWorkflowForm,
  46 + NewOaWorkflowUndo,
  47 + NewOaWorkflowFinish
  48 + },
  49 + data() {
  50 + return {
  51 + activeTab: '',
  52 + flowId: this.$route.query.flowId || ''
  53 + }
  54 + },
  55 + created() {
  56 + this.initActiveTab()
  57 + },
  58 + methods: {
  59 + initActiveTab() {
  60 + const switchValue = this.$route.query.switchValue
  61 + if (switchValue) {
  62 + this.switchTab(switchValue)
  63 + return
  64 + }
  65 + if (this.hasPrivilege('502023041839740294')) {
  66 + this.switchTab('newOaWorkflowPool')
  67 + } else {
  68 + this.switchTab('newOaWorkflowForm')
  69 + }
  70 + },
  71 + switchTab(tab) {
  72 + if (this.activeTab === tab) return
  73 + this.activeTab = tab
  74 + setTimeout(() => {
  75 + this.$refs[tab].open({ flowId: this.flowId })
  76 + }, 500)
  77 + },
  78 + }
  79 +}
  80 +</script>
  81 +
  82 +<style lang="scss" scoped>
  83 +.new-oa-workflow-container {
  84 + padding: 20px;
  85 + height: 100%;
  86 +
  87 + .menu-wrapper {
  88 + border-radius: 4px;
  89 + padding: 10px 0;
  90 + height: 100%;
  91 +
  92 + .menu-list {
  93 + list-style: none;
  94 + padding: 0;
  95 + margin: 0;
  96 +
  97 + li {
  98 + padding: 12px 20px;
  99 + cursor: pointer;
  100 + transition: all 0.3s;
  101 + border-left: 3px solid transparent;
  102 +
  103 + &:hover {
  104 + background-color: #f5f7fa;
  105 + }
  106 +
  107 + &.active {
  108 + background-color: #ecf5ff;
  109 + border-left: 3px solid #409eff;
  110 + color: #409eff;
  111 + }
  112 + }
  113 + }
  114 + }
  115 +
  116 + .content-wrapper {
  117 +
  118 + height: 100%;
  119 + }
  120 +}
  121 +</style>
0 122 \ No newline at end of file
... ...
src/views/oa/newOaWorkflowManageList.vue
... ... @@ -3,13 +3,8 @@
3 3 <el-card class="box-card">
4 4 <div v-if="newOaWorkflowManageInfo.newOaWorkflows && newOaWorkflowManageInfo.newOaWorkflows.length > 0">
5 5 <el-row :gutter="20">
6   - <el-col
7   - v-for="(item, index) in newOaWorkflowManageInfo.newOaWorkflows"
8   - :key="index"
9   - :span="4"
10   - class="text-center workflow-item"
11   - @click.native="newFlow(item)"
12   - >
  6 + <el-col v-for="(item, index) in newOaWorkflowManageInfo.newOaWorkflows" :key="index" :span="4"
  7 + class="text-center workflow-item" @click.native="newFlow(item)">
13 8 <div>
14 9 <img src="/img/flow.png" width="80px" />
15 10 </div>
... ... @@ -64,14 +59,14 @@ export default {
64 59 flowId: flow.flowId,
65 60 state: 'C'
66 61 })
67   -
  62 +
68 63 if (data.length < 1) {
69 64 this.$message.error(this.$t('newOaWorkflowManage.flowNotDeployed'))
70 65 return
71 66 }
72   -
  67 +
73 68 this.$router.push({
74   - path: '/form.html#/pages/property/newOaWorkflow',
  69 + path: '/views/oa/newOaWorkflow',
75 70 query: { flowId: flow.flowId }
76 71 })
77 72 } catch (error) {
... ... @@ -85,27 +80,27 @@ export default {
85 80 <style lang="scss" scoped>
86 81 .new-oa-workflow-manage-container {
87 82 padding: 20px;
88   -
  83 +
89 84 .box-card {
90 85 min-height: 400px;
91 86 }
92   -
  87 +
93 88 .workflow-item {
94 89 margin-bottom: 20px;
95 90 cursor: pointer;
96 91 transition: all 0.3s;
97   -
  92 +
98 93 &:hover {
99 94 transform: translateY(-5px);
100 95 }
101 96 }
102   -
  97 +
103 98 .empty-tip {
104 99 padding: 20px;
105 100 text-align: center;
106 101 color: #909399;
107 102 }
108   -
  103 +
109 104 .margin-top {
110 105 margin-top: 10px;
111 106 }
... ...
src/views/simplify/simplifyAcceptanceList.vue
... ... @@ -69,7 +69,7 @@
69 69 <div class="form-group">
70 70 <label class="col-form-label">{{ $t('simplifyAcceptance.ownerName') }}</label>
71 71 <label>
72   - <a target="_blank" :href="'/#/pages/owner/ownerDetail?ownerId=' + simplifyAcceptanceInfo.ownerId">
  72 + <a target="_blank" :href="'/#/views/owner/ownerDetail?ownerId=' + simplifyAcceptanceInfo.ownerId">
73 73 {{ simplifyAcceptanceInfo.name }}
74 74 </a>
75 75 </label>
... ... @@ -180,7 +180,7 @@
180 180 <span v-if="simplifyAcceptanceInfo.acctAmount">
181 181 {{ simplifyAcceptanceInfo.acctAmount }}(
182 182 <a target="_blank" v-if="hasPrivilege('502023032809461736')"
183   - :href="'/#/pages/owner/ownerDetail?ownerId=' + simplifyAcceptanceInfo.ownerId + '&currentTab=ownerDetailAccount'">
  183 + :href="'/#/views/owner/ownerDetail?ownerId=' + simplifyAcceptanceInfo.ownerId + '&currentTab=ownerDetailAccount'">
184 184 {{ $t('simplifyAcceptance.preDeposit') }}
185 185 </a>
186 186 )
... ... @@ -616,7 +616,7 @@ export default {
616 616 const _roomId = this.simplifyAcceptanceInfo.roomId
617 617 const _ownerId = this.simplifyAcceptanceInfo.ownerId
618 618 this.$router.push({
619   - path: '/pages/fee/refundDepositFee',
  619 + path: '/views/fee/refundDepositFee',
620 620 query: {
621 621 roomId: _roomId,
622 622 ownerId: _ownerId
... ...
vue.config.js
... ... @@ -4,19 +4,33 @@ module.exports = {
4 4 open: true, // 自动打开浏览器
5 5 proxy: {
6 6 '/app': {
7   - target: 'http://localhost:8008/app', // 后端API地址
  7 + target: 'http://demo.homecommunity.cn/app', // 后端API地址
8 8 changeOrigin: true,
9 9 pathRewrite: {
10 10 '^/app': ''
11 11 }
12 12 },
13 13 '/callComponent': {
14   - target: 'http://localhost:8008/callComponent', // 后端API地址
  14 + target: 'http://demo.homecommunity.cn/callComponent', // 后端API地址
15 15 changeOrigin: true,
16 16 pathRewrite: {
17 17 '^/callComponent': ''
18 18 }
19 19 }
  20 + // '/app': {
  21 + // target: 'http://localhost:8008/app', // 后端API地址
  22 + // changeOrigin: true,
  23 + // pathRewrite: {
  24 + // '^/app': ''
  25 + // }
  26 + // },
  27 + // '/callComponent': {
  28 + // target: 'http://localhost:8008/callComponent', // 后端API地址
  29 + // changeOrigin: true,
  30 + // pathRewrite: {
  31 + // '^/callComponent': ''
  32 + // }
  33 + // }
20 34 },
21 35 // 关键:禁止开发服务器对静态资源添加 hash
22 36 historyApiFallback: {
... ...