diff --git a/digital-avatar-app/package-lock.json b/digital-avatar-app/package-lock.json index f47d34e..77a4b65 100644 --- a/digital-avatar-app/package-lock.json +++ b/digital-avatar-app/package-lock.json @@ -17,7 +17,7 @@ "@vitejs/plugin-vue": "^5.0.0", "typescript": "^5.3.0", "vite": "^5.0.0", - "vue-tsc": "^1.8.0" + "vue-tsc": "3.3.10" } }, "node_modules/@babel/helper-string-parser": { @@ -835,34 +835,32 @@ } }, "node_modules/@volar/language-core": { - "version": "1.11.1", - "resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-1.11.1.tgz", - "integrity": "sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==", + "version": "2.4.28", + "resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.28.tgz", + "integrity": "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==", "dev": true, "license": "MIT", "dependencies": { - "@volar/source-map": "1.11.1" + "@volar/source-map": "2.4.28" } }, "node_modules/@volar/source-map": { - "version": "1.11.1", - "resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-1.11.1.tgz", - "integrity": "sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==", + "version": "2.4.28", + "resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.28.tgz", + "integrity": "sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==", "dev": true, - "license": "MIT", - "dependencies": { - "muggle-string": "^0.3.1" - } + "license": "MIT" }, "node_modules/@volar/typescript": { - "version": "1.11.1", - "resolved": "https://registry.npmmirror.com/@volar/typescript/-/typescript-1.11.1.tgz", - "integrity": "sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==", + "version": "2.4.28", + "resolved": "https://registry.npmmirror.com/@volar/typescript/-/typescript-2.4.28.tgz", + "integrity": "sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-core": "1.11.1", - "path-browserify": "^1.0.1" + "@volar/language-core": "2.4.28", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" } }, "node_modules/@vue/compiler-core": { @@ -922,29 +920,19 @@ "license": "MIT" }, "node_modules/@vue/language-core": { - "version": "1.8.27", - "resolved": "https://registry.npmmirror.com/@vue/language-core/-/language-core-1.8.27.tgz", - "integrity": "sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==", + "version": "3.3.10", + "resolved": "https://registry.npmmirror.com/@vue/language-core/-/language-core-3.3.10.tgz", + "integrity": "sha512-CR7ByBbgPHqhxrioKPOcZBqttaozzLNwtkCzXQ+uF8gLPHnUe03srPnGpdtHD3zp+bq5iyVkZ1WNx7W564RPwg==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-core": "~1.11.1", - "@volar/source-map": "~1.11.1", - "@vue/compiler-dom": "^3.3.0", - "@vue/shared": "^3.3.0", - "computeds": "^0.0.1", - "minimatch": "^9.0.3", - "muggle-string": "^0.3.1", + "@volar/language-core": "2.4.28", + "@vue/compiler-dom": "^3.5.0", + "@vue/shared": "^3.5.0", + "alien-signals": "^3.2.1", + "muggle-string": "^0.4.1", "path-browserify": "^1.0.1", - "vue-template-compiler": "^2.7.14" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "picomatch": "^4.0.4" } }, "node_modules/@vue/reactivity": { @@ -1009,6 +997,13 @@ "node": ">= 6.0.0" } }, + "node_modules/alien-signals": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/alien-signals/-/alien-signals-3.2.1.tgz", + "integrity": "sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==", + "dev": true, + "license": "MIT" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", @@ -1027,23 +1022,6 @@ "proxy-from-env": "^2.1.0" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -1069,26 +1047,12 @@ "node": ">= 0.8" } }, - "node_modules/computeds": { - "version": "0.0.1", - "resolved": "https://registry.npmmirror.com/computeds/-/computeds-0.0.1.tgz", - "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", - "dev": true, - "license": "MIT" - }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "license": "MIT" }, - "node_modules/de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", - "dev": true, - "license": "MIT" - }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", @@ -1379,16 +1343,6 @@ "node": ">= 0.4" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmmirror.com/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -1441,22 +1395,6 @@ "node": ">= 0.6" } }, - "node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", @@ -1464,9 +1402,9 @@ "license": "MIT" }, "node_modules/muggle-string": { - "version": "0.3.1", - "resolved": "https://registry.npmmirror.com/muggle-string/-/muggle-string-0.3.1.tgz", - "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==", + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/muggle-string/-/muggle-string-0.4.1.tgz", + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", "dev": true, "license": "MIT" }, @@ -1501,6 +1439,19 @@ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/pinia": { "version": "2.3.1", "resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.3.1.tgz", @@ -1605,19 +1556,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmmirror.com/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", @@ -1701,6 +1639,13 @@ } } }, + "node_modules/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "dev": true, + "license": "MIT" + }, "node_modules/vue": { "version": "3.5.39", "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.39.tgz", @@ -1763,33 +1708,21 @@ "vue": "^3.5.0" } }, - "node_modules/vue-template-compiler": { - "version": "2.7.16", - "resolved": "https://registry.npmmirror.com/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", - "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "de-indent": "^1.0.2", - "he": "^1.2.0" - } - }, "node_modules/vue-tsc": { - "version": "1.8.27", - "resolved": "https://registry.npmmirror.com/vue-tsc/-/vue-tsc-1.8.27.tgz", - "integrity": "sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==", + "version": "3.3.10", + "resolved": "https://registry.npmmirror.com/vue-tsc/-/vue-tsc-3.3.10.tgz", + "integrity": "sha512-YaDVxcW+CGtaOt3pZahMG5jYPx0hsUTxyEoPOTSMebcGUXP9lIBabQ14vfKMORb2CqqK5CxsNo/d1d+4IQwiKg==", "dev": true, "license": "MIT", "dependencies": { - "@volar/typescript": "~1.11.1", - "@vue/language-core": "1.8.27", - "semver": "^7.5.4" + "@volar/typescript": "2.4.28", + "@vue/language-core": "3.3.10" }, "bin": { "vue-tsc": "bin/vue-tsc.js" }, "peerDependencies": { - "typescript": "*" + "typescript": ">=5.0.0" } } } diff --git a/digital-avatar-app/package.json b/digital-avatar-app/package.json index fb295b1..0bb5636 100644 --- a/digital-avatar-app/package.json +++ b/digital-avatar-app/package.json @@ -1,6 +1,7 @@ { "name": "digital-avatar-app", "version": "1.0.0", + "type": "module", "description": "会会数字分身 Web App", "scripts": { "dev": "vite", @@ -8,15 +9,15 @@ "preview": "vite preview" }, "dependencies": { - "vue": "^3.3.0", - "vue-router": "^4.2.0", + "axios": "^1.6.0", "pinia": "^2.1.0", - "axios": "^1.6.0" + "vue": "^3.3.0", + "vue-router": "^4.2.0" }, "devDependencies": { "@vitejs/plugin-vue": "^5.0.0", "typescript": "^5.3.0", "vite": "^5.0.0", - "vue-tsc": "^1.8.0" + "vue-tsc": "3.3.10" } } diff --git a/digital-avatar-app/src/api/index.ts b/digital-avatar-app/src/api/index.ts index 24eebf4..fe43335 100644 --- a/digital-avatar-app/src/api/index.ts +++ b/digital-avatar-app/src/api/index.ts @@ -1,4 +1,11 @@ -import axios, { AxiosInstance, AxiosRequestConfig } from 'axios' +import axios, { AxiosRequestConfig } from 'axios' + +interface ApiClient { + get(url: string, config?: AxiosRequestConfig): Promise + post(url: string, data?: unknown, config?: AxiosRequestConfig): Promise + put(url: string, data?: unknown, config?: AxiosRequestConfig): Promise + delete(url: string, config?: AxiosRequestConfig): Promise +} // API 基址:优先级 window.__APP_CONFIG__.apiBase > 环境变量 > 默认 '/api' // - 开发/Vite 代理:'/api'(由 vite.config 代理到后端 :8000) @@ -22,7 +29,7 @@ export function getAuthToken(): string | null { } // 创建 axios 实例(复用现有项目模式) -const createRequest = (config?: AxiosRequestConfig): AxiosInstance => { +const createRequest = (config?: AxiosRequestConfig): ApiClient => { const request = axios.create({ baseURL: resolveBaseURL(), timeout: 30000, @@ -59,7 +66,8 @@ const createRequest = (config?: AxiosRequestConfig): AxiosInstance => { } ) - return request + // The response interceptor unwraps the API envelope before callers receive it. + return request as unknown as ApiClient } // 递归修复时区标识(复用现有项目逻辑) @@ -162,17 +170,26 @@ export interface Organization { id: string name: string description: string + emoji: string + type: 'team' | 'company' | 'community' role: 'admin' | 'member' | 'viewer' memberCount: number createdAt: string } +export interface CreateOrganizationInput { + name: string + desc?: string + emoji?: string + type?: 'team' | 'company' | 'community' +} + // 获取组织列表 export const getOrganizationList = (params?: any) => request.get<{ data: Organization[]; total: number }>('/organizations', { params }) // 创建组织 -export const createOrganization = (data: Partial) => +export const createOrganization = (data: CreateOrganizationInput) => request.post('/organizations', data) // ==================== 知识库管理 API ==================== diff --git a/digital-avatar-app/src/utils/avatar-page-data.d.ts b/digital-avatar-app/src/utils/avatar-page-data.d.ts new file mode 100644 index 0000000..883f30c --- /dev/null +++ b/digital-avatar-app/src/utils/avatar-page-data.d.ts @@ -0,0 +1,45 @@ +export interface AvatarPageRecord { + id?: string | null + name?: string + displayName?: string + description?: string + status?: 'active' | 'inactive' | 'training' + photoUrl?: string + config?: Partial +} + +export interface AvatarEditForm { + name: string + displayName: string + description: string + status: 'active' | 'inactive' | 'training' + photoUrl: string + replyStyle: string + creativity: number + rigor: number + humor: number + responseLength: string + systemPrompt: string + profession: string + position: string + organization: string + organizationAddress: string + autoReply: boolean +} + +export interface AvatarUpdatePayload { + name: string + displayName: string + description: string + status: AvatarEditForm['status'] + photoUrl: string + config: Omit +} + +export function unwrapListData(value: T[] | { data?: T[] } | null | undefined): T[] +export function pickAvatarId( + currentAvatarId: string | null | undefined, + avatars?: AvatarPageRecord[] +): string | null +export function normalizeAvatarEditForm(avatar?: AvatarPageRecord): AvatarEditForm +export function buildAvatarUpdatePayload(form: AvatarEditForm): AvatarUpdatePayload diff --git a/digital-avatar-app/src/utils/chat-markdown.d.ts b/digital-avatar-app/src/utils/chat-markdown.d.ts new file mode 100644 index 0000000..3322b07 --- /dev/null +++ b/digital-avatar-app/src/utils/chat-markdown.d.ts @@ -0,0 +1,11 @@ +export interface ChatMarkdownCharacter { + text: string + key: string | number + bold: boolean + italic: boolean + code: boolean + heading: boolean + newline: boolean +} + +export function renderChatMarkdownCharacters(value: string | string[]): ChatMarkdownCharacter[] diff --git a/digital-avatar-app/src/views/AvatarChat.vue b/digital-avatar-app/src/views/AvatarChat.vue index ecb4b24..2ac4838 100644 --- a/digital-avatar-app/src/views/AvatarChat.vue +++ b/digital-avatar-app/src/views/AvatarChat.vue @@ -116,12 +116,13 @@ const avatarStatus = computed(() => { return { tone: 'active', label: '在线,随时可以和我聊聊' } }) -const sourceLabel = (source?: DisplayMessage['source']) => ({ +const sourceLabels: Record, string> = { qa: '标准问答对', knowledge: '参考文件知识库', qwen: '智能回答', public: '' -}[source || ''] || '') +} +const sourceLabel = (source?: DisplayMessage['source']) => source ? sourceLabels[source] : '' const scrollToBottom = async () => { await nextTick() diff --git a/digital-avatar-app/src/views/CreateOrg.vue b/digital-avatar-app/src/views/CreateOrg.vue index 736e041..377de57 100644 --- a/digital-avatar-app/src/views/CreateOrg.vue +++ b/digital-avatar-app/src/views/CreateOrg.vue @@ -78,9 +78,14 @@ const typeOptions = [ { value: 'team', label: '团队' }, { value: 'company', label: '企业' }, { value: 'community', label: '社群' } -] +] as const -const form = ref({ emoji: '🏢', name: '', desc: '', type: 'team' }) +const form = ref({ + emoji: '🏢', + name: '', + desc: '', + type: 'team' as 'team' | 'company' | 'community' +}) const canSubmit = computed(() => form.value.name.trim().length > 0) diff --git a/digital-avatar-app/src/vite-env.d.ts b/digital-avatar-app/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/digital-avatar-app/src/vite-env.d.ts @@ -0,0 +1 @@ +///