Merge remote-tracking branch 'origin/dev_New' into dev_New
| | |
| | | '@element-plus/icons-vue': |
| | | specifier: 2.3.1 |
| | | version: 2.3.1(vue@3.4.31) |
| | | '@vue-office/docx': |
| | | specifier: ^1.6.3 |
| | | version: 1.6.3(vue-demi@0.14.10(vue@3.4.31))(vue@3.4.31) |
| | | '@vue-office/excel': |
| | | specifier: ^1.7.14 |
| | | version: 1.7.14(vue-demi@0.14.10(vue@3.4.31))(vue@3.4.31) |
| | | '@vueup/vue-quill': |
| | | specifier: 1.2.0 |
| | | version: 1.2.0(vue@3.4.31) |
| | | '@vueuse/core': |
| | | specifier: 10.11.0 |
| | | version: 10.11.0(vue@3.4.31) |
| | | autofit.js: |
| | | specifier: ^3.2.8 |
| | | version: 3.2.8 |
| | | axios: |
| | | specifier: 0.28.1 |
| | | version: 0.28.1 |
| | |
| | | pinia: |
| | | specifier: 2.1.7 |
| | | version: 2.1.7(vue@3.4.31) |
| | | print-js: |
| | | specifier: ^1.6.0 |
| | | version: 1.6.0 |
| | | qrcode: |
| | | specifier: ^1.5.4 |
| | | version: 1.5.4 |
| | | sortablejs: |
| | | specifier: ^1.15.6 |
| | | version: 1.15.6 |
| | |
| | | vue-cropper: |
| | | specifier: 1.1.1 |
| | | version: 1.1.1 |
| | | vue-easy-lightbox: |
| | | specifier: ^1.19.0 |
| | | version: 1.19.0(vue@3.4.31) |
| | | vue-esign: |
| | | specifier: ^1.1.4 |
| | | version: 1.1.4 |
| | | vue-router: |
| | | specifier: 4.4.0 |
| | | version: 4.4.0(vue@3.4.31) |
| | |
| | | resolution: {integrity: sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==} |
| | | cpu: [arm] |
| | | os: [linux] |
| | | libc: [glibc] |
| | | |
| | | '@rollup/rollup-linux-arm-musleabihf@4.40.2': |
| | | resolution: {integrity: sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==} |
| | | cpu: [arm] |
| | | os: [linux] |
| | | libc: [musl] |
| | | |
| | | '@rollup/rollup-linux-arm64-gnu@4.40.2': |
| | | resolution: {integrity: sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==} |
| | | cpu: [arm64] |
| | | os: [linux] |
| | | libc: [glibc] |
| | | |
| | | '@rollup/rollup-linux-arm64-musl@4.40.2': |
| | | resolution: {integrity: sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==} |
| | | cpu: [arm64] |
| | | os: [linux] |
| | | libc: [musl] |
| | | |
| | | '@rollup/rollup-linux-loongarch64-gnu@4.40.2': |
| | | resolution: {integrity: sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==} |
| | | cpu: [loong64] |
| | | os: [linux] |
| | | libc: [glibc] |
| | | |
| | | '@rollup/rollup-linux-powerpc64le-gnu@4.40.2': |
| | | resolution: {integrity: sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==} |
| | | cpu: [ppc64] |
| | | os: [linux] |
| | | libc: [glibc] |
| | | |
| | | '@rollup/rollup-linux-riscv64-gnu@4.40.2': |
| | | resolution: {integrity: sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==} |
| | | cpu: [riscv64] |
| | | os: [linux] |
| | | libc: [glibc] |
| | | |
| | | '@rollup/rollup-linux-riscv64-musl@4.40.2': |
| | | resolution: {integrity: sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==} |
| | | cpu: [riscv64] |
| | | os: [linux] |
| | | libc: [musl] |
| | | |
| | | '@rollup/rollup-linux-s390x-gnu@4.40.2': |
| | | resolution: {integrity: sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==} |
| | | cpu: [s390x] |
| | | os: [linux] |
| | | libc: [glibc] |
| | | |
| | | '@rollup/rollup-linux-x64-gnu@4.40.2': |
| | | resolution: {integrity: sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==} |
| | | cpu: [x64] |
| | | os: [linux] |
| | | libc: [glibc] |
| | | |
| | | '@rollup/rollup-linux-x64-musl@4.40.2': |
| | | resolution: {integrity: sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==} |
| | | cpu: [x64] |
| | | os: [linux] |
| | | libc: [musl] |
| | | |
| | | '@rollup/rollup-win32-arm64-msvc@4.40.2': |
| | | resolution: {integrity: sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==} |
| | |
| | | vite: ^5.0.0 |
| | | vue: ^3.2.25 |
| | | |
| | | '@vue-office/docx@1.6.3': |
| | | resolution: {integrity: sha512-Cs+3CAaRBOWOiW4XAhTwwxJ0dy8cPIf6DqfNvYcD3YACiLwO4kuawLF2IAXxyijhbuOeoFsfvoVbOc16A/4bZA==} |
| | | peerDependencies: |
| | | '@vue/composition-api': ^1.7.1 |
| | | vue: ^2.0.0 || >=3.0.0 |
| | | vue-demi: ^0.14.6 |
| | | peerDependenciesMeta: |
| | | '@vue/composition-api': |
| | | optional: true |
| | | |
| | | '@vue-office/excel@1.7.14': |
| | | resolution: {integrity: sha512-pVUgt+emDQUnW7q22CfnQ+jl43mM/7IFwYzOg7lwOwPEbiVB4K4qEQf+y/bc4xGXz75w1/e3Kz3G6wAafmFBFg==} |
| | | peerDependencies: |
| | | '@vue/composition-api': ^1.7.1 |
| | | vue: ^2.0.0 || >=3.0.0 |
| | | vue-demi: ^0.14.6 |
| | | peerDependenciesMeta: |
| | | '@vue/composition-api': |
| | | optional: true |
| | | |
| | | '@vue/compiler-core@3.4.31': |
| | | resolution: {integrity: sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg==} |
| | | |
| | |
| | | |
| | | '@vue/compiler-dom@3.5.14': |
| | | resolution: {integrity: sha512-1aOCSqxGOea5I80U2hQJvXYpPm/aXo95xL/m/mMhgyPUsKe9jhjwWpziNAw7tYRnbz1I61rd9Mld4W9KmmRoug==} |
| | | |
| | | '@vue/compiler-sfc@2.7.16': |
| | | resolution: {integrity: sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==} |
| | | |
| | | '@vue/compiler-sfc@3.4.31': |
| | | resolution: {integrity: sha512-einJxqEw8IIJxzmnxmJBuK2usI+lJonl53foq+9etB2HAzlPjAS/wa7r0uUpXw5ByX3/0uswVSrjNb17vJm1kQ==} |
| | |
| | | engines: {node: '>= 4.5.0'} |
| | | hasBin: true |
| | | |
| | | autofit.js@3.2.8: |
| | | resolution: {integrity: sha512-albZNwDIXvcRneEDyZLW3uAIOH0cUQG/TnCGQ7jpfnL0gPn/+1ZNVRuEz3ZuzZvVkQ4HQRplGHjUeMRtPNxjLQ==} |
| | | |
| | | available-typed-arrays@1.0.7: |
| | | resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} |
| | | engines: {node: '>= 0.4'} |
| | |
| | | resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} |
| | | engines: {node: '>= 0.4'} |
| | | |
| | | camelcase@5.3.1: |
| | | resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} |
| | | engines: {node: '>=6'} |
| | | |
| | | chalk@1.1.3: |
| | | resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} |
| | | engines: {node: '>=0.10.0'} |
| | |
| | | |
| | | clipboard@2.0.11: |
| | | resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==} |
| | | |
| | | cliui@6.0.0: |
| | | resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} |
| | | |
| | | clone@2.1.2: |
| | | resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} |
| | |
| | | supports-color: |
| | | optional: true |
| | | |
| | | decamelize@1.2.0: |
| | | resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} |
| | | engines: {node: '>=0.10.0'} |
| | | |
| | | decode-uri-component@0.2.2: |
| | | resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} |
| | | engines: {node: '>=0.10'} |
| | |
| | | |
| | | delegate@3.2.0: |
| | | resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==} |
| | | |
| | | dijkstrajs@1.0.3: |
| | | resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} |
| | | |
| | | dom-serializer@0.2.2: |
| | | resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==} |
| | |
| | | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} |
| | | engines: {node: '>=8'} |
| | | |
| | | find-up@4.1.0: |
| | | resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} |
| | | engines: {node: '>=8'} |
| | | |
| | | follow-redirects@1.15.9: |
| | | resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} |
| | | engines: {node: '>=4.0'} |
| | |
| | | fuse.js@6.6.2: |
| | | resolution: {integrity: sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==} |
| | | engines: {node: '>=10'} |
| | | |
| | | get-caller-file@2.0.5: |
| | | resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} |
| | | engines: {node: 6.* || 8.* || >= 10.*} |
| | | |
| | | get-intrinsic@1.3.0: |
| | | resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} |
| | |
| | | resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} |
| | | engines: {node: '>=14'} |
| | | |
| | | locate-path@5.0.0: |
| | | resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} |
| | | engines: {node: '>=8'} |
| | | |
| | | lodash-es@4.17.21: |
| | | resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} |
| | | |
| | |
| | | resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} |
| | | engines: {node: '>= 0.4'} |
| | | |
| | | p-limit@2.3.0: |
| | | resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} |
| | | engines: {node: '>=6'} |
| | | |
| | | p-locate@4.1.0: |
| | | resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} |
| | | engines: {node: '>=8'} |
| | | |
| | | p-try@2.2.0: |
| | | resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} |
| | | engines: {node: '>=6'} |
| | | |
| | | package-json-from-dist@1.0.1: |
| | | resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} |
| | | |
| | |
| | | pascalcase@0.1.1: |
| | | resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} |
| | | engines: {node: '>=0.10.0'} |
| | | |
| | | path-exists@4.0.0: |
| | | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} |
| | | engines: {node: '>=8'} |
| | | |
| | | path-key@3.1.1: |
| | | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} |
| | |
| | | pkg-types@2.1.0: |
| | | resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==} |
| | | |
| | | pngjs@5.0.0: |
| | | resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} |
| | | engines: {node: '>=10.13.0'} |
| | | |
| | | posix-character-classes@0.1.1: |
| | | resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} |
| | | engines: {node: '>=0.10.0'} |
| | |
| | | resolution: {integrity: sha512-spBB5sgC4cv2YcW03f/IAUN1pgDJWNWD8FzkyY4mArLUMJW+KlQhlmUdKAHQuPfb00Jl5xIfImeOsf6YL8QK7Q==} |
| | | engines: {node: '>=0.10.0'} |
| | | |
| | | prettier@2.8.8: |
| | | resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} |
| | | engines: {node: '>=10.13.0'} |
| | | hasBin: true |
| | | |
| | | print-js@1.6.0: |
| | | resolution: {integrity: sha512-BfnOIzSKbqGRtO4o0rnj/K3681BSd2QUrsIZy/+WdCIugjIswjmx3lDEZpXB2ruGf9d4b3YNINri81+J0FsBWg==} |
| | | |
| | | proto-list@1.2.4: |
| | | resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} |
| | | |
| | | proxy-from-env@1.1.0: |
| | | resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} |
| | | |
| | | qrcode@1.5.4: |
| | | resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} |
| | | engines: {node: '>=10.13.0'} |
| | | hasBin: true |
| | | |
| | | quansync@0.2.10: |
| | | resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} |
| | |
| | | repeat-string@1.6.1: |
| | | resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} |
| | | engines: {node: '>=0.10'} |
| | | |
| | | require-directory@2.1.1: |
| | | resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} |
| | | engines: {node: '>=0.10.0'} |
| | | |
| | | require-main-filename@2.0.0: |
| | | resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} |
| | | |
| | | resolve-url@0.2.1: |
| | | resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} |
| | |
| | | resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} |
| | | engines: {node: '>=10'} |
| | | hasBin: true |
| | | |
| | | set-blocking@2.0.0: |
| | | resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} |
| | | |
| | | set-function-length@1.2.2: |
| | | resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} |
| | |
| | | '@vue/composition-api': |
| | | optional: true |
| | | |
| | | vue-easy-lightbox@1.19.0: |
| | | resolution: {integrity: sha512-YxLXgjEn91UF3DuK1y8u3Pyx2sJ7a/MnBpkyrBSQkvU1glzEJASyAZ7N+5yDpmxBQDVMwCsL2VmxWGIiFrWCgA==} |
| | | engines: {node: '>=14.18.3'} |
| | | peerDependencies: |
| | | vue: ^3.0.0 |
| | | |
| | | vue-esign@1.1.4: |
| | | resolution: {integrity: sha512-7Ix5PdcyyhVfsvrT9a+yp5+36gbQ0/bpDO+QSLT58IgJ5t164PEptOy5Nslw8bZbk3n3Hc7SP5B8eXQ8X8W+OA==} |
| | | |
| | | vue-router@4.4.0: |
| | | resolution: {integrity: sha512-HB+t2p611aIZraV2aPSRNXf0Z/oLZFrlygJm+sZbdJaW6lcFqEDQwnzUBXn+DApw+/QzDU/I9TeWx9izEjTmsA==} |
| | | peerDependencies: |
| | | vue: ^3.2.0 |
| | | |
| | | vue@2.7.16: |
| | | resolution: {integrity: sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==} |
| | | deprecated: Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details. |
| | | |
| | | vue@3.4.31: |
| | | resolution: {integrity: sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ==} |
| | |
| | | resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} |
| | | engines: {node: '>= 0.4'} |
| | | |
| | | which-module@2.0.1: |
| | | resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} |
| | | |
| | | which-typed-array@1.1.19: |
| | | resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} |
| | | engines: {node: '>= 0.4'} |
| | |
| | | engines: {node: '>= 8'} |
| | | hasBin: true |
| | | |
| | | wrap-ansi@6.2.0: |
| | | resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} |
| | | engines: {node: '>=8'} |
| | | |
| | | wrap-ansi@7.0.0: |
| | | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} |
| | | engines: {node: '>=10'} |
| | |
| | | wrap-ansi@8.1.0: |
| | | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} |
| | | engines: {node: '>=12'} |
| | | |
| | | y18n@4.0.3: |
| | | resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} |
| | | |
| | | yargs-parser@18.1.3: |
| | | resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} |
| | | engines: {node: '>=6'} |
| | | |
| | | yargs@15.4.1: |
| | | resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} |
| | | engines: {node: '>=8'} |
| | | |
| | | zrender@5.6.0: |
| | | resolution: {integrity: sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==} |
| | |
| | | vite: 5.3.2(@types/node@22.15.18)(sass@1.77.5) |
| | | vue: 3.4.31 |
| | | |
| | | '@vue-office/docx@1.6.3(vue-demi@0.14.10(vue@3.4.31))(vue@3.4.31)': |
| | | dependencies: |
| | | vue: 3.4.31 |
| | | vue-demi: 0.14.10(vue@3.4.31) |
| | | |
| | | '@vue-office/excel@1.7.14(vue-demi@0.14.10(vue@3.4.31))(vue@3.4.31)': |
| | | dependencies: |
| | | vue: 3.4.31 |
| | | vue-demi: 0.14.10(vue@3.4.31) |
| | | |
| | | '@vue/compiler-core@3.4.31': |
| | | dependencies: |
| | | '@babel/parser': 7.27.2 |
| | |
| | | dependencies: |
| | | '@vue/compiler-core': 3.5.14 |
| | | '@vue/shared': 3.5.14 |
| | | |
| | | '@vue/compiler-sfc@2.7.16': |
| | | dependencies: |
| | | '@babel/parser': 7.27.2 |
| | | postcss: 8.5.3 |
| | | source-map: 0.6.1 |
| | | optionalDependencies: |
| | | prettier: 2.8.8 |
| | | |
| | | '@vue/compiler-sfc@3.4.31': |
| | | dependencies: |
| | |
| | | |
| | | atob@2.1.2: {} |
| | | |
| | | autofit.js@3.2.8: {} |
| | | |
| | | available-typed-arrays@1.0.7: |
| | | dependencies: |
| | | possible-typed-array-names: 1.1.0 |
| | |
| | | call-bind-apply-helpers: 1.0.2 |
| | | get-intrinsic: 1.3.0 |
| | | |
| | | camelcase@5.3.1: {} |
| | | |
| | | chalk@1.1.3: |
| | | dependencies: |
| | | ansi-styles: 2.2.1 |
| | |
| | | good-listener: 1.2.2 |
| | | select: 1.1.2 |
| | | tiny-emitter: 2.1.0 |
| | | |
| | | cliui@6.0.0: |
| | | dependencies: |
| | | string-width: 4.2.3 |
| | | strip-ansi: 6.0.1 |
| | | wrap-ansi: 6.2.0 |
| | | |
| | | clone@2.1.2: {} |
| | | |
| | |
| | | dependencies: |
| | | ms: 2.1.3 |
| | | |
| | | decamelize@1.2.0: {} |
| | | |
| | | decode-uri-component@0.2.2: {} |
| | | |
| | | deep-equal@1.1.2: |
| | |
| | | delayed-stream@1.0.0: {} |
| | | |
| | | delegate@3.2.0: {} |
| | | |
| | | dijkstrajs@1.0.3: {} |
| | | |
| | | dom-serializer@0.2.2: |
| | | dependencies: |
| | |
| | | dependencies: |
| | | to-regex-range: 5.0.1 |
| | | |
| | | find-up@4.1.0: |
| | | dependencies: |
| | | locate-path: 5.0.0 |
| | | path-exists: 4.0.0 |
| | | |
| | | follow-redirects@1.15.9: {} |
| | | |
| | | for-each@0.3.5: |
| | |
| | | functions-have-names@1.2.3: {} |
| | | |
| | | fuse.js@6.6.2: {} |
| | | |
| | | get-caller-file@2.0.5: {} |
| | | |
| | | get-intrinsic@1.3.0: |
| | | dependencies: |
| | |
| | | pkg-types: 2.1.0 |
| | | quansync: 0.2.10 |
| | | |
| | | locate-path@5.0.0: |
| | | dependencies: |
| | | p-locate: 4.1.0 |
| | | |
| | | lodash-es@4.17.21: {} |
| | | |
| | | lodash-unified@1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.21)(lodash@4.17.21): |
| | |
| | | object-keys: 1.1.1 |
| | | safe-push-apply: 1.0.0 |
| | | |
| | | p-limit@2.3.0: |
| | | dependencies: |
| | | p-try: 2.2.0 |
| | | |
| | | p-locate@4.1.0: |
| | | dependencies: |
| | | p-limit: 2.3.0 |
| | | |
| | | p-try@2.2.0: {} |
| | | |
| | | package-json-from-dist@1.0.1: {} |
| | | |
| | | parchment@1.1.4: {} |
| | | |
| | | pascalcase@0.1.1: {} |
| | | |
| | | path-exists@4.0.0: {} |
| | | |
| | | path-key@3.1.1: {} |
| | | |
| | |
| | | confbox: 0.2.2 |
| | | exsolve: 1.0.5 |
| | | pathe: 2.0.3 |
| | | |
| | | pngjs@5.0.0: {} |
| | | |
| | | posix-character-classes@0.1.1: {} |
| | | |
| | |
| | | posthtml-parser: 0.2.1 |
| | | posthtml-render: 1.4.0 |
| | | |
| | | prettier@2.8.8: |
| | | optional: true |
| | | |
| | | print-js@1.6.0: {} |
| | | |
| | | proto-list@1.2.4: {} |
| | | |
| | | proxy-from-env@1.1.0: {} |
| | | |
| | | qrcode@1.5.4: |
| | | dependencies: |
| | | dijkstrajs: 1.0.3 |
| | | pngjs: 5.0.0 |
| | | yargs: 15.4.1 |
| | | |
| | | quansync@0.2.10: {} |
| | | |
| | |
| | | repeat-element@1.1.4: {} |
| | | |
| | | repeat-string@1.6.1: {} |
| | | |
| | | require-directory@2.1.1: {} |
| | | |
| | | require-main-filename@2.0.0: {} |
| | | |
| | | resolve-url@0.2.1: {} |
| | | |
| | |
| | | select@1.1.2: {} |
| | | |
| | | semver@7.7.2: {} |
| | | |
| | | set-blocking@2.0.0: {} |
| | | |
| | | set-function-length@1.2.2: |
| | | dependencies: |
| | |
| | | dependencies: |
| | | vue: 3.4.31 |
| | | |
| | | vue-easy-lightbox@1.19.0(vue@3.4.31): |
| | | dependencies: |
| | | vue: 3.4.31 |
| | | |
| | | vue-esign@1.1.4: |
| | | dependencies: |
| | | vue: 2.7.16 |
| | | |
| | | vue-router@4.4.0(vue@3.4.31): |
| | | dependencies: |
| | | '@vue/devtools-api': 6.6.4 |
| | | vue: 3.4.31 |
| | | |
| | | vue@2.7.16: |
| | | dependencies: |
| | | '@vue/compiler-sfc': 2.7.16 |
| | | csstype: 3.1.3 |
| | | |
| | | vue@3.4.31: |
| | | dependencies: |
| | |
| | | is-weakmap: 2.0.2 |
| | | is-weakset: 2.0.4 |
| | | |
| | | which-module@2.0.1: {} |
| | | |
| | | which-typed-array@1.1.19: |
| | | dependencies: |
| | | available-typed-arrays: 1.0.7 |
| | |
| | | dependencies: |
| | | isexe: 2.0.0 |
| | | |
| | | wrap-ansi@6.2.0: |
| | | dependencies: |
| | | ansi-styles: 4.3.0 |
| | | string-width: 4.2.3 |
| | | strip-ansi: 6.0.1 |
| | | |
| | | wrap-ansi@7.0.0: |
| | | dependencies: |
| | | ansi-styles: 4.3.0 |
| | |
| | | string-width: 5.1.2 |
| | | strip-ansi: 7.1.0 |
| | | |
| | | y18n@4.0.3: {} |
| | | |
| | | yargs-parser@18.1.3: |
| | | dependencies: |
| | | camelcase: 5.3.1 |
| | | decamelize: 1.2.0 |
| | | |
| | | yargs@15.4.1: |
| | | dependencies: |
| | | cliui: 6.0.0 |
| | | decamelize: 1.2.0 |
| | | find-up: 4.1.0 |
| | | get-caller-file: 2.0.5 |
| | | require-directory: 2.1.1 |
| | | require-main-filename: 2.0.0 |
| | | set-blocking: 2.0.0 |
| | | string-width: 4.2.3 |
| | | which-module: 2.0.1 |
| | | y18n: 4.0.3 |
| | | yargs-parser: 18.1.3 |
| | | |
| | | zrender@5.6.0: |
| | | dependencies: |
| | | tslib: 2.3.0 |
| | |
| | | url: '/afterSalesNearExpiryService/delete?ids=' + ids, |
| | | method: 'delete', |
| | | }) |
| | | } |
| | | } |
| | | |
| | | // æ¥è¯¢ææå®¢æ·ä¿¡æ¯ |
| | | // /basic/customer/list |
| | | export function getAllCustomerList(query) { |
| | | return request({ |
| | | url: '/basic/customer/list', |
| | | method: 'get', |
| | | params: query, |
| | | }) |
| | | } |
| | | |
| | | // æ ¹æ®å®¢æ·æ¥è¯¢éå®è®¢åå· |
| | | // afterSalesService/listSalesLedger |
| | | export function getSalesLedger(query) { |
| | | return request({ |
| | | url: '/afterSalesService/listSalesLedger', |
| | | method: 'get', |
| | | params: query, |
| | | }) |
| | | } |
| | | |
| | | // æ ¹æ®éå®è®¢åå·æ¥è¯¢éå®è®¢å详æ
|
| | | // afterSalesService/count |
| | | export function getSalesLedgerDetail(query) { |
| | | return request({ |
| | | url: '/afterSalesService/count', |
| | | method: 'get', |
| | | params: query, |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | // 项ç®è§è² |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function findRoleListPage(query) { |
| | | return request({ |
| | | url: "/projectManagement/roles/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | export function createRole(params) { |
| | | return request({ |
| | | url: "/projectManagement/roles/add", |
| | | method: "post", |
| | | data: params, |
| | | }); |
| | | } |
| | | |
| | | export function updateRole(params) { |
| | | return request({ |
| | | url: "/projectManagement/roles/update", |
| | | method: "post", |
| | | data: params, |
| | | }); |
| | | } |
| | | |
| | | export function deleteRoles(params) { |
| | | return request({ |
| | | url: "/projectManagement/roles/delete", |
| | | method: "delete", |
| | | data: params, |
| | | }); |
| | | } |
| | |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="time in timeOptions" |
| | | v-for="time in startTimeOptions" |
| | | :key="time.value" |
| | | :label="time.label" |
| | | :value="time.value" |
| | |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="time in timeOptions" |
| | | v-for="time in endTimeOptions" |
| | | :key="time.value" |
| | | :label="time.label" |
| | | :value="time.value" |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref, reactive, onMounted} from 'vue' |
| | | import {ref, reactive, onMounted, computed, watch} from 'vue' |
| | | import {ElMessage} from 'element-plus' |
| | | import {Plus, Document, Promotion, Bell} from '@element-plus/icons-vue' |
| | | import {getRoomEnum, saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js' |
| | |
| | | description: '' |
| | | }) |
| | | |
| | | // è¡¨åæ ¡éªè§å |
| | | const rules = { |
| | | title: [{required: true, message: '请è¾å
¥ä¼è®®ä¸»é¢', trigger: 'blur'}], |
| | | roomId: [{required: true, message: 'è¯·éæ©ä¼è®®å®¤', trigger: 'change'}], |
| | | host: [{required: true, message: '请è¾å
¥ä¸»æäºº', trigger: 'blur'}], |
| | | meetingDate: [{required: true, message: 'è¯·éæ©ä¼è®®æ¥æ', trigger: 'change'}], |
| | | startTime: [{required: true, message: 'è¯·éæ©å¼å§æ¶é´', trigger: 'change'}], |
| | | endTime: [{required: true, message: 'è¯·éæ©ç»ææ¶é´', trigger: 'change'}], |
| | | participants: [{required: true, message: 'è¯·éæ©åä¼äººå', trigger: 'change'}] |
| | | } |
| | | |
| | | // 表åå¼ç¨ |
| | | const meetingFormRef = ref(null) |
| | | |
| | |
| | | // æ¶é´é项ï¼ä»¥åå°æ¶ä¸ºé´éï¼ |
| | | const timeOptions = ref([]) |
| | | |
| | | const getTimeInMinutes = (time) => { |
| | | if (!time) return -1 |
| | | const [hour, minute] = time.split(':').map(Number) |
| | | return hour * 60 + minute |
| | | } |
| | | |
| | | const isToday = (dateText) => { |
| | | if (!dateText) return false |
| | | const [year, month, day] = dateText.split('-').map(Number) |
| | | const now = new Date() |
| | | return year === now.getFullYear() && month === now.getMonth() + 1 && day === now.getDate() |
| | | } |
| | | |
| | | const validateStartTime = (_rule, value, callback) => { |
| | | if (!value) { |
| | | callback() |
| | | return |
| | | } |
| | | |
| | | if (isToday(meetingForm.meetingDate)) { |
| | | const now = new Date() |
| | | const currentMinutes = now.getHours() * 60 + now.getMinutes() |
| | | if (getTimeInMinutes(value) > currentMinutes) { |
| | | callback(new Error('å½å¤©å¼å§æ¶é´ä¸è½æäºå½åæ¶é´')) |
| | | return |
| | | } |
| | | } |
| | | |
| | | callback() |
| | | } |
| | | |
| | | const validateEndTime = (_rule, value, callback) => { |
| | | if (!value || !meetingForm.startTime) { |
| | | callback() |
| | | return |
| | | } |
| | | |
| | | if (getTimeInMinutes(value) <= getTimeInMinutes(meetingForm.startTime)) { |
| | | callback(new Error('ç»ææ¶é´å¿
须大äºå¼å§æ¶é´')) |
| | | return |
| | | } |
| | | |
| | | callback() |
| | | } |
| | | |
| | | // è¡¨åæ ¡éªè§å |
| | | const rules = { |
| | | title: [{required: true, message: '请è¾å
¥ä¼è®®ä¸»é¢', trigger: 'blur'}], |
| | | roomId: [{required: true, message: 'è¯·éæ©ä¼è®®å®¤', trigger: 'change'}], |
| | | host: [{required: true, message: '请è¾å
¥ä¸»æäºº', trigger: 'blur'}], |
| | | meetingDate: [{required: true, message: 'è¯·éæ©ä¼è®®æ¥æ', trigger: 'change'}], |
| | | startTime: [ |
| | | {required: true, message: 'è¯·éæ©å¼å§æ¶é´', trigger: 'change'}, |
| | | {validator: validateStartTime, trigger: 'change'} |
| | | ], |
| | | endTime: [ |
| | | {required: true, message: 'è¯·éæ©ç»ææ¶é´', trigger: 'change'}, |
| | | {validator: validateEndTime, trigger: 'change'} |
| | | ], |
| | | participants: [{required: true, message: 'è¯·éæ©åä¼äººå', trigger: 'change'}] |
| | | } |
| | | |
| | | const startTimeOptions = computed(() => { |
| | | if (!isToday(meetingForm.meetingDate)) { |
| | | return timeOptions.value |
| | | } |
| | | const now = new Date() |
| | | const currentMinutes = now.getHours() * 60 + now.getMinutes() |
| | | return timeOptions.value.filter(item => getTimeInMinutes(item.value) <= currentMinutes) |
| | | }) |
| | | |
| | | const endTimeOptions = computed(() => { |
| | | if (!meetingForm.startTime) { |
| | | return timeOptions.value |
| | | } |
| | | const startMinutes = getTimeInMinutes(meetingForm.startTime) |
| | | return timeOptions.value.filter(item => getTimeInMinutes(item.value) > startMinutes) |
| | | }) |
| | | |
| | | // åå§åæ¶é´é项 |
| | | const initTimeOptions = () => { |
| | | const options = [] |
| | | const now = new Date() |
| | | const currentHour = now.getHours() |
| | | const currentMinute = now.getMinutes() |
| | | // meetingDate æ¯ "yyyy-MM-dd" |
| | | const meetingDate = new Date(meetingForm.meetingDate) |
| | | |
| | | const isSameDay = |
| | | now.getFullYear() === meetingDate.getFullYear() && |
| | | now.getMonth() === meetingDate.getMonth() && |
| | | now.getDate() === meetingDate.getDate() |
| | | |
| | | console.log('æ¯å¦åä¸å¤©:', isSameDay) |
| | | for (let hour = 8; hour <= 18; hour++) { |
| | | // å¼å§æ¶é´å¿
é¡»æäºå½åæ¶é´ |
| | | if (hour < currentHour) { |
| | | if (hour < currentHour && isSameDay) { |
| | | continue |
| | | } |
| | | if (hour === currentHour && currentMinute > 30) { |
| | | if (hour === currentHour && currentMinute > 30 && isSameDay) { |
| | | continue |
| | | } |
| | | // æ¯ä¸ªå°æ¶æ·»å 两个éé¡¹ï¼æ´ç¹ååç¹ |
| | |
| | | timeOptions.value = options |
| | | } |
| | | |
| | | watch(() => meetingForm.meetingDate, () => { |
| | | if (meetingForm.startTime && !startTimeOptions.value.some(item => item.value === meetingForm.startTime)) { |
| | | meetingForm.startTime = '' |
| | | } |
| | | if (meetingForm.endTime && !endTimeOptions.value.some(item => item.value === meetingForm.endTime)) { |
| | | meetingForm.endTime = '' |
| | | } |
| | | if (meetingForm.startTime) { |
| | | meetingFormRef.value?.validateField('startTime') |
| | | } |
| | | if (meetingForm.endTime) { |
| | | meetingFormRef.value?.validateField('endTime') |
| | | } |
| | | initTimeOptions() |
| | | }) |
| | | |
| | | watch(() => meetingForm.startTime, () => { |
| | | if (meetingForm.endTime && getTimeInMinutes(meetingForm.endTime) <= getTimeInMinutes(meetingForm.startTime)) { |
| | | meetingForm.endTime = '' |
| | | } |
| | | if (meetingForm.endTime) { |
| | | meetingFormRef.value?.validateField('endTime') |
| | | } |
| | | |
| | | }) |
| | | |
| | | // ç¦ç¨æ¥æï¼ç¦ç¨ä»å¤©ä¹åçæ¥æï¼ |
| | | const disabledDate = (time) => { |
| | | // ç¦ç¨ä»å¤©ä¹åçæ¥æ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">å馿¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.feedbackDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <span class="search_title ml10">å¤çæ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.disDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <span style = "margin-left: 10px;" class="search_title">å¤çç¶æï¼</span> |
| | | <el-select v-model="searchForm.status" placeholder="è¯·éæ©ç¶æ" @change="handleQuery" style="width: 140px" clearable> |
| | | <el-option label="å¾
å¤ç" :value="1"></el-option> |
| | | <el-option label="å·²å¤ç" :value="2"></el-option> |
| | | </el-select> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | | <el-button @click="handleOut" style="margin-left: 10px">导åº</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="search-wrapper"> |
| | | <el-form |
| | | :model="searchForm" |
| | | class="demo-form-inline" |
| | | > |
| | | <el-row :gutter="20"> |
| | | <el-col :span="4"> |
| | | <el-form-item> |
| | | <el-input |
| | | v-model="searchForm.afterSalesServiceNo" |
| | | placeholder="请è¾å
¥å·¥åç¼å·" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item> |
| | | <el-select |
| | | v-model="searchForm.status" |
| | | placeholder="è¯·éæ©å·¥åç¶æ" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="dict in workOrderStatusOptions" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item> |
| | | <el-select |
| | | v-model="searchForm.urgency" |
| | | placeholder="è¯·éæ©ç´§æ¥ç¨åº¦" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="dict in degreeOfUrgencyOptions" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item> |
| | | <el-select |
| | | v-model="searchForm.serviceType" |
| | | placeholder="è¯·éæ©å®åç±»å" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="dict in classificationOptions" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item> |
| | | <el-input |
| | | v-model="searchForm.orderNo" |
| | | placeholder="请è¾å
¥éå®åå·" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | |
| | | |
| | | |
| | | <!-- æé® --> |
| | | <el-col :span="4"> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="handleQuery"> |
| | | æç´¢ |
| | | </el-button> |
| | | <el-button @click="handleReset"> |
| | | éç½® |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </div> |
| | | <div class="table_list"> |
| | | <PIMTable |
| | | rowKey="id" |
| | |
| | | }, |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | | /* |
| | | post_sale_waiting_list æ°å¢çå®ååç±» |
| | | degree_of_urgency æ°å¢çç´§æ¥ç¨åº¦ |
| | | work_order_status 主页çå·¥åç¶æ |
| | | */ |
| | | const { post_sale_waiting_list, degree_of_urgency, work_order_status } = proxy.useDict( |
| | | "post_sale_waiting_list", |
| | | "degree_of_urgency", |
| | | "work_order_status", |
| | | ); |
| | | |
| | | const classificationOptions = computed(() => post_sale_waiting_list?.value || []); |
| | | const degreeOfUrgencyOptions = computed(() => degree_of_urgency?.value || []); |
| | | const workOrderStatusOptions = computed(() => work_order_status?.value || []); |
| | | |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "å¤çç¶æ", |
| | | prop: "status", |
| | | dataType: "tag", |
| | | formatData: (params) => { |
| | | if (params == 1) { |
| | | return "å¾
å¤ç"; |
| | | } else if (params == 2) { |
| | | return "å·²å¤ç"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | formatType: (params) => { |
| | | if (params == 1) { |
| | | return "danger"; |
| | | } else if (params == 2) { |
| | | return "success"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | }, |
| | | { |
| | | label: "å馿¥æ", |
| | | prop: "feedbackDate", |
| | | width: 150, |
| | | }, |
| | | { |
| | | label: "ç»è®°äºº", |
| | | prop: "checkNickName", |
| | | }, |
| | | { |
| | | label: "客æ·åç§°", |
| | | prop: "customerName", |
| | | width: 200, |
| | | }, |
| | | { |
| | | label: "é®é¢æè¿°", |
| | | prop: "proDesc", |
| | | width:300 |
| | | }, |
| | | { |
| | | label: "å
³èé¨é¨", |
| | | prop: "deptName", |
| | | width: 200, |
| | | }, |
| | | { |
| | | label: "å¤ç人", |
| | | prop: "disposeNickName", |
| | | }, |
| | | { |
| | | label: "å¤çç»æ", |
| | | prop: "disRes", |
| | | width: 200, |
| | | }, |
| | | { |
| | | label: "å¤çæ¥æ", |
| | | prop: "disDate", |
| | | width: 150, |
| | | }, |
| | | label: "å·¥åç¼å·", |
| | | prop:"afterSalesServiceNo", |
| | | width: 150, |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "éå®åå·", |
| | | prop:"salesContractNo", |
| | | width: 150, |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "å¤çç¶æ", |
| | | prop: "status", |
| | | dataType: "tag", |
| | | |
| | | formatData: (params) => { |
| | | if (params === 1) { |
| | | return "å¾
å¤ç"; |
| | | } else if (params === 2) { |
| | | return "å·²å¤ç"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | formatType: (params) => { |
| | | if (params === 1) { |
| | | return "danger"; |
| | | } else if (params === 2) { |
| | | return "success"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "å馿¥æ", |
| | | prop: "feedbackDate", |
| | | width: 150, |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "ç»è®°äºº", |
| | | prop: "checkNickName", |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "ç´§æ¥ç¨åº¦", |
| | | prop: "urgency", |
| | | // æ ¹æ®degreeOfUrgencyOptionsåå
¸å»èªå¨å¹é
|
| | | formatData: (params) => { |
| | | if (params) { |
| | | const item = degreeOfUrgencyOptions.value.find(item => item.value === params); |
| | | return item?.label || params; |
| | | } |
| | | return null; |
| | | }, |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "å®åç±»å", |
| | | prop: "serviceType", |
| | | // æ ¹æ®classificationOptionsåå
¸å»èªå¨å¹é
|
| | | formatData: (params) => { |
| | | if (params) { |
| | | const item = classificationOptions.value.find(item => item.value === params); |
| | | return item?.label || params; |
| | | } |
| | | return null; |
| | | }, |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "é®é¢æè¿°", |
| | | prop: "disRes", |
| | | width:300, |
| | | }, |
| | | { |
| | | label: "å
³èé¨é¨", |
| | | prop: "deptName", |
| | | width: 200, |
| | | align: "center" |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | |
| | | const fileListDialogVisible = ref(false) |
| | | const currentFileRow = ref(null) |
| | | |
| | | // éç½® |
| | | const handleReset = () => { |
| | | Object.keys(searchForm.value).forEach(key => { |
| | | searchForm.value[key] = "" |
| | | }) |
| | | } |
| | | |
| | | // æå¼éä»¶å¼¹æ¡ |
| | | const openFilesFormDia = async (row) => { |
| | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | .search-wrapper { |
| | | background: white; |
| | | padding: 1rem 1rem 0 1rem; |
| | | border: 8px; |
| | | border-radius: 16px; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog v-model="visible" title="éæ©äº§å" width="900px" destroy-on-close :close-on-click-modal="false"> |
| | | <el-form :inline="true" :model="query" class="mb-2"> |
| | | <el-form-item label="产ååç±»"> |
| | | <el-input v-model="query.productCategory" placeholder="è¾å
¥äº§ååç±»" clearable @keyup.enter="onSearch" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="åºæ¬åä½"> |
| | | <el-input v-model="query.unit" placeholder="è¾å
¥åºæ¬åä½" clearable @keyup.enter="onSearch" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-button type="primary" @click="onSearch">æç´¢</el-button> |
| | | <el-button @click="columnsDialogVisible = true">åè¡¨åæ®µ</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <!-- å表 --> |
| | | <el-table ref="tableRef" v-loading="loading" :data="tableData" height="420" highlight-current-row row-key="id" |
| | | @selection-change="handleSelectionChange" @select="handleSelect"> |
| | | <el-table-column type="selection" width="55" /> |
| | | <el-table-column type="index" label="åºå·" width="60" /> |
| | | <template v-for="column in visibleColumns" :key="column.prop"> |
| | | <el-table-column :prop="column.prop" :label="column.label" :min-width="column.minWidth" show-overflow-tooltip align="center" /> |
| | | </template> |
| | | </el-table> |
| | | |
| | | <div class="mt-3" style="margin-top: 10px;display: flex; justify-content: flex-end;"> |
| | | |
| | | |
| | | <el-pagination background layout="total, sizes, prev, pager, next, jumper" :total="total" |
| | | v-model:page-size="page.pageSize" v-model:current-page="page.pageNum" :page-sizes="[10, 20, 50, 100]" |
| | | @size-change="onPageChange" @current-change="onPageChange" /> |
| | | </div> |
| | | |
| | | <template #footer> |
| | | <el-button type="primary" :disabled="multipleSelection.length === 0" @click="onConfirm"> |
| | | ç¡®å® |
| | | </el-button> |
| | | <el-button @click="close()">åæ¶</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <el-dialog v-model="columnsDialogVisible" title="èªå®ä¹æ¾ç¤ºå项" width="600px"> |
| | | <el-checkbox-group v-model="selectedColumns"> |
| | | <el-checkbox v-for="column in allColumns" :key="column.prop" :label="column.prop" :disabled="column.disabled"> |
| | | {{ column.label }} |
| | | </el-checkbox> |
| | | </el-checkbox-group> |
| | | <template #footer> |
| | | <el-button @click="resetColumns">æ¢å¤é»è®¤</el-button> |
| | | <el-button type="primary" @click="saveColumns">ä¿å</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, onMounted, reactive, ref, watch, nextTick } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | |
| | | const props = defineProps({ |
| | | modelValue: Boolean, |
| | | single: Boolean, // æ¯å¦åªè½éæ©ä¸ä¸ªï¼é»è®¤falseï¼å¯éæ©å¤ä¸ªï¼ |
| | | products: { |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | selectedIds: { |
| | | type: Array, |
| | | default: () => [] |
| | | } |
| | | }); |
| | | |
| | | const emit = defineEmits(['update:modelValue', 'confirm']); |
| | | |
| | | const visible = computed({ |
| | | get: () => props.modelValue, |
| | | set: (v) => emit("update:modelValue", v), |
| | | }); |
| | | |
| | | const query = reactive({ |
| | | productName: "", |
| | | model: "", |
| | | }); |
| | | |
| | | const page = reactive({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | }); |
| | | |
| | | const loading = ref(false); |
| | | const tableData = ref([]); |
| | | const total = ref(0); |
| | | const multipleSelection = ref([]); |
| | | const tableRef = ref(); |
| | | |
| | | const columnsDialogVisible = ref(false); |
| | | |
| | | const allColumns = ref([ |
| | | { prop: 'productCategory', label: '产ååç±»', selected: true, disabled: false }, |
| | | { prop: 'unit', label: 'åºæ¬åä½', selected: true, disabled: false }, |
| | | ]); |
| | | |
| | | const selectedColumns = ref(allColumns.value.filter(c => c.selected).map(c => c.prop)); |
| | | |
| | | const visibleColumns = computed(() => { |
| | | return allColumns.value.filter(c => selectedColumns.value.includes(c.prop)); |
| | | }); |
| | | |
| | | const resetColumns = () => { |
| | | selectedColumns.value = allColumns.value.filter(c => c.selected).map(c => c.prop); |
| | | }; |
| | | |
| | | const saveColumns = () => { |
| | | if (selectedColumns.value.length < 1) { |
| | | ElMessage.warning("å表项æ¾ç¤ºä¸å¾å°äº1项"); |
| | | return; |
| | | } |
| | | columnsDialogVisible.value = false; |
| | | }; |
| | | |
| | | function close() { |
| | | visible.value = false; |
| | | } |
| | | |
| | | const handleSelectionChange = (val) => { |
| | | if (props.single && val.length > 1) { |
| | | // 妿éå¶ä¸ºåä¸ªéæ©ï¼åªä¿çæåä¸ä¸ªéä¸ç |
| | | const lastSelected = val[val.length - 1]; |
| | | multipleSelection.value = [lastSelected]; |
| | | // æ¸
ç©ºè¡¨æ ¼éä¸ç¶æï¼ç¶åéæ°é䏿åä¸ä¸ª |
| | | nextTick(() => { |
| | | if (tableRef.value) { |
| | | tableRef.value.clearSelection(); |
| | | tableRef.value.toggleRowSelection(lastSelected, true); |
| | | } |
| | | }); |
| | | } else { |
| | | multipleSelection.value = val; |
| | | } |
| | | } |
| | | |
| | | // å¤çåä¸ªéæ© |
| | | const handleSelect = (selection, row) => { |
| | | if (props.single) { |
| | | // 妿éå¶ä¸ºåä¸ªï¼æ¸
空å
¶ä»éæ©ï¼åªä¿çå½åè¡ |
| | | if (selection.includes(row)) { |
| | | // éä¸å½åè¡æ¶ï¼æ¸
空å
¶ä»éä¸ |
| | | multipleSelection.value = [row]; |
| | | nextTick(() => { |
| | | if (tableRef.value) { |
| | | tableData.value.forEach((item) => { |
| | | if (item.id !== row.id) { |
| | | tableRef.value.toggleRowSelection(item, false); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | |
| | | function onSearch() { |
| | | page.pageNum = 1; |
| | | loadData(); |
| | | } |
| | | |
| | | function onReset() { |
| | | query.productName = ""; |
| | | query.model = ""; |
| | | page.pageNum = 1; |
| | | loadData(); |
| | | } |
| | | |
| | | function onPageChange() { |
| | | loadData(); |
| | | } |
| | | |
| | | function onConfirm() { |
| | | if (multipleSelection.value.length === 0) { |
| | | ElMessage.warning("è¯·éæ©ä¸æ¡äº§å"); |
| | | return; |
| | | } |
| | | if (props.single && multipleSelection.value.length > 1) { |
| | | ElMessage.warning("åªè½éæ©ä¸ä¸ªäº§å"); |
| | | return; |
| | | } |
| | | emit("confirm", props.single ? [multipleSelection.value[0]] : multipleSelection.value); |
| | | close(); |
| | | } |
| | | |
| | | async function loadData() { |
| | | loading.value = true; |
| | | try { |
| | | multipleSelection.value = []; // 翻页/æç´¢åæ¸
ç©ºéæ©æ´ç¬¦å颿 |
| | | |
| | | let filtered = props.products || []; |
| | | // æ¬å°æç´¢è¿æ»¤ |
| | | if (query.productName) { |
| | | filtered = filtered.filter(item => item.productName && item.productName.includes(query.productName)); |
| | | } |
| | | if (query.model) { |
| | | filtered = filtered.filter(item => item.model && item.model.includes(query.model)); |
| | | } |
| | | |
| | | total.value = filtered.length; |
| | | // å端å页 |
| | | const start = (page.pageNum - 1) * page.pageSize; |
| | | const end = start + page.pageSize; |
| | | tableData.value = filtered.slice(start, end); |
| | | |
| | | // èªå¨åæ¾éä¸ç¶æ |
| | | nextTick(() => { |
| | | if (tableRef.value) { |
| | | tableData.value.forEach(row => { |
| | | if (props.selectedIds && props.selectedIds.includes(row.id)) { |
| | | tableRef.value.toggleRowSelection(row, true); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | } |
| | | |
| | | // çå¬å¼¹çªæå¼ï¼éç½®éæ© |
| | | watch(() => props.modelValue, (visible) => { |
| | | if (visible) { |
| | | // æ¯æ¬¡æå¼æ¶éæ°åå§åéä¸ç¶æï¼multipleSelection ä¼éè¿ loadData ä¸çåæ¾é»è¾èªå¨æ´æ°ï¼ä½åå§é置空é¿å
éå¤ï¼ |
| | | multipleSelection.value = []; |
| | | page.pageNum = 1; |
| | | loadData(); |
| | | } |
| | | }); |
| | | |
| | | // ç嬿°æ®æºåå |
| | | watch(() => props.products, () => { |
| | | loadData(); |
| | | }, { deep: true }); |
| | | |
| | | onMounted(() => { |
| | | loadData() |
| | | }) |
| | | </script> |
| | |
| | | <div> |
| | | <el-dialog |
| | | v-model="dialogFormVisible" |
| | | title="å®åç»è®°" |
| | | width="70%" |
| | | title="æ°å¢å®åå" |
| | | width="90%" |
| | | @close="closeDia" |
| | | > |
| | | <el-form |
| | | :model="form" |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="rules" |
| | | ref="formRef" |
| | | > |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å馿¶é´ï¼" prop="feedbackDate"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.feedbackDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»è®°äººï¼" prop="checkUserId"> |
| | | <el-select |
| | | v-model="form.checkUserId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | | :key="item.userId" |
| | | :label="item.nickName" |
| | | :value="item.userId" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="客æ·åç§°ï¼" prop="customerName"> |
| | | <el-input |
| | | v-model="form.customerName" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é®é¢æè¿°ï¼" prop="proDesc"> |
| | | <el-input |
| | | v-model="form.proDesc" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | type="textarea" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div> |
| | | <span class="descriptions">åºç¡èµæ</span> |
| | | <el-form |
| | | :model="form" |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="rules" |
| | | ref="formRef" |
| | | > |
| | | <el-row :gutter="30"> |
| | | <el-col :span="4"> |
| | | <el-form-item label="客æ·åç§°ï¼" prop="customerName"> |
| | | <el-select |
| | | v-model="form.customerName" |
| | | filterable |
| | | @change="customerNameChange" |
| | | > |
| | | <el-option |
| | | v-for="item in customerNameOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item label="å®åç±»åï¼" prop="serviceType"> |
| | | <el-select |
| | | v-model="form.serviceType" |
| | | filterable |
| | | > |
| | | <el-option |
| | | v-for="dict in serviceTypeOptions" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item label="å
³èéå®åå·ï¼" prop="salesContractNo"> |
| | | <el-select |
| | | v-model="form.salesContractNo" |
| | | @change="associatedSalesOrderNumberChange" |
| | | filterable |
| | | > |
| | | <el-option |
| | | v-for="item in associatedSalesOrderNumberOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item label="ç´§æ¥ç¨åº¦ï¼" prop="urgency"> |
| | | <el-select |
| | | v-model="form.urgency" |
| | | filterable |
| | | > |
| | | <el-option |
| | | v-for="dict in urgencyOptions" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item label="é®é¢æè¿°ï¼" prop="disRes"> |
| | | <el-input |
| | | v-model="form.disRes" |
| | | placeholder="请è¾å
¥é®é¢æè¿°" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <hr> |
| | | <div style="padding-top: 20px"> |
| | | <div style="display: flex; justify-content: space-between"> |
| | | <span class="descriptions">å
³è产å</span> |
| | | <el-button |
| | | type="primary" |
| | | style="margin-right: 12px; margin-bottom: 10px" |
| | | @click="isShowProductSelectDialog = true" |
| | | > |
| | | éæ©äº§å |
| | | </el-button> |
| | | </div> |
| | | <PIMTable |
| | | :isShowPagination="false" |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | > |
| | | <template #shippingStatus="{ row }"> |
| | | <el-tag :type="getShippingStatusType(row)" size="small"> |
| | | {{ getShippingStatusText(row) }} |
| | | </el-tag> |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | </div> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- éæ©äº§åå¼¹çª --> |
| | | <ProductSelectDialog |
| | | v-model="isShowProductSelectDialog" |
| | | :products="currentSalesOrderProducts" |
| | | :selected-ids="currentSelectedProductIds" |
| | | @confirm="handleSelectProducts" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref} from "vue"; |
| | | import { ref, reactive, toRefs, getCurrentInstance, computed } from "vue"; |
| | | import ProductSelectDialog from "./ProductSelectDialog.vue"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import {userListNoPageByTenantId} from "@/api/system/user.js"; |
| | | import {afterSalesServiceAdd, afterSalesServiceUpdate} from "@/api/customerService/index.js"; |
| | | import {afterSalesServiceAdd, afterSalesServiceUpdate, getAllCustomerList, getSalesLedger } from "@/api/customerService/index.js"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | const dialogFormVisible = ref(false); |
| | | const operationType = ref('') |
| | | const formRef = ref(null) |
| | | const customerNameOptions = ref([]) |
| | | const userStore = useUserStore(); |
| | | |
| | | const data = reactive({ |
| | | form: { |
| | | feedbackDate: "", |
| | | checkUserId: "", |
| | | customerName: "", |
| | | proDesc: "", |
| | | topic: "", |
| | | serviceType: "", |
| | | urgency: "", |
| | | salesLedgerId: null, |
| | | productModelIds: "", |
| | | customerId: null, |
| | | salesContractNo: "", |
| | | disRes: "", |
| | | customerName: "" |
| | | }, |
| | | rules: { |
| | | customerName: [{required: true, message: "è¯·éæ©å®¢æ·åç§°", trigger: "change"}], |
| | | serviceType: [{required: true, message: "è¯·éæ©å®åç±»å", trigger: "change"}], |
| | | urgency: [{required: true, message: "è¯·éæ©ç´§æ¥ç¨åº¦", trigger: "change"}], |
| | | feedbackDate: [{required: true, message: "è¯·éæ©", trigger: "change"}], |
| | | checkUserId: [{required: true, message: "è¯·éæ©", trigger: "change"}], |
| | | customerName: [{required: true, message: "请è¾å
¥", trigger: "blur"}], |
| | | proDesc: [{required: true, message: "请è¾å
¥", trigger: "blur"}], |
| | | } |
| | | }) |
| | | |
| | | // èªå®ä¹æ ¡éªå½æ°ï¼å¤ææ¯å¦éè¦æ ¡éªå®åç¼å· |
| | | |
| | | const { form, rules } = toRefs(data); |
| | | const userList = ref([]) |
| | | |
| | | const formatCurrency = (val) => { |
| | | if (val === null || val === undefined || val === '') return '-' |
| | | const num = Number(val) |
| | | return Number.isFinite(num) ? num.toFixed(2) : '-' |
| | | } |
| | | |
| | | const { post_sale_waiting_list, degree_of_urgency } = proxy.useDict( |
| | | "post_sale_waiting_list", |
| | | "degree_of_urgency" |
| | | ); |
| | | |
| | | const serviceTypeOptions = computed(() => post_sale_waiting_list?.value || []); |
| | | const urgencyOptions = computed(() => degree_of_urgency?.value || []); |
| | | |
| | | const tableColumn = ref([ |
| | | { label: "产å大类", prop: "productCategory" }, |
| | | { label: "è§æ ¼åå·", prop: "specificationModel" }, |
| | | { label: "åä½", prop: "unit" }, |
| | | { |
| | | label: "产åç¶æ", |
| | | prop: "approveStatus", |
| | | width: 100, |
| | | align: "center", |
| | | dataType: "tag", |
| | | formatData: (v) => (v === 1 ? "å
è¶³" : "ä¸è¶³"), |
| | | formatType: (v) => (v === 1 ? "success" : "danger"), |
| | | }, |
| | | { |
| | | label: "åè´§ç¶æ", |
| | | align: "center", |
| | | width: 140, |
| | | dataType: "slot", |
| | | slot: "shippingStatus", |
| | | }, |
| | | { label: "å¿«éå
¬å¸", prop: "expressCompany", width: 140 }, |
| | | { label: "å¿«éåå·", prop: "expressNumber", width: 160 }, |
| | | { label: "å货车ç", prop: "shippingCarNumber", minWidth: 100, align: "center" }, |
| | | { label: "åè´§æ¥æ", prop: "shippingDate", minWidth: 100, align: "center" }, |
| | | { label: "æ°é", prop: "quantity", width: 100 }, |
| | | { label: "ç¨ç(%)", prop: "taxRate", width: 100 }, |
| | | { |
| | | label: "å«ç¨åä»·(å
)", |
| | | prop: "taxInclusiveUnitPrice", |
| | | width: 160, |
| | | formatData: formatCurrency, |
| | | }, |
| | | { |
| | | label: "å«ç¨æ»ä»·(å
)", |
| | | prop: "taxInclusiveTotalPrice", |
| | | width: 160, |
| | | formatData: formatCurrency, |
| | | }, |
| | | { |
| | | label: "ä¸å«ç¨æ»ä»·(å
)", |
| | | prop: "taxExclusiveTotalPrice", |
| | | width: 160, |
| | | formatData: formatCurrency, |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: 'right', |
| | | operation: [ |
| | | { |
| | | name: "å é¤", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | tableData.value = tableData.value.filter(i => i.id !== row.id) |
| | | }, |
| | | |
| | | }, |
| | | ], |
| | | }, |
| | | ]) |
| | | const tableData = ref([]) |
| | | // éæ©äº§åå¼¹çª |
| | | const isShowProductSelectDialog = ref(false) |
| | | const handleSelectProducts = (rows) => { |
| | | if (!Array.isArray(rows)) return |
| | | const existingIds = new Set(tableData.value.map(i => i.id)) |
| | | const mapped = rows |
| | | .filter(r => !existingIds.has(r.id)) |
| | | .map(r => ({ |
| | | id: r.id, |
| | | productCategory: r.productName, |
| | | specificationModel: r.model, |
| | | unit: r.unit || '', |
| | | approveStatus: null, |
| | | shippingStatus: '', |
| | | expressCompany: '', |
| | | expressNumber: '', |
| | | shippingCarNumber: '', |
| | | shippingDate: '', |
| | | quantity: 0, |
| | | taxRate: 0, |
| | | taxInclusiveUnitPrice: 0, |
| | | taxInclusiveTotalPrice: 0, |
| | | taxExclusiveTotalPrice: 0, |
| | | })) |
| | | tableData.value = tableData.value.concat(mapped) |
| | | } |
| | | const currentSelectedProductIds = computed(() => { |
| | | return tableData.value.map(item => item.id) |
| | | }) |
| | | |
| | | const associatedSalesOrderNumberChange = () => { |
| | | const opt = associatedSalesOrderNumberOptions.value.find( |
| | | (item) => item.value === form.value.salesContractNo |
| | | ) |
| | | tableData.value = opt?.productData || [] |
| | | form.value.salesLedgerId = opt?.id || null |
| | | } |
| | | |
| | | const associatedSalesOrderNumberOptions = ref([]) |
| | | |
| | | const currentSalesOrderProducts = computed(() => { |
| | | const opt = associatedSalesOrderNumberOptions.value.find( |
| | | (item) => item.value === form.value.salesContractNo |
| | | ) |
| | | return opt?.productData || [] |
| | | }) |
| | | |
| | | const customerNameChange = (val) => { |
| | | const opt = customerNameOptions.value.find(item => item.value === val); |
| | | if (opt) { |
| | | form.value.customerId = opt.id; |
| | | } |
| | | getSalesLedger({ |
| | | customerName: form.value.customerName |
| | | }).then(res => { |
| | | if(res.code === 200){ |
| | | associatedSalesOrderNumberOptions.value = res.data.records.map(item => ({ |
| | | label: item.salesContractNo, |
| | | value: item.salesContractNo, |
| | | productData:item.productData, |
| | | id: item.id |
| | | })) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | const getShippingStatusText = (row) => { |
| | | if (!row) return 'å¾
åè´§' |
| | | if (row.shippingDate || row.shippingCarNumber) { |
| | | return 'å·²åè´§' |
| | | } |
| | | const status = row.shippingStatus |
| | | if (status === null || status === undefined || status === '') { |
| | | return 'å¾
åè´§' |
| | | } |
| | | const map = { |
| | | 'å¾
åè´§': 'å¾
åè´§', |
| | | 'å¾
å®¡æ ¸': 'å¾
å®¡æ ¸', |
| | | 'å®¡æ ¸ä¸': 'å®¡æ ¸ä¸', |
| | | 'å®¡æ ¸æç»': 'å®¡æ ¸æç»', |
| | | 'å®¡æ ¸éè¿': 'å®¡æ ¸éè¿', |
| | | 'å·²åè´§': 'å·²åè´§' |
| | | } |
| | | return map[String(status).trim()] || 'å¾
åè´§' |
| | | } |
| | | |
| | | const getShippingStatusType = (row) => { |
| | | if (!row) return 'info' |
| | | if (row.shippingDate || row.shippingCarNumber) { |
| | | return 'success' |
| | | } |
| | | const status = row.shippingStatus |
| | | if (status === null || status === undefined || status === '') { |
| | | return 'info' |
| | | } |
| | | const map = { |
| | | 'å¾
åè´§': 'info', |
| | | 'å¾
å®¡æ ¸': 'warning', |
| | | 'å®¡æ ¸ä¸': 'warning', |
| | | 'å®¡æ ¸æç»': 'danger', |
| | | 'å®¡æ ¸éè¿': 'success', |
| | | 'å·²åè´§': 'success' |
| | | } |
| | | return map[String(status).trim()] || 'info' |
| | | } |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = (type, row) => { |
| | | const openDialog =async (type, row) => { |
| | | // 请æ±å¤ä¸ªæ¥å£ï¼è·åæ°æ® |
| | | let res = await getAllCustomerList(); |
| | | if(res.records){ |
| | | customerNameOptions.value = res.records.map(item => ({ |
| | | label: item.customerName, |
| | | value: item.customerName, |
| | | id: item.id |
| | | })); |
| | | } |
| | | |
| | | |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | form.value = {} |
| | | proxy.resetForm("formRef"); |
| | | form.value.checkUserId = userStore.id; |
| | | form.value.feedbackDate = getCurrentDate(); |
| | | // æ°å¢æ¶æ¸
空已éå
³è产å |
| | | if (type === "add") { |
| | | tableData.value = [] |
| | | } |
| | | userListNoPageByTenantId().then((res) => { |
| | | userList.value = res.data; |
| | | }); |
| | | if (type === "edit") { |
| | | form.value = {...row} |
| | | if (form.value.customerName) { |
| | | const res = await getSalesLedger({ customerName: form.value.customerName }) |
| | | if (res?.code === 200) { |
| | | console.log(res) |
| | | associatedSalesOrderNumberOptions.value = (res.data?.records || []).map(item => ({ |
| | | label: item.salesContractNo, |
| | | value: item.salesContractNo, |
| | | productData: item.productData, |
| | | id: item.id |
| | | })) |
| | | } |
| | | } |
| | | console.log(form.value) |
| | | } |
| | | } |
| | | // const setName = (code) => { |
| | | // const index = userList.value.findIndex(item => item.deviceModel === code); |
| | | // if (index > -1) { |
| | | // console.log(userList) |
| | | // form.value.name = userList.value[index].deviceName; |
| | | // } |
| | | // } |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // å¹é
产ååå·IDs |
| | | form.value.productModelIds = tableData.value.map(item => item.id).join(",") |
| | | if (operationType.value === "add") { |
| | | afterSalesServiceAdd(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå") |
| | |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | <style scoped lang="scss"> |
| | | .descriptions { |
| | | margin-bottom: 20px; |
| | | display: inline-block; |
| | | font-size: 1rem; |
| | | font-weight: 600; |
| | | padding-left: 12px; |
| | | position: relative; |
| | | } |
| | | |
| | | </style> |
| | | .descriptions::before { |
| | | content: ""; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 50%; |
| | | transform: translateY(-50%); |
| | | width: 4px; |
| | | height: 1rem; |
| | | background-color: #002FA7; /* Element é»è®¤çº¢è² */ |
| | | border-radius: 2px; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">å馿¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.feedbackDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <span style="margin-left: 10px;" class="search_title">å¤çç¶æï¼</span> |
| | | <el-select v-model="searchForm.status" placeholder="è¯·éæ©ç¶æ" @change="handleQuery" style="width: 140px" clearable> |
| | | <el-option label="å¾
å¤ç" :value="1"></el-option> |
| | | <el-option label="å·²å¤ç" :value="2"></el-option> |
| | | </el-select> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')">æ°å¢</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | ></PIMTable> |
| | | </div> |
| | | <form-dia ref="formDia" @close="handleQuery"></form-dia> |
| | | </div> |
| | | <div class="app-container"> |
| | | <div class="workorder-stats"> |
| | | <div |
| | | v-for="(item, index) in statsList" |
| | | :key="index" |
| | | class="stat-card" |
| | | > |
| | | <div class="stat-icon" :style="{ backgroundColor: item.bgColor }"> |
| | | <el-icon :color="item.color" :size="20"> |
| | | <component :is="item.icon" /> |
| | | </el-icon> |
| | | </div> |
| | | <div class="stat-info"> |
| | | <div class="stat-number">{{ item.count }}</div> |
| | | <div class="stat-label">{{ item.label }}</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="search-wrapper"> |
| | | <el-form |
| | | :model="searchForm" |
| | | class="demo-form-inline" |
| | | > |
| | | <el-row :gutter="20"> |
| | | <el-col :span="4"> |
| | | <el-form-item> |
| | | <el-input |
| | | v-model="searchForm.afterSalesServiceNo" |
| | | placeholder="请è¾å
¥å·¥åç¼å·" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item> |
| | | <el-select |
| | | v-model="searchForm.status" |
| | | placeholder="è¯·éæ©å·¥åç¶æ" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="dict in workOrderStatusOptions" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item> |
| | | <el-select |
| | | v-model="searchForm.urgency" |
| | | placeholder="è¯·éæ©ç´§æ¥ç¨åº¦" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="dict in degreeOfUrgencyOptions" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item> |
| | | <el-select |
| | | v-model="searchForm.serviceType" |
| | | placeholder="è¯·éæ©å®åç±»å" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="dict in classificationOptions" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item> |
| | | <el-input |
| | | v-model="searchForm.orderNo" |
| | | placeholder="请è¾å
¥éå®åå·" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | |
| | | |
| | | |
| | | <!-- æé® --> |
| | | <el-col :span="4"> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="handleQuery"> |
| | | æç´¢ |
| | | </el-button> |
| | | <el-button @click="handleReset"> |
| | | éç½® |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </div> |
| | | <div class="table_list"> |
| | | <div class="table_header" style="display: flex; justify-content: space-between; align-items: center;"> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')">æ°å¢å®åå</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :height="tableHeight" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | ></PIMTable> |
| | | </div> |
| | | <form-dia ref="formDia" @close="handleQuery"></form-dia> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {Search} from "@element-plus/icons-vue"; |
| | | import {onMounted, ref, getCurrentInstance, nextTick} from "vue"; |
| | | import {onMounted, reactive, ref, toRefs, computed, getCurrentInstance, nextTick} from "vue"; |
| | | import FormDia from "@/views/customerService/feedbackRegistration/components/formDia.vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {afterSalesServiceDelete, afterSalesServiceListPage} from "@/api/customerService/index.js"; |
| | | import {afterSalesServiceDelete, afterSalesServiceListPage, getSalesLedgerDetail} from "@/api/customerService/index.js"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const userStore = useUserStore() |
| | | import { Document, FolderOpened, UserFilled } from "@element-plus/icons-vue" |
| | | import { markRaw } from 'vue' |
| | | |
| | | const statsList = ref([ |
| | | { |
| | | icon: markRaw(Document), |
| | | count: 0, |
| | | label: 'å
¨é¨å·¥å', |
| | | color: '#4080ff', |
| | | bgColor: '#eaf2ff' |
| | | }, |
| | | { |
| | | icon: markRaw(FolderOpened), |
| | | count: 0, |
| | | label: 'å·²å¤ç', |
| | | color: '#ff9a2e', |
| | | bgColor: '#fff5e6' |
| | | }, |
| | | { |
| | | icon: markRaw(UserFilled), |
| | | count: 0, |
| | | label: '已宿', |
| | | color: '#00b42a', |
| | | bgColor: '#e6f7ed' |
| | | }, |
| | | ]) |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | feedbackDate: "", |
| | | }, |
| | | searchForm : { |
| | | customerName: "", |
| | | status: "", |
| | | urgency: "", |
| | | serviceType: "", |
| | | reviewStatus: "", |
| | | orderNo: "", |
| | | } |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | | |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "å¤çç¶æ", |
| | | prop: "status", |
| | | dataType: "tag", |
| | | formatData: (params) => { |
| | | if (params == 1) { |
| | | return "å¾
å¤ç"; |
| | | } else if (params == 2) { |
| | | return "å·²å¤ç"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | formatType: (params) => { |
| | | if (params == 1) { |
| | | return "danger"; |
| | | } else if (params == 2) { |
| | | return "success"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | }, |
| | | { |
| | | label: "å馿¥æ", |
| | | prop: "feedbackDate", |
| | | width: 150, |
| | | }, |
| | | { |
| | | label: "ç»è®°äºº", |
| | | prop: "checkNickName", |
| | | }, |
| | | { |
| | | label: "客æ·åç§°", |
| | | prop: "customerName", |
| | | width: 200, |
| | | }, |
| | | { |
| | | label: "é®é¢æè¿°", |
| | | prop: "proDesc", |
| | | width:300 |
| | | }, |
| | | { |
| | | label: "å
³èé¨é¨", |
| | | prop: "deptName", |
| | | width: 200, |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: 'right', |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.status !== 1 |
| | | } |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: "å·¥åç¼å·", |
| | | prop:"afterSalesServiceNo", |
| | | width: 150, |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "éå®åå·", |
| | | prop:"salesContractNo", |
| | | width: 150, |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "å¤çç¶æ", |
| | | prop: "status", |
| | | dataType: "tag", |
| | | |
| | | formatData: (params) => { |
| | | if (params === 1) { |
| | | return "å¾
å¤ç"; |
| | | } else if (params === 2) { |
| | | return "å·²å¤ç"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | formatType: (params) => { |
| | | if (params === 1) { |
| | | return "danger"; |
| | | } else if (params === 2) { |
| | | return "success"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "å馿¥æ", |
| | | prop: "feedbackDate", |
| | | width: 150, |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "ç»è®°äºº", |
| | | prop: "checkNickName", |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "ç´§æ¥ç¨åº¦", |
| | | prop: "urgency", |
| | | // æ ¹æ®degreeOfUrgencyOptionsåå
¸å»èªå¨å¹é
|
| | | formatData: (params) => { |
| | | if (params) { |
| | | const item = degreeOfUrgencyOptions.value.find(item => item.value === params); |
| | | return item?.label || params; |
| | | } |
| | | return null; |
| | | }, |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "å®åç±»å", |
| | | prop: "serviceType", |
| | | // æ ¹æ®classificationOptionsåå
¸å»èªå¨å¹é
|
| | | formatData: (params) => { |
| | | if (params) { |
| | | const item = classificationOptions.value.find(item => item.value === params); |
| | | return item?.label || params; |
| | | } |
| | | return null; |
| | | }, |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "é®é¢æè¿°", |
| | | prop: "disRes", |
| | | width:300, |
| | | }, |
| | | { |
| | | label: "å
³èé¨é¨", |
| | | prop: "deptName", |
| | | width: 200, |
| | | align: "center" |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: 'right', |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | console.log(row) |
| | | openForm("edit", row); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.status !== 1 |
| | | } |
| | | }, |
| | | ], |
| | | align: "center" |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | | const tableLoading = ref(false); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0, |
| | | current: 1, |
| | | size: 100, |
| | | total: 0, |
| | | }); |
| | | const selectedRows = ref([]); |
| | | const tableHeight = computed(() => "calc(100% -80px)"); |
| | | |
| | | const handleReset = () => { |
| | | Object.keys(searchForm.value).forEach(key => { |
| | | searchForm.value[key] = "" |
| | | }) |
| | | } |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | selectedRows.value = selection; |
| | | }; |
| | | const formDia = ref() |
| | | |
| | | // åå
¸è·å |
| | | /* |
| | | post_sale_waiting_list æ°å¢çå®ååç±» |
| | | degree_of_urgency æ°å¢çç´§æ¥ç¨åº¦ |
| | | work_order_status 主页çå·¥åç¶æ |
| | | review_status é¦é¡µçå®¡æ ¸ç¶æ |
| | | */ |
| | | const { post_sale_waiting_list, degree_of_urgency, work_order_status, review_status } = proxy.useDict( |
| | | "post_sale_waiting_list", |
| | | "degree_of_urgency", |
| | | "work_order_status", |
| | | "review_status" |
| | | ); |
| | | |
| | | const classificationOptions = computed(() => post_sale_waiting_list?.value || []); |
| | | const degreeOfUrgencyOptions = computed(() => degree_of_urgency?.value || []); |
| | | const workOrderStatusOptions = computed(() => work_order_status?.value || []); |
| | | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | afterSalesServiceListPage({ ...searchForm.value, ...page }).then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records; |
| | | page.total = res.data.total; |
| | | }); |
| | | tableLoading.value = true; |
| | | getSalesLedgerDetails() |
| | | afterSalesServiceListPage({ ...searchForm.value, ...page }).then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records; |
| | | page.total = res.data.total; |
| | | }); |
| | | }; |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openForm = (type, row) => { |
| | | nextTick(() => { |
| | | formDia.value?.openDialog(type, row) |
| | | }) |
| | | nextTick(() => { |
| | | formDia.value?.openDialog(type, row) |
| | | }) |
| | | }; |
| | | |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | // æ£æ¥æ¯å¦æä»äººç»´æ¤çæ°æ® |
| | | const unauthorizedData = selectedRows.value.filter(item => item.checkUserId !== userStore.id); |
| | | if (unauthorizedData.length > 0) { |
| | | proxy.$modal.msgWarning("ä¸å¯å é¤ä»äººç»´æ¤çæ°æ®"); |
| | | return; |
| | | } |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | | return; |
| | | } |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼", "å é¤æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | tableLoading.value = true; |
| | | afterSalesServiceDelete(ids) |
| | | .then((res) => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getList(); |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | function handleDelete() { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | // æ£æ¥æ¯å¦æä»äººç»´æ¤çæ°æ® |
| | | const unauthorizedData = selectedRows.value.filter(item => item.checkUserId !== userStore.id); |
| | | if (unauthorizedData.length > 0) { |
| | | proxy.$modal.msgWarning("ä¸å¯å é¤ä»äººç»´æ¤çæ°æ®"); |
| | | return; |
| | | } |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | | return; |
| | | } |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼", "å é¤æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | tableLoading.value = true; |
| | | afterSalesServiceDelete(ids) |
| | | .then(() => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getList(); |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/afterSalesService/export", {}, "åé¦ç»è®°.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/afterSalesService/export", {}, "åé¦ç»è®°.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // è·åç»è®¡æ°æ®å¹¶å·æ°é¡¶é¨å¡ç |
| | | const getSalesLedgerDetails = () => { |
| | | getSalesLedgerDetail({}).then((res) => { |
| | | if (res.code === 200) { |
| | | statsList.value[0].count = res.data.filter((item) => item.status === 3)[0].count; |
| | | statsList.value[1].count = res.data.filter((item) => item.status === 2)[0].count; |
| | | statsList.value[2].count = res.data.filter((item) => item.status === 1)[0].count; |
| | | |
| | | // }); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | getList(); |
| | | |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | <style scoped lang="scss"> |
| | | .search-wrapper { |
| | | background: white; |
| | | padding: 1rem 1rem 0 1rem; |
| | | border: 8px; |
| | | border-radius: 16px; |
| | | } |
| | | |
| | | </style> |
| | | .expand-btn { |
| | | width: 100%; |
| | | padding: 20px; /* ä¸ä¸å·¦å³å20pxï¼ç¹å»è¿ä¸ªèå´é½è½è§¦åäºä»¶ */ |
| | | cursor: pointer; /* é¼ æ æ¬æµ®æ¾ç¤ºæåï¼æåä½éª */ |
| | | text-align: center; |
| | | } |
| | | |
| | | .workorder-stats { |
| | | display: flex; |
| | | gap: 16px; |
| | | padding-bottom:1rem; |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | .stat-card { |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 12px; |
| | | padding: 20px; |
| | | background-color: #fff; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06); |
| | | } |
| | | |
| | | .stat-icon { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | width: 48px; |
| | | height: 48px; |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | .stat-info { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 4px; |
| | | } |
| | | |
| | | .stat-number { |
| | | font-size: 24px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | line-height: 1; |
| | | } |
| | | |
| | | .stat-label { |
| | | font-size: 14px; |
| | | color: #909399; |
| | | line-height: 1; |
| | | } |
| | | .table_header{ |
| | | padding-bottom: 10px; |
| | | } |
| | | |
| | | .table_list { |
| | | height: calc(100vh - 380px); |
| | | min-height: 360px; |
| | | background: #fff; |
| | | margin-top: 20px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | :deep(.table_list .pagination-container) { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | align-items: center; |
| | | margin-top: auto; |
| | | padding: 12px 0 0; |
| | | } |
| | | |
| | | :deep(.table_list .el-pagination) { |
| | | flex-wrap: nowrap; |
| | | justify-content: flex-end; |
| | | width: 100%; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" v-show="showSearch" :inline="true" label-width="68px"> |
| | | <el-form-item label="è§è²åç§°" prop="roleName"> |
| | | <el-input |
| | | v-model="queryParams.name" |
| | | placeholder="请è¾å
¥è§è²åç§°" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select |
| | | v-model="queryParams.status" |
| | | placeholder="è§è²ç¶æ" |
| | | clearable |
| | | style="width: 240px" |
| | | > |
| | | <el-option label="å¯ç¨" value="0" /> |
| | | <el-option label="ç¦ç¨" value="1" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:role:add']" |
| | | >æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="Edit" |
| | | :disabled="single" |
| | | @click="handleUpdate" |
| | | v-hasPermi="['system:role:edit']" |
| | | >ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['system:role:remove']" |
| | | >å é¤</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <!-- è¡¨æ ¼æ°æ® --> |
| | | <el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="è§è²ç¼å·" prop="no" /> |
| | | <el-table-column label="è§è²åç§°" prop="name" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç¶æ" align="center" width="100"> |
| | | <template #default="scope"> |
| | | <el-switch |
| | | v-model="scope.row.status" |
| | | :active-value="0" |
| | | :inactive-value="1" |
| | | @change="handleStatusChange(scope.row)" |
| | | ></el-switch> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column fixed="right" label="æä½" align="center" width="120"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top" v-if="scope.row.roleId !== 1"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:role:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top" v-if="scope.row.roleId !== 1"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:role:remove']"></el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.current" |
| | | v-model:limit="queryParams.size" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- æ·»å æä¿®æ¹è§è²é
ç½®å¯¹è¯æ¡ --> |
| | | <el-dialog :title="title" v-model="open" width="500px" append-to-body> |
| | | <el-form ref="roleRef" :model="form" :rules="rules" label-width="100px"> |
| | | <el-form-item label="è§è²ç¼å·" prop="no"> |
| | | <el-input |
| | | v-model="form.no" |
| | | style="max-width: 600px" |
| | | :placeholder="form.isDefaultNo ? '使ç¨ç³»ç»ç¼å·' : '请è¾å
¥è§è²ç¼å·'" |
| | | :disabled="form.isDefaultNo" |
| | | > |
| | | <template #append> |
| | | <el-checkbox v-model="form.isDefaultNo" size="large" /> |
| | | </template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item label="è§è²åç§°" prop="name"> |
| | | <el-input v-model="form.name" placeholder="请è¾å
¥è§è²åç§°" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Role"> |
| | | import {onMounted} from "vue"; |
| | | import {createRole, deleteRoles, findRoleListPage, updateRole} from "@/api/projectManagement/role.js"; |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_normal_disable } = proxy.useDict("sys_normal_disable") |
| | | |
| | | const roleList = ref([]) |
| | | const open = ref(false) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const ids = ref([]) |
| | | const single = ref(true) |
| | | const multiple = ref(true) |
| | | const total = ref(0) |
| | | const title = ref("") |
| | | const editingId = ref(undefined) |
| | | const form = reactive({ |
| | | isDefaultNo: true, |
| | | no: "", |
| | | name: "", |
| | | }); |
| | | |
| | | const rules = computed(() => ({ |
| | | no: [{ required: !form.isDefaultNo, message: "è§è²ç¼å·ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | name: [{ required: true, message: "è§è²åç§°ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | })); |
| | | |
| | | const data = reactive({ |
| | | queryParams: { |
| | | current: 1, |
| | | size: 10, |
| | | name: undefined, |
| | | status: undefined |
| | | }, |
| | | }) |
| | | |
| | | const { queryParams } = toRefs(data) |
| | | |
| | | /** æ¥è¯¢è§è²å表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | findRoleListPage(queryParams.value).then(res => { |
| | | roleList.value = res.data.records |
| | | total.value = res.data.total |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.value.current = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | proxy.resetForm("queryRef") |
| | | queryParams.value.name = undefined |
| | | queryParams.value.status = undefined |
| | | handleQuery() |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | let roleIds = [] |
| | | if (row.id) { |
| | | roleIds = [row.id] |
| | | } else { |
| | | roleIds = ids.value |
| | | } |
| | | proxy.$modal.confirm('ç¡®å®è¦å é¤è¯¥æ°æ®å?').then(function () { |
| | | return deleteRoles(roleIds) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | function handleSelectionChange(selection) { |
| | | ids.value = selection.map(item => item.id) |
| | | single.value = selection.length != 1 |
| | | multiple.value = !selection.length |
| | | } |
| | | |
| | | /** è§è²ç¶æä¿®æ¹ */ |
| | | function handleStatusChange(row) { |
| | | let text = row.status === 0 ? "å¯ç¨" : "åç¨" |
| | | proxy.$modal.confirm('确认è¦"' + text + '""' + row.name + '"è§è²å?').then(function () { |
| | | return updateRole(row) |
| | | }).then(() => { |
| | | proxy.$modal.msgSuccess(text + "æå") |
| | | }).catch(function () { |
| | | row.status = row.status === 0 ? 1 : 0 |
| | | }) |
| | | } |
| | | |
| | | /** éç½®æ°å¢ç表å以åå
¶ä»æ°æ® */ |
| | | function reset() { |
| | | // éç½®è¡¨åæ°æ® |
| | | Object.assign(form, { |
| | | isDefaultNo: true, |
| | | no: "", |
| | | name: "", |
| | | }) |
| | | editingId.value = undefined |
| | | } |
| | | |
| | | /** æ·»å è§è² */ |
| | | function handleAdd() { |
| | | reset() |
| | | open.value = true |
| | | title.value = "æ·»å è§è²" |
| | | } |
| | | |
| | | /** ä¿®æ¹è§è² */ |
| | | function handleUpdate(row) { |
| | | reset() |
| | | editingId.value = row.id |
| | | form.no = row.no |
| | | form.name = row.name |
| | | title.value = "ä¿®æ¹è§è²" |
| | | open.value = true |
| | | } |
| | | |
| | | /** æäº¤æé® */ |
| | | function submitForm() { |
| | | proxy.$refs["roleRef"].validate(valid => { |
| | | if (valid) { |
| | | if (editingId.value) { |
| | | const data = { |
| | | id: editingId.value, |
| | | ...form |
| | | } |
| | | updateRole(data).then(response => { |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå") |
| | | }).finally(() => { |
| | | proxy.$refs["roleRef"].resetFields() |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } else { |
| | | createRole(form).then(response => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå") |
| | | }).finally(() => { |
| | | proxy.$refs["roleRef"].resetFields() |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** åæ¶æé® */ |
| | | function cancel() { |
| | | open.value = false |
| | | reset() |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | | </script> |
| | |
| | | |
| | | // éæ©ååå¤ç |
| | | const handleSelectionChange = selection => { |
| | | // ä¸»è¡¨æ ¼ä¹åªä¿çæåä¸ä¸ªéä¸ç项 |
| | | if (selection.length > 1) { |
| | | const lastSelected = selection[selection.length - 1]; |
| | | selectedIds.value = [lastSelected.id]; |
| | | } else if (selection.length === 1) { |
| | | selectedIds.value = [selection[0].id]; |
| | | } else { |
| | | selectedIds.value = []; |
| | | } |
| | | selectedIds.value = selection.map(item => item.id); |
| | | }; |
| | | |
| | | // æå¼è¡¨å |