Commit af3bc72e authored by tyyin lan's avatar tyyin lan

chore: markdown parser调整

parent 1a0c546c
...@@ -19,16 +19,17 @@ ...@@ -19,16 +19,17 @@
"@icon-park/vue-next": "^1.4.2", "@icon-park/vue-next": "^1.4.2",
"@iconify/vue": "^4.1.2", "@iconify/vue": "^4.1.2",
"@microsoft/fetch-event-source": "^2.0.1", "@microsoft/fetch-event-source": "^2.0.1",
"@traptitech/markdown-it-katex": "^3.6.0",
"@unocss/reset": "^0.61.9", "@unocss/reset": "^0.61.9",
"@vueuse/core": "^10.11.1", "@vueuse/core": "^10.11.1",
"axios": "^1.7.7", "axios": "^1.7.7",
"clipboardy": "^4.0.0", "clipboardy": "^4.0.0",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"dompurify": "^3.2.0",
"github-markdown-css": "^5.7.0",
"highlight.js": "^11.10.0", "highlight.js": "^11.10.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"markdown-it": "^14.1.0", "marked": "^15.0.0",
"markdown-it-link-attributes": "^4.0.1", "marked-highlight": "^2.2.1",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"nanoid": "^5.0.7", "nanoid": "^5.0.7",
"pinia": "^2.2.2", "pinia": "^2.2.2",
...@@ -45,8 +46,6 @@ ...@@ -45,8 +46,6 @@
"@commitlint/types": "^19.5.0", "@commitlint/types": "^19.5.0",
"@intlify/unplugin-vue-i18n": "^4.0.0", "@intlify/unplugin-vue-i18n": "^4.0.0",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/markdown-it": "^14.1.2",
"@types/markdown-it-link-attributes": "^3.0.5",
"@types/node": "^20.16.5", "@types/node": "^20.16.5",
"@types/spark-md5": "^3.0.4", "@types/spark-md5": "^3.0.4",
"@types/validator": "^13.12.2", "@types/validator": "^13.12.2",
......
...@@ -17,9 +17,6 @@ importers: ...@@ -17,9 +17,6 @@ importers:
'@microsoft/fetch-event-source': '@microsoft/fetch-event-source':
specifier: ^2.0.1 specifier: ^2.0.1
version: 2.0.1 version: 2.0.1
'@traptitech/markdown-it-katex':
specifier: ^3.6.0
version: 3.6.0
'@unocss/reset': '@unocss/reset':
specifier: ^0.61.9 specifier: ^0.61.9
version: 0.61.9 version: 0.61.9
...@@ -35,18 +32,24 @@ importers: ...@@ -35,18 +32,24 @@ importers:
dayjs: dayjs:
specifier: ^1.11.13 specifier: ^1.11.13
version: 1.11.13 version: 1.11.13
dompurify:
specifier: ^3.2.0
version: 3.2.0
github-markdown-css:
specifier: ^5.7.0
version: 5.7.0
highlight.js: highlight.js:
specifier: ^11.10.0 specifier: ^11.10.0
version: 11.10.0 version: 11.10.0
lodash-es: lodash-es:
specifier: ^4.17.21 specifier: ^4.17.21
version: 4.17.21 version: 4.17.21
markdown-it: marked:
specifier: ^14.1.0 specifier: ^15.0.0
version: 14.1.0 version: 15.0.0
markdown-it-link-attributes: marked-highlight:
specifier: ^4.0.1 specifier: ^2.2.1
version: 4.0.1 version: 2.2.1(marked@15.0.0)
mitt: mitt:
specifier: ^3.0.1 specifier: ^3.0.1
version: 3.0.1 version: 3.0.1
...@@ -90,12 +93,6 @@ importers: ...@@ -90,12 +93,6 @@ importers:
'@types/lodash-es': '@types/lodash-es':
specifier: ^4.17.12 specifier: ^4.17.12
version: 4.17.12 version: 4.17.12
'@types/markdown-it':
specifier: ^14.1.2
version: 14.1.2
'@types/markdown-it-link-attributes':
specifier: ^3.0.5
version: 3.0.5
'@types/node': '@types/node':
specifier: ^20.16.5 specifier: ^20.16.5
version: 20.16.5 version: 20.16.5
...@@ -993,9 +990,6 @@ packages: ...@@ -993,9 +990,6 @@ packages:
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@traptitech/markdown-it-katex@3.6.0':
resolution: {integrity: sha512-CnJzTWxsgLGXFdSrWRaGz7GZ1kUUi8g3E9HzJmeveX1YwVJavrKYqysktfHZQsujdnRqV5O7g8FPKEA/aeTkOQ==}
'@trysound/sax@0.2.0': '@trysound/sax@0.2.0':
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
...@@ -1009,24 +1003,12 @@ packages: ...@@ -1009,24 +1003,12 @@ packages:
'@types/katex@0.16.7': '@types/katex@0.16.7':
resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==}
'@types/linkify-it@5.0.0':
resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
'@types/lodash-es@4.17.12': '@types/lodash-es@4.17.12':
resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==}
'@types/lodash@4.17.7': '@types/lodash@4.17.7':
resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==} resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==}
'@types/markdown-it-link-attributes@3.0.5':
resolution: {integrity: sha512-VZ2BGN3ywUg7mBD8W6PwR8ChpOxaQSBDbLqPgvNI+uIra3zY2af1eG/3XzWTKjEraTWskMKnZqZd6m1fDF67Bg==}
'@types/markdown-it@14.1.2':
resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
'@types/mdurl@2.0.0':
resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
'@types/node@20.16.5': '@types/node@20.16.5':
resolution: {integrity: sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==} resolution: {integrity: sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==}
...@@ -1644,6 +1626,9 @@ packages: ...@@ -1644,6 +1626,9 @@ packages:
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
engines: {node: '>= 4'} engines: {node: '>= 4'}
dompurify@3.2.0:
resolution: {integrity: sha512-AMdOzK44oFWqHEi0wpOqix/fUNY707OmoeFDnbi3Q5I8uOpy21ufUA5cDJPr0bosxrflOVD/H2DMSvuGKJGfmQ==}
domutils@3.1.0: domutils@3.1.0:
resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==}
...@@ -1915,6 +1900,10 @@ packages: ...@@ -1915,6 +1900,10 @@ packages:
engines: {node: '>=16'} engines: {node: '>=16'}
hasBin: true hasBin: true
github-markdown-css@5.7.0:
resolution: {integrity: sha512-GoYhaqELL4YUjz4tZ00PQ4JzFQkMfrBVuEeRB8W74HoikHWNiaGqSgynpwJEc+xom5uf04qoD/tUSS6ziZltaQ==}
engines: {node: '>=10'}
glob-parent@5.1.2: glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
...@@ -2171,10 +2160,6 @@ packages: ...@@ -2171,10 +2160,6 @@ packages:
resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==}
engines: {'0': node >= 0.2.0} engines: {'0': node >= 0.2.0}
katex@0.16.11:
resolution: {integrity: sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==}
hasBin: true
keyv@4.5.4: keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
...@@ -2199,9 +2184,6 @@ packages: ...@@ -2199,9 +2184,6 @@ packages:
lines-and-columns@1.2.4: lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
linkify-it@5.0.0:
resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
lint-staged@15.2.10: lint-staged@15.2.10:
resolution: {integrity: sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==} resolution: {integrity: sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==}
engines: {node: '>=18.12.0'} engines: {node: '>=18.12.0'}
...@@ -2280,11 +2262,14 @@ packages: ...@@ -2280,11 +2262,14 @@ packages:
magic-string@0.30.12: magic-string@0.30.12:
resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==}
markdown-it-link-attributes@4.0.1: marked-highlight@2.2.1:
resolution: {integrity: sha512-pg5OK0jPLg62H4k7M9mRJLT61gUp9nvG0XveKYHMOOluASo9OEF13WlXrpAp2aj35LbedAy3QOCgQCw0tkLKAQ==} resolution: {integrity: sha512-SiCIeEiQbs9TxGwle9/OwbOejHCZsohQRaNTY2u8euEXYt2rYUFoiImUirThU3Gd/o6Q1gHGtH9qloHlbJpNIA==}
peerDependencies:
marked: '>=4 <16'
markdown-it@14.1.0: marked@15.0.0:
resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} resolution: {integrity: sha512-0mouKmBROJv/WSHJBPZZyYofUgawMChnD5je/g+aOBXsHDjb/IsnTQj7mnhQZu+qPJmRQ0ecX3mLGEUm3BgwYA==}
engines: {node: '>= 18'}
hasBin: true hasBin: true
mathml-tag-names@2.1.3: mathml-tag-names@2.1.3:
...@@ -2296,9 +2281,6 @@ packages: ...@@ -2296,9 +2281,6 @@ packages:
mdn-data@2.0.30: mdn-data@2.0.30:
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
mdurl@2.0.0:
resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
meow@12.1.1: meow@12.1.1:
resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==}
engines: {node: '>=16.10'} engines: {node: '>=16.10'}
...@@ -2623,10 +2605,6 @@ packages: ...@@ -2623,10 +2605,6 @@ packages:
proxy-from-env@1.1.0: proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
punycode.js@2.3.1:
resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
engines: {node: '>=6'}
punycode@2.3.1: punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'} engines: {node: '>=6'}
...@@ -2978,9 +2956,6 @@ packages: ...@@ -2978,9 +2956,6 @@ packages:
engines: {node: '>=14.17'} engines: {node: '>=14.17'}
hasBin: true hasBin: true
uc.micro@2.1.0:
resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==}
ufo@1.5.4: ufo@1.5.4:
resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==}
...@@ -3985,10 +3960,6 @@ snapshots: ...@@ -3985,10 +3960,6 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.21.3': '@rollup/rollup-win32-x64-msvc@4.21.3':
optional: true optional: true
'@traptitech/markdown-it-katex@3.6.0':
dependencies:
katex: 0.16.11
'@trysound/sax@0.2.0': {} '@trysound/sax@0.2.0': {}
'@types/conventional-commits-parser@5.0.0': '@types/conventional-commits-parser@5.0.0':
...@@ -3999,25 +3970,12 @@ snapshots: ...@@ -3999,25 +3970,12 @@ snapshots:
'@types/katex@0.16.7': {} '@types/katex@0.16.7': {}
'@types/linkify-it@5.0.0': {}
'@types/lodash-es@4.17.12': '@types/lodash-es@4.17.12':
dependencies: dependencies:
'@types/lodash': 4.17.7 '@types/lodash': 4.17.7
'@types/lodash@4.17.7': {} '@types/lodash@4.17.7': {}
'@types/markdown-it-link-attributes@3.0.5':
dependencies:
'@types/markdown-it': 14.1.2
'@types/markdown-it@14.1.2':
dependencies:
'@types/linkify-it': 5.0.0
'@types/mdurl': 2.0.0
'@types/mdurl@2.0.0': {}
'@types/node@20.16.5': '@types/node@20.16.5':
dependencies: dependencies:
undici-types: 6.19.8 undici-types: 6.19.8
...@@ -4801,6 +4759,8 @@ snapshots: ...@@ -4801,6 +4759,8 @@ snapshots:
dependencies: dependencies:
domelementtype: 2.3.0 domelementtype: 2.3.0
dompurify@3.2.0: {}
domutils@3.1.0: domutils@3.1.0:
dependencies: dependencies:
dom-serializer: 2.0.0 dom-serializer: 2.0.0
...@@ -5126,6 +5086,8 @@ snapshots: ...@@ -5126,6 +5086,8 @@ snapshots:
meow: 12.1.1 meow: 12.1.1
split2: 4.2.0 split2: 4.2.0
github-markdown-css@5.7.0: {}
glob-parent@5.1.2: glob-parent@5.1.2:
dependencies: dependencies:
is-glob: 4.0.3 is-glob: 4.0.3
...@@ -5332,10 +5294,6 @@ snapshots: ...@@ -5332,10 +5294,6 @@ snapshots:
jsonparse@1.3.1: {} jsonparse@1.3.1: {}
katex@0.16.11:
dependencies:
commander: 8.3.0
keyv@4.5.4: keyv@4.5.4:
dependencies: dependencies:
json-buffer: 3.0.1 json-buffer: 3.0.1
...@@ -5355,10 +5313,6 @@ snapshots: ...@@ -5355,10 +5313,6 @@ snapshots:
lines-and-columns@1.2.4: {} lines-and-columns@1.2.4: {}
linkify-it@5.0.0:
dependencies:
uc.micro: 2.1.0
lint-staged@15.2.10: lint-staged@15.2.10:
dependencies: dependencies:
chalk: 5.3.0 chalk: 5.3.0
...@@ -5444,16 +5398,11 @@ snapshots: ...@@ -5444,16 +5398,11 @@ snapshots:
dependencies: dependencies:
'@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/sourcemap-codec': 1.5.0
markdown-it-link-attributes@4.0.1: {} marked-highlight@2.2.1(marked@15.0.0):
markdown-it@14.1.0:
dependencies: dependencies:
argparse: 2.0.1 marked: 15.0.0
entities: 4.5.0
linkify-it: 5.0.0 marked@15.0.0: {}
mdurl: 2.0.0
punycode.js: 2.3.1
uc.micro: 2.1.0
mathml-tag-names@2.1.3: {} mathml-tag-names@2.1.3: {}
...@@ -5461,8 +5410,6 @@ snapshots: ...@@ -5461,8 +5410,6 @@ snapshots:
mdn-data@2.0.30: {} mdn-data@2.0.30: {}
mdurl@2.0.0: {}
meow@12.1.1: {} meow@12.1.1: {}
meow@13.2.0: {} meow@13.2.0: {}
...@@ -5710,8 +5657,6 @@ snapshots: ...@@ -5710,8 +5657,6 @@ snapshots:
proxy-from-env@1.1.0: {} proxy-from-env@1.1.0: {}
punycode.js@2.3.1: {}
punycode@2.3.1: {} punycode@2.3.1: {}
queue-microtask@1.2.3: {} queue-microtask@1.2.3: {}
...@@ -6075,8 +6020,6 @@ snapshots: ...@@ -6075,8 +6020,6 @@ snapshots:
typescript@5.6.2: {} typescript@5.6.2: {}
uc.micro@2.1.0: {}
ufo@1.5.4: {} ufo@1.5.4: {}
unconfig@0.5.5: unconfig@0.5.5:
......
<script setup lang="ts"> <script setup lang="ts">
import { computed, onMounted, onUnmounted, onUpdated, ref } from 'vue' import { computed, ref, watchEffect } from 'vue'
import MarkdownIt from 'markdown-it' import { marked } from 'marked'
import mdKatex from '@traptitech/markdown-it-katex' import { markedHighlight } from 'marked-highlight'
import mila from 'markdown-it-link-attributes' import { throttle } from 'lodash-es'
import DOMPurify from 'dompurify'
import hljs from 'highlight.js' import hljs from 'highlight.js'
import { useClipboard } from '@vueuse/core' import 'highlight.js/styles/panda-syntax-light.css'
import 'github-markdown-css'
interface Props { interface Props {
rawTextContent: string rawTextContent: string
...@@ -18,106 +20,51 @@ const props = withDefaults(defineProps<Props>(), { ...@@ -18,106 +20,51 @@ const props = withDefaults(defineProps<Props>(), {
color: '#333', color: '#333',
}) })
const mkrContainer = ref() marked.use({ gfm: true, async: true }).use(
const copyCodeText = ref('') markedHighlight({
emptyLangClass: 'hljs',
langPrefix: 'hljs language-',
highlight(code, lang, _info) {
const language = hljs.getLanguage(lang) ? lang : 'plaintext'
const { copy: copyTool } = useClipboard({ source: copyCodeText }) return hljs.highlight(code, { language }).value
const mdi = new MarkdownIt({
html: true,
linkify: true,
highlight(code: any, language: any) {
const validLang = !!(language && hljs.getLanguage(language))
if (validLang) {
const lang = language ?? ''
return highlightBlock(hljs.highlight(code, { language: lang }).value, lang)
}
return highlightBlock(hljs.highlightAuto(code).value, '')
}, },
}) }),
)
mdi.use(mila, { attrs: { target: '_blank', rel: 'noopener' } })
mdi.use(mdKatex, { blockClass: 'katexmath-block rounded-md p-[10px]', errorColor: ' #cc0000' })
const renderTextContent = computed(() => {
if (props.rawTextContent) {
const urlRegex = /((https?:\/\/[^\s]+))/g
const rawTextContent = props.rawTextContent.replace(urlRegex, '($1)')
return mdi.render(rawTextContent)
}
return '' const renderTextContent = ref('')
})
const wrapStyle = computed(() => { const articleContainerStyle = computed(() => {
return { return {
fontSize: props.fontSize, fontSize: props.fontSize,
color: props.color, color: props.color,
} }
}) })
function highlightBlock(str: string, lang?: string) { const textContentParser = throttle(
return ( (text: string) => {
'<pre class="code-block-wrapper">' + ;(marked.parse(text) as Promise<string>).then((res) => {
'<div class="code-block-header">' + renderTextContent.value = DOMPurify.sanitize(res)
`<span class="code-block-header__lang">${lang}</span>` +
'<span class="code-block-header__copy">复制代码</span>' +
'</div>' +
`<code class="hljs code-block-body ${lang}">${str}</code>` +
'</pre>'
)
}
function addCopyEvents() {
if (mkrContainer.value) {
const copyBtn = mkrContainer.value.querySelectorAll('.code-block-header__copy')
copyBtn.forEach((btn: HTMLSpanElement) => {
btn.addEventListener('click', () => {
const code = btn.parentElement?.nextElementSibling?.textContent
if (code) {
copyTool(code).then(() => {
btn.textContent = '复制成功'
setTimeout(() => (btn.textContent = '复制代码'), 1000)
})
}
}) })
}) },
} 500,
} { leading: true, trailing: true },
)
function removeCopyEvents() {
if (mkrContainer.value) {
const copyBtn = mkrContainer.value.querySelectorAll('.code-block-header__copy')
copyBtn.forEach((btn: HTMLSpanElement) => {
btn.removeEventListener('click', () => {})
})
}
}
onMounted(() => {
addCopyEvents()
})
onUpdated(() => {
addCopyEvents()
})
onUnmounted(() => { watchEffect(() => {
removeCopyEvents() textContentParser(props.rawTextContent)
}) })
</script> </script>
<template> <template>
<div ref="mkrContainer" class="markdown-render-container"> <div class="markdown-render-container">
<article class="markdown-body" :style="wrapStyle" v-html="renderTextContent" /> <article class="markdown-body article-container" :style="articleContainerStyle" v-html="renderTextContent" />
</div> </div>
</template> </template>
<style lang="scss"> <style lang="scss" scoped>
@import './style/highlight.scss'; .article-container {
@import './style/github-markdown.scss'; letter-spacing: 0.1ch;
@import './style/custom-style.scss'; background-color: unset;
}
</style> </style>
.markdown-body {
background-color: transparent;
font-size: 14px;
p {
white-space: pre-wrap;
}
ol {
list-style-type: decimal;
}
ul {
list-style-type: disc;
}
pre code,
pre tt {
line-height: 1.65;
}
.highlight pre,
pre {
background-color: #f4fafd;
}
code.hljs {
padding: 0;
}
.code-block {
&-wrapper {
position: relative;
padding-top: 24px;
}
&-header {
position: absolute;
top: 5px;
right: 0;
width: 100%;
padding: 0 1rem;
display: flex;
justify-content: flex-end;
align-items: center;
color: #b3b3b3;
&__copy {
cursor: pointer;
margin-left: 0.5rem;
user-select: none;
&:hover {
color: #65a665;
}
}
}
}
}
html.dark {
.message-reply {
.whitespace-pre-wrap {
white-space: pre-wrap;
word-break: break-all;
color: var(--n-text-color);
}
}
.highlight pre,
pre {
background-color: #282c34;
}
}
@media (prefers-color-scheme: dark) {
.markdown-body,
[data-theme='dark'] {
/*dark*/
color-scheme: dark;
--color-prettylights-syntax-comment: #8b949e;
--color-prettylights-syntax-constant: #79c0ff;
--color-prettylights-syntax-entity: #d2a8ff;
--color-prettylights-syntax-storage-modifier-import: #c9d1d9;
--color-prettylights-syntax-entity-tag: #7ee787;
--color-prettylights-syntax-keyword: #ff7b72;
--color-prettylights-syntax-string: #a5d6ff;
--color-prettylights-syntax-variable: #ffa657;
--color-prettylights-syntax-brackethighlighter-unmatched: #f85149;
--color-prettylights-syntax-invalid-illegal-text: #f0f6fc;
--color-prettylights-syntax-invalid-illegal-bg: #8e1519;
--color-prettylights-syntax-carriage-return-text: #f0f6fc;
--color-prettylights-syntax-carriage-return-bg: #b62324;
--color-prettylights-syntax-string-regexp: #7ee787;
--color-prettylights-syntax-markup-list: #f2cc60;
--color-prettylights-syntax-markup-heading: #1f6feb;
--color-prettylights-syntax-markup-italic: #c9d1d9;
--color-prettylights-syntax-markup-bold: #c9d1d9;
--color-prettylights-syntax-markup-deleted-text: #ffdcd7;
--color-prettylights-syntax-markup-deleted-bg: #67060c;
--color-prettylights-syntax-markup-inserted-text: #aff5b4;
--color-prettylights-syntax-markup-inserted-bg: #033a16;
--color-prettylights-syntax-markup-changed-text: #ffdfb6;
--color-prettylights-syntax-markup-changed-bg: #5a1e02;
--color-prettylights-syntax-markup-ignored-text: #c9d1d9;
--color-prettylights-syntax-markup-ignored-bg: #1158c7;
--color-prettylights-syntax-meta-diff-range: #d2a8ff;
--color-prettylights-syntax-brackethighlighter-angle: #8b949e;
--color-prettylights-syntax-sublimelinter-gutter-mark: #484f58;
--color-prettylights-syntax-constant-other-reference-link: #a5d6ff;
--color-fg-default: #e6edf3;
--color-fg-muted: #7d8590;
--color-fg-subtle: #6e7681;
--color-canvas-default: #0d1117;
--color-canvas-subtle: #161b22;
--color-border-default: #30363d;
--color-border-muted: #21262d;
--color-neutral-muted: rgba(110, 118, 129, 0.4);
--color-accent-fg: #2f81f7;
--color-accent-emphasis: #1f6feb;
--color-attention-subtle: rgba(187, 128, 9, 0.15);
--color-danger-fg: #f85149;
}
}
@media (prefers-color-scheme: light) {
.markdown-body,
[data-theme='light'] {
/*light*/
color-scheme: light;
--color-prettylights-syntax-comment: #6e7781;
--color-prettylights-syntax-constant: #0550ae;
--color-prettylights-syntax-entity: #6639ba;
--color-prettylights-syntax-storage-modifier-import: #24292f;
--color-prettylights-syntax-entity-tag: #116329;
--color-prettylights-syntax-keyword: #cf222e;
--color-prettylights-syntax-string: #0a3069;
--color-prettylights-syntax-variable: #953800;
--color-prettylights-syntax-brackethighlighter-unmatched: #82071e;
--color-prettylights-syntax-invalid-illegal-text: #f6f8fa;
--color-prettylights-syntax-invalid-illegal-bg: #82071e;
--color-prettylights-syntax-carriage-return-text: #f6f8fa;
--color-prettylights-syntax-carriage-return-bg: #cf222e;
--color-prettylights-syntax-string-regexp: #116329;
--color-prettylights-syntax-markup-list: #3b2300;
--color-prettylights-syntax-markup-heading: #0550ae;
--color-prettylights-syntax-markup-italic: #24292f;
--color-prettylights-syntax-markup-bold: #24292f;
--color-prettylights-syntax-markup-deleted-text: #82071e;
--color-prettylights-syntax-markup-deleted-bg: #ffebe9;
--color-prettylights-syntax-markup-inserted-text: #116329;
--color-prettylights-syntax-markup-inserted-bg: #dafbe1;
--color-prettylights-syntax-markup-changed-text: #953800;
--color-prettylights-syntax-markup-changed-bg: #ffd8b5;
--color-prettylights-syntax-markup-ignored-text: #eaeef2;
--color-prettylights-syntax-markup-ignored-bg: #0550ae;
--color-prettylights-syntax-meta-diff-range: #8250df;
--color-prettylights-syntax-brackethighlighter-angle: #57606a;
--color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f;
--color-prettylights-syntax-constant-other-reference-link: #0a3069;
--color-fg-default: #1f2328;
--color-fg-muted: #656d76;
--color-fg-subtle: #6e7781;
--color-canvas-default: #ffffff;
--color-canvas-subtle: #f6f8fa;
--color-border-default: #d0d7de;
--color-border-muted: hsla(210, 18%, 87%, 1);
--color-neutral-muted: rgba(175, 184, 193, 0.2);
--color-accent-fg: #0969da;
--color-accent-emphasis: #0969da;
--color-attention-subtle: #fff8c5;
--color-danger-fg: #d1242f;
--color-prettylights-syntax-comment: #6e7781;
--color-prettylights-syntax-constant: #0550ae;
--color-prettylights-syntax-entity: #6639ba;
--color-prettylights-syntax-storage-modifier-import: #24292f;
--color-prettylights-syntax-entity-tag: #116329;
--color-prettylights-syntax-keyword: #cf222e;
--color-prettylights-syntax-string: #0a3069;
--color-prettylights-syntax-variable: #953800;
--color-prettylights-syntax-brackethighlighter-unmatched: #82071e;
--color-prettylights-syntax-invalid-illegal-text: #f6f8fa;
--color-prettylights-syntax-invalid-illegal-bg: #82071e;
--color-prettylights-syntax-carriage-return-text: #f6f8fa;
--color-prettylights-syntax-carriage-return-bg: #cf222e;
--color-prettylights-syntax-string-regexp: #116329;
--color-prettylights-syntax-markup-list: #3b2300;
--color-prettylights-syntax-markup-heading: #0550ae;
--color-prettylights-syntax-markup-italic: #24292f;
--color-prettylights-syntax-markup-bold: #24292f;
--color-prettylights-syntax-markup-deleted-text: #82071e;
--color-prettylights-syntax-markup-deleted-bg: #ffebe9;
--color-prettylights-syntax-markup-inserted-text: #116329;
--color-prettylights-syntax-markup-inserted-bg: #dafbe1;
--color-prettylights-syntax-markup-changed-text: #953800;
--color-prettylights-syntax-markup-changed-bg: #ffd8b5;
--color-prettylights-syntax-markup-ignored-text: #eaeef2;
--color-prettylights-syntax-markup-ignored-bg: #0550ae;
--color-prettylights-syntax-meta-diff-range: #8250df;
--color-prettylights-syntax-brackethighlighter-angle: #57606a;
--color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f;
--color-prettylights-syntax-constant-other-reference-link: #0a3069;
--color-fg-default: #1f2328;
--color-fg-muted: #656d76;
--color-fg-subtle: #6e7781;
--color-canvas-default: #ffffff;
--color-canvas-subtle: #f6f8fa;
--color-border-default: #d0d7de;
--color-border-muted: hsla(210, 18%, 87%, 1);
--color-neutral-muted: rgba(175, 184, 193, 0.2);
--color-accent-fg: #0969da;
--color-accent-emphasis: #0969da;
--color-attention-subtle: #fff8c5;
--color-danger-fg: #d1242f;
}
}
.markdown-body {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
margin: 0;
color: var(--color-fg-default);
background-color: var(--color-canvas-default);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji';
font-size: 16px;
line-height: 1.5;
word-wrap: break-word;
}
.markdown-body .octicon {
display: inline-block;
fill: currentColor;
vertical-align: text-bottom;
}
.markdown-body h1:hover .anchor .octicon-link:before,
.markdown-body h2:hover .anchor .octicon-link:before,
.markdown-body h3:hover .anchor .octicon-link:before,
.markdown-body h4:hover .anchor .octicon-link:before,
.markdown-body h5:hover .anchor .octicon-link:before,
.markdown-body h6:hover .anchor .octicon-link:before {
width: 16px;
height: 16px;
content: ' ';
display: inline-block;
background-color: currentColor;
-webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>");
mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>");
}
.markdown-body details,
.markdown-body figcaption,
.markdown-body figure {
display: block;
}
.markdown-body summary {
display: list-item;
}
.markdown-body [hidden] {
display: none !important;
}
.markdown-body a {
background-color: transparent;
color: var(--color-accent-fg);
text-decoration: none;
}
.markdown-body abbr[title] {
border-bottom: none;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
}
.markdown-body b,
.markdown-body strong {
font-weight: var(--base-text-weight-semibold, 600);
}
.markdown-body dfn {
font-style: italic;
}
.markdown-body h1 {
margin: 0.67em 0;
font-weight: var(--base-text-weight-semibold, 600);
padding-bottom: 0.3em;
font-size: 2em;
border-bottom: 1px solid var(--color-border-muted);
}
.markdown-body mark {
background-color: var(--color-attention-subtle);
color: var(--color-fg-default);
}
.markdown-body small {
font-size: 90%;
}
.markdown-body sub,
.markdown-body sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
.markdown-body sub {
bottom: -0.25em;
}
.markdown-body sup {
top: -0.5em;
}
.markdown-body img {
border-style: none;
max-width: 100%;
box-sizing: content-box;
background-color: var(--color-canvas-default);
}
.markdown-body code,
.markdown-body kbd,
.markdown-body pre,
.markdown-body samp {
font-family: monospace;
font-size: 1em;
}
.markdown-body figure {
margin: 1em 40px;
}
.markdown-body hr {
box-sizing: content-box;
overflow: hidden;
background: transparent;
border-bottom: 1px solid var(--color-border-muted);
height: 0.25em;
padding: 0;
margin: 24px 0;
background-color: var(--color-border-default);
border: 0;
}
.markdown-body input {
font: inherit;
margin: 0;
overflow: visible;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
.markdown-body [type='button'],
.markdown-body [type='reset'],
.markdown-body [type='submit'] {
-webkit-appearance: button;
}
.markdown-body [type='checkbox'],
.markdown-body [type='radio'] {
box-sizing: border-box;
padding: 0;
}
.markdown-body [type='number']::-webkit-inner-spin-button,
.markdown-body [type='number']::-webkit-outer-spin-button {
height: auto;
}
.markdown-body [type='search']::-webkit-search-cancel-button,
.markdown-body [type='search']::-webkit-search-decoration {
-webkit-appearance: none;
}
.markdown-body ::-webkit-input-placeholder {
color: inherit;
opacity: 0.54;
}
.markdown-body ::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit;
}
.markdown-body a:hover {
text-decoration: underline;
}
.markdown-body ::placeholder {
color: var(--color-fg-subtle);
opacity: 1;
}
.markdown-body hr::before {
display: table;
content: '';
}
.markdown-body hr::after {
display: table;
clear: both;
content: '';
}
.markdown-body table {
border-spacing: 0;
border-collapse: collapse;
display: block;
width: max-content;
max-width: 100%;
overflow: auto;
}
.markdown-body td,
.markdown-body th {
padding: 0;
}
.markdown-body details summary {
cursor: pointer;
}
.markdown-body details:not([open]) > *:not(summary) {
display: none !important;
}
.markdown-body a:focus,
.markdown-body [role='button']:focus,
.markdown-body input[type='radio']:focus,
.markdown-body input[type='checkbox']:focus {
outline: 2px solid var(--color-accent-fg);
outline-offset: -2px;
box-shadow: none;
}
.markdown-body a:focus:not(:focus-visible),
.markdown-body [role='button']:focus:not(:focus-visible),
.markdown-body input[type='radio']:focus:not(:focus-visible),
.markdown-body input[type='checkbox']:focus:not(:focus-visible) {
outline: solid 1px transparent;
}
.markdown-body a:focus-visible,
.markdown-body [role='button']:focus-visible,
.markdown-body input[type='radio']:focus-visible,
.markdown-body input[type='checkbox']:focus-visible {
outline: 2px solid var(--color-accent-fg);
outline-offset: -2px;
box-shadow: none;
}
.markdown-body a:not([class]):focus,
.markdown-body a:not([class]):focus-visible,
.markdown-body input[type='radio']:focus,
.markdown-body input[type='radio']:focus-visible,
.markdown-body input[type='checkbox']:focus,
.markdown-body input[type='checkbox']:focus-visible {
outline-offset: 0;
}
.markdown-body kbd {
display: inline-block;
padding: 3px 5px;
font:
11px ui-monospace,
SFMono-Regular,
SF Mono,
Menlo,
Consolas,
Liberation Mono,
monospace;
line-height: 10px;
color: var(--color-fg-default);
vertical-align: middle;
background-color: var(--color-canvas-subtle);
border: solid 1px var(--color-neutral-muted);
border-bottom-color: var(--color-neutral-muted);
border-radius: 6px;
box-shadow: inset 0 -1px 0 var(--color-neutral-muted);
}
.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
margin-top: 24px;
margin-bottom: 16px;
font-weight: var(--base-text-weight-semibold, 600);
line-height: 1.25;
}
.markdown-body h2 {
font-weight: var(--base-text-weight-semibold, 600);
padding-bottom: 0.3em;
font-size: 1.5em;
border-bottom: 1px solid var(--color-border-muted);
}
.markdown-body h3 {
font-weight: var(--base-text-weight-semibold, 600);
font-size: 1.25em;
}
.markdown-body h4 {
font-weight: var(--base-text-weight-semibold, 600);
font-size: 1em;
}
.markdown-body h5 {
font-weight: var(--base-text-weight-semibold, 600);
font-size: 0.875em;
}
.markdown-body h6 {
font-weight: var(--base-text-weight-semibold, 600);
font-size: 0.85em;
color: var(--color-fg-muted);
}
.markdown-body p {
margin-top: 0;
margin-bottom: 10px;
}
.markdown-body blockquote {
margin: 0;
padding: 0 1em;
color: var(--color-fg-muted);
border-left: 0.25em solid var(--color-border-default);
}
.markdown-body ul,
.markdown-body ol {
margin-top: 0;
margin-bottom: 0;
padding-left: 2em;
}
.markdown-body ol ol,
.markdown-body ul ol {
list-style-type: lower-roman;
}
.markdown-body ul ul ol,
.markdown-body ul ol ol,
.markdown-body ol ul ol,
.markdown-body ol ol ol {
list-style-type: lower-alpha;
}
.markdown-body dd {
margin-left: 0;
}
.markdown-body tt,
.markdown-body code,
.markdown-body samp {
font-family:
ui-monospace,
SFMono-Regular,
SF Mono,
Menlo,
Consolas,
Liberation Mono,
monospace;
font-size: 12px;
}
.markdown-body pre {
margin-top: 0;
margin-bottom: 0;
font-family:
ui-monospace,
SFMono-Regular,
SF Mono,
Menlo,
Consolas,
Liberation Mono,
monospace;
font-size: 12px;
word-wrap: normal;
}
.markdown-body .octicon {
display: inline-block;
overflow: visible !important;
vertical-align: text-bottom;
fill: currentColor;
}
.markdown-body input::-webkit-outer-spin-button,
.markdown-body input::-webkit-inner-spin-button {
margin: 0;
-webkit-appearance: none;
appearance: none;
}
.markdown-body::before {
display: table;
content: '';
}
.markdown-body::after {
display: table;
clear: both;
content: '';
}
.markdown-body > *:first-child {
margin-top: 0 !important;
}
.markdown-body > *:last-child {
margin-bottom: 0 !important;
}
.markdown-body a:not([href]) {
color: inherit;
text-decoration: none;
}
.markdown-body .absent {
color: var(--color-danger-fg);
}
.markdown-body .anchor {
float: left;
padding-right: 4px;
margin-left: -20px;
line-height: 1;
}
.markdown-body .anchor:focus {
outline: none;
}
.markdown-body p,
.markdown-body blockquote,
.markdown-body ul,
.markdown-body ol,
.markdown-body dl,
.markdown-body table,
.markdown-body pre,
.markdown-body details {
margin-top: 0;
margin-bottom: 16px;
}
.markdown-body blockquote > :first-child {
margin-top: 0;
}
.markdown-body blockquote > :last-child {
margin-bottom: 0;
}
.markdown-body h1 .octicon-link,
.markdown-body h2 .octicon-link,
.markdown-body h3 .octicon-link,
.markdown-body h4 .octicon-link,
.markdown-body h5 .octicon-link,
.markdown-body h6 .octicon-link {
color: var(--color-fg-default);
vertical-align: middle;
visibility: hidden;
}
.markdown-body h1:hover .anchor,
.markdown-body h2:hover .anchor,
.markdown-body h3:hover .anchor,
.markdown-body h4:hover .anchor,
.markdown-body h5:hover .anchor,
.markdown-body h6:hover .anchor {
text-decoration: none;
}
.markdown-body h1:hover .anchor .octicon-link,
.markdown-body h2:hover .anchor .octicon-link,
.markdown-body h3:hover .anchor .octicon-link,
.markdown-body h4:hover .anchor .octicon-link,
.markdown-body h5:hover .anchor .octicon-link,
.markdown-body h6:hover .anchor .octicon-link {
visibility: visible;
}
.markdown-body h1 tt,
.markdown-body h1 code,
.markdown-body h2 tt,
.markdown-body h2 code,
.markdown-body h3 tt,
.markdown-body h3 code,
.markdown-body h4 tt,
.markdown-body h4 code,
.markdown-body h5 tt,
.markdown-body h5 code,
.markdown-body h6 tt,
.markdown-body h6 code {
padding: 0 0.2em;
font-size: inherit;
}
.markdown-body summary h1,
.markdown-body summary h2,
.markdown-body summary h3,
.markdown-body summary h4,
.markdown-body summary h5,
.markdown-body summary h6 {
display: inline-block;
}
.markdown-body summary h1 .anchor,
.markdown-body summary h2 .anchor,
.markdown-body summary h3 .anchor,
.markdown-body summary h4 .anchor,
.markdown-body summary h5 .anchor,
.markdown-body summary h6 .anchor {
margin-left: -40px;
}
.markdown-body summary h1,
.markdown-body summary h2 {
padding-bottom: 0;
border-bottom: 0;
}
.markdown-body ul.no-list,
.markdown-body ol.no-list {
padding: 0;
list-style-type: none;
}
.markdown-body ol[type='a s'] {
list-style-type: lower-alpha;
}
.markdown-body ol[type='A s'] {
list-style-type: upper-alpha;
}
.markdown-body ol[type='i s'] {
list-style-type: lower-roman;
}
.markdown-body ol[type='I s'] {
list-style-type: upper-roman;
}
.markdown-body ol[type='1'] {
list-style-type: decimal;
}
.markdown-body div > ol:not([type]) {
list-style-type: decimal;
}
.markdown-body ul ul,
.markdown-body ul ol,
.markdown-body ol ol,
.markdown-body ol ul {
margin-top: 0;
margin-bottom: 0;
}
.markdown-body li > p {
margin-top: 16px;
}
.markdown-body li + li {
margin-top: 0.25em;
}
.markdown-body dl {
padding: 0;
}
.markdown-body dl dt {
padding: 0;
margin-top: 16px;
font-size: 1em;
font-style: italic;
font-weight: var(--base-text-weight-semibold, 600);
}
.markdown-body dl dd {
padding: 0 16px;
margin-bottom: 16px;
}
.markdown-body table th {
font-weight: var(--base-text-weight-semibold, 600);
}
.markdown-body table th,
.markdown-body table td {
padding: 6px 13px;
border: 1px solid var(--color-border-default);
}
.markdown-body table td > :last-child {
margin-bottom: 0;
}
.markdown-body table tr {
background-color: var(--color-canvas-default);
border-top: 1px solid var(--color-border-muted);
}
.markdown-body table tr:nth-child(2n) {
background-color: var(--color-canvas-subtle);
}
.markdown-body table img {
background-color: transparent;
}
.markdown-body img[align='right'] {
padding-left: 20px;
}
.markdown-body img[align='left'] {
padding-right: 20px;
}
.markdown-body .emoji {
max-width: none;
vertical-align: text-top;
background-color: transparent;
}
.markdown-body span.frame {
display: block;
overflow: hidden;
}
.markdown-body span.frame > span {
display: block;
float: left;
width: auto;
padding: 7px;
margin: 13px 0 0;
overflow: hidden;
border: 1px solid var(--color-border-default);
}
.markdown-body span.frame span img {
display: block;
float: left;
}
.markdown-body span.frame span span {
display: block;
padding: 5px 0 0;
clear: both;
color: var(--color-fg-default);
}
.markdown-body span.align-center {
display: block;
overflow: hidden;
clear: both;
}
.markdown-body span.align-center > span {
display: block;
margin: 13px auto 0;
overflow: hidden;
text-align: center;
}
.markdown-body span.align-center span img {
margin: 0 auto;
text-align: center;
}
.markdown-body span.align-right {
display: block;
overflow: hidden;
clear: both;
}
.markdown-body span.align-right > span {
display: block;
margin: 13px 0 0;
overflow: hidden;
text-align: right;
}
.markdown-body span.align-right span img {
margin: 0;
text-align: right;
}
.markdown-body span.float-left {
display: block;
float: left;
margin-right: 13px;
overflow: hidden;
}
.markdown-body span.float-left span {
margin: 13px 0 0;
}
.markdown-body span.float-right {
display: block;
float: right;
margin-left: 13px;
overflow: hidden;
}
.markdown-body span.float-right > span {
display: block;
margin: 13px auto 0;
overflow: hidden;
text-align: right;
}
.markdown-body code,
.markdown-body tt {
padding: 0.2em 0.4em;
margin: 0;
font-size: 85%;
white-space: break-spaces;
background-color: var(--color-neutral-muted);
border-radius: 6px;
}
.markdown-body code br,
.markdown-body tt br {
display: none;
}
.markdown-body del code {
text-decoration: inherit;
}
.markdown-body samp {
font-size: 85%;
}
.markdown-body pre code {
font-size: 100%;
}
.markdown-body pre > code {
padding: 0;
margin: 0;
word-break: normal;
white-space: pre;
background: transparent;
border: 0;
}
.markdown-body .highlight {
margin-bottom: 16px;
}
.markdown-body .highlight pre {
margin-bottom: 0;
word-break: normal;
}
.markdown-body .highlight pre,
.markdown-body pre {
padding: 16px;
overflow: auto;
font-size: 85%;
line-height: 1.45;
color: var(--color-fg-default);
background-color: var(--color-canvas-subtle);
border-radius: 6px;
}
.markdown-body pre code,
.markdown-body pre tt {
display: inline;
max-width: auto;
padding: 0;
margin: 0;
overflow: visible;
line-height: inherit;
word-wrap: normal;
background-color: transparent;
border: 0;
}
.markdown-body .csv-data td,
.markdown-body .csv-data th {
padding: 5px;
overflow: hidden;
font-size: 12px;
line-height: 1;
text-align: left;
white-space: nowrap;
}
.markdown-body .csv-data .blob-num {
padding: 10px 8px 9px;
text-align: right;
background: var(--color-canvas-default);
border: 0;
}
.markdown-body .csv-data tr {
border-top: 0;
}
.markdown-body .csv-data th {
font-weight: var(--base-text-weight-semibold, 600);
background: var(--color-canvas-subtle);
border-top: 0;
}
.markdown-body [data-footnote-ref]::before {
content: '[';
}
.markdown-body [data-footnote-ref]::after {
content: ']';
}
.markdown-body .footnotes {
font-size: 12px;
color: var(--color-fg-muted);
border-top: 1px solid var(--color-border-default);
}
.markdown-body .footnotes ol {
padding-left: 16px;
}
.markdown-body .footnotes ol ul {
display: inline-block;
padding-left: 16px;
margin-top: 16px;
}
.markdown-body .footnotes li {
position: relative;
}
.markdown-body .footnotes li:target::before {
position: absolute;
top: -8px;
right: -8px;
bottom: -8px;
left: -24px;
pointer-events: none;
content: '';
border: 2px solid var(--color-accent-emphasis);
border-radius: 6px;
}
.markdown-body .footnotes li:target {
color: var(--color-fg-default);
}
.markdown-body .footnotes .data-footnote-backref g-emoji {
font-family: monospace;
}
.markdown-body .pl-c {
color: var(--color-prettylights-syntax-comment);
}
.markdown-body .pl-c1,
.markdown-body .pl-s .pl-v {
color: var(--color-prettylights-syntax-constant);
}
.markdown-body .pl-e,
.markdown-body .pl-en {
color: var(--color-prettylights-syntax-entity);
}
.markdown-body .pl-smi,
.markdown-body .pl-s .pl-s1 {
color: var(--color-prettylights-syntax-storage-modifier-import);
}
.markdown-body .pl-ent {
color: var(--color-prettylights-syntax-entity-tag);
}
.markdown-body .pl-k {
color: var(--color-prettylights-syntax-keyword);
}
.markdown-body .pl-s,
.markdown-body .pl-pds,
.markdown-body .pl-s .pl-pse .pl-s1,
.markdown-body .pl-sr,
.markdown-body .pl-sr .pl-cce,
.markdown-body .pl-sr .pl-sre,
.markdown-body .pl-sr .pl-sra {
color: var(--color-prettylights-syntax-string);
}
.markdown-body .pl-v,
.markdown-body .pl-smw {
color: var(--color-prettylights-syntax-variable);
}
.markdown-body .pl-bu {
color: var(--color-prettylights-syntax-brackethighlighter-unmatched);
}
.markdown-body .pl-ii {
color: var(--color-prettylights-syntax-invalid-illegal-text);
background-color: var(--color-prettylights-syntax-invalid-illegal-bg);
}
.markdown-body .pl-c2 {
color: var(--color-prettylights-syntax-carriage-return-text);
background-color: var(--color-prettylights-syntax-carriage-return-bg);
}
.markdown-body .pl-sr .pl-cce {
font-weight: bold;
color: var(--color-prettylights-syntax-string-regexp);
}
.markdown-body .pl-ml {
color: var(--color-prettylights-syntax-markup-list);
}
.markdown-body .pl-mh,
.markdown-body .pl-mh .pl-en,
.markdown-body .pl-ms {
font-weight: bold;
color: var(--color-prettylights-syntax-markup-heading);
}
.markdown-body .pl-mi {
font-style: italic;
color: var(--color-prettylights-syntax-markup-italic);
}
.markdown-body .pl-mb {
font-weight: bold;
color: var(--color-prettylights-syntax-markup-bold);
}
.markdown-body .pl-md {
color: var(--color-prettylights-syntax-markup-deleted-text);
background-color: var(--color-prettylights-syntax-markup-deleted-bg);
}
.markdown-body .pl-mi1 {
color: var(--color-prettylights-syntax-markup-inserted-text);
background-color: var(--color-prettylights-syntax-markup-inserted-bg);
}
.markdown-body .pl-mc {
color: var(--color-prettylights-syntax-markup-changed-text);
background-color: var(--color-prettylights-syntax-markup-changed-bg);
}
.markdown-body .pl-mi2 {
color: var(--color-prettylights-syntax-markup-ignored-text);
background-color: var(--color-prettylights-syntax-markup-ignored-bg);
}
.markdown-body .pl-mdr {
font-weight: bold;
color: var(--color-prettylights-syntax-meta-diff-range);
}
.markdown-body .pl-ba {
color: var(--color-prettylights-syntax-brackethighlighter-angle);
}
.markdown-body .pl-sg {
color: var(--color-prettylights-syntax-sublimelinter-gutter-mark);
}
.markdown-body .pl-corl {
text-decoration: underline;
color: var(--color-prettylights-syntax-constant-other-reference-link);
}
.markdown-body g-emoji {
display: inline-block;
min-width: 1ch;
font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
font-size: 1em;
font-style: normal !important;
font-weight: var(--base-text-weight-normal, 400);
line-height: 1;
vertical-align: -0.075em;
}
.markdown-body g-emoji img {
width: 1em;
height: 1em;
}
.markdown-body .task-list-item {
list-style-type: none;
}
.markdown-body .task-list-item label {
font-weight: var(--base-text-weight-normal, 400);
}
.markdown-body .task-list-item.enabled label {
cursor: pointer;
}
.markdown-body .task-list-item + .task-list-item {
margin-top: 4px;
}
.markdown-body .task-list-item .handle {
display: none;
}
.markdown-body .task-list-item-checkbox {
margin: 0 0.2em 0.25em -1.4em;
vertical-align: middle;
}
.markdown-body .contains-task-list:dir(rtl) .task-list-item-checkbox {
margin: 0 -1.6em 0.25em 0.2em;
}
.markdown-body .contains-task-list {
position: relative;
}
.markdown-body .contains-task-list:hover .task-list-item-convert-container,
.markdown-body .contains-task-list:focus-within .task-list-item-convert-container {
display: block;
width: auto;
height: 24px;
overflow: visible;
clip: auto;
}
.markdown-body ::-webkit-calendar-picker-indicator {
filter: invert(50%);
}
html.dark {
pre code.hljs {
display: block;
overflow-x: auto;
padding: 1em;
}
code.hljs {
padding: 3px 5px;
}
.hljs {
color: #abb2bf;
background: #282c34;
}
.hljs-keyword,
.hljs-operator,
.hljs-pattern-match {
color: #f92672;
}
.hljs-function,
.hljs-pattern-match .hljs-constructor {
color: #61aeee;
}
.hljs-function .hljs-params {
color: #a6e22e;
}
.hljs-function .hljs-params .hljs-typing {
color: #fd971f;
}
.hljs-module-access .hljs-module {
color: #7e57c2;
}
.hljs-constructor {
color: #e2b93d;
}
.hljs-constructor .hljs-string {
color: #9ccc65;
}
.hljs-comment,
.hljs-quote {
color: #b18eb1;
font-style: italic;
}
.hljs-doctag,
.hljs-formula {
color: #c678dd;
}
.hljs-deletion,
.hljs-name,
.hljs-section,
.hljs-selector-tag,
.hljs-subst {
color: #e06c75;
}
.hljs-literal {
color: #56b6c2;
}
.hljs-addition,
.hljs-attribute,
.hljs-meta .hljs-string,
.hljs-regexp,
.hljs-string {
color: #98c379;
}
.hljs-built_in,
.hljs-class .hljs-title,
.hljs-title.class_ {
color: #e6c07b;
}
.hljs-attr,
.hljs-number,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-pseudo,
.hljs-template-variable,
.hljs-type,
.hljs-variable {
color: #d19a66;
}
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-symbol,
.hljs-title {
color: #61aeee;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: 700;
}
.hljs-link {
text-decoration: underline;
}
}
html {
pre code.hljs {
display: block;
overflow-x: auto;
padding: 1em;
}
code.hljs {
padding: 3px 5px;
&::-webkit-scrollbar {
height: 4px;
}
}
.hljs {
color: #383a42;
background: #fafafa;
}
.hljs-comment,
.hljs-quote {
color: #a0a1a7;
font-style: italic;
}
.hljs-doctag,
.hljs-formula,
.hljs-keyword {
color: #a626a4;
}
.hljs-deletion,
.hljs-name,
.hljs-section,
.hljs-selector-tag,
.hljs-subst {
color: #e45649;
}
.hljs-literal {
color: #0184bb;
}
.hljs-addition,
.hljs-attribute,
.hljs-meta .hljs-string,
.hljs-regexp,
.hljs-string {
color: #50a14f;
}
.hljs-attr,
.hljs-number,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-pseudo,
.hljs-template-variable,
.hljs-type,
.hljs-variable {
color: #986801;
}
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-symbol,
.hljs-title {
color: #4078f2;
}
.hljs-built_in,
.hljs-class .hljs-title,
.hljs-title.class_ {
color: #c18401;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: 700;
}
.hljs-link {
text-decoration: underline;
}
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import { computed, h, ref, watchEffect } from 'vue' import { computed, h, ref, watchEffect } from 'vue'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { Plus, Logout } from '@icon-park/vue-next' import { Plus, Logout, Me } from '@icon-park/vue-next'
import type { MenuOption } from 'naive-ui' import type { MenuOption } from 'naive-ui'
import { useUserStore } from '@/store/modules/user' import { useUserStore } from '@/store/modules/user'
// import LanguageSetting from '@/components/language-setting/language-setting.vue' // import LanguageSetting from '@/components/language-setting/language-setting.vue'
...@@ -47,11 +47,11 @@ const menuOptions = computed<MenuOption[]>(() => { ...@@ -47,11 +47,11 @@ const menuOptions = computed<MenuOption[]>(() => {
const userConfigOptions = computed(() => { const userConfigOptions = computed(() => {
return [ return [
// { {
// label: () => h('div', '个人设置'), label: () => h('div', t('personal_settings_module.personal_settings_title')),
// key: 'PersonalSettings', key: 'PersonalSettings',
// icon: () => h(Me, { theme: 'outline', size: 14, strokeWidth: 3 }), icon: () => h(Me, { theme: 'outline', size: 14, strokeWidth: 3 }),
// }, },
{ {
label: () => h('div', t('common_module.logout')), label: () => h('div', t('common_module.logout')),
key: 'Logout', key: 'Logout',
...@@ -135,8 +135,10 @@ function handleMenuValueChange(key: string) { ...@@ -135,8 +135,10 @@ function handleMenuValueChange(key: string) {
> >
<n-avatar round :size="40" object-fit="cover" :src="userStore.userInfo.avatarUrl || defaultAvatar" /> <n-avatar round :size="40" object-fit="cover" :src="userStore.userInfo.avatarUrl || defaultAvatar" />
<div class="ml-3 line-clamp-1 max-w-[140px] flex-1 select-none break-all text-base"> <div class="ml-3 max-w-[140px] flex-1 select-none break-all text-base">
<n-ellipsis :tooltip="{ placement: 'top', width: 220 }">
{{ userStore.userInfo.nickName || t('common_module.not_login_text') }} {{ userStore.userInfo.nickName || t('common_module.not_login_text') }}
</n-ellipsis>
</div> </div>
</div> </div>
</n-dropdown> </n-dropdown>
......
...@@ -82,6 +82,13 @@ common_module: ...@@ -82,6 +82,13 @@ common_module:
view_file: 'View file' view_file: 'View file'
total_file: '1 file in total | {count} files in total' total_file: '1 file in total | {count} files in total'
expired_identity: 'Your identity has expired. Please login again' expired_identity: 'Your identity has expired. Please login again'
avatar: 'Avatar'
mobile_phone_number: 'Mobile phone number'
email: 'Email'
password: 'Password'
language: 'Language'
change: 'Change'
bind: 'Bind'
dialogue_module: dialogue_module:
continue_question_message: 'You can keep asking questions' continue_question_message: 'You can keep asking questions'
...@@ -425,3 +432,23 @@ applications_square_module: ...@@ -425,3 +432,23 @@ applications_square_module:
create_application_btn_text: 'Create application' create_application_btn_text: 'Create application'
all_application_btn_text: 'All applications' all_application_btn_text: 'All applications'
immediate_use_btn_text: 'Immediate use' immediate_use_btn_text: 'Immediate use'
personal_settings_module:
personal_settings_title: 'Personal settings'
basic_information_setting: 'Basic information setting'
account_nickname: 'Account nickname'
personal_profile: 'Personal profile'
click_bind_email: 'Click Bind Email'
click_to_set_password: 'Click to set Password'
language_setting: 'Language setting'
language_setting_doc: 'Set your preferred language for the interface and AI responses.'
email_binding: 'Email binding'
password_change: 'Password change'
new_password: 'New password'
please_enter_your_new_password: 'Please enter your new password'
confirm_new_password: 'Confirm new password'
please_enter_confirm_new_password: 'Please enter Confirm new password'
the_password_contains_a_maximum_of_6_characters: 'The password contains a maximum of 6 characters'
verify_that_the_new_password_is_inconsistent_with_the_new_password: 'Verify that the new password is inconsistent with the new password'
please_enter_the_account_nickname: 'Please enter the account nickname'
please_enter_a_personal_profile: 'Please enter a personal profile'
...@@ -81,6 +81,13 @@ common_module: ...@@ -81,6 +81,13 @@ common_module:
view_file: '查看文件' view_file: '查看文件'
total_file: '共{count}个文件' total_file: '共{count}个文件'
expired_identity: '身份已过期,请重新登录' expired_identity: '身份已过期,请重新登录'
avatar: '头像'
mobile_phone_number: '手机号'
email: '邮箱'
password: '密码'
language: '语言'
change: '更换'
bind: '绑定'
dialogue_module: dialogue_module:
continue_question_message: '你可以继续提问' continue_question_message: '你可以继续提问'
...@@ -423,3 +430,23 @@ applications_square_module: ...@@ -423,3 +430,23 @@ applications_square_module:
create_application_btn_text: '创建应用' create_application_btn_text: '创建应用'
all_application_btn_text: '所有应用' all_application_btn_text: '所有应用'
immediate_use_btn_text: '立即使用' immediate_use_btn_text: '立即使用'
personal_settings_module:
personal_settings_title: '个人设置'
basic_information_setting: '基础信息设置'
account_nickname: '账号昵称'
personal_profile: '个人简介'
click_bind_email: '点击绑定邮箱'
click_to_set_password: '点击设置密码'
language_setting: '语言设置'
language_setting_doc: '设定您的首选语言,用于界面和AI回应。'
email_binding: '邮箱绑定'
password_change: '密码修改'
new_password: '新密码'
please_enter_your_new_password: '请输入新密码'
confirm_new_password: '确认新密码'
please_enter_confirm_new_password: '请输入确定新密码'
the_password_contains_a_maximum_of_6_characters: '密码长度不能小于6位'
verify_that_the_new_password_is_inconsistent_with_the_new_password: '确认新密码与新密码不一致'
please_enter_the_account_nickname: '请输入账号昵称'
please_enter_a_personal_profile: '请输入个人简介'
...@@ -81,6 +81,13 @@ common_module: ...@@ -81,6 +81,13 @@ common_module:
view_file: '查看文件' view_file: '查看文件'
total_file: '共{count}個文件' total_file: '共{count}個文件'
expired_identity: '身份已過期,請重新登錄' expired_identity: '身份已過期,請重新登錄'
avatar: '頭像'
mobile_phone_number: '手機號'
email: '郵箱'
password: '密碼'
language: '語言'
change: '更換'
bind: '綁定'
dialogue_module: dialogue_module:
continue_question_message: '你可以繼續提問' continue_question_message: '你可以繼續提問'
...@@ -423,3 +430,23 @@ applications_square_module: ...@@ -423,3 +430,23 @@ applications_square_module:
create_application_btn_text: '創建應用' create_application_btn_text: '創建應用'
all_application_btn_text: '所有應用' all_application_btn_text: '所有應用'
immediate_use_btn_text: '立即使用' immediate_use_btn_text: '立即使用'
personal_settings_module:
personal_settings_title: '個人設置'
basic_information_setting: '基礎信息設置'
account_nickname: '賬號昵稱'
personal_profile: '個人簡介'
click_bind_email: '點擊綁定郵箱'
click_to_set_password: '點擊設置密碼'
language_setting: '語言設置'
language_setting_doc: '設定您的首選語言,用於界面和AI回應。'
email_binding: '郵箱綁定'
password_change: '密碼修改'
new_password: '新密碼'
please_enter_your_new_password: '請輸入新密碼'
confirm_new_password: '確認新密碼'
please_enter_confirm_new_password: '請輸入確定新密碼'
the_password_contains_a_maximum_of_6_characters: '密碼長度不能小於6位'
verify_that_the_new_password_is_inconsistent_with_the_new_password: '確認新密碼與新密碼不一致'
please_enter_the_account_nickname: '請輸入賬號昵稱'
please_enter_a_personal_profile: '請輸入個人簡介'
...@@ -4,7 +4,7 @@ import { defaultLocale } from '@/locales/index' ...@@ -4,7 +4,7 @@ import { defaultLocale } from '@/locales/index'
interface SystemLanguageState { interface SystemLanguageState {
currentLanguageInfo: { currentLanguageInfo: {
key: string key: I18n.LangType
label: string label: string
} }
...@@ -23,10 +23,10 @@ const defaultLanguageOptions = [ ...@@ -23,10 +23,10 @@ const defaultLanguageOptions = [
label: '中文繁體', label: '中文繁體',
key: 'zh-HK', key: 'zh-HK',
}, },
// { {
// label: 'English', label: 'English',
// key: 'en', key: 'en',
// }, },
] ]
const localeKey = ss.get('i18nextLng') || defaultLocale const localeKey = ss.get('i18nextLng') || defaultLocale
...@@ -47,7 +47,7 @@ export const useSystemLanguageStore = defineStore('system-language-store', { ...@@ -47,7 +47,7 @@ export const useSystemLanguageStore = defineStore('system-language-store', {
ss.set('i18nextLng', key) ss.set('i18nextLng', key)
this.currentLanguageInfo = this.languageOptions.find((optionItem) => optionItem.key === key) as { this.currentLanguageInfo = this.languageOptions.find((optionItem) => optionItem.key === key) as {
key: string key: I18n.LangType
label: string label: string
} }
}, },
......
...@@ -5,10 +5,12 @@ import type { FormItemRule, FormInst, InputInst } from 'naive-ui' ...@@ -5,10 +5,12 @@ import type { FormItemRule, FormInst, InputInst } from 'naive-ui'
import isEmail from 'validator/es/lib/isEmail' import isEmail from 'validator/es/lib/isEmail'
import { useSystemLanguageStore } from '@/store/modules/system-language' import { useSystemLanguageStore } from '@/store/modules/system-language'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
const userStore = useUserStore() const userStore = useUserStore()
const systemLanguageStore = useSystemLanguageStore() const systemLanguageStore = useSystemLanguageStore()
const router = useRouter() const router = useRouter()
const { t } = useI18n()
const inputRefs = useTemplateRef<InputInst | InputInst[]>('inputRefs') const inputRefs = useTemplateRef<InputInst | InputInst[]>('inputRefs')
const avatarInputRef = useTemplateRef('avatarInputRef') const avatarInputRef = useTemplateRef('avatarInputRef')
...@@ -38,9 +40,9 @@ const emailInfoFormRules = shallowReadonly({ ...@@ -38,9 +40,9 @@ const emailInfoFormRules = shallowReadonly({
trigger: 'blur', trigger: 'blur',
validator: (_rule: FormItemRule, value: string) => { validator: (_rule: FormItemRule, value: string) => {
if (!value) { if (!value) {
return new Error('请填写邮箱地址') return new Error(t('login_module.please_enter_your_email_address'))
} else if (!isEmail(value)) { } else if (!isEmail(value)) {
return new Error('请填写正确邮箱地址') return new Error(t('login_module.please_enter_the_correct_email_address'))
} }
return return
...@@ -62,9 +64,9 @@ const passwordFormRules = shallowReadonly({ ...@@ -62,9 +64,9 @@ const passwordFormRules = shallowReadonly({
trigger: 'blur', trigger: 'blur',
validator: (_rule: FormItemRule, value: string) => { validator: (_rule: FormItemRule, value: string) => {
if (!value) { if (!value) {
return new Error('请输入新密码') return new Error(t('personal_settings_module.please_enter_your_new_password'))
} else if (value.length <= 6) { } else if (value.length <= 6) {
return new Error('密码长度不能小于6位') return new Error(t('personal_settings_module.the_password_contains_a_maximum_of_6_characters'))
} }
return return
...@@ -75,9 +77,11 @@ const passwordFormRules = shallowReadonly({ ...@@ -75,9 +77,11 @@ const passwordFormRules = shallowReadonly({
trigger: 'blur', trigger: 'blur',
validator: (_rule: FormItemRule, value: string) => { validator: (_rule: FormItemRule, value: string) => {
if (!value) { if (!value) {
return new Error('请输入确定密码') return new Error(t('personal_settings_module.please_enter_confirm_new_password'))
} else if (value !== passwordInfoForm.value.password) { } else if (value !== passwordInfoForm.value.password) {
return new Error('确认密码与密码不一致') return new Error(
t('personal_settings_module.verify_that_the_new_password_is_inconsistent_with_the_new_password'),
)
} }
return return
...@@ -85,6 +89,9 @@ const passwordFormRules = shallowReadonly({ ...@@ -85,6 +89,9 @@ const passwordFormRules = shallowReadonly({
}, },
}) })
const listItemLabelWidth = ref(systemLanguageStore.currentLanguageInfo.key === 'en' ? '168px' : '100px')
// const confirmBtnLoading = ref(true)
const currentLanguage = computed({ const currentLanguage = computed({
get() { get() {
return systemLanguageStore.currentLanguageInfo.key return systemLanguageStore.currentLanguageInfo.key
...@@ -158,11 +165,11 @@ function handlePasswordChangeSubmit() { ...@@ -158,11 +165,11 @@ function handlePasswordChangeSubmit() {
<ul> <ul>
<li class="font-600 flex items-center text-[18px]"> <li class="font-600 flex items-center text-[18px]">
<i class="iconfont icon-personal-info text-theme-color"></i> <i class="iconfont icon-personal-info text-theme-color"></i>
<span class="ml-[4px]">基础信息设置</span> <span class="ml-[4px]">{{ t('personal_settings_module.basic_information_setting') }}</span>
</li> </li>
<li class="mb-[30px] mt-[24px] flex items-center"> <li class="mb-[30px] mt-[24px] flex items-center">
<h4 class="font-600 list-item-label mr-[19px] text-[14px]">头像</h4> <h4 class="font-600 list-item-label mr-[19px] text-[14px]">{{ t('common_module.avatar') }}</h4>
<div <div
class="group relative h-[60px] w-[60px] cursor-pointer overflow-hidden rounded-full bg-[#EAECEC]" class="group relative h-[60px] w-[60px] cursor-pointer overflow-hidden rounded-full bg-[#EAECEC]"
...@@ -173,7 +180,7 @@ function handlePasswordChangeSubmit() { ...@@ -173,7 +180,7 @@ function handlePasswordChangeSubmit() {
<div <div
class="flex-center absolute bottom-0 h-[26px] w-full bg-[rgba(0,0,0,0.4)] text-[10px] text-white opacity-0 transition group-hover:opacity-100" class="flex-center absolute bottom-0 h-[26px] w-full bg-[rgba(0,0,0,0.4)] text-[10px] text-white opacity-0 transition group-hover:opacity-100"
> >
<span>更换</span> <span>{{ t('common_module.change') }}</span>
</div> </div>
<input ref="avatarInputRef" type="file" class="hidden" accept="image/*" @change="handleAvatarUpload" /> <input ref="avatarInputRef" type="file" class="hidden" accept="image/*" @change="handleAvatarUpload" />
...@@ -181,14 +188,22 @@ function handlePasswordChangeSubmit() { ...@@ -181,14 +188,22 @@ function handlePasswordChangeSubmit() {
</li> </li>
<li class="mb-[30px] mt-[24px] flex items-center"> <li class="mb-[30px] mt-[24px] flex items-center">
<h4 class="font-600 list-item-label mr-[19px] text-[14px]">账号昵称:</h4> <h4 class="font-600 list-item-label mr-[19px] text-[14px]">
{{ t('personal_settings_module.account_nickname') }}
</h4>
<div v-if="userInfoFormItemEdit.nickName" class="flex"> <div v-if="userInfoFormItemEdit.nickName" class="flex">
<div class="flex w-[220px] items-center"> <div class="flex w-[220px] items-center">
<n-input ref="inputRefs" v-model:value="userInfoForm.nickName" type="text" size="small" /> <n-input
ref="inputRefs"
v-model:value="userInfoForm.nickName"
:placeholder="t('personal_settings_module.please_enter_the_account_nickname')"
type="text"
size="small"
/>
</div> </div>
<div class="ml-[20px]"> <div class="ml-[20px] flex items-center">
<n-button class="!mr-[6px]" size="tiny" @click="handleUserInfoFormItemEditUpdate('nickName', false)"> <n-button class="!mr-[6px]" size="tiny" @click="handleUserInfoFormItemEditUpdate('nickName', false)">
<i class="iconfont icon-close"></i> <i class="iconfont icon-close"></i>
</n-button> </n-button>
...@@ -209,7 +224,9 @@ function handlePasswordChangeSubmit() { ...@@ -209,7 +224,9 @@ function handlePasswordChangeSubmit() {
</li> </li>
<li class="mb-[30px] mt-[24px] flex items-center"> <li class="mb-[30px] mt-[24px] flex items-center">
<h4 class="font-600 list-item-label mr-[19px] text-[14px]">个人简介:</h4> <h4 class="font-600 list-item-label mr-[19px] text-[14px]">
{{ t('personal_settings_module.personal_profile') }}
</h4>
<div v-if="userInfoFormItemEdit.remark" class="flex"> <div v-if="userInfoFormItemEdit.remark" class="flex">
<div class="flex w-[220px] items-center"> <div class="flex w-[220px] items-center">
...@@ -218,6 +235,7 @@ function handlePasswordChangeSubmit() { ...@@ -218,6 +235,7 @@ function handlePasswordChangeSubmit() {
v-model:value="userInfoForm.remark" v-model:value="userInfoForm.remark"
type="textarea" type="textarea"
size="small" size="small"
:placeholder="t('personal_settings_module.please_enter_a_personal_profile')"
:autosize="{ minRows: 4, maxRows: 4 }" :autosize="{ minRows: 4, maxRows: 4 }"
/> />
</div> </div>
...@@ -243,30 +261,30 @@ function handlePasswordChangeSubmit() { ...@@ -243,30 +261,30 @@ function handlePasswordChangeSubmit() {
</li> </li>
<li class="mb-[30px] mt-[24px] flex items-center"> <li class="mb-[30px] mt-[24px] flex items-center">
<h4 class="font-600 list-item-label mr-[19px] text-[14px]">手机号</h4> <h4 class="font-600 list-item-label mr-[19px] text-[14px]">{{ t('common_module.mobile_phone_number') }}</h4>
<div class="text-[14px] text-[#999]">{{ userInfo.mobilePhone || '-' }}</div> <div class="text-[14px] text-[#999]">{{ userInfo.mobilePhone || '-' }}</div>
</li> </li>
<li class="mb-[30px] mt-[24px] flex items-center"> <li class="mb-[30px] mt-[24px] flex items-center">
<h4 class="font-600 list-item-label mr-[19px] text-[14px]">邮箱</h4> <h4 class="font-600 list-item-label mr-[19px] text-[14px]">{{ t('common_module.email') }}</h4>
<div class="text-[14px] text-[#999]"> <div class="text-[14px] text-[#999]">
<span v-if="userInfo.email">{{ userInfo.email }}</span> <span v-if="userInfo.email">{{ userInfo.email }}</span>
<span v-else class="text-theme-color cursor-pointer select-none" @click="isShowMailboxBindingModal = true"> <span v-else class="text-theme-color cursor-pointer select-none" @click="isShowMailboxBindingModal = true">
点击绑定邮箱 {{ t('personal_settings_module.click_bind_email') }}
</span> </span>
</div> </div>
</li> </li>
<li class="mb-[30px] mt-[24px] flex items-center"> <li class="mb-[30px] mt-[24px] flex items-center">
<h4 class="font-600 list-item-label mr-[19px] text-[14px]">密码</h4> <h4 class="font-600 list-item-label mr-[19px] text-[14px]">{{ t('common_module.password') }}</h4>
<div <div
class="text-theme-color cursor-pointer select-none text-[14px]" class="text-theme-color cursor-pointer select-none text-[14px]"
@click="isShowPasswordChangeModal = true" @click="isShowPasswordChangeModal = true"
> >
点击设置密码 {{ t('personal_settings_module.click_to_set_password') }}
</div> </div>
</li> </li>
</ul> </ul>
...@@ -274,15 +292,15 @@ function handlePasswordChangeSubmit() { ...@@ -274,15 +292,15 @@ function handlePasswordChangeSubmit() {
<ul class="mt-[60px]"> <ul class="mt-[60px]">
<li class="font-600 flex items-center text-[18px]"> <li class="font-600 flex items-center text-[18px]">
<i class="iconfont icon-language text-theme-color"></i> <i class="iconfont icon-language text-theme-color"></i>
<span class="ml-[4px]">语言设置</span> <span class="ml-[4px]">{{ t('personal_settings_module.language_setting') }}</span>
</li> </li>
<li class="mb-[8px] ml-[121px]"> <li class="mb-[8px] ml-[121px] mt-[8px]">
<h5 class="text-[12px] text-[#999]">设定您的首选语言,用于界面和AI回应。</h5> <h5 class="text-[12px] text-[#999]">{{ t('personal_settings_module.language_setting_doc') }}</h5>
</li> </li>
<li class="mb-[30px] flex items-center"> <li class="mb-[30px] flex items-center">
<h4 class="font-600 list-item-label mr-[19px] text-[14px]">语言</h4> <h4 class="font-600 list-item-label mr-[19px] text-[14px]">{{ t('common_module.language') }}</h4>
<div class="w-[200px]"> <div class="w-[200px]">
<n-select v-model:value="currentLanguage" :options="languageOptions" /> <n-select v-model:value="currentLanguage" :options="languageOptions" />
...@@ -294,7 +312,7 @@ function handlePasswordChangeSubmit() { ...@@ -294,7 +312,7 @@ function handlePasswordChangeSubmit() {
<n-modal v-model:show="isShowMailboxBindingModal" :mask-closable="false" :on-after-leave="onModalAfterLeave"> <n-modal v-model:show="isShowMailboxBindingModal" :mask-closable="false" :on-after-leave="onModalAfterLeave">
<n-card <n-card
class="!w-[600px]" class="!w-[600px]"
title="邮箱绑定" :title="t('personal_settings_module.email_binding')"
:bordered="false" :bordered="false"
size="medium" size="medium"
closable closable
...@@ -307,17 +325,22 @@ function handlePasswordChangeSubmit() { ...@@ -307,17 +325,22 @@ function handlePasswordChangeSubmit() {
:model="emailInfoForm" :model="emailInfoForm"
:rules="emailInfoFormRules" :rules="emailInfoFormRules"
> >
<n-form-item label="邮箱地址" path="email"> <n-form-item :label="t('common_module.email')" path="email">
<n-input v-model:value="emailInfoForm.email" placeholder="请输入邮箱地址" /> <n-input
v-model:value="emailInfoForm.email"
:placeholder="t('login_module.please_enter_your_email_address')"
/>
</n-form-item> </n-form-item>
</n-form> </n-form>
<template #footer> <template #footer>
<div class="text-end"> <div class="text-end">
<n-space justify="end"> <n-space justify="end">
<n-button @click="() => (isShowMailboxBindingModal = false)">取消</n-button> <n-button @click="() => (isShowMailboxBindingModal = false)">{{
t('common_module.cancel_btn_text')
}}</n-button>
<n-button type="primary" :loading="mailboxBindingSubmitBtnLoading" @click="handleMailboxBindingSubmit"> <n-button type="primary" :loading="mailboxBindingSubmitBtnLoading" @click="handleMailboxBindingSubmit">
确定 {{ t('common_module.confirm_btn_text') }}
</n-button> </n-button>
</n-space> </n-space>
</div> </div>
...@@ -328,7 +351,7 @@ function handlePasswordChangeSubmit() { ...@@ -328,7 +351,7 @@ function handlePasswordChangeSubmit() {
<n-modal v-model:show="isShowPasswordChangeModal" :mask-closable="false" :on-after-leave="onModalAfterLeave"> <n-modal v-model:show="isShowPasswordChangeModal" :mask-closable="false" :on-after-leave="onModalAfterLeave">
<n-card <n-card
class="!w-[600px]" class="!w-[600px]"
title="密码修改" :title="t('personal_settings_module.password_change')"
:bordered="false" :bordered="false"
size="medium" size="medium"
closable closable
...@@ -341,20 +364,28 @@ function handlePasswordChangeSubmit() { ...@@ -341,20 +364,28 @@ function handlePasswordChangeSubmit() {
:model="passwordInfoForm" :model="passwordInfoForm"
:rules="passwordFormRules" :rules="passwordFormRules"
> >
<n-form-item label="密码" path="password"> <n-form-item :label="t('personal_settings_module.new_password')" path="password">
<n-input v-model:value="passwordInfoForm.password" placeholder="请输入密码" /> <n-input
v-model:value="passwordInfoForm.password"
:placeholder="t('personal_settings_module.please_enter_your_new_password')"
/>
</n-form-item> </n-form-item>
<n-form-item label="确认密码" path="confirmPassword"> <n-form-item :label="t('personal_settings_module.confirm_new_password')" path="confirmPassword">
<n-input v-model:value="passwordInfoForm.confirmPassword" placeholder="请输入确定密码" /> <n-input
v-model:value="passwordInfoForm.confirmPassword"
:placeholder="t('personal_settings_module.please_enter_confirm_new_password')"
/>
</n-form-item> </n-form-item>
</n-form> </n-form>
<template #footer> <template #footer>
<div class="text-end"> <div class="text-end">
<n-space justify="end"> <n-space justify="end">
<n-button @click="() => (isShowPasswordChangeModal = false)">取消</n-button> <n-button @click="() => (isShowPasswordChangeModal = false)">{{
t('common_module.cancel_btn_text')
}}</n-button>
<n-button type="primary" :loading="passwordChangeSubmitBtnLoading" @click="handlePasswordChangeSubmit"> <n-button type="primary" :loading="passwordChangeSubmitBtnLoading" @click="handlePasswordChangeSubmit">
确定 {{ t('common_module.confirm_btn_text') }}
</n-button> </n-button>
</n-space> </n-space>
</div> </div>
...@@ -366,7 +397,8 @@ function handlePasswordChangeSubmit() { ...@@ -366,7 +397,8 @@ function handlePasswordChangeSubmit() {
<style lang="scss" scoped> <style lang="scss" scoped>
.list-item-label { .list-item-label {
width: 100px; /* stylelint-disable-next-line value-keyword-case */
width: v-bind(listItemLabelWidth);
text-align: end; text-align: end;
} }
</style> </style>
...@@ -82,6 +82,13 @@ declare namespace I18n { ...@@ -82,6 +82,13 @@ declare namespace I18n {
view_file: string view_file: string
total_file: string total_file: string
expired_identity: string expired_identity: string
avatar: string
mobile_phone_number: string
email: string
password: string
language: string
change: string
bind: string
dialogue_module: { dialogue_module: {
continue_question_message: string continue_question_message: string
...@@ -116,6 +123,25 @@ declare namespace I18n { ...@@ -116,6 +123,25 @@ declare namespace I18n {
} }
} }
router_title_module: {
login: string
server_error: string
universal: string
home: string
personal: string
app_setting: string
agent_application: string
share_application: string
knowledge: string
upload_knowledge_document: string
knowledge_document_list: string
knowledge_document_detail: string
multi_model_dialogue: string
explore: string
application_square: string
personal_settings: string
}
login_module: { login_module: {
app_welcome_words: string app_welcome_words: string
please_enter_your_account_number: string please_enter_your_account_number: string
...@@ -151,25 +177,6 @@ declare namespace I18n { ...@@ -151,25 +177,6 @@ declare namespace I18n {
interrupt_the_conversation_and_apply_the_history_prompt: string interrupt_the_conversation_and_apply_the_history_prompt: string
} }
router_title_module: {
login: string
server_error: string
universal: string
home: string
personal: string
app_setting: string
agent_application: string
share_application: string
knowledge: string
upload_knowledge_document: string
knowledge_document_list: string
knowledge_document_detail: string
multi_model_dialogue: string
explore: string
application_square: string
personal_settings: string
}
personal_space_module: { personal_space_module: {
title: string title: string
create_btn_text: string create_btn_text: string
...@@ -439,5 +446,26 @@ declare namespace I18n { ...@@ -439,5 +446,26 @@ declare namespace I18n {
all_application_btn_text: string all_application_btn_text: string
immediate_use_btn_text: string immediate_use_btn_text: string
} }
personal_settings_module: {
personal_settings_title: string
basic_information_setting: string
account_nickname: string
personal_profile: string
click_bind_email: string
click_to_set_password: string
language_setting: string
language_setting_doc: string
email_binding: string
password_change: string
new_password: string
please_enter_your_new_password: string
confirm_new_password: string
please_enter_confirm_new_password: string
the_password_contains_a_maximum_of_6_characters: string
verify_that_the_new_password_is_inconsistent_with_the_new_password: string
please_enter_the_account_nickname: string
please_enter_a_personal_profile: string
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment