sheldon 1 mesiac pred
rodič
commit
4d5e4a175c

+ 1 - 1
.env.development

@@ -1,7 +1,7 @@
 # 应用配置面板
 VITE_APP_SETTING = false
 # 页面标题
-VITE_APP_TITLE = Anycall|AI HUB
+VITE_APP_TITLE = Anycall AI HUB
 # 接口请求地址,会设置到 axios 的 baseURL 参数上
 VITE_APP_API_BASEURL = https://dev.nexthuman.cn/fara/api
 # 上传文件接口地址cdn

+ 1 - 1
.env.prod

@@ -1,7 +1,7 @@
 # 应用配置面板
 VITE_APP_SETTING = true
 # 页面标题
-VITE_APP_TITLE = Anycall|AI HUB
+VITE_APP_TITLE = Anycall AI HUB
 VITE_BASE_URL = https://dev.nexthuman.cn
 # 接口请求地址,会设置到 axios 的 baseURL 参数上
 VITE_APP_API_BASEURL = 	https://dev.nexthuman.cn/fara/api

+ 0 - 2
package.json

@@ -23,7 +23,6 @@
     "@antv/g2plot": "^2.4.33",
     "@bytemd/plugin-gfm": "^1.22.0",
     "@bytemd/vue-next": "^1.22.0",
-    "@tinymce/tinymce-vue": "^6.3.0",
     "@vee-validate/zod": "^4.15.1",
     "@visactor/vchart": "^2.0.4",
     "@vue-office/docx": "^1.6.3",
@@ -60,7 +59,6 @@
     "splitpanes": "^4.0.4",
     "swiper": "^12.0.1",
     "tailwind-merge": "^3.3.1",
-    "tinymce": "^7.9.1",
     "ua-parser-js": "^2.0.5",
     "vconsole": "^3.15.1",
     "vee-validate": "^4.15.1",

+ 0 - 79
pnpm-lock.yaml

@@ -17,9 +17,6 @@ importers:
       '@bytemd/vue-next':
         specifier: ^1.22.0
         version: 1.22.0(vue@3.5.21(typescript@5.9.2))
-      '@tinymce/tinymce-vue':
-        specifier: ^6.3.0
-        version: 6.3.0(tinymce@7.9.1)(vue@3.5.21(typescript@5.9.2))
       '@vee-validate/zod':
         specifier: ^4.15.1
         version: 4.15.1(vue@3.5.21(typescript@5.9.2))(zod@4.1.8)
@@ -128,9 +125,6 @@ importers:
       tailwind-merge:
         specifier: ^3.3.1
         version: 3.3.1
-      tinymce:
-        specifier: ^7.9.1
-        version: 7.9.1
       ua-parser-js:
         specifier: ^2.0.5
         version: 2.0.5
@@ -1947,42 +1941,36 @@ packages:
     engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-minify/binding-linux-arm64-musl@0.80.0':
     resolution: {integrity: sha512-D2j5L9Z4OO42We0Lo2GkXT/AaNikzZJ8KZ9V2VVwu7kofI4RsO8kSu8ydWlqRlRdiAprmUpRZU/pNW0ZA7A68w==}
     engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [linux]
-    libc: [musl]
 
   '@oxc-minify/binding-linux-riscv64-gnu@0.80.0':
     resolution: {integrity: sha512-2AztlLcio5OGil70wjRLbxbjlfS1yCTzO+CYan49vfUOCXpwSWwwLD2WDzFokhEXAzf8epbbu7pruYk8qorRRg==}
     engines: {node: '>=14.0.0'}
     cpu: [riscv64]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-minify/binding-linux-s390x-gnu@0.80.0':
     resolution: {integrity: sha512-5GMKARe4gYHhA7utM8qOgv3WM7KAXGZGG3Jhvk4UQSRBp0v6PKFmHmz8Q93+Ep8w1m4NqRL30Zk9CZHMH/qi5g==}
     engines: {node: '>=14.0.0'}
     cpu: [s390x]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-minify/binding-linux-x64-gnu@0.80.0':
     resolution: {integrity: sha512-iw45N+OVnPioRQXLHfrsqEcTpydcGSHLphilS3aSpc4uVKnOqCybskKnbEnxsIJqHWbzDZeJgzuRuQa7EhNcqg==}
     engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-minify/binding-linux-x64-musl@0.80.0':
     resolution: {integrity: sha512-4+dhYznVM+L9Jh855JBbqVyDjwi3p8rpL7RfgN+Ee1oQMaZl2ZPy2shS1Kj56Xr5haTTVGdRKcIqTU8SuF37UQ==}
     engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [linux]
-    libc: [musl]
 
   '@oxc-minify/binding-wasm32-wasi@0.80.0':
     resolution: {integrity: sha512-flADFeNwC1/XsBBsESAigsJZyONEBloQO86Z38ZNzLSuMmpGRdwB9gUwlPCQgDRND/aB+tvR29hKTSuQoS3yrg==}
@@ -2078,84 +2066,72 @@ packages:
     engines: {node: '>=20.0.0'}
     cpu: [arm64]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-parser/binding-linux-arm64-gnu@0.80.0':
     resolution: {integrity: sha512-y2NEhbFfKPdOkf3ZR/3xwJFJVji6IKxwXKHUN4bEdqpcO0tkXSCiP0MzTxjEY6ql2/MXdkqK0Ym92dYsRsgsyg==}
     engines: {node: '>=20.0.0'}
     cpu: [arm64]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-parser/binding-linux-arm64-musl@0.75.1':
     resolution: {integrity: sha512-8ilN7iG7Y4qvXJTuHERPKy5LKcT1ioSGRn7Yyd988tzuR9Cvp4+gJu8azYZnSUJKfNV6SGOEfVnxLabCLRkG/A==}
     engines: {node: '>=20.0.0'}
     cpu: [arm64]
     os: [linux]
-    libc: [musl]
 
   '@oxc-parser/binding-linux-arm64-musl@0.80.0':
     resolution: {integrity: sha512-j3tKausSXwHS/Ej6ct2dmKJtw0UIME2XJmj6QfPT6LyUSNTndj4yXRXuMSrCOrX9/0qH9GhmqeL9ouU27dQRFw==}
     engines: {node: '>=20.0.0'}
     cpu: [arm64]
     os: [linux]
-    libc: [musl]
 
   '@oxc-parser/binding-linux-riscv64-gnu@0.75.1':
     resolution: {integrity: sha512-/JPJXjT/fkG699rlxzLNvQx0URjvzdk7oHln54F159ybgVJKLLWqb8M45Nhw5z6TeaIYyhwIqMNlrA7yb1Rlrw==}
     engines: {node: '>=20.0.0'}
     cpu: [riscv64]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-parser/binding-linux-riscv64-gnu@0.80.0':
     resolution: {integrity: sha512-h+uPvyTcpTFd946fGPU57sZeec2qHPUYQRZeXHB2uuZjps+9pxQ5zIz0EBM/JgBtnwdtoR93RAu1YNAVbqY5Zw==}
     engines: {node: '>=20.0.0'}
     cpu: [riscv64]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-parser/binding-linux-s390x-gnu@0.75.1':
     resolution: {integrity: sha512-t6/E4j+2dT7/4R5hQNX4LBtR1+wxxtJNUVBD89YuiWHPgeEoghqSa0mGMrGyOZPbHMb4V8xdT/CrMMeDpuqRaQ==}
     engines: {node: '>=20.0.0'}
     cpu: [s390x]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-parser/binding-linux-s390x-gnu@0.80.0':
     resolution: {integrity: sha512-+u74hV+WwCPL4UBNOJaIGRozTCfZ7pM5JCEe8zAlMkKexftUzbtvW02314bVD9bqoRAL3Gg6jcZrjNjwDX2FwQ==}
     engines: {node: '>=20.0.0'}
     cpu: [s390x]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-parser/binding-linux-x64-gnu@0.75.1':
     resolution: {integrity: sha512-zJ2t+d1rV5dcPJHxN3B1Fxc2KDN+gPgdXtlzp0/EH4iO3s5OePpPvTTZA/d1vfPoQFiFOT7VYNmaD9XjHfMQaw==}
     engines: {node: '>=20.0.0'}
     cpu: [x64]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-parser/binding-linux-x64-gnu@0.80.0':
     resolution: {integrity: sha512-N9UGnWVWMlOJH+6550tqyBxd9qkMd0f4m+YRA0gly6efJTuLbPQpjkJm7pJbMu+GULcvSJ/Y0bkMAIQTtwP0vQ==}
     engines: {node: '>=20.0.0'}
     cpu: [x64]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-parser/binding-linux-x64-musl@0.75.1':
     resolution: {integrity: sha512-62hG/1IoOr0hpmGtF2k1MJUzAXLH7DH3fSAttZ1vEvDThhLplqA7jcqOP0IFMIVZ0kt9cA/rW5pF4tnXjiWeSA==}
     engines: {node: '>=20.0.0'}
     cpu: [x64]
     os: [linux]
-    libc: [musl]
 
   '@oxc-parser/binding-linux-x64-musl@0.80.0':
     resolution: {integrity: sha512-l2N/GlFEri27QBMi0e53V/SlpQotIvHbz+rZZG/EO+vn58ZEr0eTG+PjJoOY/T8+TQb8nrCtRe4S/zNDpV6zSQ==}
     engines: {node: '>=20.0.0'}
     cpu: [x64]
     os: [linux]
-    libc: [musl]
 
   '@oxc-parser/binding-wasm32-wasi@0.75.1':
     resolution: {integrity: sha512-txS7vK0EU/1Ey7d1pxGrlp2q/JrxkvLU+r9c3gKxW9mVgvFMQzAxQhuc9tT3ZiS793pkvZ+C1w9GS2DpJi7QYg==}
@@ -2238,42 +2214,36 @@ packages:
     engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-transform/binding-linux-arm64-musl@0.80.0':
     resolution: {integrity: sha512-kBBCQwr1GCkr/b0iXH+ijsg+CSPCAMSV2tu4LmG2PFaxBnZilMYfUyWHCAiskbbUADikecUfwX6hHIaQoMaixg==}
     engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [linux]
-    libc: [musl]
 
   '@oxc-transform/binding-linux-riscv64-gnu@0.80.0':
     resolution: {integrity: sha512-8CGJhHoD2Ttw8HtCNd/IWnGtL0Nsn448L2hZJtbDDGVUZUF4bbZFdXPnRt0QrEbupywoH6InN6q2imLous6xnw==}
     engines: {node: '>=14.0.0'}
     cpu: [riscv64]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-transform/binding-linux-s390x-gnu@0.80.0':
     resolution: {integrity: sha512-V/Lb6m5loWzvdB/qo6eYvVXidQku/PA706JbeE/PPCup8At+BwOXnZjktv7LDxrpuqnO32tZDHUUc9Y3bzOEBw==}
     engines: {node: '>=14.0.0'}
     cpu: [s390x]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-transform/binding-linux-x64-gnu@0.80.0':
     resolution: {integrity: sha512-03hHW04MQNb+ak27xo79nUkMjVu6146TNgeSapcDRATH4R0YMmXB2oPQK1K2nuBJzVZjBjH7Bus/I7tR3JasAg==}
     engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [linux]
-    libc: [glibc]
 
   '@oxc-transform/binding-linux-x64-musl@0.80.0':
     resolution: {integrity: sha512-BkXniuuHpo9cR2S3JDKIvmUrNvmm335owGW4rfp07HjVUsbq9e7bSnvOnyA3gXGdrPR2IgCWGi5nnXk2NN5Q0A==}
     engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [linux]
-    libc: [musl]
 
   '@oxc-transform/binding-wasm32-wasi@0.80.0':
     resolution: {integrity: sha512-jfRRXLtfSgTeJXBHj6qb+HHUd6hmYcyUNMBcTY8/k+JVsx0ThfrmCIufNlSJTt1zB+ugnMVMuQGeB0oF+aa86w==}
@@ -2321,42 +2291,36 @@ packages:
     engines: {node: '>= 10.0.0'}
     cpu: [arm]
     os: [linux]
-    libc: [glibc]
 
   '@parcel/watcher-linux-arm-musl@2.5.1':
     resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==}
     engines: {node: '>= 10.0.0'}
     cpu: [arm]
     os: [linux]
-    libc: [musl]
 
   '@parcel/watcher-linux-arm64-glibc@2.5.1':
     resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==}
     engines: {node: '>= 10.0.0'}
     cpu: [arm64]
     os: [linux]
-    libc: [glibc]
 
   '@parcel/watcher-linux-arm64-musl@2.5.1':
     resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==}
     engines: {node: '>= 10.0.0'}
     cpu: [arm64]
     os: [linux]
-    libc: [musl]
 
   '@parcel/watcher-linux-x64-glibc@2.5.1':
     resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==}
     engines: {node: '>= 10.0.0'}
     cpu: [x64]
     os: [linux]
-    libc: [glibc]
 
   '@parcel/watcher-linux-x64-musl@2.5.1':
     resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==}
     engines: {node: '>= 10.0.0'}
     cpu: [x64]
     os: [linux]
-    libc: [musl]
 
   '@parcel/watcher-wasm@2.5.1':
     resolution: {integrity: sha512-RJxlQQLkaMMIuWRozy+z2vEqbaQlCuaCgVZIUCzQLYggY22LZbP5Y1+ia+FD724Ids9e+XIyOLXLrLgQSHIthw==}
@@ -2447,28 +2411,24 @@ packages:
     engines: {node: '>= 10'}
     cpu: [arm64]
     os: [linux]
-    libc: [glibc]
 
   '@resvg/resvg-js-linux-arm64-musl@2.4.1':
     resolution: {integrity: sha512-6mT0+JBCsermKMdi/O2mMk3m7SqOjwi9TKAwSngRZ/nQoL3Z0Z5zV+572ztgbWr0GODB422uD8e9R9zzz38dRQ==}
     engines: {node: '>= 10'}
     cpu: [arm64]
     os: [linux]
-    libc: [musl]
 
   '@resvg/resvg-js-linux-x64-gnu@2.4.1':
     resolution: {integrity: sha512-60KnrscLj6VGhkYOJEmmzPlqqfcw1keDh6U+vMcNDjPhV3B5vRSkpP/D/a8sfokyeh4VEacPSYkWGezvzS2/mg==}
     engines: {node: '>= 10'}
     cpu: [x64]
     os: [linux]
-    libc: [glibc]
 
   '@resvg/resvg-js-linux-x64-musl@2.4.1':
     resolution: {integrity: sha512-0AMyZSICC1D7ge115cOZQW8Pcad6PjWuZkBFF3FJuSxC6Dgok0MQnLTs2MfMdKBlAcwO9dXsf3bv9tJZj8pATA==}
     engines: {node: '>= 10'}
     cpu: [x64]
     os: [linux]
-    libc: [musl]
 
   '@resvg/resvg-js-win32-arm64-msvc@2.4.1':
     resolution: {integrity: sha512-76XDFOFSa3d0QotmcNyChh2xHwk+JTFiEQBVxMlHpHMeq7hNrQJ1IpE1zcHSQvrckvkdfLboKRrlGB86B10Qjw==}
@@ -2604,67 +2564,56 @@ packages:
     resolution: {integrity: sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==}
     cpu: [arm]
     os: [linux]
-    libc: [glibc]
 
   '@rollup/rollup-linux-arm-musleabihf@4.46.2':
     resolution: {integrity: sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==}
     cpu: [arm]
     os: [linux]
-    libc: [musl]
 
   '@rollup/rollup-linux-arm64-gnu@4.46.2':
     resolution: {integrity: sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==}
     cpu: [arm64]
     os: [linux]
-    libc: [glibc]
 
   '@rollup/rollup-linux-arm64-musl@4.46.2':
     resolution: {integrity: sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==}
     cpu: [arm64]
     os: [linux]
-    libc: [musl]
 
   '@rollup/rollup-linux-loongarch64-gnu@4.46.2':
     resolution: {integrity: sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==}
     cpu: [loong64]
     os: [linux]
-    libc: [glibc]
 
   '@rollup/rollup-linux-ppc64-gnu@4.46.2':
     resolution: {integrity: sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==}
     cpu: [ppc64]
     os: [linux]
-    libc: [glibc]
 
   '@rollup/rollup-linux-riscv64-gnu@4.46.2':
     resolution: {integrity: sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==}
     cpu: [riscv64]
     os: [linux]
-    libc: [glibc]
 
   '@rollup/rollup-linux-riscv64-musl@4.46.2':
     resolution: {integrity: sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==}
     cpu: [riscv64]
     os: [linux]
-    libc: [musl]
 
   '@rollup/rollup-linux-s390x-gnu@4.46.2':
     resolution: {integrity: sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==}
     cpu: [s390x]
     os: [linux]
-    libc: [glibc]
 
   '@rollup/rollup-linux-x64-gnu@4.46.2':
     resolution: {integrity: sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==}
     cpu: [x64]
     os: [linux]
-    libc: [glibc]
 
   '@rollup/rollup-linux-x64-musl@4.46.2':
     resolution: {integrity: sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==}
     cpu: [x64]
     os: [linux]
-    libc: [musl]
 
   '@rollup/rollup-win32-arm64-msvc@4.46.2':
     resolution: {integrity: sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==}
@@ -2731,15 +2680,6 @@ packages:
     peerDependencies:
       vue: ^2.7.0 || ^3.0.0
 
-  '@tinymce/tinymce-vue@6.3.0':
-    resolution: {integrity: sha512-DSP8Jhd3XqCCliTnusfbmz3D8GqQ4iRzkc4aadYHDcJPVjkaqopJ61McOdH82CSy599vGLkPjGzqJYWJkRMiUA==}
-    peerDependencies:
-      tinymce: ^8.0.0 || ^7.0.0 || ^6.0.0 || ^5.5.1
-      vue: ^3.0.0
-    peerDependenciesMeta:
-      tinymce:
-        optional: true
-
   '@trysound/sax@0.2.0':
     resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
     engines: {node: '>=10.13.0'}
@@ -7950,56 +7890,48 @@ packages:
     engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [linux]
-    libc: glibc
 
   sass-embedded-linux-arm@1.92.1:
     resolution: {integrity: sha512-cT3w8yoQTqrtZvWLJeutEGmawITDTY4J6oSVQjeDcPnnoPt0gOFxem8YMznraACXvahw/2+KJDH33BTNgiPo0A==}
     engines: {node: '>=14.0.0'}
     cpu: [arm]
     os: [linux]
-    libc: glibc
 
   sass-embedded-linux-musl-arm64@1.92.1:
     resolution: {integrity: sha512-TfiEBkCyNzVoOhjHXUT+vZ6+p0ueDbvRw6f4jHdkvljZzXdXMby4wh7BU1odl69rgRTkSvYKhgbErRLDR/F7pQ==}
     engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [linux]
-    libc: musl
 
   sass-embedded-linux-musl-arm@1.92.1:
     resolution: {integrity: sha512-nPBos6lI31ef2zQhqTZhFOU7ar4impJbLIax0XsqS269YsiCwjhk11VmUloJTpFlJuKMiVXNo7dPx+katxhD/Q==}
     engines: {node: '>=14.0.0'}
     cpu: [arm]
     os: [linux]
-    libc: musl
 
   sass-embedded-linux-musl-riscv64@1.92.1:
     resolution: {integrity: sha512-R+RcJA4EYpJDE9JM1GgPYgZo7x94FlxZ6jPodOQkEaZ1S9kvXVCuP5X/0PXRPhu08KJOfeMsAElzfdAjUf7KJg==}
     engines: {node: '>=14.0.0'}
     cpu: [riscv64]
     os: [linux]
-    libc: musl
 
   sass-embedded-linux-musl-x64@1.92.1:
     resolution: {integrity: sha512-/HolYRGXJjx8nLw6oj5ZrkR7PFM7X/5kE4MYZaFMpDIPIcw3bqB2fUXLo/MYlRLsw7gBAT6hJAMBrNdKuTphfw==}
     engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [linux]
-    libc: musl
 
   sass-embedded-linux-riscv64@1.92.1:
     resolution: {integrity: sha512-b9bxe0CMsbSsLx3nrR0cq8xpIkoAC6X36o4DGMITF3m2v3KsojC7ru9X0Gz+zUFr6rwpq/0lTNzFLNu6sPNo3w==}
     engines: {node: '>=14.0.0'}
     cpu: [riscv64]
     os: [linux]
-    libc: glibc
 
   sass-embedded-linux-x64@1.92.1:
     resolution: {integrity: sha512-xuiK5Jp5NldW4bvlC7AuX1Wf7o0gLZ3md/hNg+bkTvxtCDgnUHtfdo8Q+xWP11bD9QX31xXFWpmUB8UDLi6XQQ==}
     engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [linux]
-    libc: glibc
 
   sass-embedded-unknown-all@1.92.1:
     resolution: {integrity: sha512-AT9oXvtNY4N+Nd0wvoWqq9A5HjdH/X3aUH4boQUtXyaJ/9DUwnQmBpP5Gtn028ZS8exOGBdobmmWAuigv0k/OA==}
@@ -8610,9 +8542,6 @@ packages:
     resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
     engines: {node: '>=12.0.0'}
 
-  tinymce@7.9.1:
-    resolution: {integrity: sha512-zaOHwmiP1EqTeLRXAvVriDb00JYnfEjWGPdKEuac7MiZJ5aiDMZ4Unc98Gmajn+PBljOmO1GKV6G0KwWn3+k8A==}
-
   tippy.js@6.3.7:
     resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==}
 
@@ -12107,12 +12036,6 @@ snapshots:
       '@tanstack/virtual-core': 3.13.9
       vue: 3.5.21(typescript@5.9.2)
 
-  '@tinymce/tinymce-vue@6.3.0(tinymce@7.9.1)(vue@3.5.21(typescript@5.9.2))':
-    dependencies:
-      vue: 3.5.21(typescript@5.9.2)
-    optionalDependencies:
-      tinymce: 7.9.1
-
   '@trysound/sax@0.2.0': {}
 
   '@turf/boolean-clockwise@6.5.0':
@@ -19403,8 +19326,6 @@ snapshots:
       fdir: 6.5.0(picomatch@4.0.3)
       picomatch: 4.0.3
 
-  tinymce@7.9.1: {}
-
   tippy.js@6.3.7:
     dependencies:
       '@popperjs/core': 2.11.8

+ 5 - 1
src/api/modules/anycallService.ts

@@ -1,8 +1,12 @@
 // anycall
 import { request } from '@/api'
+import type { TAgent } from '@/types/role'
 
 export function anycallPage(params: any){
-  return request(`/anycall/selectLib`, params)
+  return request<{
+    total: number,
+    content: TAgent[]
+  }>(`/anycall/selectLib`, params)
 }
 export function updateCallings(params: any){
   return request(`/anycall/updateCallings`, params)

+ 4 - 2
src/layouts/components/MainSidebar/index.vue

@@ -36,7 +36,9 @@ onUnmounted(() => {
   <Transition name="main-sidebar">
     <div v-if="settingsStore.settings.menu.mode === 'side' || (settingsStore.mode === 'mobile' && settingsStore.settings.menu.mode !== 'single')" class="main-sidebar-container">
       <component :is="useSlots('main-sidebar-top')" />
-      <Logo :show-title="false" class="sidebar-logo" />
+      <div class="sidebar-logo flex-center h-16 border-b border-border/50 px-4 text-3">
+        AI HUB
+      </div>
       <component :is="useSlots('main-sidebar-after-logo')" />
       <FaScrollArea :scrollbar="false" mask gradient-color="var(--g-main-sidebar-bg)" class="menu flex-1">
         <!-- 侧边栏模式(含主导航) -->
@@ -63,7 +65,7 @@ onUnmounted(() => {
           </template>
         </div>
       </FaScrollArea>
-      <component :is="useSlots('main-sidebar-after-menu')" />
+      <!-- <component :is="useSlots('main-sidebar-after-menu')" /> -->
       <div class="flex-center px-4 py-3">
         <AccountButton only-avatar :button-variant="settingsStore.settings.menu.mode === 'side' ? 'secondary' : 'ghost'" class="size-12 p-2" />
       </div>

+ 1 - 1
src/layouts/index.vue

@@ -116,7 +116,7 @@ const enableAppSetting = import.meta.env.VITE_APP_SETTING
       </div>
       <AppSetting />
     </template>
-    <component :is="useSlots('free-position')" />
+    <!-- <component :is="useSlots('free-position')" /> -->
   </div>
 </template>
 

+ 0 - 100
src/router/modules/ecology.example.ts

@@ -1,100 +0,0 @@
-import type { RouteRecordRaw } from 'vue-router'
-
-function Layout() {
-  return import('@/layouts/index.vue')
-}
-
-const routes: RouteRecordRaw[] = [
-  {
-    path: '/official',
-    component: Layout,
-    meta: {
-      title: '官方周边',
-      icon: 'i-ion:apps',
-    },
-    children: [
-      {
-        path: 'fantastic-startkit',
-        redirect: '',
-        name: 'officialFantasticStartkit',
-        meta: {
-          title: 'Fantastic-startkit 项目启动套件',
-          icon: 'https://cn.vuejs.org/logo.svg',
-          link: 'https://hooray.github.io/fantastic-startkit/',
-        },
-      },
-      {
-        path: 'one-step-admin',
-        redirect: '',
-        name: 'officialOneStepAdmin',
-        meta: {
-          title: 'One-step-admin 干啥都快人一步的中后台框架',
-          icon: 'https://one-step-admin.hurui.me/logo.png',
-          link: 'https://one-step-admin.hurui.me',
-        },
-      },
-      {
-        path: 'fantastic-mobile',
-        redirect: '',
-        name: 'officialFantasticMobile',
-        meta: {
-          title: 'Fantastic-mobile 自成一派的 H5 框架',
-          icon: 'https://fantastic-mobile.hurui.me/logo.png',
-          link: 'https://fantastic-mobile.hurui.me',
-        },
-      },
-    ],
-  },
-  {
-    path: '/recommand',
-    component: Layout,
-    meta: {
-      title: '友情推荐',
-      icon: 'i-ic:outline-handshake',
-    },
-    children: [
-      {
-        path: 'vform',
-        redirect: '',
-        name: 'recommandVform',
-        meta: {
-          title: 'VForm 低代码表单',
-          icon: 'https://www.vform666.com/mini-logo.png',
-          link: 'https://www.vform666.com',
-        },
-      },
-      {
-        path: 'form-create',
-        redirect: '',
-        name: 'recommandFormcreate',
-        meta: {
-          title: 'FormCreate 可视化表单设计器',
-          icon: 'https://form-create.com/logo.png',
-          link: 'https://form-create.com',
-        },
-      },
-      {
-        path: 'vexip',
-        redirect: '',
-        name: 'recommandVexip',
-        meta: {
-          title: 'Vexip UI 组件库',
-          icon: 'https://www.vexipui.com/vexip-ui.png',
-          link: 'https://www.vexipui.com/zh-CN',
-        },
-      },
-      {
-        path: 'mineadmin',
-        redirect: '',
-        name: 'recommandMineadmin',
-        meta: {
-          title: 'MineAdmin 开箱即用后台系统',
-          icon: 'https://www.mineadmin.com/favicon.ico',
-          link: 'https://github.com/mineadmin/mineadmin',
-        },
-      },
-    ],
-  },
-]
-
-export default routes

+ 32 - 0
src/router/modules/recomendation.ts

@@ -0,0 +1,32 @@
+
+import type { RouteRecordRaw } from 'vue-router'
+
+function Layout() {
+  return import('@/layouts/index.vue')
+}
+
+const routes: RouteRecordRaw = {
+  path: '/recomendation',
+  component: Layout,
+  name: 'recomendation',
+  meta: {
+    title: 'Recomendation Management',
+    icon: 'i-ep:starFilled',
+    singleMenu: true,
+  },
+  children: [
+    {
+      path: '',
+      name: 'recomendationIndex',
+      component: () => import('@/views/role-management/index.vue'),
+      meta: {
+        title: 'Role Management',
+        menu: false,
+        breadcrumb: false,
+        activeMenu: '/recomendation',
+      },
+    },
+  ],
+}
+
+export default routes

+ 4 - 3
src/router/modules/role.management.ts → src/router/modules/role.ts

@@ -5,12 +5,13 @@ function Layout() {
 }
 
 const routes: RouteRecordRaw = {
-  path: '/role_management',
+  path: '/roleManagement',
   component: Layout,
   name: 'roleManagement',
   meta: {
     title: 'Role Management',
-    icon: 'i-file-icons:jsx',
+    icon: 'i-ep:avatar',
+    singleMenu: true,
   },
   children: [
     {
@@ -21,7 +22,7 @@ const routes: RouteRecordRaw = {
         title: 'Role Management',
         menu: false,
         breadcrumb: false,
-        activeMenu: '/role_management',
+        activeMenu: '/roleManagement',
       },
     },
   ],

+ 31 - 0
src/router/modules/voice.ts

@@ -0,0 +1,31 @@
+import type { RouteRecordRaw } from 'vue-router'
+
+function Layout() {
+  return import('@/layouts/index.vue')
+}
+
+const routes: RouteRecordRaw = {
+  path: '/voiceManagement',
+  component: Layout,
+  name: 'voiceManagement',
+  meta: {
+    title: 'Voice Management',
+    icon: 'i-ep:microphone',
+    singleMenu: true,
+  },
+  children: [
+    {
+      path: '',
+      name: 'voiceManagementIndex',
+      component: () => import('@/views/role-management/index.vue'),
+      meta: {
+        title: 'Role Management',
+        menu: false,
+        breadcrumb: false,
+        activeMenu: '/voiceManagement',
+      },
+    },
+  ],
+}
+
+export default routes

+ 13 - 13
src/router/routes.ts

@@ -4,7 +4,6 @@ import generatedRoutes from 'virtual:generated-pages'
 import { setupLayouts } from 'virtual:meta-layouts'
 import BreadcrumbExample from './modules/breadcrumb.example'
 import ComponentExample from './modules/component.example'
-import EcologyExample from './modules/ecology.example'
 import ExternalLinkExample from './modules/external.link.example'
 import FeatureExample from './modules/feature.example'
 import IconExample from './modules/icon.example'
@@ -15,8 +14,15 @@ import MultilevelMenuExample from './modules/multilevel.menu.example'
 import PermissionExample from './modules/permission.example'
 import PluginExample from './modules/plugin.example'
 import TabExample from './modules/tab.example'
-import RoleManagement from './modules/role.management'
 
+import RoleManagement from './modules/role'
+import VoiceManagement from './modules/voice'
+import recomendation from './modules/recomendation'
+
+
+function Layout() {
+  return import('@/layouts/index.vue')
+}
 // 固定路由(默认路由)
 const constantRoutes: RouteRecordRaw[] = [
   {
@@ -73,11 +79,14 @@ const systemRoutes: RouteRecordRaw[] = [
 const asyncRoutes: Route.recordMainRaw[] = [
   {
     meta: {
-      title: 'Role Management',
-      icon: 'i-uim:box',
+      title: 'Managerment',
+      icon: 'i-ep:grid',
+      auth: '',
     },
     children: [
       RoleManagement,
+      VoiceManagement,
+      recomendation,
     ],
   },
   {
@@ -100,15 +109,6 @@ const asyncRoutes: Route.recordMainRaw[] = [
       ExternalLinkExample,
     ],
   },
-  {
-    meta: {
-      title: '生态',
-      icon: 'i-icon-park-outline:circular-connection',
-    },
-    children: [
-      ...EcologyExample,
-    ],
-  },
 ]
 
 const constantRoutesByFilesystem = generatedRoutes.filter((item) => {

+ 2 - 2
src/settings.ts

@@ -26,13 +26,13 @@ const globalSettings: Settings.all = {
   toolbar: {
     fullscreen: true,
     pageReload: true,
-    colorScheme: true,
+    colorScheme: false,
   },
   mainPage: {
     enableHotkeys: true,
   },
   copyright: {
-    enable: true,
+    enable: false,
     dates: '2020-present',
     company: 'Anycall',
     website: 'https://nexthuman.cn',

+ 2 - 2
src/store/modules/user.ts

@@ -80,8 +80,8 @@ export const useUserStore = defineStore(
 
     // 获取权限
     async function getPermissions() {
-      const res = await apiUser.permission()
-      permissions.value = res.data.permissions
+      // const res = await apiUser.permission()
+      // permissions.value = res.data.permissions
     }
     // 修改密码
     async function editPassword(data: {

+ 14 - 0
src/types/role.ts

@@ -0,0 +1,14 @@
+export type TAgent = {
+  agentId?: string;
+  callings?: number;
+  contactFlag?: boolean;
+  id?: string;
+  name?: string;
+  nationality?: string;
+  photo?: string;
+  prompt?: string;
+  topFlag?: boolean;
+  uid?: string;
+  voice?: string;
+  voiceName?: string;
+};

+ 17 - 0
src/types/voice.ts

@@ -0,0 +1,17 @@
+export type TVoice = {
+  ctime?: number;
+  customEdit?: boolean;
+  fromTrained?: boolean;
+  gender?: number;
+  id?: string;
+  name?: string;
+  service?: string;
+  spaceId?: string;
+  status?: number;
+  trial?: {
+    url?: string;
+    duration?: number;
+    srcName?: string;
+  };
+  userId?: string;
+};

+ 5 - 0
src/utils/index.ts

@@ -2,6 +2,7 @@ import type { ClassValue } from 'clsx'
 import { clsx } from 'clsx'
 import path from 'path-browserify'
 import { twMerge } from 'tailwind-merge'
+import dayjs from 'dayjs'
 
 export function cn(...inputs: ClassValue[]) {
   return twMerge(clsx(inputs))
@@ -10,3 +11,7 @@ export function cn(...inputs: ClassValue[]) {
 export function resolveRoutePath(basePath?: string, routePath?: string) {
   return basePath ? path.resolve(basePath, routePath ?? '') : routePath ?? ''
 }
+
+export function formatDateGeneral(timestamp: number, format?: string) {
+  return dayjs(timestamp).format(format ?? 'YYYY-MM-DD HH:mm:ss')
+}

+ 118 - 205
src/views/index.vue

@@ -5,228 +5,141 @@ meta:
 </route>
 
 <script setup lang="ts">
-const versionType = ref('basic')
-watch(versionType, (val) => {
-  if (val === 'pro') {
-    location.href = `${location.origin}${location.pathname}`.replace('basic-example', 'pro-example')
-  }
-})
-
-const fantasticStartkitInfo = ref({
-  feature: [
-    '支持 TypeScript',
-    '默认集成 vue-router 和 pinia',
-    '支持基于文件系统的路由',
-    '全局组件自动引入',
-    '全局 SCSS 资源引入',
-    '支持 Unocss',
-    '支持 SVG 文件图标、Iconify 图标、UnoCSS 图标',
-    '支持 mock 数据,可脱离后端束缚独立开发',
-    '支持 gzip / brotli 优化项目体积,提高加载速度',
-    '结合 IDE 插件、ESlint 、stylelint 、Git 钩子,轻松实现团队代码规范',
-  ],
-})
-
-const fantasticAdminInfo = ref({
-  imageVisible: false,
-  index: 0,
-  data: [
-    'https://fantastic-admin.hurui.me/preview1.png',
-    'https://fantastic-admin.hurui.me/preview2.png',
-    'https://fantastic-admin.hurui.me/preview3.png',
-    'https://fantastic-admin.hurui.me/preview4.png',
-    'https://fantastic-admin.hurui.me/preview5.png',
-    'https://fantastic-admin.hurui.me/preview6.png',
-  ],
-})
-
-const oneStepAdminInfo = ref({
-  imageVisible: false,
-  index: 0,
-  data: [
-    'https://one-step-admin.hurui.me/preview1.png',
-    'https://one-step-admin.hurui.me/preview2.png',
-    'https://one-step-admin.hurui.me/preview3.png',
-    'https://one-step-admin.hurui.me/preview4.png',
-    'https://one-step-admin.hurui.me/preview5.png',
-    'https://one-step-admin.hurui.me/preview6.png',
-  ],
-})
-
-function open(url: string) {
-  window.open(url, '_blank')
-}
+const dataList = ref([
+  {
+    date: '2016-05-02',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1518 弄',
+  },
+  {
+    date: '2016-05-04',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1517 弄',
+  },
+  {
+    date: '2016-05-01',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1519 弄',
+  },
+  {
+    date: '2016-05-03',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1516 弄',
+  },
+  {
+    date: '2016-05-04',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1517 弄',
+  },
+  {
+    date: '2016-05-01',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1519 弄',
+  },
+  {
+    date: '2016-05-03',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1516 弄',
+  },
+  {
+    date: '2016-05-04',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1517 弄',
+  },
+  {
+    date: '2016-05-01',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1519 弄',
+  },
+  {
+    date: '2016-05-03',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1516 弄',
+  },
+  {
+    date: '2016-05-04',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1517 弄',
+  },
+  {
+    date: '2016-05-01',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1519 弄',
+  },
+  {
+    date: '2016-05-03',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1516 弄',
+  },
+  {
+    date: '2016-05-04',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1517 弄',
+  },
+  {
+    date: '2016-05-01',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1519 弄',
+  },
+  {
+    date: '2016-05-03',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1516 弄',
+  },
+  {
+    date: '2016-05-03',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1516 弄',
+  },
+  {
+    date: '2016-05-04',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1517 弄',
+  },
+  {
+    date: '2016-05-01',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1519 弄',
+  },
+  {
+    date: '2016-05-03',
+    name: '王小虎',
+    address: '上海市普陀区金沙江路 1516 弄',
+  },
+])
 </script>
 
 <template>
-  <div>
+  <div class="absolute-container">
     <FaPageHeader>
       <template #title>
         <div class="flex items-center gap-4">
-          欢迎使用 Fantastic-admin
-          <FaTabs
-            v-model="versionType" :list="[
-              { label: '基础版', value: 'basic' },
-              { label: '专业版', value: 'pro' },
-            ]" class="-mb-2"
-          />
+          欢迎使用角色管理系统
         </div>
       </template>
       <template #description>
         <div class="text-sm/6">
-          <div>
-            这是一款<b class="text-emphasis">开箱即用</b>的中后台框架,同时它也经历过数十个真实项目的技术沉淀,确保框架在开发中可落地、可使用、可维护
-          </div>
-          <div>
-            注:在作者就职过的公司,本框架已在电商、直播、OA、ERP等多个不同领域的中后台系统中应用并稳定运行
-          </div>
+         helloworld
         </div>
       </template>
-      <div class="flex gap-2">
-        <FaButton variant="outline" @click="open('https://fantastic-admin.hurui.me')">
-          <FaIcon name="i-ri:file-text-line" />
-          开发文档
-        </FaButton>
-        <FaDropdown
-          :items="[
-            [
-              { label: 'Github', icon: 'i-simple-icons:github', handle: () => open('https://github.com/fantastic-admin/basic') },
-              { label: 'Gitee', icon: 'i-simple-icons:gitee', handle: () => open('https://gitee.com/fantastic-admin/basic') },
-            ],
-          ]"
-        >
-          <FaButton>
-            <FaIcon name="i-ri:code-s-slash-line" />
-            代码仓库
-            <FaIcon name="i-ep:arrow-down" />
-          </FaButton>
-        </FaDropdown>
-      </div>
     </FaPageHeader>
-    <div class="w-full flex flex-col gap-4 px-4 xl-flex-row">
-      <FaPageMain class="m-0 flex-1" title-class="flex flex-wrap items-center justify-between gap-4">
-        <template #title>
-          <div class="title-info">
-            <img src="https://cn.vuejs.org/logo.svg">
-            <div>
-              <h1 class="c-[#41b883]">
-                Fantastic-startkit
-              </h1>
-              <h2>一款简单好用的 Vue3 项目启动套件</h2>
-            </div>
-          </div>
-          <div class="ms-auto">
-            <FaButton @click="open('https://hooray.github.io/fantastic-startkit')">
-              访问官网
-            </FaButton>
-          </div>
-        </template>
-        <ul class="m-0 list-disc px-8 text-sm leading-6 space-y-1">
-          <li v-for="item in fantasticStartkitInfo.feature" :key="item">
-            {{ item }}
-          </li>
-        </ul>
-      </FaPageMain>
-      <FaPageMain class="m-0 flex-1" title-class="flex flex-wrap items-center justify-between gap-4">
-        <template #title>
-          <div class="title-info">
-            <img src="https://fantastic-admin.hurui.me/logo.svg">
-            <div>
-              <h1 class="c-[#41b883]">
-                Fantastic-admin
-              </h1>
-              <h2>一款开箱即用的 Vue 中后台管理系统框架</h2>
-            </div>
-          </div>
-          <div class="ms-auto">
-            <FaButton @click="open('https://fantastic-admin.hurui.me')">
-              访问官网
-            </FaButton>
-          </div>
-        </template>
-        <ElCarousel trigger="click" indicator-position="none" :interval="5000" height="250px">
-          <ElCarouselItem v-for="(item, index) in fantasticAdminInfo.data" :key="item">
-            <ElImage :src="item" fit="cover" style="width: 100%; height: 250px; margin: auto; cursor: pointer;" @click="fantasticAdminInfo.imageVisible = true; fantasticAdminInfo.index = index" />
-          </ElCarouselItem>
-        </ElCarousel>
-        <ElImageViewer v-if="fantasticAdminInfo.imageVisible" :url-list="fantasticAdminInfo.data" :initial-index="fantasticAdminInfo.index" @close="fantasticAdminInfo.imageVisible = false" />
-      </FaPageMain>
-      <FaPageMain class="m-0 flex-1" title-class="flex flex-wrap items-center justify-between gap-4">
-        <template #title>
-          <div class="title-info">
-            <img src="https://one-step-admin.hurui.me/logo.png">
-            <div>
-              <h1 class="c-[#67c23a]">
-                One-step-admin
-              </h1>
-              <h2>一款干啥都快人一步的 Vue 中后台系统框架</h2>
-            </div>
-          </div>
-          <div class="ms-auto">
-            <FaButton @click="open('https://one-step-admin.hurui.me')">
-              访问官网
-            </FaButton>
-          </div>
-        </template>
-        <ElCarousel trigger="click" indicator-position="none" :interval="5000" height="250px">
-          <ElCarouselItem v-for="(item, index) in oneStepAdminInfo.data" :key="item">
-            <ElImage :src="item" fit="cover" style="width: 100%; height: 250px; margin: auto; cursor: pointer;" @click="oneStepAdminInfo.imageVisible = true; oneStepAdminInfo.index = index" />
-          </ElCarouselItem>
-        </ElCarousel>
-        <ElImageViewer v-if="oneStepAdminInfo.imageVisible" :url-list="oneStepAdminInfo.data" :initial-index="oneStepAdminInfo.index" @close="oneStepAdminInfo.imageVisible = false" />
-      </FaPageMain>
-    </div>
-    <FaPageMain title="应用场景">
-      <ol class="qa">
-        <li><span>没有前端开发人员的小型公司。</span>有很多小型公司没有前端开发人员,而这些公司在开发中后台系统的时候,会要求后端开发人员来进行开发工作。所以借助 Vue 的易学习易上手特性,再加上本框架的加持,可以让后端开发人员能在短时间内转型成为全栈开发。</li>
-        <li><span>前端开发人员不足的中小型公司。</span>根据招聘网站统计,几乎所有公司都缺前端,其中有很大一部分中小型公司标配只有1-2名前端开发人员,而这些公司在开发中后台系统的时候,如果能有一套现成的中后台框架系统,不仅能提高项目开发效率,同时还大大减轻前端开发人员工作压力。</li>
-        <li><span>项目型公司。</span>特点为项目多,周期短,甲方对页面布局和主题风格有绝对话语权,而通过专业版提供的布局和主题风格,可应对绝大部分甲方需求,并且可自定义扩展主题风格的样式,实现高度定制化。</li>
-        <li><span>产品型公司。</span>产品型公司最担心的就是产品开发中代码不可控的因素,本框架除了提供完善的开发文档和代码注释外,专业版用户还可加入技术群,确保开发人员尽可能理解整套框架源码的方方面面,为产品保驾护航。</li>
-        <li><span>个人开发者。</span>手里有一套可高度定制化的中后台框架,什么项目都不用担心啦~</li>
-      </ol>
-    </FaPageMain>
-    <FaPageMain title="优势">
-      <ol class="qa">
-        <li><span>作者拥有10年+的前后端开发经验。</span>部分框架的作者由于缺少后端开发经验,可能会在设计框架的时候,很少或者没有考虑后端的实现逻辑,导致框架在实际使用中,业务场景无法落地,开发人员得通过修改源码自行实现业务。</li>
-        <li><span>经历过数十个真实项目的打磨。</span>没用在真实业务场景中使用过的框架都是纸飞机,哪怕它提供的演示功能特别华丽。而本框架在作者就职的公司,已经稳定应用在电商、直播、OA、CRM、ERP等多个不同领域的中后台系统中。</li>
-        <li><span>丰富的组件库。</span>除了可以接入市面上任意 UI 组件库外,框架还扩充了一些业务组件,以及第三方插件。借助以往的项目经验,提供最佳实践方案,方便开发人员直接使用。</li>
-        <li><span>持续更新的业务应用静态页面。</span>通过项目积累,沉淀出数十个业务应用的静态页面,做到开发人员拿来即可使用,极大提升开发效率的同时,还省去了产品和设计人员的工作。</li>
-        <li><span>长期维护。</span>无论是免费的基础版,还是付费的专业版,均提供长期维护。区别在于基础版侧重于稳定性维护,主要在修复 bug ,不定期增加新特性;专业版侧重于新特性开发,在确保稳定的基础上,会长期深挖中后台系统框架,持续产出可落地的特性或开发规范。</li>
-      </ol>
+    <FaPageMain class="flex-1 overflow-auto" main-class="flex-1 flex flex-col overflow-auto">
+      <ElTable :data="dataList" stripe highlight-current-row border height="100%">
+        <ElTableColumn type="index" width="50" />
+        <ElTableColumn prop="date" label="日期" width="180" />
+        <ElTableColumn prop="name" label="姓名" width="180" />
+        <ElTableColumn prop="address" label="地址" />
+      </ElTable>
     </FaPageMain>
   </div>
 </template>
 
 <style scoped>
-.text-emphasis {
-  text-emphasis-style: "❤";
-}
-
-.title-info {
-  --uno: flex items-center gap-4;
-
-  img {
-    --uno: block w-12 h-12;
-  }
-
-  h1 {
-    --uno: m-0 text-2xl;
-  }
-
-  h2 {
-    --uno: m-0 text-base text-secondary-foreground/50 font-normal;
-  }
-}
-
-.qa {
-  --uno: m-0 pl-6 text-secondary-foreground/50 list-disc;
-
-  li {
-    --uno: mb-2 lh-6 last-mb-0;
-  }
-
-  span {
-    --uno: text-secondary-foreground font-bold;
-  }
+.absolute-container {
+  position: absolute;
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+  height: 100%;
 }
 </style>

+ 132 - 8
src/views/role-management/index.vue

@@ -1,18 +1,129 @@
-<route lang="yaml">
-meta:
-  title: Role Management
-</route>
-
 <script setup lang="ts">
 
 defineOptions({
   name: 'Role Management',
 })
+import { Plus } from '@element-plus/icons-vue'
+import { ElButton, ElDialog, ElEmpty, ElInput, ElOption, ElPagination, ElSelect, ElTable, ElTableColumn, ElTag } from 'element-plus'
+// import SearchForm from './components/SearchForm.vue'
+
+import type { TAgent } from '@/types/role'
+import { anycallPage } from '@/api/modules/anycallService'
+import { formatDateGeneral } from '@/utils'
 
+const tableRef = ref()
+const loading = ref(false)
 const router = useRouter()
+const route = useRoute()
+
+// 搜索参数
+const searchParams = ref({
+  name: '',
+})
+const dataList = ref<TAgent[]>([]);
+
+// 从URL获取初始分页参数
+const getInitialPagination = () => {
+  const page = Number(route.query.page) || 1
+  const size = Number(route.query.size) || 20
+  return {
+    total: 0,
+    page: page > 0 ? page : 1,
+    size: [10, 20, 50, 100].includes(size) ? size : 20,
+  }
+}
+
+// 分页信息
+const pagination = ref(getInitialPagination())
+
+// 更新URL中的分页参数
+const updateUrlParams = (page: number, size: number) => {
+  const query = {
+    ...route.query,
+    page: page.toString(),
+    size: size.toString(),
+  }
+
+  // 使用replace模式更新URL,避免产生历史记录
+  router.replace({
+    path: route.path,
+    query
+  })
+}
+
+
+const  handleCreate = ()=> {
+  router.push({
+    name: 'CharacterEdit',  // 使用路由名称跳转,更推荐
+    params: {
+      id: ''  // 传递角色ID
+    }
+  })
+}
+
+async function fetchList() {
+  loading.value = true
+  const res = await anycallPage({
+    name: searchParams.value.name,
+    page: pagination.value.page,
+    size: pagination.value.size,
+  })
+  if(res.code === 0){
+    dataList.value = res.data.content
+    pagination.value.total = res.data.total
+  }
+  loading.value = false
+}
+function handlePageChange(page: number) {
+  pagination.value.page = page
+  updateUrlParams(page, pagination.value.size)
+  fetchList()
+}
+
+function handleSizeChange(size: number) {
+  pagination.value.size = size
+  pagination.value.page = 1
+  updateUrlParams(1, size)
+  fetchList()
+}
+
+function handleSearch () {
+  pagination.value.page = 1 // 搜索时重置到第一页
+  updateUrlParams(1, pagination.value.size)
+  fetchList()
+}
+
+function handleReset () {
+  searchParams.value = {
+    name: '',
+  }
+  pagination.value.page = 1 // 重置时重置到第一页
+  updateUrlParams(1, pagination.value.size)
+  fetchList()
+}
+
+
+// 监听URL参数变化,用于处理浏览器后退/前进
+watch(
+  () => route.query,
+  (newQuery) => {
+    const newPage = Number(newQuery.page) || 1
+    const newSize = Number(newQuery.size) || 20
+
+    // 只有当参数真正发生变化时才更新
+    if (newPage !== pagination.value.page || newSize !== pagination.value.size) {
+      pagination.value.page = newPage > 0 ? newPage : 1
+      pagination.value.size = [10, 20, 50, 100].includes(newSize) ? newSize : 20
+      fetchList()
+    }
+  },
+  { deep: true }
+)
+
+onMounted(async () => {
+  await fetchList()
+})
 
-const settingsStore = useSettingsStore()
-const userStore = useUserStore()
 
 </script>
 
@@ -20,9 +131,22 @@ const userStore = useUserStore()
   <div>
     <FaPageHeader title="Role Management" />
     <FaPageMain>
-      <ElTable>
+      <ElTable
+        ref="tableRef" :data="dataList" stripe highlight-current-row border height="100%"
+      >
         <ElTableColumn label="Role Name" prop="name" />
       </ElTable>
+      <div class="p-4">
+        <ElPagination
+          v-model:current-page="pagination.page"
+          v-model:page-size="pagination.size"
+          :total="pagination.total"
+          :page-sizes="[10, 20, 50, 100]"
+          layout="total, sizes, prev, pager, next, jumper"
+          @size-change="handleSizeChange"
+          @current-change="handlePageChange"
+        />
+      </div>
     </FaPageMain>
   </div>
 </template>