diff --git a/.env b/.env index 9ac29dc..2f030ec 100644 Binary files a/.env and b/.env differ diff --git a/env.d.ts b/env.d.ts index 11f02fe..323c78a 100644 --- a/env.d.ts +++ b/env.d.ts @@ -1 +1,7 @@ /// + +declare module '*.vue' { + import type { DefineComponent } from 'vue' + const component: DefineComponent<{}, {}, any> + export default component +} diff --git a/package.json b/package.json index c3e77cd..8f124bc 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ }, "dependencies": { "axios": "^1.9.0", + "element-plus": "^2.7.7", "pinia": "^3.0.1", "qrcode": "^1.5.4", "vue": "^3.5.13", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7e85cbb..1b2ef78 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: axios: specifier: ^1.9.0 version: 1.9.0 + element-plus: + specifier: ^2.7.7 + version: 2.10.3(vue@3.5.16(typescript@5.8.3)) pinia: specifier: ^3.0.1 version: 3.0.2(typescript@5.8.3)(vue@3.5.16(typescript@5.8.3)) @@ -218,6 +221,15 @@ packages: resolution: {integrity: sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==} engines: {node: '>=6.9.0'} + '@ctrl/tinycolor@3.6.1': + resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} + engines: {node: '>=10'} + + '@element-plus/icons-vue@2.3.1': + resolution: {integrity: sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==} + peerDependencies: + vue: ^3.2.0 + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -394,6 +406,15 @@ packages: resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@floating-ui/core@1.7.2': + resolution: {integrity: sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==} + + '@floating-ui/dom@1.7.2': + resolution: {integrity: sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==} + + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -578,6 +599,9 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} + '@sxzz/popperjs-es@2.11.7': + resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==} + '@tsconfig/node22@22.0.2': resolution: {integrity: sha512-Kmwj4u8sDRDrMYRoN9FDEcXD8UpBSaPQQ24Gz+Gamqfm7xxn+GBR7ge/Z7pK8OXNGyUzbSwJj+TH6B+DS/epyA==} @@ -587,12 +611,21 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.20': + resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} + '@types/node@22.15.29': resolution: {integrity: sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==} '@types/qrcode@1.5.5': resolution: {integrity: sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==} + '@types/web-bluetooth@0.0.16': + resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} + '@typescript-eslint/eslint-plugin@8.33.0': resolution: {integrity: sha512-CACyQuqSHt7ma3Ns601xykeBK/rDeZa3w6IS6UtMQbixO5DWy+8TilKkviGDH6jtWCo8FGRKEK5cLLkPvEammQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -767,6 +800,15 @@ packages: vue: optional: true + '@vueuse/core@9.13.0': + resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==} + + '@vueuse/metadata@9.13.0': + resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==} + + '@vueuse/shared@9.13.0': + resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -798,6 +840,9 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + async-validator@4.2.5: + resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -887,6 +932,9 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + de-indent@1.0.2: resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} @@ -932,6 +980,11 @@ packages: electron-to-chromium@1.5.161: resolution: {integrity: sha512-hwtetwfKNZo/UlwHIVBlKZVdy7o8bIZxxKs0Mv/ROPiQQQmDgdm5a+KvKtBsxM8ZjFzTaCeLoodZ8jiBE3o9rA==} + element-plus@2.10.3: + resolution: {integrity: sha512-OLpf0iekuvWJrz1+H9ybvem6TYTKSNk6L1QDA3tYq2YWbogKXJnWpHG1UAGKR1B7gx+vUH7M15VIH3EijE9Kgw==} + peerDependencies: + vue: ^3.2.0 + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -967,6 +1020,9 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -1315,6 +1371,16 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash-unified@1.0.3: + resolution: {integrity: sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==} + peerDependencies: + '@types/lodash-es': '*' + lodash: '*' + lodash-es: '*' + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -1331,6 +1397,9 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + memoize-one@6.0.0: + resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} + memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} @@ -1387,6 +1456,9 @@ packages: node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + normalize-wheel-es@1.2.0: + resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==} + npm-normalize-package-bin@4.0.0: resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==} engines: {node: ^18.17.0 || >=20.5.0} @@ -1744,6 +1816,17 @@ packages: vscode-uri@3.1.0: resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + vue-eslint-parser@10.1.3: resolution: {integrity: sha512-dbCBnd2e02dYWsXoqX5yKUZlOt+ExIpq7hmHKPb5ZqKcjf++Eo0hMseFTZMLKThrUk61m+Uv6A2YSBve6ZvuDQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2014,6 +2097,12 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@ctrl/tinycolor@3.6.1': {} + + '@element-plus/icons-vue@2.3.1(vue@3.5.16(typescript@5.8.3))': + dependencies: + vue: 3.5.16(typescript@5.8.3) + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -2127,6 +2216,17 @@ snapshots: '@eslint/core': 0.14.0 levn: 0.4.1 + '@floating-ui/core@1.7.2': + dependencies: + '@floating-ui/utils': 0.2.10 + + '@floating-ui/dom@1.7.2': + dependencies: + '@floating-ui/core': 1.7.2 + '@floating-ui/utils': 0.2.10 + + '@floating-ui/utils@0.2.10': {} + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': @@ -2245,12 +2345,20 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} + '@sxzz/popperjs-es@2.11.7': {} + '@tsconfig/node22@22.0.2': {} '@types/estree@1.0.7': {} '@types/json-schema@7.0.15': {} + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.20 + + '@types/lodash@4.17.20': {} + '@types/node@22.15.29': dependencies: undici-types: 6.21.0 @@ -2259,6 +2367,8 @@ snapshots: dependencies: '@types/node': 22.15.29 + '@types/web-bluetooth@0.0.16': {} + '@typescript-eslint/eslint-plugin@8.33.0(@typescript-eslint/parser@8.33.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -2528,6 +2638,25 @@ snapshots: typescript: 5.8.3 vue: 3.5.16(typescript@5.8.3) + '@vueuse/core@9.13.0(vue@3.5.16(typescript@5.8.3))': + dependencies: + '@types/web-bluetooth': 0.0.16 + '@vueuse/metadata': 9.13.0 + '@vueuse/shared': 9.13.0(vue@3.5.16(typescript@5.8.3)) + vue-demi: 0.14.10(vue@3.5.16(typescript@5.8.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@9.13.0': {} + + '@vueuse/shared@9.13.0(vue@3.5.16(typescript@5.8.3))': + dependencies: + vue-demi: 0.14.10(vue@3.5.16(typescript@5.8.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + acorn-jsx@5.3.2(acorn@8.14.1): dependencies: acorn: 8.14.1 @@ -2553,6 +2682,8 @@ snapshots: argparse@2.0.1: {} + async-validator@4.2.5: {} + asynckit@0.4.0: {} axios@1.9.0: @@ -2643,6 +2774,8 @@ snapshots: csstype@3.1.3: {} + dayjs@1.11.13: {} + de-indent@1.0.2: {} debug@4.4.1: @@ -2674,6 +2807,27 @@ snapshots: electron-to-chromium@1.5.161: {} + element-plus@2.10.3(vue@3.5.16(typescript@5.8.3)): + dependencies: + '@ctrl/tinycolor': 3.6.1 + '@element-plus/icons-vue': 2.3.1(vue@3.5.16(typescript@5.8.3)) + '@floating-ui/dom': 1.7.2 + '@popperjs/core': '@sxzz/popperjs-es@2.11.7' + '@types/lodash': 4.17.20 + '@types/lodash-es': 4.17.12 + '@vueuse/core': 9.13.0(vue@3.5.16(typescript@5.8.3)) + async-validator: 4.2.5 + dayjs: 1.11.13 + escape-html: 1.0.3 + lodash: 4.17.21 + 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) + memoize-one: 6.0.0 + normalize-wheel-es: 1.2.0 + vue: 3.5.16(typescript@5.8.3) + transitivePeerDependencies: + - '@vue/composition-api' + emoji-regex@8.0.0: {} entities@4.5.0: {} @@ -2723,6 +2877,8 @@ snapshots: escalade@3.2.0: {} + escape-html@1.0.3: {} + escape-string-regexp@4.0.0: {} eslint-config-prettier@10.1.5(eslint@9.28.0(jiti@2.4.2)): @@ -3055,6 +3211,14 @@ snapshots: dependencies: p-locate: 5.0.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): + dependencies: + '@types/lodash-es': 4.17.12 + lodash: 4.17.21 + lodash-es: 4.17.21 + lodash.merge@4.6.2: {} lodash@4.17.21: {} @@ -3069,6 +3233,8 @@ snapshots: math-intrinsics@1.1.0: {} + memoize-one@6.0.0: {} + memorystream@0.3.1: {} merge2@1.4.1: {} @@ -3108,6 +3274,8 @@ snapshots: node-releases@2.0.19: {} + normalize-wheel-es@1.2.0: {} + npm-normalize-package-bin@4.0.0: {} npm-run-all2@7.0.2: @@ -3439,6 +3607,10 @@ snapshots: vscode-uri@3.1.0: {} + vue-demi@0.14.10(vue@3.5.16(typescript@5.8.3)): + dependencies: + vue: 3.5.16(typescript@5.8.3) + vue-eslint-parser@10.1.3(eslint@9.28.0(jiti@2.4.2)): dependencies: debug: 4.4.1 diff --git a/src/App.vue b/src/App.vue index 080ea4e..28fd4c7 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,9 +3,11 @@ import { RouterView } from 'vue-router' \ No newline at end of file + diff --git a/src/views/CaseView.vue b/src/views/CaseView.vue index 5ab0b9b..559efeb 100644 --- a/src/views/CaseView.vue +++ b/src/views/CaseView.vue @@ -1,7 +1,13 @@ @@ -168,12 +324,99 @@ const formatDate = (dateStr: string | null | undefined): string => { -
+
+ +
+

案例咨询与留言

+ + +
@@ -210,7 +453,9 @@ const formatDate = (dateStr: string | null | undefined): string => { } @keyframes spin { - to { transform: rotate(360deg); } + to { + transform: rotate(360deg); + } } .error { @@ -350,18 +595,75 @@ const formatDate = (dateStr: string | null | undefined): string => { flex-wrap: wrap; } -.btn-home, .btn-more { +/* 添加法律卡片相关样式 */ +:deep(.law-card) { + margin: 1.5rem 0; + border: 1px solid #e0e0e0; + border-radius: 8px; + overflow: hidden; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); + background-color: #f9f9f9; +} + +:deep(.law-card-header) { + padding: 1rem 1.5rem; + background-color: #f0f0f0; + display: flex; + justify-content: space-between; + align-items: center; + cursor: pointer; + transition: background-color 0.3s; + user-select: none; /* 防止选中文本 */ +} + +:deep(.law-card-header:hover) { + background-color: #e0e0e0; +} + +:deep(.law-card-title) { + font-weight: bold; + color: #333; + font-size: 1.1rem; +} + +:deep(.law-card-toggle) { + transition: transform 0.3s; +} + +:deep(.law-card-content) { + padding: 0; + max-height: 0; + overflow: hidden; + transition: + max-height 0.5s ease, + padding 0.5s ease; +} + +:deep(.law-card.expanded .law-card-content) { + padding: 1.5rem; + max-height: 2000px; +} + +:deep(.law-card.expanded .law-card-toggle) { + transform: rotate(180deg); +} + +.btn-home, +.btn-more { display: inline-block; padding: 0.6rem 1.5rem; background-color: var(--color-primary); color: white; text-decoration: none; border-radius: 4px; - transition: background-color 0.3s, transform 0.3s; + transition: + background-color 0.3s, + transform 0.3s; font-size: 0.9rem; } -.btn-home:hover, .btn-more:hover { +.btn-home:hover, +.btn-more:hover { background-color: #0069d9; transform: translateY(-2px); } @@ -390,6 +692,10 @@ const formatDate = (dateStr: string | null | undefined): string => { .content .body { font-size: 0.95rem; } + + :deep(.law-card-title) { + font-size: 1rem; + } } @media (max-width: 576px) { @@ -426,10 +732,23 @@ const formatDate = (dateStr: string | null | undefined): string => { padding-top: 1rem; } - .btn-home, .btn-more { + .btn-home, + .btn-more { padding: 0.5rem 1.2rem; font-size: 0.85rem; } + + :deep(.law-card-header) { + padding: 0.8rem 1rem; + } + + :deep(.law-card-title) { + font-size: 0.9rem; + } + + :deep(.law-card.expanded .law-card-content) { + padding: 1rem; + } } @media (min-width: 1200px) { @@ -446,4 +765,249 @@ const formatDate = (dateStr: string | null | undefined): string => { padding: 0; } } + +.feedback-section { + background-color: #f9f9f9; + border-radius: 8px; + margin-top: 2rem; + padding: 2rem; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); +} + +.feedback-section h3 { + font-size: 1.5rem; + color: var(--color-primary); + margin-bottom: 1.5rem; + display: flex; + align-items: center; +} + +.feedback-section .icon-chat::before { + content: '💬'; /* Chat bubble icon */ + margin-right: 10px; + font-size: 1.8rem; +} + +.feedback-section .icon-search::before { + content: '🔍'; /* Search icon */ + margin-right: 10px; + font-size: 1.8rem; +} + +.feedback-section .section-description { + color: var(--color-text-light); + margin-bottom: 1.5rem; + line-height: 1.6; +} + +.feedback-form .form-group, +.feedback-query .form-group { + margin-bottom: 1rem; +} + +.feedback-form label, +.feedback-query label { + display: block; + margin-bottom: 0.5rem; + font-weight: 500; + color: var(--color-text); +} + +.feedback-form input[type='text'], +.feedback-form textarea, +.feedback-form select, +.feedback-query input[type='text'], +.feedback-query select { + width: calc(100% - 20px); + padding: 0.8rem 10px; + border: 1px solid #ccc; + border-radius: 4px; + font-size: 1rem; + box-sizing: border-box; +} + +.feedback-form textarea { + resize: vertical; +} + +.feedback-form .required, +.feedback-query .required { + color: var(--color-danger); + margin-left: 5px; +} + +.feedback-form .submit-btn, +.feedback-query .submit-btn { + display: inline-block; + padding: 0.8rem 2rem; + background-color: var(--color-primary); + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 1rem; + transition: background-color 0.3s ease; + margin-top: 1rem; +} + +.feedback-form .submit-btn:hover, +.feedback-query .submit-btn:hover { + background-color: #0069d9; +} + +.feedback-query .submit-btn:disabled { + background-color: #cccccc; + cursor: not-allowed; +} + +.feedback-success { + text-align: center; + padding: 2rem; + background-color: #e6ffe6; + border: 1px solid #aaffaa; + border-radius: 8px; + color: #336633; +} + +.feedback-success h4 { + color: #28a745; + margin-bottom: 1rem; + font-size: 1.3rem; +} + +.feedback-success .feedback-no { + font-weight: bold; + color: var(--color-primary); + font-size: 1.5rem; +} + +.feedback-success button { + margin-top: 1.5rem; + padding: 0.7rem 1.5rem; + background-color: var(--color-success); + border: none; + border-radius: 4px; + color: white; + cursor: pointer; + transition: background-color 0.3s; +} + +.feedback-success button:hover { + background-color: #218838; +} + +.query-title { + margin-top: 3rem; + border-top: 1px dashed #eee; + padding-top: 2rem; +} + +.query-result { + background-color: #e9f7fe; + border: 1px solid #b3e0ff; + border-radius: 8px; + padding: 1.5rem; + margin-top: 2rem; +} + +.query-result h4 { + color: #007bff; + margin-bottom: 1rem; + font-size: 1.3rem; + padding-bottom: 0.8rem; + border-bottom: 1px dashed #cceeff; +} + +.query-result .result-item { + margin-bottom: 0.8rem; + color: var(--color-text); + font-size: 0.95rem; +} + +.query-result .result-item strong { + color: #333; +} + +.query-result .admin-reply-content { + background-color: #ffffff; + border: 1px solid #e0e0e0; + border-radius: 4px; + padding: 1rem; + margin-top: 0.5rem; + line-height: 1.6; + color: #555; +} + +.error-message { + color: var(--color-danger); + margin-top: 1rem; + font-size: 0.9rem; +} + +.status-pending { + color: orange; + font-weight: bold; +} + +.status-replied { + color: green; + font-weight: bold; +} + +.status-closed { + color: gray; + font-weight: bold; +} + +@media (max-width: 768px) { + .feedback-section { + padding: 1.5rem; + } +} + +@media (max-width: 576px) { + .feedback-section { + padding: 1rem; + } + + .feedback-section h3 { + font-size: 1.3rem; + } + + .feedback-section .icon-chat::before, + .feedback-section .icon-search::before { + font-size: 1.5rem; + } + + .feedback-form input[type='text'], + .feedback-form textarea, + .feedback-form select, + .feedback-query input[type='text'], + .feedback-query select { + padding: 0.6rem 8px; + font-size: 0.9rem; + } + + .feedback-form .submit-btn, + .feedback-query .submit-btn { + padding: 0.6rem 1.5rem; + font-size: 0.9rem; + } + + .feedback-success h4 { + font-size: 1.1rem; + } + + .feedback-success .feedback-no { + font-size: 1.3rem; + } + + .query-result h4 { + font-size: 1.1rem; + } + + .query-result .result-item { + font-size: 0.85rem; + } +} diff --git a/src/views/FeedbackQueryView.vue b/src/views/FeedbackQueryView.vue new file mode 100644 index 0000000..fb19a8a --- /dev/null +++ b/src/views/FeedbackQueryView.vue @@ -0,0 +1,515 @@ + + + + + diff --git a/src/views/FormListView.vue b/src/views/FormListView.vue index 9609552..0aa0f01 100644 --- a/src/views/FormListView.vue +++ b/src/views/FormListView.vue @@ -5,107 +5,107 @@ import TheNavbar from '../components/TheNavbar.vue' import Pagination from '../components/Pagination.vue' interface PageItem { - id: number; - formatId: string; - title: string; - pageUrl?: string; - createTime: string; - viewCount: number; - author?: string; - multiAttachments?: string; - attachmentUrl?: string; + id: number + formatId: string + title: string + pageUrl?: string + createTime: string + viewCount: number + author?: string + multiAttachments?: string + attachmentUrl?: string } -const formList = ref([]); -const loading = ref(true); -const error = ref(''); -const total = ref(0); -const currentPage = ref(1); -const pageSize = ref(15); +const formList = ref([]) +const loading = ref(true) +const error = ref('') +const total = ref(0) +const currentPage = ref(1) +const pageSize = ref(15) const fetchForms = async () => { try { - loading.value = true; - error.value = ''; - - const result = await getPageList('form', currentPage.value, pageSize.value); - + loading.value = true + error.value = '' + + const result = await getPageList('form', currentPage.value, pageSize.value) + if (result.code === 200) { - formList.value = result.rows || []; - total.value = result.total || formList.value.length; - + formList.value = result.rows || [] + total.value = result.total || formList.value.length + // 如果当前页没有数据且不是第一页,尝试请求前一页 if (formList.value.length === 0 && currentPage.value > 1) { - currentPage.value = currentPage.value - 1; - await fetchForms(); + currentPage.value = currentPage.value - 1 + await fetchForms() } } else { - error.value = result.msg || '获取数据失败'; - formList.value = []; + error.value = result.msg || '获取数据失败' + formList.value = [] } } catch (e) { - console.error(e); - error.value = '获取数据失败,请稍后重试'; - formList.value = []; + console.error(e) + error.value = '获取数据失败,请稍后重试' + formList.value = [] } finally { - loading.value = false; + loading.value = false } -}; +} // 页码或每页数量变化时重新获取数据 watch([currentPage, pageSize], () => { - fetchForms(); -}); + fetchForms() +}) // 分页变化处理 const handlePageChange = (page: number, size: number) => { - currentPage.value = page; - pageSize.value = size; -}; + currentPage.value = page + pageSize.value = size +} onMounted(() => { - fetchForms(); -}); + fetchForms() +}) // 添加页面激活时重新获取数据的处理函数 onActivated(() => { - console.log('表单下载列表页面被激活,重新获取数据'); - fetchForms(); -}); + console.log('表单下载列表页面被激活,重新获取数据') + fetchForms() +}) // 判断是否有附件 function hasAttachments(item: PageItem): boolean { // 首先检查是否有直接附件链接 - if (item.attachmentUrl) return true; - + if (item.attachmentUrl) return true + // 再检查多附件数据 - if (!item.multiAttachments) return false; - + if (!item.multiAttachments) return false + try { - const attachments = JSON.parse(item.multiAttachments); - return Array.isArray(attachments) && attachments.length > 0; + const attachments = JSON.parse(item.multiAttachments) + return Array.isArray(attachments) && attachments.length > 0 } catch (e) { - console.error('解析附件列表失败:', e); - return false; + console.error('解析附件列表失败:', e) + return false } } // 格式化日期 const formatDate = (dateStr: string | null | undefined): string => { - if (!dateStr) return '未知日期'; + if (!dateStr) return '未知日期' try { - const date = new Date(dateStr); + const date = new Date(dateStr) if (isNaN(date.getTime())) { - return '未知日期'; + return '未知日期' } - return date.toLocaleDateString('zh-CN', { - year: 'numeric', - month: '2-digit', - day: '2-digit' - }); + return date.toLocaleDateString('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + }) } catch (e) { - console.error('日期格式化错误:', e); - return '未知日期'; + console.error('日期格式化错误:', e) + return '未知日期' } } @@ -113,14 +113,14 @@ const formatDate = (dateStr: string | null | undefined): string => {