diff --git a/.gitignore b/.gitignore index 3feb64f..d3b08c5 100644 --- a/.gitignore +++ b/.gitignore @@ -79,4 +79,6 @@ go/*.pem .mimocode/package-lock.json .mimocode/bun.lock -docs/sql/ \ No newline at end of file +docs/sql/ + +go/update-server-outside.bat \ No newline at end of file diff --git a/backend/src/api/user.js b/backend/src/api/user.js index 6da15ef..8799685 100644 --- a/backend/src/api/user.js +++ b/backend/src/api/user.js @@ -1,102 +1,111 @@ -import request from '@/utils/request'; - -//获取所有用户信息 -export function getAllUsers(params) { - return request({ - url: '/backend/getAllUsers', - method: 'get', - params, - }); -} - -//获取租户用户 -export function getTenantUsers(tenantId) { - return request({ - url: `/backend/getTenantUsers/${tenantId}`, - method: 'get', - }); -} - -// 获取用户信息 -// params.by === 'id':按 yz_system_tenant_user 主键精确查询(用户管理页传列表行 id 时必须携带); -// 缺省时后端兼容 identity_id / 老 uid(个人中心等场景) -export function getUserInfo(userId, params) { - return request({ - url: `/backend/getUserInfo/${userId}`, - method: 'get', - params, - }); -} - -// 添加用户 -export function addUser(data) { - return request({ - url: '/backend/addUser', - method: 'post', - data, - }); -} - -// 编辑用户信息(params.by === 'id' 时后端按主键精确匹配) -export function editUser(userId, data, params) { - return request({ - url: `/backend/editUser/${userId}`, - method: 'post', - data, - params, - }); -} - -// 更新用户信息(编辑用户的别名) -export function updateUserInfo(userId, data) { - return editUser(userId, data); -} - -// 更新个人资料 -export function updateUserProfile(userId, data) { - return editUser(userId, data); -} - -// 绑定/更换手机号 -export function bindPhone(userId, phone) { - return editUser(userId, { phone }); -} - -// 绑定/更换邮箱 -export function bindEmail(userId, email) { - return editUser(userId, { email }); -} - -// 上传并设置当前登录用户头像(一步到位:上传文件 + 写入认证中心头像) -// formData 需包含 file 字段;返回 data.url 为头像地址 -export function uploadAvatar(formData) { - return request({ - url: '/backend/uploadavatar', - method: 'post', - data: formData, - // 上传不设超时;不要手写 Content-Type,需浏览器生成 multipart boundary - timeout: 0, - }); -} - -// 删除用户(params.by === 'id' 时后端按主键精确匹配) -export function deleteUser(userId, params) { - return request({ - url: `/backend/deleteUser/${userId}`, - method: 'delete', - params, - }); -} - -// 修改密码;byID=true 表示 userId 是用户管理列表行主键,后端按主键精确匹配 -export function changePassword(userId, data, byID = false) { - return request({ - url: '/backend/changePassword', - method: 'post', - data: { - id: userId, - password: data.newPassword, - by: byID ? 'id' : undefined, - }, - }); -} +import request from '@/utils/request'; + +// 将所选租户用户与人员档案进行比对,有差异时同步人员信息 +export function syncTenantUsersToEmployees(userIds) { + return request({ + url: "/backend/syncTenantUsersToEmployees", + method: "post", + data: { user_ids: userIds }, + }); +} + +//获取所有用户信息 +export function getAllUsers(params) { + return request({ + url: '/backend/getAllUsers', + method: 'get', + params, + }); +} + +//获取租户用户 +export function getTenantUsers(tenantId) { + return request({ + url: `/backend/getTenantUsers/${tenantId}`, + method: 'get', + }); +} + +// 获取用户信息 +// params.by === 'id':按 yz_system_tenant_user 主键精确查询(用户管理页传列表行 id 时必须携带); +// 缺省时后端兼容 identity_id / 老 uid(个人中心等场景) +export function getUserInfo(userId, params) { + return request({ + url: `/backend/getUserInfo/${userId}`, + method: 'get', + params, + }); +} + +// 添加用户 +export function addUser(data) { + return request({ + url: '/backend/addUser', + method: 'post', + data, + }); +} + +// 编辑用户信息(params.by === 'id' 时后端按主键精确匹配) +export function editUser(userId, data, params) { + return request({ + url: `/backend/editUser/${userId}`, + method: 'post', + data, + params, + }); +} + +// 更新用户信息(编辑用户的别名) +export function updateUserInfo(userId, data) { + return editUser(userId, data); +} + +// 更新个人资料 +export function updateUserProfile(userId, data) { + return editUser(userId, data); +} + +// 绑定/更换手机号 +export function bindPhone(userId, phone) { + return editUser(userId, { phone }); +} + +// 绑定/更换邮箱 +export function bindEmail(userId, email) { + return editUser(userId, { email }); +} + +// 上传并设置当前登录用户头像(一步到位:上传文件 + 写入认证中心头像) +// formData 需包含 file 字段;返回 data.url 为头像地址 +export function uploadAvatar(formData) { + return request({ + url: '/backend/uploadavatar', + method: 'post', + data: formData, + // 上传不设超时;不要手写 Content-Type,需浏览器生成 multipart boundary + timeout: 0, + }); +} + +// 删除用户(params.by === 'id' 时后端按主键精确匹配) +export function deleteUser(userId, params) { + return request({ + url: `/backend/deleteUser/${userId}`, + method: 'delete', + params, + }); +} + +// 修改密码;byID=true 表示 userId 是用户管理列表行主键,后端按主键精确匹配 +export function changePassword(userId, data, byID = false) { + return request({ + url: '/backend/changePassword', + method: 'post', + data: { + id: userId, + password: data.newPassword, + by: byID ? 'id' : undefined, + }, + }); +} diff --git a/backend/src/views/apps/ai/components/chatWindow.vue b/backend/src/views/apps/ai/components/chatWindow.vue index dbf6cc9..4e792e3 100644 --- a/backend/src/views/apps/ai/components/chatWindow.vue +++ b/backend/src/views/apps/ai/components/chatWindow.vue @@ -158,16 +158,20 @@
首字 {{ (msg.firstTokenMs / 1000).toFixed(1) }}s · - {{ formatDuration(msg.durationMs) }} - · - {{ msg.tokens }} tokens - · - {{ msg.model }} + + {{ msg.providerName || msg.provider_name || '未知厂商' }} + + · + 用时 {{ formatDuration(msg.durationMs) }} + · + {{ formatTokenRate(msg.tokens, msg.durationMs) }} token/s + · + {{ msg.tokens }} tokens
@@ -369,6 +373,17 @@ const currentModels = computed(() => { return p && p.models ? p.models : [] }) +const currentProvider = computed(() => + providerList.value.find((item) => item.id === selectedProviderId.value) || null +) + +function formatTokenRate(tokens, durationMs) { + const count = Number(tokens || 0) + const elapsed = Number(durationMs || 0) + if (!count || !elapsed) return '—' + return (count / (elapsed / 1000)).toFixed(1) +} + onMounted(() => { fetchProviders() fetchDefaultPreset() @@ -475,7 +490,11 @@ async function fetchMessages(sessionId) { try { const res = await getChatMessageList(sessionId) if (res.code === 200) { - messages.value = res.data.list || [] + messages.value = (res.data.list || []).map((msg) => ({ + ...msg, + durationMs: msg.durationMs ?? msg.duration_ms ?? 0, + providerName: msg.providerName || msg.provider_name || '', + })) scrollToBottom() } } catch (e) { @@ -748,9 +767,10 @@ async function doSend(content, images = []) { scrollToBottom() } else if (eventType === 'done') { aiMsg.id = parsed.message_id - if (parsed.tokens) aiMsg.tokens = parsed.tokens - if (parsed.duration_ms) aiMsg.durationMs = parsed.duration_ms + if (parsed.tokens !== undefined) aiMsg.tokens = parsed.tokens + if (parsed.duration_ms !== undefined) aiMsg.durationMs = parsed.duration_ms if (parsed.model) aiMsg.model = parsed.model + aiMsg.providerName = parsed.provider_name || currentProvider.value?.name || '' } else if (eventType === 'error') { streamError = new Error(parsed.error || 'AI调用失败') } diff --git a/backend/src/views/apps/oa/reimburse/components/detail.vue b/backend/src/views/apps/oa/reimburse/components/detail.vue index b937737..0b4e3e8 100644 --- a/backend/src/views/apps/oa/reimburse/components/detail.vue +++ b/backend/src/views/apps/oa/reimburse/components/detail.vue @@ -322,7 +322,7 @@ > 确认到账 -
+
diff --git a/backend/src/views/apps/organization/components/EmployeeEditDialog.vue b/backend/src/views/apps/organization/components/EmployeeEditDialog.vue index 67a04c1..603985a 100644 --- a/backend/src/views/apps/organization/components/EmployeeEditDialog.vue +++ b/backend/src/views/apps/organization/components/EmployeeEditDialog.vue @@ -13,6 +13,9 @@ + + 账号与用户管理保持一致,不可直接修改 + diff --git a/backend/src/views/apps/organization/components/EmployeePage.vue b/backend/src/views/apps/organization/components/EmployeePage.vue index 824f9dc..322d143 100644 --- a/backend/src/views/apps/organization/components/EmployeePage.vue +++ b/backend/src/views/apps/organization/components/EmployeePage.vue @@ -3,7 +3,8 @@