fix: restore reproducible frontend builds

This commit is contained in:
stefanfeng
2026-08-19 14:56:39 +08:00
parent 68ea87e1b2
commit 6bf446f889
8 changed files with 153 additions and 139 deletions
+21 -4
View File
@@ -1,4 +1,11 @@
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'
import axios, { AxiosRequestConfig } from 'axios'
interface ApiClient {
get<T>(url: string, config?: AxiosRequestConfig): Promise<T>
post<T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>
put<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>
delete<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>
}
// 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<Organization>) =>
export const createOrganization = (data: CreateOrganizationInput) =>
request.post<Organization>('/organizations', data)
// ==================== 知识库管理 API ====================
+45
View File
@@ -0,0 +1,45 @@
export interface AvatarPageRecord {
id?: string | null
name?: string
displayName?: string
description?: string
status?: 'active' | 'inactive' | 'training'
photoUrl?: string
config?: Partial<AvatarEditForm>
}
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<AvatarEditForm, 'name' | 'displayName' | 'description' | 'status' | 'photoUrl'>
}
export function unwrapListData<T>(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
+11
View File
@@ -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[]
+3 -2
View File
@@ -116,12 +116,13 @@ const avatarStatus = computed(() => {
return { tone: 'active', label: '在线,随时可以和我聊聊' }
})
const sourceLabel = (source?: DisplayMessage['source']) => ({
const sourceLabels: Record<NonNullable<DisplayMessage['source']>, string> = {
qa: '标准问答对',
knowledge: '参考文件知识库',
qwen: '智能回答',
public: ''
}[source || ''] || '')
}
const sourceLabel = (source?: DisplayMessage['source']) => source ? sourceLabels[source] : ''
const scrollToBottom = async () => {
await nextTick()
+7 -2
View File
@@ -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)
+1
View File
@@ -0,0 +1 @@
/// <reference types="vite/client" />