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 => {
-
+
+
+
+
案例咨询与留言
+
+
+
留言提交成功!
+
+ 您的留言查询编号是:{{ feedbackNoReturned }}
+
+
请牢记此编号,以便查询回复。
+
+
+
@@ -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 @@
+
+
+
+
+
+
+
+
+
+
留言查询
+
请输入您的留言编号和联系方式以查询留言回复情况。
+
+
+
+
+
留言回复详情
+
+ 留言编号: {{ feedbackQueryResult.feedbackNo }}
+
+
+ 留言标题: {{ feedbackQueryResult.legalArticle }}
+
+
+ 问题描述: {{ feedbackQueryResult.issueDescription }}
+
+
+ 留言时间: {{ formatDate(feedbackQueryResult.createTime) }}
+
+
+ 留言状态:
+
+ {{ getFeedbackStatus(feedbackQueryResult.adminReplyContent) }}
+
+
+
+
+ 回复时间: {{ formatDate(feedbackQueryResult.adminReplyTime) }}
+
+
+
+
+
+
扫描二维码
+
在手机上扫描此二维码,快速打开当前查询页面。
+
+
正在生成二维码...
+
+
+
+
+
+
+
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 => {
@@ -534,7 +650,9 @@ function removeFileFromList(index) {
}
@keyframes spin {
- to { transform: rotate(360deg); }
+ to {
+ transform: rotate(360deg);
+ }
}
.error {
@@ -669,6 +787,59 @@ function removeFileFromList(index) {
background-color: #f8f9fa;
}
+/* 添加法律卡片相关样式 */
+: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);
+}
+
.attachments {
background-color: #f9f9f9;
border-radius: 8px;
@@ -728,7 +899,9 @@ function removeFileFromList(index) {
padding: 0.4rem 0.8rem;
font-size: 0.85rem;
text-decoration: none;
- transition: background-color 0.3s, transform 0.3s;
+ transition:
+ background-color 0.3s,
+ transform 0.3s;
cursor: pointer;
}
@@ -747,18 +920,22 @@ function removeFileFromList(index) {
flex-wrap: wrap;
}
-.btn-home, .btn-more {
+.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);
}
@@ -791,6 +968,10 @@ function removeFileFromList(index) {
.attachments {
padding: 1.2rem;
}
+
+ :deep(.law-card-title) {
+ font-size: 1rem;
+ }
}
@media (max-width: 576px) {
@@ -835,10 +1016,23 @@ function removeFileFromList(index) {
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) {
@@ -855,4 +1049,249 @@ function removeFileFromList(index) {
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/LawListView.vue b/src/views/LawListView.vue
index c94990e..692609b 100644
--- a/src/views/LawListView.vue
+++ b/src/views/LawListView.vue
@@ -5,118 +5,118 @@ import TheNavbar from '../components/TheNavbar.vue'
import Pagination from '../components/Pagination.vue'
interface PageItem {
- id: number;
- formatId: string;
- title: string;
- content: string;
- pageType: string;
- pageUrl?: string;
- createTime: string;
- updateTime: string;
- status: number;
- sortOrder: number;
- viewCount: number;
- author?: string;
- keywords?: string;
- description?: string;
- attachmentUrl?: string;
+ id: number
+ formatId: string
+ title: string
+ content: string
+ pageType: string
+ pageUrl?: string
+ createTime: string
+ updateTime: string
+ status: number
+ sortOrder: number
+ viewCount: number
+ author?: string
+ keywords?: string
+ description?: string
+ attachmentUrl?: string
}
interface PageData {
- code: number;
- rows: PageItem[];
- total: number;
- msg: string;
+ code: number
+ rows: PageItem[]
+ total: number
+ msg: string
}
-const laws = ref([]);
-const loading = ref(true);
-const error = ref('');
-const total = ref(0);
-const currentPage = ref(1);
-const pageSize = ref(15);
+const laws = ref([])
+const loading = ref(true)
+const error = ref('')
+const total = ref(0)
+const currentPage = ref(1)
+const pageSize = ref(15)
const fetchLaws = async () => {
try {
- loading.value = true;
- error.value = '';
-
- const response = await getPageList('law', currentPage.value, pageSize.value);
-
+ loading.value = true
+ error.value = ''
+
+ const response = await getPageList('law', currentPage.value, pageSize.value)
+
if (response.code === 200) {
- laws.value = response.rows || [];
- total.value = response.total || laws.value.length;
-
+ laws.value = response.rows || []
+ total.value = response.total || laws.value.length
+
// 如果当前页没有数据且不是第一页,尝试请求前一页
if (laws.value.length === 0 && currentPage.value > 1) {
- currentPage.value = currentPage.value - 1;
- await fetchLaws();
+ currentPage.value = currentPage.value - 1
+ await fetchLaws()
}
} else {
- error.value = response.msg || '获取数据失败';
- laws.value = [];
+ error.value = response.msg || '获取数据失败'
+ laws.value = []
}
} catch (err) {
- console.error('获取法律规定列表失败:', err);
- error.value = '获取数据失败,请稍后重试';
- laws.value = [];
+ console.error('获取法律规定列表失败:', err)
+ error.value = '获取数据失败,请稍后重试'
+ laws.value = []
} finally {
- loading.value = false;
+ loading.value = false
}
-};
+}
// 页码或每页数量变化时重新获取数据
watch([currentPage, pageSize], () => {
- fetchLaws();
-});
+ fetchLaws()
+})
// 分页变化处理
const handlePageChange = (page: number, size: number) => {
- currentPage.value = page;
- pageSize.value = size;
-};
+ currentPage.value = page
+ pageSize.value = size
+}
// 格式化日期
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 '未知日期'
}
}
onMounted(() => {
- fetchLaws();
-});
+ fetchLaws()
+})
// 添加页面激活时重新获取数据的处理函数
onActivated(() => {
- console.log('法律规定列表页面被激活,重新获取数据');
- fetchLaws();
-});
+ console.log('法律规定列表页面被激活,重新获取数据')
+ fetchLaws()
+})
-
+
-
+
@@ -124,19 +124,19 @@ onActivated(() => {
加载中...
-
+
-
+
-
+
@@ -155,14 +155,14 @@ onActivated(() => {
-
+
-
@@ -247,7 +247,9 @@ onActivated(() => {
width: 100%;
}
-.loading, .error, .empty {
+.loading,
+.error,
+.empty {
display: flex;
flex-direction: column;
align-items: center;
@@ -267,10 +269,13 @@ onActivated(() => {
}
@keyframes spin {
- to { transform: rotate(360deg); }
+ to {
+ transform: rotate(360deg);
+ }
}
-.btn-retry, .btn-home {
+.btn-retry,
+.btn-home {
background-color: var(--color-primary);
color: white;
border: none;
@@ -285,7 +290,8 @@ onActivated(() => {
display: inline-block;
}
-.btn-retry:hover, .btn-home:hover {
+.btn-retry:hover,
+.btn-home:hover {
background-color: var(--color-primary-dark);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 123, 255, 0.3);
@@ -363,13 +369,15 @@ onActivated(() => {
gap: 0.5rem;
}
-.law-date, .law-views {
+.law-date,
+.law-views {
display: flex;
align-items: center;
gap: 0.5rem;
}
-.law-date::before, .law-views::before {
+.law-date::before,
+.law-views::before {
content: '';
display: inline-block;
width: 16px;
@@ -416,16 +424,16 @@ onActivated(() => {
.page-header {
padding: 2.5rem 0;
}
-
+
.page-header h1 {
font-size: 2.2rem;
}
-
+
.law-grid {
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 1rem;
}
-
+
.law-list {
padding: 1.5rem;
}
@@ -435,26 +443,26 @@ onActivated(() => {
.page-header {
padding: 2rem 0;
}
-
+
.page-header h1 {
font-size: 1.8rem;
}
-
+
.subtitle {
font-size: 1rem;
}
-
+
.law-grid {
grid-template-columns: 1fr;
}
-
+
.law-list {
padding: 1rem;
border-radius: 8px;
}
-
+
.law-link {
padding: 1.2rem;
}
}
-
\ No newline at end of file
+
diff --git a/src/views/LawView.vue b/src/views/LawView.vue
index db6b5d5..6ff3c62 100644
--- a/src/views/LawView.vue
+++ b/src/views/LawView.vue
@@ -1,139 +1,310 @@
@@ -168,12 +339,100 @@ const formatDate = (dateStr: string | null | undefined): string => {
-
-
+
+
+
+
法律咨询与留言
+
+
+
留言提交成功!
+
+ 您的留言查询编号是:{{ feedbackNoReturned }}
+
+
请牢记此编号,以便查询回复。
+
+
+
@@ -210,7 +469,9 @@ const formatDate = (dateStr: string | null | undefined): string => {
}
@keyframes spin {
- to { transform: rotate(360deg); }
+ to {
+ transform: rotate(360deg);
+ }
}
.error {
@@ -295,6 +556,11 @@ const formatDate = (dateStr: string | null | undefined): string => {
margin-right: 5px;
}
+.icon-user::before {
+ content: '👤';
+ margin-right: 5px;
+}
+
.content .body {
line-height: 1.8;
color: var(--color-text);
@@ -340,6 +606,61 @@ const formatDate = (dateStr: string | null | undefined): string => {
background-color: #f8f9fa;
}
+/* 添加法律卡片相关样式 */
+: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;
+ transform: rotate(180deg); /* 默认显示为向上箭头,表示展开状态 */
+}
+
+:deep(.law-card-content) {
+ padding: 1.5rem; /* 默认有内边距 */
+ max-height: 2000px; /* 默认展开高度 */
+ overflow: hidden;
+ transition:
+ max-height 0.5s ease,
+ padding 0.5s ease;
+}
+
+/* 非展开状态的样式 */
+:deep(.law-card:not(.expanded) .law-card-content) {
+ padding: 0;
+ max-height: 0;
+}
+
+:deep(.law-card:not(.expanded) .law-card-toggle) {
+ transform: rotate(0deg);
+}
+
.content .footer {
margin-top: 3rem;
padding-top: 1.5rem;
@@ -350,18 +671,22 @@ const formatDate = (dateStr: string | null | undefined): string => {
flex-wrap: wrap;
}
-.btn-home, .btn-more {
+.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 +715,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 +755,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 +788,258 @@ const formatDate = (dateStr: string | null | undefined): string => {
padding: 0;
}
}
+
+:deep(.law-card.expanded .law-card-content) {
+ padding: 1.5rem;
+ max-height: 2000px;
+}
+
+:deep(.law-card.expanded .law-card-toggle) {
+ transform: rotate(180deg);
+}
+
+.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/vite.config.ts b/vite.config.ts
index 1e307ec..53c8700 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -19,11 +19,13 @@ export default defineConfig({
return () => {
server.middlewares.use((req, res, next) => {
// 如果是前端路由路径,直接返回index.html
- if (req.url === '/hasfjlaw' || req.url === '/hasfjcase' || req.url === '/hasfjform' || req.url === '/qrcodes') {
- const indexHtml = fs.readFileSync(
- path.resolve(__dirname, 'index.html'),
- 'utf-8'
- )
+ if (
+ req.url === '/hasfjlaw' ||
+ req.url === '/hasfjcase' ||
+ req.url === '/hasfjform' ||
+ req.url === '/qrcodes'
+ ) {
+ const indexHtml = fs.readFileSync(path.resolve(__dirname, 'index.html'), 'utf-8')
res.statusCode = 200
res.setHeader('Content-Type', 'text/html')
res.end(indexHtml)
@@ -32,12 +34,12 @@ export default defineConfig({
next()
})
}
- }
- }
+ },
+ },
],
resolve: {
alias: {
- '@': fileURLToPath(new URL('./src', import.meta.url))
+ '@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
server: {
@@ -46,79 +48,86 @@ export default defineConfig({
proxy: {
// 配置跨域
'/api': {
- // target: 'http://127.0.0.1:9799', // 后端服务地址
- target: 'http://222.184.49.22:9799', // 后端服务地址
+ // target: 'http://127.0.0.1:19696', // 后端服务地址
+ target: 'http://222.184.49.22:19696', // 后端服务地址
changeOrigin: true, // 支持跨域
rewrite: (path) => path.replace(/^\/api/, ''), // 移除/api前缀
configure: (proxy, options) => {
// 添加代理错误处理
proxy.on('error', (err, req, res) => {
- console.error('API代理错误:', err);
+ console.error('API代理错误:', err)
// 返回友好的错误响应
if (!res.headersSent) {
res.writeHead(500, {
- 'Content-Type': 'application/json'
- });
+ 'Content-Type': 'application/json',
+ })
- res.end(JSON.stringify({
- code: 500,
- msg: '后端服务暂时不可用,请稍后重试',
- data: null
- }));
+ res.end(
+ JSON.stringify({
+ code: 500,
+ msg: '后端服务暂时不可用,请稍后重试',
+ data: null,
+ }),
+ )
}
- });
- }
+ })
+ },
},
// 添加司法局后台管理接口代理
'/hasfj': {
- // target: 'http://127.0.0.1:9799', // 后端服务地址
- target: 'http://222.184.49.22:9799', // 司法局后端服务
+ // target: 'http://127.0.0.1:19696', // 后端服务地址
+ target: 'http://222.184.49.22:19696', // 后端服务地址
changeOrigin: true,
rewrite: (path) => path, // 保持路径不变
configure: (proxy, options) => {
// 添加代理错误处理
proxy.on('error', (err, req, res) => {
- console.error('后台管理接口代理错误:', err);
+ console.error('后台管理接口代理错误:', err)
// 返回友好的错误响应
if (!res.headersSent) {
res.writeHead(500, {
- 'Content-Type': 'application/json'
- });
+ 'Content-Type': 'application/json',
+ })
- res.end(JSON.stringify({
- code: 500,
- msg: '后端服务暂时不可用,请稍后重试',
- data: null
- }));
+ res.end(
+ JSON.stringify({
+ code: 500,
+ msg: '后端服务暂时不可用,请稍后重试',
+ data: null,
+ }),
+ )
}
- });
- }
+ })
+ },
},
// 添加文件下载代理,专门处理静态资源文件请求
'/profile': {
- target: 'http://222.184.49.22:9799', // 后端静态资源服务地址
+ // target: 'http://127.0.0.1:19696', // 后端服务地址
+ target: 'http://222.184.49.22:19696', // 后端静态资源服务地址
changeOrigin: true,
rewrite: (path) => path, // 保持路径不变
configure: (proxy, options) => {
proxy.on('error', (err, req, res) => {
- console.error('文件下载代理错误:', err);
+ console.error('文件下载代理错误:', err)
if (!res.headersSent) {
res.writeHead(500, {
- 'Content-Type': 'application/json'
- });
+ 'Content-Type': 'application/json',
+ })
- res.end(JSON.stringify({
- code: 500,
- msg: '文件下载失败,请稍后重试',
- data: null
- }));
+ res.end(
+ JSON.stringify({
+ code: 500,
+ msg: '文件下载失败,请稍后重试',
+ data: null,
+ }),
+ )
}
- });
- }
- }
- }
- }
+ })
+ },
+ },
+ },
+ },
})