Commit 61a43a4a by lijiabin

【需求 17679】 feat: 加入富文本框,回复弹窗等内容

parent 22f0e398
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
"@element-plus/icons-vue": "^2.3.2", "@element-plus/icons-vue": "^2.3.2",
"@vueuse/components": "^14.0.0", "@vueuse/components": "^14.0.0",
"@vueuse/core": "^14.0.0", "@vueuse/core": "^14.0.0",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12",
"@wecom/jssdk": "^2.3.3", "@wecom/jssdk": "^2.3.3",
"archiver": "^7.0.1", "archiver": "^7.0.1",
"axios": "^1.13.0", "axios": "^1.13.0",
......
...@@ -17,6 +17,12 @@ importers: ...@@ -17,6 +17,12 @@ importers:
'@vueuse/core': '@vueuse/core':
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0(vue@3.5.22(typescript@5.9.3)) version: 14.0.0(vue@3.5.22(typescript@5.9.3))
'@wangeditor/editor':
specifier: ^5.1.23
version: 5.1.23
'@wangeditor/editor-for-vue':
specifier: ^5.1.12
version: 5.1.12(@wangeditor/editor@5.1.23)(vue@3.5.22(typescript@5.9.3))
'@wecom/jssdk': '@wecom/jssdk':
specifier: ^2.3.3 specifier: ^2.3.3
version: 2.3.3 version: 2.3.3
...@@ -95,7 +101,7 @@ importers: ...@@ -95,7 +101,7 @@ importers:
version: 5.9.3 version: 5.9.3
unocss: unocss:
specifier: ^66.5.4 specifier: ^66.5.4
version: 66.5.4(postcss@8.5.6)(vite@7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2)) version: 66.5.4(postcss@5.2.18)(vite@7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2))
unplugin-auto-import: unplugin-auto-import:
specifier: ^20.2.0 specifier: ^20.2.0
version: 20.2.0(@vueuse/core@14.0.0(vue@3.5.22(typescript@5.9.3))) version: 20.2.0(@vueuse/core@14.0.0(vue@3.5.22(typescript@5.9.3)))
...@@ -256,6 +262,10 @@ packages: ...@@ -256,6 +262,10 @@ packages:
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0-0 '@babel/core': ^7.0.0-0
'@babel/runtime@7.28.4':
resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==}
engines: {node: '>=6.9.0'}
'@babel/template@7.27.2': '@babel/template@7.27.2':
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
...@@ -890,6 +900,9 @@ packages: ...@@ -890,6 +900,9 @@ packages:
'@sxzz/popperjs-es@2.11.7': '@sxzz/popperjs-es@2.11.7':
resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==} resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==}
'@transloadit/prettier-bytes@0.0.7':
resolution: {integrity: sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA==}
'@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'}
...@@ -900,6 +913,9 @@ packages: ...@@ -900,6 +913,9 @@ packages:
'@types/estree@1.0.8': '@types/estree@1.0.8':
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
'@types/event-emitter@0.3.5':
resolution: {integrity: sha512-zx2/Gg0Eg7gwEiOIIh5w9TrhKKTeQh7CPCOPNc0el4pLSwzebA8SmnHwZs2dWlLONvyulykSwGSQxQHLhjGLvQ==}
'@types/json-schema@7.0.15': '@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
...@@ -1066,6 +1082,23 @@ packages: ...@@ -1066,6 +1082,23 @@ packages:
peerDependencies: peerDependencies:
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0
'@uppy/companion-client@2.2.2':
resolution: {integrity: sha512-5mTp2iq97/mYSisMaBtFRry6PTgZA6SIL7LePteOV5x0/DxKfrZW3DEiQERJmYpHzy7k8johpm2gHnEKto56Og==}
'@uppy/core@2.3.4':
resolution: {integrity: sha512-iWAqppC8FD8mMVqewavCz+TNaet6HPXitmGXpGGREGrakZ4FeuWytVdrelydzTdXx6vVKkOmI2FLztGg73sENQ==}
'@uppy/store-default@2.1.1':
resolution: {integrity: sha512-xnpTxvot2SeAwGwbvmJ899ASk5tYXhmZzD/aCFsXePh/v8rNvR2pKlcQUH7cF/y4baUGq3FHO/daKCok/mpKqQ==}
'@uppy/utils@4.1.3':
resolution: {integrity: sha512-nTuMvwWYobnJcytDO3t+D6IkVq/Qs4Xv3vyoEZ+Iaf8gegZP+rEyoaFT2CK5XLRMienPyqRqNbIfRuFaOWSIFw==}
'@uppy/xhr-upload@2.1.3':
resolution: {integrity: sha512-YWOQ6myBVPs+mhNjfdWsQyMRWUlrDLMoaG7nvf/G6Y3GKZf8AyjFDjvvJ49XWQ+DaZOftGkHmF1uh/DBeGivJQ==}
peerDependencies:
'@uppy/core': ^2.3.3
'@vitejs/plugin-vue-jsx@5.1.1': '@vitejs/plugin-vue-jsx@5.1.1':
resolution: {integrity: sha512-uQkfxzlF8SGHJJVH966lFTdjM/lGcwJGzwAHpVqAPDD/QcsqoUGa+q31ox1BrUfi+FLP2ChVp7uLXE3DkHyDdQ==} resolution: {integrity: sha512-uQkfxzlF8SGHJJVH966lFTdjM/lGcwJGzwAHpVqAPDD/QcsqoUGa+q31ox1BrUfi+FLP2ChVp7uLXE3DkHyDdQ==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
...@@ -1220,6 +1253,93 @@ packages: ...@@ -1220,6 +1253,93 @@ packages:
'@vueuse/shared@9.13.0': '@vueuse/shared@9.13.0':
resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
'@wangeditor/basic-modules@1.1.7':
resolution: {integrity: sha512-cY9CPkLJaqF05STqfpZKWG4LpxTMeGSIIF1fHvfm/mz+JXatCagjdkbxdikOuKYlxDdeqvOeBmsUBItufDLXZg==}
peerDependencies:
'@wangeditor/core': 1.x
dom7: ^3.0.0
lodash.throttle: ^4.1.1
nanoid: ^3.2.0
slate: ^0.72.0
snabbdom: ^3.1.0
'@wangeditor/code-highlight@1.0.3':
resolution: {integrity: sha512-iazHwO14XpCuIWJNTQTikqUhGKyqj+dUNWJ9288Oym9M2xMVHvnsOmDU2sgUDWVy+pOLojReMPgXCsvvNlOOhw==}
peerDependencies:
'@wangeditor/core': 1.x
dom7: ^3.0.0
slate: ^0.72.0
snabbdom: ^3.1.0
'@wangeditor/core@1.1.19':
resolution: {integrity: sha512-KevkB47+7GhVszyYF2pKGKtCSj/YzmClsD03C3zTt+9SR2XWT5T0e3yQqg8baZpcMvkjs1D8Dv4fk8ok/UaS2Q==}
peerDependencies:
'@uppy/core': ^2.1.1
'@uppy/xhr-upload': ^2.0.3
dom7: ^3.0.0
is-hotkey: ^0.2.0
lodash.camelcase: ^4.3.0
lodash.clonedeep: ^4.5.0
lodash.debounce: ^4.0.8
lodash.foreach: ^4.5.0
lodash.isequal: ^4.5.0
lodash.throttle: ^4.1.1
lodash.toarray: ^4.4.0
nanoid: ^3.2.0
slate: ^0.72.0
snabbdom: ^3.1.0
'@wangeditor/editor-for-vue@5.1.12':
resolution: {integrity: sha512-0Ds3D8I+xnpNWezAeO7HmPRgTfUxHLMd9JKcIw+QzvSmhC5xUHbpCcLU+KLmeBKTR/zffnS5GQo6qi3GhTMJWQ==}
peerDependencies:
'@wangeditor/editor': '>=5.1.0'
vue: ^3.0.5
'@wangeditor/editor@5.1.23':
resolution: {integrity: sha512-0RxfeVTuK1tktUaPROnCoFfaHVJpRAIE2zdS0mpP+vq1axVQpLjM8+fCvKzqYIkH0Pg+C+44hJpe3VVroSkEuQ==}
'@wangeditor/list-module@1.0.5':
resolution: {integrity: sha512-uDuYTP6DVhcYf7mF1pTlmNn5jOb4QtcVhYwSSAkyg09zqxI1qBqsfUnveeDeDqIuptSJhkh81cyxi+MF8sEPOQ==}
peerDependencies:
'@wangeditor/core': 1.x
dom7: ^3.0.0
slate: ^0.72.0
snabbdom: ^3.1.0
'@wangeditor/table-module@1.1.4':
resolution: {integrity: sha512-5saanU9xuEocxaemGdNi9t8MCDSucnykEC6jtuiT72kt+/Hhh4nERYx1J20OPsTCCdVr7hIyQenFD1iSRkIQ6w==}
peerDependencies:
'@wangeditor/core': 1.x
dom7: ^3.0.0
lodash.isequal: ^4.5.0
lodash.throttle: ^4.1.1
nanoid: ^3.2.0
slate: ^0.72.0
snabbdom: ^3.1.0
'@wangeditor/upload-image-module@1.0.2':
resolution: {integrity: sha512-z81lk/v71OwPDYeQDxj6cVr81aDP90aFuywb8nPD6eQeECtOymrqRODjpO6VGvCVxVck8nUxBHtbxKtjgcwyiA==}
peerDependencies:
'@uppy/core': ^2.0.3
'@uppy/xhr-upload': ^2.0.3
'@wangeditor/basic-modules': 1.x
'@wangeditor/core': 1.x
dom7: ^3.0.0
lodash.foreach: ^4.5.0
slate: ^0.72.0
snabbdom: ^3.1.0
'@wangeditor/video-module@1.1.4':
resolution: {integrity: sha512-ZdodDPqKQrgx3IwWu4ZiQmXI8EXZ3hm2/fM6E3t5dB8tCaIGWQZhmqd6P5knfkRAd3z2+YRSRbxOGfoRSp/rLg==}
peerDependencies:
'@uppy/core': ^2.1.4
'@uppy/xhr-upload': ^2.0.7
'@wangeditor/core': 1.x
dom7: ^3.0.0
nanoid: ^3.2.0
slate: ^0.72.0
snabbdom: ^3.1.0
'@wecom/jssdk@2.3.3': '@wecom/jssdk@2.3.3':
resolution: {integrity: sha512-bazYSD39MoiaUV1xMVxrOPsTFa37ARY0xXAqDgth4kU/xk8n61o1YiAcdn4dPM+kBnJKOfukFYPjOPQv8K5l+w==} resolution: {integrity: sha512-bazYSD39MoiaUV1xMVxrOPsTFa37ARY0xXAqDgth4kU/xk8n61o1YiAcdn4dPM+kBnJKOfukFYPjOPQv8K5l+w==}
...@@ -1522,6 +1642,9 @@ packages: ...@@ -1522,6 +1642,9 @@ packages:
resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==}
engines: {node: '>= 14'} engines: {node: '>= 14'}
compute-scroll-into-view@1.0.20:
resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==}
concat-map@0.0.1: concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
...@@ -1597,6 +1720,10 @@ packages: ...@@ -1597,6 +1720,10 @@ packages:
csstype@3.1.3: csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
d@1.0.2:
resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==}
engines: {node: '>=0.12'}
data-view-buffer@1.0.2: data-view-buffer@1.0.2:
resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
...@@ -1693,6 +1820,9 @@ packages: ...@@ -1693,6 +1820,9 @@ packages:
dom-serializer@1.4.1: dom-serializer@1.4.1:
resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==}
dom7@3.0.0:
resolution: {integrity: sha512-oNlcUdHsC4zb7Msx7JN3K0Nro1dzJ48knvBOnDPKJ2GV9wl1i5vydJZUSyOfrkKFDZEud/jBsTk92S/VGSAe/g==}
domelementtype@1.3.1: domelementtype@1.3.1:
resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==}
...@@ -1780,6 +1910,17 @@ packages: ...@@ -1780,6 +1910,17 @@ packages:
resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
es5-ext@0.10.64:
resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==}
engines: {node: '>=0.10'}
es6-iterator@2.0.3:
resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==}
es6-symbol@3.1.4:
resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==}
engines: {node: '>=0.12'}
esbuild@0.25.11: esbuild@0.25.11:
resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==} resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==}
engines: {node: '>=18'} engines: {node: '>=18'}
...@@ -1857,6 +1998,10 @@ packages: ...@@ -1857,6 +1998,10 @@ packages:
jiti: jiti:
optional: true optional: true
esniff@2.0.1:
resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==}
engines: {node: '>=0.10'}
espree@10.4.0: espree@10.4.0:
resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
...@@ -1887,6 +2032,9 @@ packages: ...@@ -1887,6 +2032,9 @@ packages:
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
event-emitter@0.3.5:
resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==}
event-target-shim@5.0.1: event-target-shim@5.0.1:
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
engines: {node: '>=6'} engines: {node: '>=6'}
...@@ -1905,6 +2053,9 @@ packages: ...@@ -1905,6 +2053,9 @@ packages:
exsolve@1.0.7: exsolve@1.0.7:
resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==}
ext@1.7.0:
resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==}
extend-shallow@2.0.1: extend-shallow@2.0.1:
resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
...@@ -2151,9 +2302,15 @@ packages: ...@@ -2151,9 +2302,15 @@ packages:
hookable@5.5.3: hookable@5.5.3:
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
html-void-elements@2.0.1:
resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==}
htmlparser2@3.10.1: htmlparser2@3.10.1:
resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==} resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==}
i18next@20.6.1:
resolution: {integrity: sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A==}
iconv-lite@0.7.0: iconv-lite@0.7.0:
resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
...@@ -2174,6 +2331,9 @@ packages: ...@@ -2174,6 +2331,9 @@ packages:
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
hasBin: true hasBin: true
immer@9.0.21:
resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==}
immutable@5.1.4: immutable@5.1.4:
resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==} resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==}
...@@ -2290,6 +2450,9 @@ packages: ...@@ -2290,6 +2450,9 @@ packages:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
is-hotkey@0.2.0:
resolution: {integrity: sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==}
is-inside-container@1.0.0: is-inside-container@1.0.0:
resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
engines: {node: '>=14.16'} engines: {node: '>=14.16'}
...@@ -2323,6 +2486,10 @@ packages: ...@@ -2323,6 +2486,10 @@ packages:
resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
is-plain-object@5.0.0:
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
engines: {node: '>=0.10.0'}
is-regex@1.2.1: is-regex@1.2.1:
resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
...@@ -2351,6 +2518,9 @@ packages: ...@@ -2351,6 +2518,9 @@ packages:
resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
is-url@1.2.4:
resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==}
is-weakmap@2.0.2: is-weakmap@2.0.2:
resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
...@@ -2502,9 +2672,31 @@ packages: ...@@ -2502,9 +2672,31 @@ packages:
lodash: '*' lodash: '*'
lodash-es: '*' lodash-es: '*'
lodash.camelcase@4.3.0:
resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
lodash.clonedeep@4.5.0:
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
lodash.debounce@4.0.8:
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
lodash.foreach@4.5.0:
resolution: {integrity: sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==}
lodash.isequal@4.5.0:
resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead.
lodash.merge@4.6.2: lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
lodash.throttle@4.1.1:
resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==}
lodash.toarray@4.4.0:
resolution: {integrity: sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw==}
lodash@4.17.21: lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
...@@ -2562,6 +2754,9 @@ packages: ...@@ -2562,6 +2754,9 @@ packages:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
mime-match@1.0.2:
resolution: {integrity: sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==}
mime-types@2.1.35: mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
...@@ -2611,6 +2806,9 @@ packages: ...@@ -2611,6 +2806,9 @@ packages:
resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==}
engines: {node: ^20.17.0 || >=22.9.0} engines: {node: ^20.17.0 || >=22.9.0}
namespace-emitter@2.0.1:
resolution: {integrity: sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==}
nan@2.23.1: nan@2.23.1:
resolution: {integrity: sha512-r7bBUGKzlqk8oPBDYxt6Z0aEdF1G1rwlMcLk8LCOMbOzf0mG+JUfUzG4fIMWwHWP0iyaLWEQZJmtB7nOHEm/qw==} resolution: {integrity: sha512-r7bBUGKzlqk8oPBDYxt6Z0aEdF1G1rwlMcLk8LCOMbOzf0mG+JUfUzG4fIMWwHWP0iyaLWEQZJmtB7nOHEm/qw==}
...@@ -2631,6 +2829,9 @@ packages: ...@@ -2631,6 +2829,9 @@ packages:
natural-compare@1.4.0: natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
next-tick@1.1.0:
resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==}
node-addon-api@7.1.1: node-addon-api@7.1.1:
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
...@@ -2831,6 +3032,9 @@ packages: ...@@ -2831,6 +3032,9 @@ packages:
resolution: {integrity: sha512-spBB5sgC4cv2YcW03f/IAUN1pgDJWNWD8FzkyY4mArLUMJW+KlQhlmUdKAHQuPfb00Jl5xIfImeOsf6YL8QK7Q==} resolution: {integrity: sha512-spBB5sgC4cv2YcW03f/IAUN1pgDJWNWD8FzkyY4mArLUMJW+KlQhlmUdKAHQuPfb00Jl5xIfImeOsf6YL8QK7Q==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
preact@10.28.0:
resolution: {integrity: sha512-rytDAoiXr3+t6OIP3WGlDd0ouCUG1iCWzkcY3++Nreuoi17y6T5i/zRhe6uYfoVcxq6YU+sBtJouuRDsq8vvqA==}
prelude-ls@1.2.1: prelude-ls@1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
...@@ -2844,6 +3048,10 @@ packages: ...@@ -2844,6 +3048,10 @@ packages:
engines: {node: '>=14'} engines: {node: '>=14'}
hasBin: true hasBin: true
prismjs@1.30.0:
resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
engines: {node: '>=6'}
process-nextick-args@2.0.1: process-nextick-args@2.0.1:
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
...@@ -3107,6 +3315,9 @@ packages: ...@@ -3107,6 +3315,9 @@ packages:
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
hasBin: true hasBin: true
scroll-into-view-if-needed@2.2.31:
resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==}
scule@1.3.0: scule@1.3.0:
resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
...@@ -3171,6 +3382,18 @@ packages: ...@@ -3171,6 +3382,18 @@ packages:
resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==}
engines: {node: '>=18'} engines: {node: '>=18'}
slate-history@0.66.0:
resolution: {integrity: sha512-6MWpxGQZiMvSINlCbMW43E2YBSVMCMCIwQfBzGssjWw4kb0qfvj0pIdblWNRQZD0hR6WHP+dHHgGSeVdMWzfng==}
peerDependencies:
slate: '>=0.65.3'
slate@0.72.8:
resolution: {integrity: sha512-/nJwTswQgnRurpK+bGJFH1oM7naD5qDmHd89JyiKNT2oOKD8marW0QSBtuFnwEbL5aGCS8AmrhXQgNOsn4osAw==}
snabbdom@3.6.3:
resolution: {integrity: sha512-W2lHLLw2qR2Vv0DcMmcxXqcfdBaIcoN+y/86SmHv8fn4DazEQSH6KN3TjZcWvwujW56OHiiirsbHWZb4vx/0fg==}
engines: {node: '>=12.17.0'}
snapdragon-node@2.1.1: snapdragon-node@2.1.1:
resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
...@@ -3219,6 +3442,9 @@ packages: ...@@ -3219,6 +3442,9 @@ packages:
resolution: {integrity: sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==} resolution: {integrity: sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==}
engines: {node: '>=10.16.0'} engines: {node: '>=10.16.0'}
ssr-window@3.0.0:
resolution: {integrity: sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==}
stable@0.1.8: stable@0.1.8:
resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
...@@ -3333,6 +3559,9 @@ packages: ...@@ -3333,6 +3559,9 @@ packages:
text-decoder@1.2.3: text-decoder@1.2.3:
resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==}
tiny-warning@1.0.3:
resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
tinyexec@1.0.1: tinyexec@1.0.1:
resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==}
...@@ -3380,6 +3609,9 @@ packages: ...@@ -3380,6 +3609,9 @@ packages:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
type@2.7.3:
resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==}
typed-array-buffer@1.0.3: typed-array-buffer@1.0.3:
resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
...@@ -3660,6 +3892,9 @@ packages: ...@@ -3660,6 +3892,9 @@ packages:
engines: {node: ^18.17.0 || >=20.5.0} engines: {node: ^18.17.0 || >=20.5.0}
hasBin: true hasBin: true
wildcard@1.1.2:
resolution: {integrity: sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==}
word-wrap@1.2.5: word-wrap@1.2.5:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
...@@ -3888,6 +4123,8 @@ snapshots: ...@@ -3888,6 +4123,8 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@babel/runtime@7.28.4': {}
'@babel/template@7.27.2': '@babel/template@7.27.2':
dependencies: dependencies:
'@babel/code-frame': 7.27.1 '@babel/code-frame': 7.27.1
...@@ -4395,12 +4632,16 @@ snapshots: ...@@ -4395,12 +4632,16 @@ snapshots:
'@sxzz/popperjs-es@2.11.7': {} '@sxzz/popperjs-es@2.11.7': {}
'@transloadit/prettier-bytes@0.0.7': {}
'@trysound/sax@0.2.0': {} '@trysound/sax@0.2.0': {}
'@tsconfig/node22@22.0.2': {} '@tsconfig/node22@22.0.2': {}
'@types/estree@1.0.8': {} '@types/estree@1.0.8': {}
'@types/event-emitter@0.3.5': {}
'@types/json-schema@7.0.15': {} '@types/json-schema@7.0.15': {}
'@types/lodash-es@4.17.12': '@types/lodash-es@4.17.12':
...@@ -4558,13 +4799,13 @@ snapshots: ...@@ -4558,13 +4799,13 @@ snapshots:
sirv: 3.0.2 sirv: 3.0.2
vue-flow-layout: 0.2.0 vue-flow-layout: 0.2.0
'@unocss/postcss@66.5.4(postcss@8.5.6)': '@unocss/postcss@66.5.4(postcss@5.2.18)':
dependencies: dependencies:
'@unocss/config': 66.5.4 '@unocss/config': 66.5.4
'@unocss/core': 66.5.4 '@unocss/core': 66.5.4
'@unocss/rule-utils': 66.5.4 '@unocss/rule-utils': 66.5.4
css-tree: 3.1.0 css-tree: 3.1.0
postcss: 8.5.6 postcss: 5.2.18
tinyglobby: 0.2.15 tinyglobby: 0.2.15
'@unocss/preset-attributify@66.5.4': '@unocss/preset-attributify@66.5.4':
...@@ -4663,6 +4904,35 @@ snapshots: ...@@ -4663,6 +4904,35 @@ snapshots:
unplugin-utils: 0.3.1 unplugin-utils: 0.3.1
vite: 7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2) vite: 7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2)
'@uppy/companion-client@2.2.2':
dependencies:
'@uppy/utils': 4.1.3
namespace-emitter: 2.0.1
'@uppy/core@2.3.4':
dependencies:
'@transloadit/prettier-bytes': 0.0.7
'@uppy/store-default': 2.1.1
'@uppy/utils': 4.1.3
lodash.throttle: 4.1.1
mime-match: 1.0.2
namespace-emitter: 2.0.1
nanoid: 3.3.11
preact: 10.28.0
'@uppy/store-default@2.1.1': {}
'@uppy/utils@4.1.3':
dependencies:
lodash.throttle: 4.1.1
'@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4)':
dependencies:
'@uppy/companion-client': 2.2.2
'@uppy/core': 2.3.4
'@uppy/utils': 4.1.3
nanoid: 3.3.11
'@vitejs/plugin-vue-jsx@5.1.1(vite@7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2))(vue@3.5.22(typescript@5.9.3))': '@vitejs/plugin-vue-jsx@5.1.1(vite@7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2))(vue@3.5.22(typescript@5.9.3))':
dependencies: dependencies:
'@babel/core': 7.28.5 '@babel/core': 7.28.5
...@@ -4899,6 +5169,114 @@ snapshots: ...@@ -4899,6 +5169,114 @@ snapshots:
- '@vue/composition-api' - '@vue/composition-api'
- vue - vue
'@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)':
dependencies:
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
dom7: 3.0.0
is-url: 1.2.4
lodash.throttle: 4.1.1
nanoid: 3.3.11
slate: 0.72.8
snabbdom: 3.6.3
'@wangeditor/code-highlight@1.0.3(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.3)':
dependencies:
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
dom7: 3.0.0
prismjs: 1.30.0
slate: 0.72.8
snabbdom: 3.6.3
'@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)':
dependencies:
'@types/event-emitter': 0.3.5
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
dom7: 3.0.0
event-emitter: 0.3.5
html-void-elements: 2.0.1
i18next: 20.6.1
is-hotkey: 0.2.0
lodash.camelcase: 4.3.0
lodash.clonedeep: 4.5.0
lodash.debounce: 4.0.8
lodash.foreach: 4.5.0
lodash.isequal: 4.5.0
lodash.throttle: 4.1.1
lodash.toarray: 4.4.0
nanoid: 3.3.11
scroll-into-view-if-needed: 2.2.31
slate: 0.72.8
slate-history: 0.66.0(slate@0.72.8)
snabbdom: 3.6.3
'@wangeditor/editor-for-vue@5.1.12(@wangeditor/editor@5.1.23)(vue@3.5.22(typescript@5.9.3))':
dependencies:
'@wangeditor/editor': 5.1.23
vue: 3.5.22(typescript@5.9.3)
'@wangeditor/editor@5.1.23':
dependencies:
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
'@wangeditor/basic-modules': 1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
'@wangeditor/code-highlight': 1.0.3(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.3)
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
'@wangeditor/list-module': 1.0.5(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.3)
'@wangeditor/table-module': 1.1.4(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
'@wangeditor/upload-image-module': 1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.6.3)
'@wangeditor/video-module': 1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
dom7: 3.0.0
is-hotkey: 0.2.0
lodash.camelcase: 4.3.0
lodash.clonedeep: 4.5.0
lodash.debounce: 4.0.8
lodash.foreach: 4.5.0
lodash.isequal: 4.5.0
lodash.throttle: 4.1.1
lodash.toarray: 4.4.0
nanoid: 3.3.11
slate: 0.72.8
snabbdom: 3.6.3
'@wangeditor/list-module@1.0.5(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.3)':
dependencies:
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
dom7: 3.0.0
slate: 0.72.8
snabbdom: 3.6.3
'@wangeditor/table-module@1.1.4(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)':
dependencies:
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
dom7: 3.0.0
lodash.isequal: 4.5.0
lodash.throttle: 4.1.1
nanoid: 3.3.11
slate: 0.72.8
snabbdom: 3.6.3
'@wangeditor/upload-image-module@1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.6.3)':
dependencies:
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
'@wangeditor/basic-modules': 1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
dom7: 3.0.0
lodash.foreach: 4.5.0
slate: 0.72.8
snabbdom: 3.6.3
'@wangeditor/video-module@1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)':
dependencies:
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)
dom7: 3.0.0
nanoid: 3.3.11
slate: 0.72.8
snabbdom: 3.6.3
'@wecom/jssdk@2.3.3': {} '@wecom/jssdk@2.3.3': {}
abort-controller@3.0.0: abort-controller@3.0.0:
...@@ -5217,6 +5595,8 @@ snapshots: ...@@ -5217,6 +5595,8 @@ snapshots:
normalize-path: 3.0.0 normalize-path: 3.0.0
readable-stream: 4.7.0 readable-stream: 4.7.0
compute-scroll-into-view@1.0.20: {}
concat-map@0.0.1: {} concat-map@0.0.1: {}
confbox@0.1.8: {} confbox@0.1.8: {}
...@@ -5287,6 +5667,11 @@ snapshots: ...@@ -5287,6 +5667,11 @@ snapshots:
csstype@3.1.3: {} csstype@3.1.3: {}
d@1.0.2:
dependencies:
es5-ext: 0.10.64
type: 2.7.3
data-view-buffer@1.0.2: data-view-buffer@1.0.2:
dependencies: dependencies:
call-bound: 1.0.4 call-bound: 1.0.4
...@@ -5375,6 +5760,10 @@ snapshots: ...@@ -5375,6 +5760,10 @@ snapshots:
domhandler: 4.3.1 domhandler: 4.3.1
entities: 2.2.0 entities: 2.2.0
dom7@3.0.0:
dependencies:
ssr-window: 3.0.0
domelementtype@1.3.1: {} domelementtype@1.3.1: {}
domelementtype@2.3.0: {} domelementtype@2.3.0: {}
...@@ -5524,6 +5913,24 @@ snapshots: ...@@ -5524,6 +5913,24 @@ snapshots:
is-date-object: 1.1.0 is-date-object: 1.1.0
is-symbol: 1.1.1 is-symbol: 1.1.1
es5-ext@0.10.64:
dependencies:
es6-iterator: 2.0.3
es6-symbol: 3.1.4
esniff: 2.0.1
next-tick: 1.1.0
es6-iterator@2.0.3:
dependencies:
d: 1.0.2
es5-ext: 0.10.64
es6-symbol: 3.1.4
es6-symbol@3.1.4:
dependencies:
d: 1.0.2
ext: 1.7.0
esbuild@0.25.11: esbuild@0.25.11:
optionalDependencies: optionalDependencies:
'@esbuild/aix-ppc64': 0.25.11 '@esbuild/aix-ppc64': 0.25.11
...@@ -5637,6 +6044,13 @@ snapshots: ...@@ -5637,6 +6044,13 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
esniff@2.0.1:
dependencies:
d: 1.0.2
es5-ext: 0.10.64
event-emitter: 0.3.5
type: 2.7.3
espree@10.4.0: espree@10.4.0:
dependencies: dependencies:
acorn: 8.15.0 acorn: 8.15.0
...@@ -5663,6 +6077,11 @@ snapshots: ...@@ -5663,6 +6077,11 @@ snapshots:
etag@1.8.1: {} etag@1.8.1: {}
event-emitter@0.3.5:
dependencies:
d: 1.0.2
es5-ext: 0.10.64
event-target-shim@5.0.1: {} event-target-shim@5.0.1: {}
events-universal@1.0.1: events-universal@1.0.1:
...@@ -5687,6 +6106,10 @@ snapshots: ...@@ -5687,6 +6106,10 @@ snapshots:
exsolve@1.0.7: {} exsolve@1.0.7: {}
ext@1.7.0:
dependencies:
type: 2.7.3
extend-shallow@2.0.1: extend-shallow@2.0.1:
dependencies: dependencies:
is-extendable: 0.1.1 is-extendable: 0.1.1
...@@ -5932,6 +6355,8 @@ snapshots: ...@@ -5932,6 +6355,8 @@ snapshots:
hookable@5.5.3: {} hookable@5.5.3: {}
html-void-elements@2.0.1: {}
htmlparser2@3.10.1: htmlparser2@3.10.1:
dependencies: dependencies:
domelementtype: 1.3.1 domelementtype: 1.3.1
...@@ -5941,6 +6366,10 @@ snapshots: ...@@ -5941,6 +6366,10 @@ snapshots:
inherits: 2.0.4 inherits: 2.0.4
readable-stream: 3.6.2 readable-stream: 3.6.2
i18next@20.6.1:
dependencies:
'@babel/runtime': 7.28.4
iconv-lite@0.7.0: iconv-lite@0.7.0:
dependencies: dependencies:
safer-buffer: 2.1.2 safer-buffer: 2.1.2
...@@ -5953,6 +6382,8 @@ snapshots: ...@@ -5953,6 +6382,8 @@ snapshots:
image-size@0.5.5: {} image-size@0.5.5: {}
immer@9.0.21: {}
immutable@5.1.4: {} immutable@5.1.4: {}
import-fresh@3.3.1: import-fresh@3.3.1:
...@@ -6072,6 +6503,8 @@ snapshots: ...@@ -6072,6 +6503,8 @@ snapshots:
dependencies: dependencies:
is-extglob: 2.1.1 is-extglob: 2.1.1
is-hotkey@0.2.0: {}
is-inside-container@1.0.0: is-inside-container@1.0.0:
dependencies: dependencies:
is-docker: 3.0.0 is-docker: 3.0.0
...@@ -6097,6 +6530,8 @@ snapshots: ...@@ -6097,6 +6530,8 @@ snapshots:
dependencies: dependencies:
isobject: 3.0.1 isobject: 3.0.1
is-plain-object@5.0.0: {}
is-regex@1.2.1: is-regex@1.2.1:
dependencies: dependencies:
call-bound: 1.0.4 call-bound: 1.0.4
...@@ -6127,6 +6562,8 @@ snapshots: ...@@ -6127,6 +6562,8 @@ snapshots:
dependencies: dependencies:
which-typed-array: 1.1.19 which-typed-array: 1.1.19
is-url@1.2.4: {}
is-weakmap@2.0.2: {} is-weakmap@2.0.2: {}
is-weakref@1.1.1: is-weakref@1.1.1:
...@@ -6255,8 +6692,22 @@ snapshots: ...@@ -6255,8 +6692,22 @@ snapshots:
lodash: 4.17.21 lodash: 4.17.21
lodash-es: 4.17.21 lodash-es: 4.17.21
lodash.camelcase@4.3.0: {}
lodash.clonedeep@4.5.0: {}
lodash.debounce@4.0.8: {}
lodash.foreach@4.5.0: {}
lodash.isequal@4.5.0: {}
lodash.merge@4.6.2: {} lodash.merge@4.6.2: {}
lodash.throttle@4.1.1: {}
lodash.toarray@4.4.0: {}
lodash@4.17.21: {} lodash@4.17.21: {}
lru-cache@10.4.3: {} lru-cache@10.4.3: {}
...@@ -6316,6 +6767,10 @@ snapshots: ...@@ -6316,6 +6767,10 @@ snapshots:
mime-db@1.52.0: {} mime-db@1.52.0: {}
mime-match@1.0.2:
dependencies:
wildcard: 1.1.2
mime-types@2.1.35: mime-types@2.1.35:
dependencies: dependencies:
mime-db: 1.52.0 mime-db: 1.52.0
...@@ -6360,6 +6815,8 @@ snapshots: ...@@ -6360,6 +6815,8 @@ snapshots:
mute-stream@3.0.0: {} mute-stream@3.0.0: {}
namespace-emitter@2.0.1: {}
nan@2.23.1: nan@2.23.1:
optional: true optional: true
...@@ -6385,6 +6842,8 @@ snapshots: ...@@ -6385,6 +6842,8 @@ snapshots:
natural-compare@1.4.0: {} natural-compare@1.4.0: {}
next-tick@1.1.0: {}
node-addon-api@7.1.1: node-addon-api@7.1.1:
optional: true optional: true
...@@ -6591,6 +7050,8 @@ snapshots: ...@@ -6591,6 +7050,8 @@ snapshots:
posthtml-parser: 0.2.1 posthtml-parser: 0.2.1
posthtml-render: 1.4.0 posthtml-render: 1.4.0
preact@10.28.0: {}
prelude-ls@1.2.1: {} prelude-ls@1.2.1: {}
prettier-linter-helpers@1.0.0: prettier-linter-helpers@1.0.0:
...@@ -6599,6 +7060,8 @@ snapshots: ...@@ -6599,6 +7060,8 @@ snapshots:
prettier@3.6.2: {} prettier@3.6.2: {}
prismjs@1.30.0: {}
process-nextick-args@2.0.1: {} process-nextick-args@2.0.1: {}
process@0.11.10: {} process@0.11.10: {}
...@@ -6871,6 +7334,10 @@ snapshots: ...@@ -6871,6 +7334,10 @@ snapshots:
'@parcel/watcher': 2.5.1 '@parcel/watcher': 2.5.1
optional: true optional: true
scroll-into-view-if-needed@2.2.31:
dependencies:
compute-scroll-into-view: 1.0.20
scule@1.3.0: {} scule@1.3.0: {}
semver@6.3.1: {} semver@6.3.1: {}
...@@ -6950,6 +7417,19 @@ snapshots: ...@@ -6950,6 +7417,19 @@ snapshots:
mrmime: 2.0.1 mrmime: 2.0.1
totalist: 3.0.1 totalist: 3.0.1
slate-history@0.66.0(slate@0.72.8):
dependencies:
is-plain-object: 5.0.0
slate: 0.72.8
slate@0.72.8:
dependencies:
immer: 9.0.21
is-plain-object: 5.0.0
tiny-warning: 1.0.3
snabbdom@3.6.3: {}
snapdragon-node@2.1.1: snapdragon-node@2.1.1:
dependencies: dependencies:
define-property: 1.0.0 define-property: 1.0.0
...@@ -7005,6 +7485,8 @@ snapshots: ...@@ -7005,6 +7485,8 @@ snapshots:
cpu-features: 0.0.10 cpu-features: 0.0.10
nan: 2.23.1 nan: 2.23.1
ssr-window@3.0.0: {}
stable@0.1.8: {} stable@0.1.8: {}
static-extend@0.1.2: static-extend@0.1.2:
...@@ -7166,6 +7648,8 @@ snapshots: ...@@ -7166,6 +7648,8 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- react-native-b4a - react-native-b4a
tiny-warning@1.0.3: {}
tinyexec@1.0.1: {} tinyexec@1.0.1: {}
tinyglobby@0.2.15: tinyglobby@0.2.15:
...@@ -7213,6 +7697,8 @@ snapshots: ...@@ -7213,6 +7697,8 @@ snapshots:
dependencies: dependencies:
prelude-ls: 1.2.1 prelude-ls: 1.2.1
type@2.7.3: {}
typed-array-buffer@1.0.3: typed-array-buffer@1.0.3:
dependencies: dependencies:
call-bound: 1.0.4 call-bound: 1.0.4
...@@ -7314,12 +7800,12 @@ snapshots: ...@@ -7314,12 +7800,12 @@ snapshots:
universalify@2.0.1: {} universalify@2.0.1: {}
unocss@66.5.4(postcss@8.5.6)(vite@7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2)): unocss@66.5.4(postcss@5.2.18)(vite@7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2)):
dependencies: dependencies:
'@unocss/astro': 66.5.4(vite@7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2)) '@unocss/astro': 66.5.4(vite@7.1.12(@types/node@22.18.12)(jiti@2.6.1)(sass-embedded@1.93.2)(sass@1.93.2))
'@unocss/cli': 66.5.4 '@unocss/cli': 66.5.4
'@unocss/core': 66.5.4 '@unocss/core': 66.5.4
'@unocss/postcss': 66.5.4(postcss@8.5.6) '@unocss/postcss': 66.5.4(postcss@5.2.18)
'@unocss/preset-attributify': 66.5.4 '@unocss/preset-attributify': 66.5.4
'@unocss/preset-icons': 66.5.4 '@unocss/preset-icons': 66.5.4
'@unocss/preset-mini': 66.5.4 '@unocss/preset-mini': 66.5.4
...@@ -7580,6 +8066,8 @@ snapshots: ...@@ -7580,6 +8066,8 @@ snapshots:
dependencies: dependencies:
isexe: 3.1.1 isexe: 3.1.1
wildcard@1.1.2: {}
word-wrap@1.2.5: {} word-wrap@1.2.5: {}
wrap-ansi@7.0.0: wrap-ansi@7.0.0:
......
...@@ -312,3 +312,44 @@ export const addComplaint = (data: { articleId: number; reason: string }) => { ...@@ -312,3 +312,44 @@ export const addComplaint = (data: { articleId: number; reason: string }) => {
data, data,
}) })
} }
/**
* 问吧-获取回答列表的评论(二级评论)
*/
export const getSecondCommentList = (data: { pId: number }) => {
return service.request<boolean>({
url: `/api/cultureComment/getQuestionComment`,
method: 'POST',
data,
})
}
/**
* 问吧 获取二级评论的子评论
*/
export const getSecondCommentChildren = (data: {
pid: number
current: number
size: number
articleId: number
}) => {
return service.request<BackendServicePageResult<CommentItemDto>>({
url: `/api/cultureComment/comment/children`,
method: 'POST',
data,
})
}
/**
* 根据commentid 获取这个评论的详情
*/
export const getCommentDetail = (id: number) => {
return service.request<CommentItemDto>({
url: `/api/cultureComment/questionCommentData`,
method: 'POST',
data: {
id,
},
})
}
...@@ -143,11 +143,13 @@ ...@@ -143,11 +143,13 @@
class="cursor-pointer hover:text-blue-500 transition-colors" class="cursor-pointer hover:text-blue-500 transition-colors"
@click="handleReply(item)" @click="handleReply(item)"
> >
回复 回复111111111
</button> </button>
</div> </div>
</div> </div>
<!-- 回复列表 --> <!-- 回复列表 -->
<!-- 问吧 和 其他 做区分 -->
<template v-if="!isQuestion">
<div v-if="item.children?.length" class="mt-3 ml-4 space-y-3"> <div v-if="item.children?.length" class="mt-3 ml-4 space-y-3">
<!-- 回复评论的内容 里面可能是 展示全部的 也有可能是展示5条之内容 --> <!-- 回复评论的内容 里面可能是 展示全部的 也有可能是展示5条之内容 -->
<div <div
...@@ -200,6 +202,18 @@ ...@@ -200,6 +202,18 @@
</div> </div>
</div> </div>
</div> </div>
</template>
<!-- 问吧 如果有 子评论 直接变成 查看更多 -->
<template v-else>
<div v-if="item.childNum">
<button
class="cursor-pointer text-sm text-gray-500 mt-2"
@click="handleOpenCommentDialog(item)"
>
查看全部{{ item.childNum }} 条回复>
</button>
</div>
</template>
<!-- 只有大于5 才会显示这个 --> <!-- 只有大于5 才会显示这个 -->
<div class="ml-4" v-show="item.childrenNum > 5"> <div class="ml-4" v-show="item.childrenNum > 5">
<!-- 展示 展开回复 --> <!-- 展示 展开回复 -->
...@@ -293,27 +307,38 @@ ...@@ -293,27 +307,38 @@
</div> </div>
</div> </div>
</div> </div>
<CommentDialog ref="commentDialogRef" :articleId="id" :pid="currentDialogCommentPid" />
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { getCommentList, addOrCancelCommentLike, addComment, getCommentChildren } from '@/api' import {
getCommentList,
addOrCancelCommentLike,
addComment,
getCommentChildren,
getSecondCommentList,
} from '@/api'
import { usePageSearch, useScrollTop, useHintAnimation } from '@/hooks' import { usePageSearch, useScrollTop, useHintAnimation } from '@/hooks'
import { BooleanFlag } from '@/constants' import { BooleanFlag } from '@/constants'
import type { CommentItemDto } from '@/api' import type { CommentItemDto } from '@/api'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { useUserStore } from '@/stores' import { useUserStore } from '@/stores'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import CommentDialog from '../CommentDialog/index.vue'
const { const {
id, id,
defaultSize = 10, defaultSize = 10,
isReal, isReal,
immediate = true, immediate = true,
isQuestion = false,
commentId = 0,
} = defineProps<{ } = defineProps<{
id: number | string id: number
defaultSize?: number defaultSize?: number
isReal: BooleanFlag isReal: BooleanFlag
isQuestion?: boolean // 如果是问题的话 展示有点不一样
immediate?: boolean immediate?: boolean
commentId?: number // 如果是问题的话 需要传入评论id
}>() }>()
const emit = defineEmits<{ const emit = defineEmits<{
...@@ -326,8 +351,9 @@ const total = defineModel<number>('total', { required: true, default: 0 }) ...@@ -326,8 +351,9 @@ const total = defineModel<number>('total', { required: true, default: 0 })
const userStore = useUserStore() const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore) const { userInfo } = storeToRefs(userStore)
const userAvatar = computed(() => (isReal ? userInfo.value.avatar : userInfo.value.hiddenAvatar)) const userAvatar = computed(() => (isReal ? userInfo.value.avatar : userInfo.value.hiddenAvatar))
console.log(userAvatar)
const commentRef = useTemplateRef<HTMLElement | null>('commentRef') const commentRef = useTemplateRef<HTMLElement | null>('commentRef')
const commentDialogRef = useTemplateRef<HTMLElement | null>('commentDialogRef')
const commentInputRef = useTemplateRef<HTMLElement | null>('commentInputRef') const commentInputRef = useTemplateRef<HTMLElement | null>('commentInputRef')
const commentItemRefList = ref<HTMLElement[]>([]) const commentItemRefList = ref<HTMLElement[]>([])
// 回滚到评论框 // 回滚到评论框
...@@ -340,11 +366,15 @@ const { triggerAnimation } = useHintAnimation(commentInputRef, { ...@@ -340,11 +366,15 @@ const { triggerAnimation } = useHintAnimation(commentInputRef, {
}) })
const { list, searchParams, goToPage, loading, changePageSize, refresh, search } = usePageSearch( const { list, searchParams, goToPage, loading, changePageSize, refresh, search } = usePageSearch(
getCommentList, isQuestion ? getSecondCommentList : getCommentList,
{ {
defaultParams: { defaultParams: {
...(commentId
? { pid: commentId, sortType: 2 }
: {
articleId: id, articleId: id,
sortType: 2, sortType: 2,
}),
}, },
defaultSize, defaultSize,
formatList(list: CommentItemDto[]) { formatList(list: CommentItemDto[]) {
...@@ -422,6 +452,7 @@ const handleMyComment = async () => { ...@@ -422,6 +452,7 @@ const handleMyComment = async () => {
await addComment({ await addComment({
articleId: id, articleId: id,
content: myComment.value, content: myComment.value,
...(commentId ? { pid: commentId } : {}),
}) })
ElMessage.success('发表评论成功') ElMessage.success('发表评论成功')
refresh() refresh()
...@@ -497,6 +528,12 @@ const handleUserInfo = (item: CommentItemDto) => { ...@@ -497,6 +528,12 @@ const handleUserInfo = (item: CommentItemDto) => {
router.push(`/otherUserPage/${item.userId}/${isReal}`) router.push(`/otherUserPage/${item.userId}/${isReal}`)
} }
const currentDialogCommentPid = ref(0)
const handleOpenCommentDialog = (item: CommentItemDto) => {
currentDialogCommentPid.value = item.id
commentDialogRef.value?.open()
}
defineExpose({ defineExpose({
scrollToCommentBox: () => handleBackTop(), scrollToCommentBox: () => handleBackTop(),
search: () => search(), search: () => search(),
......
<template>
<el-dialog
v-model="visible"
:title="dialogTitle"
width="600px"
class="comment-reply-dialog rounded-xl overflow-hidden"
:show-close="false"
append-to-body
destroy-on-close
>
<!-- 自定义头部 -->
<template #header="{ close, titleId, titleClass }">
<div class="flex items-center gap-2 py-2 border-b border-gray-100">
<el-icon class="cursor-pointer hover:text-blue-500" @click="close" :size="20">
<ArrowLeft />
</el-icon>
<span :id="titleId" :class="titleClass" class="text-base font-bold text-gray-800"
>评论回复</span
>
</div>
</template>
<div class="flex flex-col h-[70vh]">
<!-- 中间滚动区域 -->
<div class="flex-1 overflow-y-auto custom-scrollbar p-4" ref="scrollContainer">
<!-- 1. 顶部:父级评论展示 -->
<div v-if="parentComment" class="flex gap-3 mb-6">
<img
:src="parentComment.hiddenAvatar"
class="w-10 h-10 rounded-full object-cover border border-gray-100"
/>
<div class="flex-1">
<div class="flex items-center justify-between mb-1">
<span class="font-bold text-gray-900 text-sm">{{ parentComment.hiddenName }}</span>
<!-- 点赞按钮 -->
<div
class="flex items-center gap-1 cursor-pointer text-gray-400 hover:text-blue-500 transition-colors"
@click="handleLike(parentComment)"
>
<el-icon :size="16">
<svg-icon :name="parentComment.hasPraise ? 'praise_fill' : 'praise'"></svg-icon>
</el-icon>
<span class="text-xs">{{ parentComment.postPriseCount || 0 }}</span>
</div>
</div>
<p class="text-gray-800 text-sm leading-relaxed mb-2">{{ parentComment.content }}</p>
<div class="text-xs text-gray-400 flex items-center gap-3">
<span>{{ dayjs(parentComment.createTime * 1000).format('MM-DD HH:mm') }}</span>
<!-- <span>IP: {{ parentComment.ipLocation || '未知' }}</span> -->
<!-- <span class="bg-red-50 text-red-500 px-1.5 py-0.5 rounded text-[10px]">热评</span> -->
</div>
</div>
</div>
<!-- 分割线 & 统计 -->
<div class="h-2 bg-gray-50 -mx-4 mb-4"></div>
<div class="text-sm font-bold text-gray-800 mb-4">{{ total }} 条回复</div>
<!-- 2. 下方:回复列表 -->
<div v-loading="loading" class="space-y-6">
<div v-for="item in list" :key="item.id" class="flex gap-3 relative group">
<img
:src="item.avatar"
class="w-8 h-8 rounded-full object-cover cursor-pointer hover:opacity-80"
@click="handleUserInfo(item)"
/>
<div class="flex-1 border-b border-gray-50 pb-4">
<div class="flex items-center justify-between mb-1">
<div class="flex items-center gap-2">
<span class="font-semibold text-gray-800 text-sm">{{ item.replyUser }}</span>
<span
v-if="item.replyName && item.replyName !== parentComment?.replyUser"
class="text-gray-400 text-xs flex items-center"
>
<el-icon class="mx-1"><CaretRight /></el-icon>
{{ item.replyName }}
</span>
</div>
<!-- 列表项点赞 -->
<div class="flex items-center gap-4">
<div
class="flex items-center gap-1 cursor-pointer text-gray-400 hover:text-blue-500 transition-colors"
@click="handleReplyInline(item)"
>
<span class="text-xs">回复</span>
</div>
<div
class="flex items-center gap-1 cursor-pointer text-gray-400 hover:text-blue-500 transition-colors"
@click="handleLike(item)"
>
<el-icon :size="16">
<svg-icon :name="item.hasPraise ? 'praise_fill' : 'praise'"></svg-icon>
</el-icon>
<span class="text-xs">{{ item.postPriseCount || 0 }}</span>
</div>
</div>
</div>
<p class="text-gray-700 text-sm mb-2 break-all">{{ item.content }}</p>
<div class="text-xs text-gray-400">
<span>{{ formatDate(item.createTime) }}</span>
</div>
<!-- 内嵌回复框 (点击列表回复按钮出现) -->
<div
v-if="currentInlineReplyId === item.id"
class="mt-3 bg-gray-50 p-3 rounded-lg border border-gray-100 animate-fade-in"
>
<el-input
v-model="inlineCommentContent"
type="textarea"
:rows="2"
:placeholder="`回复 ${item.replyUser}`"
class="bg-white mb-2"
resize="none"
/>
<div class="flex justify-between items-center">
<div class="flex gap-2 text-gray-400 text-lg">
<i class="cursor-pointer i-carbon-face-satisfied hover:text-yellow-500"></i>
<i class="cursor-pointer i-carbon-image hover:text-blue-500"></i>
</div>
<el-button
type="primary"
size="small"
class="!rounded-full !px-4"
:disabled="!inlineCommentContent.trim()"
@click="submitReply(item.id)"
>
发布
</el-button>
</div>
</div>
</div>
</div>
<!-- 加载更多 / 分页 -->
<div class="flex justify-end py-4" v-if="total > 0">
<el-pagination
v-model:current-page="searchParams.current"
:page-size="searchParams.size"
:total="total"
layout="prev, pager, next"
small
background
@current-change="goToPage"
@size-change="changePageSize"
/>
</div>
<el-empty v-if="!loading && list.length === 0" description="暂无回复" :image-size="60" />
</div>
</div>
<!-- 3. 底部固定回复框 (回复给最上方的父评论) -->
<div
class="border-t border-gray-100 p-3 bg-white flex items-center gap-3 z-10 shadow-[0_-2px_10px_rgba(0,0,0,0.02)]"
>
<img :src="currentUserAvatar" class="w-8 h-8 rounded-full object-cover" />
<div
class="flex-1 bg-gray-100 rounded-full px-4 py-2 flex items-center cursor-text hover:bg-gray-200 transition-colors"
@click="focusBottomInput"
>
<input
ref="bottomInputRef"
v-model="bottomCommentContent"
type="text"
class="bg-transparent w-full outline-none text-sm text-gray-700 placeholder-gray-400"
:placeholder="`回复 ${parentComment?.replyUser || '...'}`"
@keyup.enter="submitReply(parentComment?.id)"
/>
</div>
<el-button
type="primary"
circle
:disabled="!bottomCommentContent.trim()"
@click="submitReply(parentComment?.id)"
>
<el-icon><Position /></el-icon>
</el-button>
</div>
</div>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, reactive, computed, nextTick } from 'vue'
import { ArrowLeft, Star, StarFilled, CaretRight, Position } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import dayjs from 'dayjs'
import { useUserStore } from '@/stores'
import { storeToRefs } from 'pinia'
import {
getSecondCommentChildren,
addComment,
addOrCancelCommentLike,
getCommentDetail,
} from '@/api'
import type { CommentItemDto } from '@/api'
import { BooleanFlag } from '@/constants'
import { usePageSearch } from '@/hooks' // 假设你有这个hook
// Props
const { articleId, pid } = defineProps<{
articleId: number
pid: number
}>()
const emit = defineEmits<{
(e: 'refresh'): void // 通知父组件刷新
}>()
// Store
const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const currentUserAvatar = computed(() => userInfo.value.hiddenAvatar)
// State
const visible = ref(false)
const parentComment = ref<CommentItemDto | null>(null)
const dialogTitle = ref('详情')
// Inline Reply State
const currentInlineReplyId = ref<number | null>(null)
const inlineCommentContent = ref('')
const bottomCommentContent = ref('')
const bottomInputRef = ref<HTMLInputElement>()
const scrollContainer = ref<HTMLElement>()
// --- Actions ---
const { list, total, search, searchParams, goToPage, changePageSize } = usePageSearch(
getSecondCommentChildren,
{
defaultParams: {
articleId: articleId,
pid: 0,
},
immediate: false,
},
)
const open = async (item: CommentItemDto) => {
// const { data } = await getSecondCommentChildren({
// pid: item.id,
// current: 1,
// size: 10,
// articleId: articleId,
// })
// console.log('res', data)
// list.value = data.list
// parentComment.value = item
// // Reset state
// currentInlineReplyId.value = null
// inlineCommentContent.value = ''
// bottomCommentContent.value = ''
console.log('pid', pid)
await nextTick()
searchParams.value.pid = pid
search()
const { data } = await getCommentDetail(pid)
console.log('data', data)
parentComment.value = data
visible.value = true
}
const close = () => {
visible.value = false
}
const formatDate = (time: number) => {
return dayjs(time * 1000).format('MM-DD HH:mm')
}
// 点击列表中的“回复”
const handleReplyInline = (item: CommentItemDto) => {
if (currentInlineReplyId.value === item.id) {
currentInlineReplyId.value = null // Toggle off
} else {
currentInlineReplyId.value = item.id
inlineCommentContent.value = '' // Clear previous
}
}
// 聚焦底部输入框
const focusBottomInput = () => {
bottomInputRef.value?.focus()
}
// 提交评论 (共用逻辑)
// targetId: 如果是回复父评论,传 parentComment.id;如果是回复子评论,传 item.id
const submitReply = async (targetId: number | undefined) => {
if (!targetId) return
// 判断使用的是哪个输入框的内容
const isBottom = targetId === parentComment.value?.id
const content = isBottom ? bottomCommentContent.value : inlineCommentContent.value
if (!content.trim()) return
try {
await addComment({
articleId: articleId,
content: content,
pid: targetId, // 这里的pid逻辑根据您的后端接口来,通常回复子评论也是传该子评论ID作为pid
})
ElMessage.success('回复成功')
// 清空输入框
if (isBottom) {
bottomCommentContent.value = ''
} else {
inlineCommentContent.value = ''
currentInlineReplyId.value = null
}
// 刷新列表
refresh()
// 通知父组件可能需要更新评论数
emit('refresh')
} catch (error) {
console.error(error)
}
}
// 点赞
const handleLike = async (item: CommentItemDto) => {
try {
await addOrCancelCommentLike(item.id)
// 乐观更新 UI
if (item.hasPraise === BooleanFlag.YES) {
item.hasPraise = BooleanFlag.NO
item.postPriseCount--
} else {
item.hasPraise = BooleanFlag.YES
item.postPriseCount++
}
} catch (error) {
console.error(error)
}
}
const handleUserInfo = (item: CommentItemDto) => {
// 您的跳转逻辑
// router.push(...)
}
defineExpose({
open,
})
</script>
<style scoped lang="scss">
/* 使用 UnoCSS 这里写一些 Element Plus 的样式覆盖 */
:deep(.el-dialog__header) {
margin-right: 0;
padding: 0 16px;
}
:deep(.el-dialog__body) {
padding: 0;
}
/* 自定义滚动条 */
.custom-scrollbar::-webkit-scrollbar {
width: 6px;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background-color: #e5e7eb;
border-radius: 4px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background-color: transparent;
}
.animate-fade-in {
animation: fadeIn 0.2s ease-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(-5px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>
<template>
<div style="border: 1px solid #ccc" class="h-full">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 500px; overflow-y: hidden"
v-model="valueHtml"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="handleCreated"
/>
</div>
</template>
<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { onBeforeUnmount, ref, shallowRef, onMounted } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { uploadFile } from '@/api'
const mode = 'default'
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef()
// 内容 HTML
const valueHtml = defineModel<string>()
// 模拟 ajax 异步获取内容
onMounted(() => {
setTimeout(() => {
valueHtml.value = '<p>模拟 Ajax 异步设置内容</p>'
}, 1500)
})
const toolbarConfig = {}
const editorConfig = { placeholder: '请输入内容...', MENU_CONF: {} }
// 修改 uploadImage 菜单配置
editorConfig.MENU_CONF['uploadImage'] = {
customUpload: async (file, insertFn) => {
const { data } = await uploadFile(file)
console.log(data)
insertFn(data.data[0].filePath)
},
}
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value
if (editor == null) return
editor.destroy()
})
const handleCreated = (editor) => {
editorRef.value = editor // 记录 editor 实例,重要!
}
</script>
...@@ -6,6 +6,7 @@ export enum ArticleTypeEnum { ...@@ -6,6 +6,7 @@ export enum ArticleTypeEnum {
COLUMN = 'column', // 专栏 COLUMN = 'column', // 专栏
PRACTICE = 'practice', // 实践 PRACTICE = 'practice', // 实践
INTERVIEW = 'interview', // 专访 INTERVIEW = 'interview', // 专访
LONG_ARTICLE = 'longArticle', // 长文章
} }
// 发布状态枚举 // 发布状态枚举
......
...@@ -87,6 +87,7 @@ ...@@ -87,6 +87,7 @@
>专访</el-dropdown-item >专访</el-dropdown-item
> >
</el-dropdown-menu> </el-dropdown-menu>
<el-dropdown-item :command="ArticleTypeEnum.LONG_ARTICLE">长文章</el-dropdown-item>
</template> </template>
</el-dropdown> </el-dropdown>
</div> </div>
...@@ -154,6 +155,8 @@ const handlePost = async (type: ArticleTypeEnum) => { ...@@ -154,6 +155,8 @@ const handlePost = async (type: ArticleTypeEnum) => {
router.push('/publishVideo') router.push('/publishVideo')
} else if (type === ArticleTypeEnum.QUESTION) { } else if (type === ArticleTypeEnum.QUESTION) {
router.push(`/homePage/askTab#tabsRef?t=${Date.now()}`) router.push(`/homePage/askTab#tabsRef?t=${Date.now()}`)
} else if (type === ArticleTypeEnum.LONG_ARTICLE) {
router.push('/publishLongArticle')
} else { } else {
PublishDialogRef.value?.open(type) PublishDialogRef.value?.open(type)
} }
......
...@@ -166,6 +166,11 @@ export const constantsRoute = [ ...@@ -166,6 +166,11 @@ export const constantsRoute = [
name: 'CultureQuestionDetail', name: 'CultureQuestionDetail',
component: () => import('@/views/questionDetail/index.vue'), component: () => import('@/views/questionDetail/index.vue'),
}, },
{
path: 'publishLongArticle',
name: 'CulturePublishLongArticle',
component: () => import('@/views/publishLongArticle/index.vue'),
},
// 发布文章 // 发布文章
// { // {
// { // {
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
<!-- 问题标题 --> <!-- 问题标题 -->
<h2 <h2
class="text-xl line-clamp-1 font-semibold text-gray-900 mb-2 leading-relaxed cursor-pointer hover:text-blue-600 transition-colors" class="text-xl line-clamp-1 font-semibold text-gray-900 mb-2 leading-relaxed cursor-pointer hover:text-blue-600 transition-colors"
@click="router.push(`/questionDetail/${item.id}`)" @click="openNewPage(`/questionDetail/${item.id}`)"
> >
{{ item.title }} {{ item.title }}
</h2> </h2>
...@@ -158,6 +158,8 @@ ...@@ -158,6 +158,8 @@
:defaultSize="5" :defaultSize="5"
:isReal="0" :isReal="0"
:immediate="false" :immediate="false"
:isQuestion="true"
:commentId="item.cultureCommentListVo?.id"
@commentSuccess="() => handleCommentSuccess(item)" @commentSuccess="() => handleCommentSuccess(item)"
/> />
</Transition> </Transition>
...@@ -216,11 +218,15 @@ import { TABS_REF_KEY } from '@/constants' ...@@ -216,11 +218,15 @@ import { TABS_REF_KEY } from '@/constants'
import PublishBox from '@/components/common/PublishBox/index.vue' import PublishBox from '@/components/common/PublishBox/index.vue'
import { ArticleTypeEnum } from '@/constants' import { ArticleTypeEnum } from '@/constants'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { getArticleList, addOrCanceArticlelCollect, addOrCancelToAnswerList } from '@/api' import {
getArticleList,
addOrCanceArticlelCollect,
addOrCancelToAnswerList,
getSecondCommentList,
} from '@/api'
import type { ArticleItemDto } from '@/api/article/types' import type { ArticleItemDto } from '@/api/article/types'
import { useQuestionStore } from '@/stores/question' import { useQuestionStore } from '@/stores/question'
import ActionMore from '@/components/common/ActionMore/index.vue' import ActionMore from '@/components/common/ActionMore/index.vue'
import router from '@/router'
const { fetchUserQestionNum } = useQuestionStore() const { fetchUserQestionNum } = useQuestionStore()
...@@ -307,6 +313,10 @@ const handleExpand = (item: ArticleItemDto) => { ...@@ -307,6 +313,10 @@ const handleExpand = (item: ArticleItemDto) => {
item.isExpand = !item.isExpand item.isExpand = !item.isExpand
} }
const openNewPage = (path: string) => {
window.open(path)
}
// 是否打开漫游 // 是否打开漫游
watch( watch(
() => route.fullPath, () => route.fullPath,
...@@ -325,6 +335,10 @@ onActivated(async () => { ...@@ -325,6 +335,10 @@ onActivated(async () => {
} }
refresh() refresh()
}) })
onMounted(() => {
console.log('父组件onmounted')
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.fade-enter-from, .fade-enter-from,
......
<template>
<div class="min-h-screen bg-[#fff] p-6 font-sans">
<div class="max-w-7xl mx-auto">
<!-- 顶部面包屑或标题(可选) -->
<el-form :model="form" label-position="top" class="grid grid-cols-12 gap-6 items-start">
<!-- 左侧:沉浸式创作区 (占 9 列) -->
<div class="col-span-12 lg:col-span-9 space-y-6">
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-8 min-h-[80vh]">
<!-- 标题输入:模拟大标题风格,去掉边框 -->
<el-form-item prop="title" class="mb-6 !border-b !border-gray-100 pb-2">
<el-input
v-model="form.title"
placeholder="请输入文章标题..."
class="title-input"
:maxlength="100"
show-word-limit
type="textarea"
:autosize="{ minRows: 1, maxRows: 2 }"
resize="none"
/>
</el-form-item>
<!-- 富文本编辑器 -->
<div class="editor-container">
<WangEditor v-model="form.content" style="height: 600px" />
</div>
</div>
</div>
<!-- 右侧:配置侧边栏 (占 3 列,吸顶) -->
<div class="col-span-12 lg:col-span-3 space-y-4 sticky top-4">
<!-- 卡片1:基础设置 -->
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
<div class="font-bold text-gray-800 mb-4 flex items-center gap-2">
<div class="w-1 h-4 bg-blue-500 rounded-full"></div>
基础设置
</div>
<!-- 文章类型 -->
<el-form-item label="文章类型" prop="type">
<el-radio-group v-model="form.type" class="w-full grid grid-cols-3 gap-2">
<el-radio-button :value="ArticleTypeEnum.POST">帖子</el-radio-button>
<el-radio-button :value="ArticleTypeEnum.COLUMN">专栏</el-radio-button>
<el-radio-button :value="ArticleTypeEnum.INTERVIEW">专访</el-radio-button>
</el-radio-group>
</el-form-item>
<!-- 封面图 -->
<el-form-item label="封面图" prop="faceUrl">
<div class="w-full">
<UploadFile v-model="form.faceUrl" :limit="1" class="w-full" />
<div class="text-xs text-gray-400 mt-2">建议尺寸 16:9,支持 jpg/png</div>
</div>
</el-form-item>
</div>
<!-- 卡片2:高级配置 (专栏/专访特有) -->
<template
v-if="form.type === ArticleTypeEnum.COLUMN || form.type === ArticleTypeEnum.INTERVIEW"
>
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
<div class="font-bold text-gray-800 mb-4 flex items-center gap-2">
<div class="w-1 h-4 bg-purple-500 rounded-full"></div>
专栏配置
</div>
<el-form-item label="所属栏目" prop="relateColumnId">
<el-select
v-model="form.relateColumnId"
placeholder="请选择专栏栏目"
class="w-full"
>
<el-option
v-for="item in columnList"
:key="item.id"
:value="item.id"
:label="item.title"
/>
</el-select>
</el-form-item>
<el-form-item label="主标签" prop="mainTagId">
<SelectTags v-model="form.mainTagId" class="w-full" />
</el-form-item>
<el-form-item label="副标签">
<SelectTags
v-model="form.tagList"
:filter-tags-fn="filterTagsFn"
:max-selected-tags="3"
class="w-full"
/>
</el-form-item>
<el-form-item label="推荐设置">
<div class="flex items-center justify-between w-full">
<span class="text-gray-600 text-sm">是否推荐</span>
<el-switch
v-model="form.isRecommend"
:active-value="BooleanFlag.YES"
:inactive-value="BooleanFlag.NO"
/>
</div>
</el-form-item>
<el-form-item v-if="form.type === ArticleTypeEnum.COLUMN">
<div class="flex items-center justify-between w-full">
<span class="text-gray-600 text-sm">同步同事吧</span>
<el-switch
v-model="form.isRelateColleague"
:active-value="BooleanFlag.YES"
:inactive-value="BooleanFlag.NO"
/>
</div>
</el-form-item>
</div>
</template>
<!-- 卡片3:发布设置 -->
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-5">
<div class="font-bold text-gray-800 mb-4 flex items-center gap-2">
<div class="w-1 h-4 bg-orange-500 rounded-full"></div>
发布设置
</div>
<el-form-item prop="sendType" class="!mb-2">
<el-radio-group v-model="form.sendType" class="flex flex-col gap-3 w-full">
<div
class="flex items-center p-3 rounded-lg border cursor-pointer transition-all"
:class="
form.sendType === SendTypeEnum.IMMEDIATE
? 'border-blue-500 bg-blue-50'
: 'border-gray-200 hover:border-blue-300'
"
@click="form.sendType = SendTypeEnum.IMMEDIATE"
>
<el-radio :value="SendTypeEnum.IMMEDIATE" class="!mr-2">立即发布</el-radio>
<span class="text-xs text-gray-400 ml-auto">当前时间</span>
</div>
<div
class="flex flex-col p-3 rounded-lg border cursor-pointer transition-all"
:class="
form.sendType === SendTypeEnum.SCHEDULED
? 'border-blue-500 bg-blue-50'
: 'border-gray-200 hover:border-blue-300'
"
@click="form.sendType = SendTypeEnum.SCHEDULED"
>
<div class="flex items-center mb-2">
<el-radio :value="SendTypeEnum.SCHEDULED" class="!mr-2">定时发布</el-radio>
</div>
<el-date-picker
v-if="form.sendType === SendTypeEnum.SCHEDULED"
v-model="form.sendTime"
type="datetime"
placeholder="选择时间"
class="!w-full"
:disabled-date="
(time: Date) => time.getTime() < Date.now() - 1000 * 60 * 60 * 24
"
value-format="X"
size="small"
/>
</div>
</el-radio-group>
</el-form-item>
</div>
<div class="mb-6 flex items-center justify-end w-full">
<div class="flex gap-3">
<el-button type="primary" round class="!px-8 w-full!" @click="handlePublish">
发布
</el-button>
</div>
</div>
</div>
</el-form>
</div>
</div>
</template>
<script setup lang="ts">
import WangEditor from '@/components/common/WangEditor/index.vue'
import { ArticleTypeEnum, SendTypeEnum, BooleanFlag, ReleaseStatusTypeEnum } from '@/constants'
import UploadFile from '@/components/common/UploadFile/index.vue'
import { useResetData } from '@/hooks'
import { useColumnStore } from '@/stores/column'
import { storeToRefs } from 'pinia'
import { addOrUpdateArticle } from '@/api'
// ... (逻辑部分保持不变,直接复用您的即可)
const columnStore = useColumnStore()
const { columnList } = storeToRefs(columnStore)
const [form, resetForm] = useResetData({
articleType: ArticleTypeEnum.POST,
title: '',
content: '',
faceUrl: '',
relateColumnId: null, // 建议初始值设为null或undefined,配合placeholder
mainTagId: '',
tagList: [],
isRelateColleague: BooleanFlag.NO,
isRecommend: BooleanFlag.NO,
sendType: SendTypeEnum.IMMEDIATE,
sendTime: '',
releaseStatus: ReleaseStatusTypeEnum.PUBLISH,
})
const filterTagsFn = (allTags: any[]) => {
return allTags.filter((tag) => tag.id !== Number(form.value.mainTagId))
}
const handlePublish = async () => {
const res = await addOrUpdateArticle(form.value)
console.log(res)
}
</script>
<style scoped lang="scss">
/* 覆盖 Element Plus 默认样式,使其更符合大标题风格 */
:deep(.title-input .el-textarea__inner) {
font-size: 24px;
font-weight: bold;
color: #333;
padding: 0;
border: none;
box-shadow: none;
background: transparent;
&::placeholder {
color: #a8abb2;
}
}
/* 隐藏 Radio Button 的圆点,改用卡片选择样式时需要 */
:deep(.el-radio-button__inner) {
border-radius: 8px !important;
border: 1px solid #dcdfe6;
border-left: 1px solid #dcdfe6 !important;
box-shadow: none !important;
padding: 8px 16px;
width: 100%;
}
:deep(.el-radio-button:first-child .el-radio-button__inner) {
border-left: 1px solid #dcdfe6;
}
:deep(.el-radio-button__original-radio:checked + .el-radio-button__inner) {
background-color: #ecf5ff;
border-color: #409eff;
color: #409eff;
box-shadow: none;
}
/* 让侧边栏标签文字稍微小一点 */
:deep(.el-form-item__label) {
font-weight: 500;
color: #4b5563;
}
</style>
<script setup lang="ts">
import { ref } from 'vue'
import { CaretTop, CaretBottom, ChatDotRound, Share, Star, Plus } from '@element-plus/icons-vue'
// --- 模拟数据 ---
const tags = ref([
{ id: 1, name: 'React' },
{ id: 2, name: 'Vue.js' },
])
const question = ref({
title: 'vue转react是什么感受?',
description:
'最近在面试,有一家公司各方面都很满意,但是因为他们是做阿里巴巴网店模板,只能用react写,所以要考虑学习react,来知乎问问各位大佬意见...',
viewCount: '12,304',
followCount: 52,
})
const answers = ref([
{
id: 1,
user: {
name: '我们',
avatar: 'https://picsum.photos/id/64/100/100',
bio: '各位都脑测了就回复了,你们的一切脑测都是对的',
},
votes: 2,
content: '什么时候这群人才能明白框架没那么重要,重要的是逻辑能力和代码水平',
publishDate: '2025-10-13 11:42',
commentCount: 0,
},
{
id: 2,
user: {
name: '老富甲',
avatar: 'https://picsum.photos/id/1025/100/100',
bio: '程序员',
},
votes: 12,
content: `初入前端的时候,写的是 vue 2,非常简单的就入门了,然后就是自己研究html和css,对调样式很感兴趣,乐在其中。<br><br>换公司学 react,由于连 ts 都不会,同时学 react 官网和 ts 官网,两个官网都撸了4-5遍,差不多3天吧,就差不多能写基础的页面了,后续就是熟练度问题了,然后就是要学习各种组件库,其实还好,不会很难的,并且会了之后感觉很爽,比写vue爽了非常非常多。<br><br>写 react 我感觉就是比写 vue 更有激情,可能因为 vscode 对 ts、react 的插件体验更好点...`,
publishDate: '2025-10-12 18:20',
commentCount: 2,
},
])
const isFollowing = ref(false)
</script>
<template> <template>
<div class="min-h-screen p-6 font-sans text-gray-800 flex justify-center"> <div class="min-h-screen p-6 font-sans text-gray-800 flex justify-center">
<!-- <!--
...@@ -70,12 +22,12 @@ const isFollowing = ref(false) ...@@ -70,12 +22,12 @@ const isFollowing = ref(false)
<!-- 标题 --> <!-- 标题 -->
<h1 class="text-2xl font-bold text-gray-900 mb-3 leading-snug"> <h1 class="text-2xl font-bold text-gray-900 mb-3 leading-snug">
{{ question.title }} {{ questionDetail.title }}
</h1> </h1>
<!-- 描述 --> <!-- 描述 -->
<p class="text-gray-600 leading-relaxed mb-6 text-sm md:text-base"> <p class="text-gray-600 leading-relaxed mb-6 text-sm md:text-base">
{{ question.description }} {{ questionDetail.description }}
<span class="text-blue-600 cursor-pointer hover:underline text-sm font-medium ml-1" <span class="text-blue-600 cursor-pointer hover:underline text-sm font-medium ml-1"
>显示全部</span >显示全部</span
> >
...@@ -213,11 +165,23 @@ const isFollowing = ref(false) ...@@ -213,11 +165,23 @@ const isFollowing = ref(false)
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts">
import { getArticleDetail } from '@/api/article'
import type { ArticleItemDto } from '@/api/article/types'
<style scoped> const route = useRoute()
/* const questionId = route.params.id as string
样式微调:
1. 卡片边框改为 border-gray-100,这是一种极淡的边框,配合阴影,质感更细腻。 const questionDetail = ref<ArticleItemDto>({} as ArticleItemDto)
2. 字体大小微调:正文使用 text-sm md:text-base,让信息密度稍微高一点,更像知乎PC端的阅读体验。
*/ const getQuestionDetail = async () => {
</style> const res = await getArticleDetail(questionId)
console.log(res)
}
getQuestionDetail()
onMounted(() => {
getQuestionDetail()
})
</script>
<style scoped></style>
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