\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/src/components/LangSelect/index.vue b/src/components/LangSelect/index.vue
index ef04637eaf9739acd6fcde328fda9d7a4a3c7030..5a29f8301c400ca8606124982b4b8b3da546487b 100644
--- a/src/components/LangSelect/index.vue
+++ b/src/components/LangSelect/index.vue
@@ -8,10 +8,10 @@
{{ languageText }}
@@ -38,9 +38,11 @@ import { LanguageEnum } from '@/enums/LanguageEnum';
import defaultSettings from '@/settings';
import AuthAPI from '@/api/auth';
import { IconSuccess } from '@computing/opendesign-icons';
+import { useAssets } from '@/composables/useAssets';
const languageText = ref();
const language = ref();
const userInfo = ref();
+const { getImageUrl } = useAssets();
defineProps({
size: {
type: String,
diff --git a/src/components/RoleDialog/PermissionGroupCard.vue b/src/components/RoleDialog/PermissionGroupCard.vue
new file mode 100644
index 0000000000000000000000000000000000000000..e758f76024738082d9ae942a3a9e92d506e6213f
--- /dev/null
+++ b/src/components/RoleDialog/PermissionGroupCard.vue
@@ -0,0 +1,269 @@
+
+
+
+
+
+
+
+
+ {{ item.actionName }}
+
+
+
+
+
+
+
+
diff --git a/src/components/RoleDialog/index.vue b/src/components/RoleDialog/index.vue
new file mode 100644
index 0000000000000000000000000000000000000000..bbf27125bebfaab3b6ddc1a90128ef570e91ee44
--- /dev/null
+++ b/src/components/RoleDialog/index.vue
@@ -0,0 +1,535 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ isEdit ? t('groupDetail.reset') : t('groupDetail.restoreDefault') }}
+
+
+
+
+
+
+
+ {{ t('groupDetail.loadingPermissionGroups') || '正在加载权限组数据...' }}
+
+
+
+
+
+
+ handlePermissionGroupUpdate(group.actionType, permissions)"
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/composables/useAssets.ts b/src/composables/useAssets.ts
new file mode 100644
index 0000000000000000000000000000000000000000..88b09b2bd7d0ead6d25a75899a868abc01abdff8
--- /dev/null
+++ b/src/composables/useAssets.ts
@@ -0,0 +1,49 @@
+/**
+ * 静态资源处理组合式函数
+ */
+import { resolveAssetUrl } from '@/utils';
+
+export function useAssets() {
+ /**
+ * 解析静态资源 URL
+ * @param assetPath 静态资源路径
+ * @returns 处理后的完整 URL
+ */
+ const resolveAsset = (assetPath: string): string => {
+ return resolveAssetUrl(assetPath);
+ };
+
+ /**
+ * 批量解析静态资源 URL
+ * @param assetPaths 静态资源路径数组
+ * @returns 处理后的完整 URL 数组
+ */
+ const resolveAssets = (assetPaths: string[]): string[] => {
+ return assetPaths.map(path => resolveAssetUrl(path));
+ };
+
+ /**
+ * 获取图片 URL
+ * @param imagePath 图片路径
+ * @returns 处理后的图片 URL
+ */
+ const getImageUrl = (imagePath: string): string => {
+ return resolveAssetUrl(`/assets/images/${imagePath}`);
+ };
+
+ /**
+ * 获取 SVG 图标 URL
+ * @param iconPath SVG 图标路径
+ * @returns 处理后的图标 URL
+ */
+ const getSvgUrl = (iconPath: string): string => {
+ return resolveAssetUrl(`/assets/svg/${iconPath}`);
+ };
+
+ return {
+ resolveAsset,
+ resolveAssets,
+ getImageUrl,
+ getSvgUrl
+ };
+}
diff --git a/src/lang/package/en.ts b/src/lang/package/en.ts
index 48378f384a19b21cdb00790facce903d3936e5a2..e4b24970ea70c35a42da0052ab62d33da2ef8fd9 100644
--- a/src/lang/package/en.ts
+++ b/src/lang/package/en.ts
@@ -69,6 +69,7 @@ export default {
teamAuth: 'Team Permission',
isPublic: 'isPublic',
creator: 'Creator',
+ owner: 'Owner',
createTime: 'Create Time',
noData: 'No data.',
teamDetail: 'Team Details',
@@ -79,10 +80,18 @@ export default {
create: 'Create',
},
groupDetail: {
+ memberPermission: 'Member Management',
teamSet: 'Team Settings',
teamNews: 'Team News',
- roleManage: 'Role Management',
+ roleManage: 'Role/Permission',
MemberAuthority: 'Member/Authority',
+ transferTeam: 'Transfer Team',
+ transfer: 'Transfer',
+ transferTip: 'Transfer team ownership to other members',
+ transferDialog: 'Transfer Team',
+ selectReceiver: 'Select Receiver',
+ pleaseSelectReceiver: 'Please select receiver',
+ transferMessage: 'Transfer team ownership to other members',
dissolveTeam: 'Dissolve Team',
dissolve: 'Dissolve',
dissolveTip:
@@ -95,6 +104,132 @@ export default {
createTeamSuccess: 'Team created successfully.',
updateTeamSuccess: 'Team updated successfully.',
inviteMember: 'Invite Member',
+ placeholderMember: 'Enter member ID/name',
+ memberId: 'Member ID',
+ memberName: 'Member Name',
+ roleAuth: 'Role',
+ // Role management related
+ createRole: 'Create Role',
+ batchDeleteRole: 'Batch Delete',
+ roleFilter: 'Enter role name',
+ roleName: 'Role Name',
+ permissionAssignment: 'Permission Assignment',
+ createTime: 'Create Time',
+ operation: 'Operation',
+ editRole: 'Edit',
+ deleteRole: 'Delete',
+ // Member management related
+ batchDeleteMember: 'Batch Delete',
+ memberFilter: 'Enter member ID/name',
+ editMember: 'Edit',
+ deleteMember: 'Delete',
+ // Role dialog
+ newRole: 'Create Role',
+ editRoleTitle: 'Edit Role',
+ roleNamePlaceholderEdit: 'Role name',
+ roleNamePlaceholderNew: 'Custom role',
+ permissionAllocation: 'Permission Allocation',
+ restoreDefault: 'Restore Default',
+ reset: 'Reset',
+ teamPermission: 'Team',
+ assetPermissions: 'Asset',
+ knowledgePermission: 'Knowledge',
+ documentPermission: 'Document',
+ datasetPermission: 'Dataset',
+ testingPermission: 'Testing',
+ evaluationPermissions: 'Evaluation',
+ modifyTeamInfo: 'Modify team info',
+ inviteMembers: 'Invite members',
+ manageRoles: 'Manage roles',
+ createKnowledge: 'Create knowledge',
+ editKnowledge: 'Edit knowledge',
+ deleteKnowledge: 'Delete knowledge',
+ uploadDocument: 'Upload document',
+ editDocument: 'Edit document',
+ deleteDocument: 'Delete document',
+ createDataset: 'Create dataset',
+ editDataset: 'Edit dataset',
+ deleteDataset: 'Delete dataset',
+ createTesting: 'Create testing',
+ editTesting: 'Edit testing',
+ deleteTesting: 'Delete testing',
+ // Role dialog related
+ newRoleDialog: 'Create Role',
+ editRoleDialog: 'Edit Role',
+ roleNameLabel: 'Role Name',
+ roleNamePlaceholder: 'Custom role',
+ permissionConfig: 'Permission Config',
+ resetToDefault: 'Restore Default',
+ resetToInitial: 'Reset',
+ roleCreateSuccess: 'Role created successfully',
+ roleEditSuccess: 'Role edited successfully',
+ roleCreateFailed: 'Role creation failed',
+ roleEditFailed: 'Role edit failed',
+ roleNameRequired: 'Please enter role name',
+ roleNameLength: 'Role name length should be 1-20 characters',
+ // Specific permission items
+ permModifyTeamInfo: 'Modify team info',
+ permInviteMembers: 'Invite members',
+ permManageRoles: 'Manage roles',
+ permViewAsset: 'View asset content',
+ permImportAsset: 'Import asset',
+ permExportAsset: 'Export asset',
+ permCreateAsset: 'Create asset',
+ permModifyAsset: 'Modify asset info',
+ permDeleteAsset: 'Delete asset',
+ permUploadDocument: 'Upload document',
+ permImportDocument: 'Import document',
+ permDeleteDocument: 'Delete document',
+ permModifyDocument: 'Modify document info',
+ permEditDocument: 'Edit document content',
+ permDownloadDocument: 'Download document',
+ permViewDataset: 'View dataset details',
+ permGenerateDataset: 'Generate dataset',
+ permExportDataset: 'Export dataset',
+ permDeleteDataset: 'Delete dataset',
+ permModifyDataset: 'Modify dataset info',
+ permEditDataset: 'Edit dataset content',
+ permCreateTesting: 'Create testing',
+ permViewTesting: 'View testing',
+ permDeleteTesting: 'Delete testing',
+ permModifyTesting: 'Modify testing info',
+ permDownloadReport: 'Download report',
+ permViewTask: 'View evaluation task details',
+ // Team permission items
+ permModifyRoleInfo: 'Modify role info',
+ permDeleteMembers: 'Delete members',
+ permModifyMemberRoles: 'Modify member roles',
+ permAddRoles: 'Add roles',
+ permTransferTeam: 'Transfer team',
+ permDissolveTeam: 'Dissolve team',
+ // Asset permission items
+ permAccessAsset: 'Access asset content',
+ // Document permission items
+ permAccessDocumentAnalysis: 'Access document analysis results',
+ permParseDocument: 'Parse document',
+ permBatchUseDocument: 'Enable/disable document',
+ permBatchParseDocument: 'Enable/disable document analysis results',
+ // Member role editing related
+ pleaseSelectRole: 'Please select role',
+ confirmChangeRole: 'Confirm Role Change',
+ // Invite member related
+ addMember: 'Add',
+ pendingMembers: 'Pending Members',
+ defaultRole: 'member',
+ // Dataset permission items
+ permAccessDatasetDetails: 'Access dataset details',
+ permExportImport: 'Import/export',
+ permModifySingleData: 'Modify single data',
+ // Testing permission items
+ permCreateTest: 'Create test',
+ permViewTest: 'View test',
+ permDeleteTest: 'Delete test',
+ permModifyTest: 'Modify test',
+ // NoData
+ noPermissionGroups: 'No Permissions Could be Assigned',
+ // Role deletion related messages
+ systemRoleCannotDelete: 'This role is a system fixed role and cannot be deleted',
+ confirmDeleteRole: 'Are you sure to delete role {roleName}?',
},
assetLibrary: {
assetLibrary: 'Asset Libraries',
@@ -121,6 +256,8 @@ export default {
embeddedModel: 'Embedded Model',
analyticMethod: 'Parsing Method',
fileChunkSize: 'File Block Size',
+ uploadCountLimit: 'Max documents per upload',
+ character: 'character',
configCategory: 'Document Categories',
fileConfigCategory: 'Document Information Categories',
supAddCategoris: 'A maximum of 10 document categories can be added.',
@@ -385,5 +522,22 @@ export default {
datasetDesc: 'This is a dataset description',
testingName: 'Test Data 01',
},
+ chunkMethod: {
+ chunkSettings: 'Chunk Settings',
+ chunkMethod: 'Chunk Method',
+ default: 'Default',
+ customDelimiter: 'Custom Delimiter',
+ chunkIdentifier: 'Chunk Identifier',
+ pleaseSelectChunkMethod: 'Please select chunk method',
+ pleaseEnterChunkIdentifier: 'Please enter chunk identifier',
+ },
+ tabs: {
+ basicSettings: 'Basic Settings',
+ parseSettings: 'Parse Settings',
+ retrievalSettings: 'Retrieval Settings',
+ },
+ vectorization: {
+ vectorizationSettings: 'Vectorization Settings',
+ },
copyright: 'Copyright© Huawei Software Technologies Co., Ltd.2024. All rights reserved.',
};
diff --git a/src/lang/package/zh-cn.ts b/src/lang/package/zh-cn.ts
index 6c7a273ed2ec2505530c01e55ba3b0ddd4da82f5..3d5e895110ce188c3cdffe6248cd4a7244999377 100644
--- a/src/lang/package/zh-cn.ts
+++ b/src/lang/package/zh-cn.ts
@@ -75,6 +75,7 @@ export default {
teamAuth: '团队权限',
isPublic: '是否公开',
creator: '创建人',
+ owner: '所有者',
createTime: '创建时间',
noData: '暂无数据',
teamDetail: '团队详情',
@@ -85,10 +86,17 @@ export default {
create: '创建',
},
groupDetail: {
- teamSet: '团队设置',
+ memberPermission: '成员管理',
+ roleManage: '角色/权限',
teamNews: '团队动态',
- roleManage: '角色管理',
- MemberAuthority: '成员/权限',
+ teamSet: '团队设置',
+ transferTeam: '移交团队',
+ transfer: '移交',
+ transferTip: '将团队的所有者权限移交给其他成员',
+ transferDialog: '移交团队',
+ selectReceiver: '选择接收人',
+ pleaseSelectReceiver: '请选择接收人',
+ transferMessage: '将团队的所有者权限移交给其他成员',
dissolveTeam: '解散团队',
dissolve: '解散',
dissolveTip: '解散团队后相关资源都会被释放,请谨慎操作',
@@ -103,7 +111,134 @@ export default {
placeholderMember: '请输入成员ID/姓名',
memberId: '成员ID',
memberName: '成员名称',
- roleAuth: '角色权限',
+ roleAuth: '角色',
+ // 角色管理相关
+ createRole: '新建角色',
+ batchDeleteRole: '批量删除',
+ roleFilter: '请输入角色名称',
+ roleName: '角色名称',
+ permissionAssignment: '权限分配',
+ createTime: '创建时间',
+ operation: '操作',
+ editRole: '编辑',
+ deleteRole: '删除',
+ // 成员管理相关
+ batchDeleteMember: '批量删除',
+ memberFilter: '请输入成员ID/名称',
+ editMember: '编辑',
+ deleteMember: '删除',
+ // 角色对话框
+ newRole: '新建角色',
+ editRoleTitle: '编辑角色',
+ roleNamePlaceholderEdit: '角色名称',
+ roleNamePlaceholderNew: '自定义角色',
+ permissionAllocation: '权限分配',
+ restoreDefault: '恢复默认',
+ reset: '重置',
+ teamPermission: '团队',
+ assetPermissions: '资产',
+ knowledgePermission: '知识库',
+ documentPermission: '文档管理',
+ datasetPermission: '数据集管理',
+ testingPermission: '评测管理',
+ evaluationPermissions: '评估任务',
+ modifyTeamInfo: '修改团队信息',
+ inviteMembers: '邀请成员',
+ manageRoles: '管理角色',
+ createKnowledge: '创建知识库',
+ editKnowledge: '编辑知识库',
+ deleteKnowledge: '删除知识库',
+ uploadDocument: '上传文档',
+ editDocument: '编辑文档',
+ deleteDocument: '删除文档',
+ createDataset: '创建数据集',
+ editDataset: '编辑数据集',
+ deleteDataset: '删除数据集',
+ createTesting: '创建评测',
+ editTesting: '编辑评测',
+ deleteTesting: '删除评测',
+ // 角色对话框相关
+ newRoleDialog: '新建角色',
+ editRoleDialog: '编辑角色',
+ roleNameLabel: '角色名称',
+ roleNamePlaceholder: '自定义角色',
+ permissionConfig: '权限配置',
+ resetToDefault: '恢复默认',
+ resetToInitial: '重置',
+ roleCreateSuccess: '角色创建成功',
+ roleEditSuccess: '角色编辑成功',
+ roleCreateFailed: '角色创建失败',
+ roleEditFailed: '角色编辑失败',
+ roleNameRequired: '请输入角色名称',
+ roleNameLength: '角色名称长度为1-20个字符',
+ // 权限组名称
+ teamPermissions: '团队',
+ documentPermissions: '文档',
+ datasetPermissions: '数据集',
+ testingPermissions: '评测管理',
+ // 具体权限项
+ permModifyTeamInfo: '修改团队信息',
+ permInviteMembers: '邀请成员',
+ permManageRoles: '管理角色',
+ permViewAsset: '查询资产内容',
+ permImportAsset: '导入资产',
+ permExportAsset: '导出资产',
+ permCreateAsset: '创建资产',
+ permModifyAsset: '修改资产或信息',
+ permDeleteAsset: '删除资产',
+ permUploadDocument: '上传文档到信息新增',
+ permImportDocument: '导入文档',
+ permDeleteDocument: '删除文档',
+ permModifyDocument: '修改文档信息',
+ permEditDocument: '编辑文档内容',
+ permDownloadDocument: '下载文档',
+ permViewDataset: '访问数据集数据详情',
+ permGenerateDataset: '生成数据集',
+ permExportDataset: '导出数据集',
+ permDeleteDataset: '删除数据集',
+ permModifyDataset: '修改数据集信息',
+ permEditDataset: '编辑数据集内容',
+ permCreateTesting: '创建数据集评测',
+ permViewTesting: '查看数据集评测',
+ permDeleteTesting: '删除数据集评测',
+ permModifyTesting: '修改数据集评测信息',
+ permDownloadReport: '下载数据集评测报告',
+ permViewTask: '查询评估任务详情',
+ // 团队权限项
+ permModifyRoleInfo: '修改角色信息',
+ permDeleteMembers: '删除成员',
+ permModifyMemberRoles: '修改成员角色',
+ permAddRoles: '新增角色',
+ permTransferTeam: '移交团队',
+ permDissolveTeam: '解散团队',
+ // 资产权限项
+ permAccessAsset: '访问资产内容',
+ // 文档权限项
+ permAccessDocumentAnalysis: '访问文档解析结果',
+ permParseDocument: '解析文档',
+ permBatchUseDocument: '启用/禁用文档',
+ permBatchParseDocument: '启用/禁用文档解析结果',
+ // 成员角色编辑相关
+ pleaseSelectRole: '请选择角色',
+ confirmChangeRole: '确认修改角色',
+ // 邀请成员相关
+ addMember: '添加',
+ pendingMembers: '待邀请成员',
+ defaultRole: '成员',
+ // 数据集权限项
+ permAccessDatasetDetails: '访问数据集详情',
+ permExportImport: '导入/导出',
+ permModifySingleData: '修改单条数据',
+ // 评测权限项
+ permCreateTest: '创建测试',
+ permViewTest: '查看测试',
+ permDeleteTest: '删除测试',
+ permModifyTest: '修改测试',
+ // NoData
+ noPermissionGroups: '无可配置权限',
+ // 角色删除相关提示
+ systemRoleCannotDelete: '该角色为系统固定角色,不可删除',
+ confirmDeleteRole: '确定删除角色 {roleName} 吗?',
},
assetLibrary: {
assetLibrary: '资产库',
@@ -130,6 +265,8 @@ export default {
embeddedModel: '嵌入模型',
analyticMethod: '文档解析器',
fileChunkSize: '文件分块大小',
+ uploadCountLimit: '单次文档上传个数上限',
+ character: '字符',
configCategory: '文档类别',
fileConfigCategory: '文档信息类别',
supAddCategoris: '最多支持添加10个文档信息类别',
@@ -389,5 +526,22 @@ export default {
datasetDesc: '这是一段数据集简介',
testingName: '测试数据01',
},
+ chunkMethod: {
+ chunkSettings: '分块设置',
+ chunkMethod: '分块方法',
+ default: '默认',
+ customDelimiter: '自定义分隔符',
+ chunkIdentifier: '分块标识符',
+ pleaseSelectChunkMethod: '请选择分块方法',
+ pleaseEnterChunkIdentifier: '请输入分块标识符',
+ },
+ tabs: {
+ basicSettings: '基本设置',
+ parseSettings: '解析设置',
+ retrievalSettings: '检索设置',
+ },
+ vectorization: {
+ vectorizationSettings: '向量化设置',
+ },
copyright: '版权所有© 华为软件技术有限公司2024。保留一切权利',
};
diff --git a/src/main.ts b/src/main.ts
index ae30564fb1998b419ea6fb84988a8a9cef8a3def..0f0a0cd0158c298a7bee2c0e999217e4127839d4 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -9,6 +9,7 @@ import '@computing/opendesign2/themes/es/css';
import zhCn from 'element-plus/es/locale/lang/zh-cn';
import App from './App.vue';
import setupPlugins from '@/plugins';
+import { initCssAssetResolver } from '@/utils/cssAssetResolver';
// 本地SVG图标
import 'virtual:svg-icons-register';
@@ -30,4 +31,8 @@ app.use(ElementPlus, {
});
app.use(setupPlugins);
app.use(opendesign2);
+
+// 初始化 CSS 静态资源解析器
+initCssAssetResolver();
+
app.mount('#app');
diff --git a/src/plugins/assetResolver.ts b/src/plugins/assetResolver.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3bcddebfcb7b8b1326f8589096b4fd49f16c0157
--- /dev/null
+++ b/src/plugins/assetResolver.ts
@@ -0,0 +1,19 @@
+/**
+ * 静态资源解析插件
+ * 用于解决 iframe 环境下的跨域静态资源访问问题
+ */
+import type { App } from 'vue';
+import { resolveAssetUrl } from '@/utils';
+
+export default {
+ install(app: App) {
+ // 全局属性:解析静态资源 URL
+ app.config.globalProperties.$resolveAsset = resolveAssetUrl;
+
+ // 全局方法:提供给组合式 API 使用
+ app.provide('resolveAsset', resolveAssetUrl);
+ }
+};
+
+// 导出工具函数供直接使用
+export { resolveAssetUrl };
diff --git a/src/plugins/cssAssetResolver.ts b/src/plugins/cssAssetResolver.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a00ce14c50326a1f5b9ecc8a11ba8da6d6edf528
--- /dev/null
+++ b/src/plugins/cssAssetResolver.ts
@@ -0,0 +1,113 @@
+/**
+ * CSS 静态资源解析插件
+ * 用于在 iframe 环境下动态替换 CSS 中的静态资源 URL
+ */
+import type { Plugin } from 'vite';
+
+export function cssAssetResolverPlugin(): Plugin {
+ return {
+ name: 'css-asset-resolver',
+ generateBundle(options, bundle) {
+ // 在生产构建时处理 CSS 文件
+ Object.keys(bundle).forEach(fileName => {
+ const chunk = bundle[fileName];
+ if (chunk.type === 'asset' && fileName.endsWith('.css')) {
+ let cssContent = chunk.source as string;
+
+ // 替换 CSS 中的静态资源路径
+ cssContent = cssContent.replace(
+ /url\(['"]?\/src\/assets\/(.*?)['"]?\)/g,
+ "url('#{INTEGRATION_ORIGIN}#{BASE_URL}assets/$1')"
+ );
+
+ cssContent = cssContent.replace(
+ /url\(['"]?@\/assets\/(.*?)['"]?\)/g,
+ "url('#{INTEGRATION_ORIGIN}#{BASE_URL}assets/$1')"
+ );
+
+ chunk.source = cssContent;
+ }
+ });
+ },
+ transformIndexHtml: {
+ enforce: 'post',
+ transform(html) {
+ // 在 HTML 中注入动态替换脚本
+ const script = `
+`;
+
+ return html.replace('', script + '');
+ }
+ }
+ };
+}
diff --git a/src/plugins/index.ts b/src/plugins/index.ts
index 9aafdebe8a6c5cccbd45e22b485e61d0b33c861c..65b9ab1ed55677adcc10c05a4a051fc688f2dfcb 100644
--- a/src/plugins/index.ts
+++ b/src/plugins/index.ts
@@ -3,6 +3,7 @@ import { setupRouter } from '@/router';
import { setupStore } from '@/store';
import type { App } from 'vue';
import { setupElIcons } from './icons';
+import assetResolver from './assetResolver';
export default {
install(app: App
) {
@@ -14,5 +15,7 @@ export default {
setupElIcons(app);
// 状态管理(store)
setupStore(app);
+ // 静态资源解析器
+ app.use(assetResolver);
},
};
diff --git a/src/styles/app.scss b/src/styles/app.scss
index 4f3f02b6a5839efafacccd7b0af950097a1a2a3c..61260a411d7c06274a85327ccd58622702ec9807 100644
--- a/src/styles/app.scss
+++ b/src/styles/app.scss
@@ -14,7 +14,7 @@ body,
width: 100%;
min-width: 600px;
overflow-y: auto;
- background: url('/src/assets/images/login-background-light.webp') center/100% 100%;
+ background: var(--login-bg-light, url('/src/assets/images/login-background-light.webp')) center/100% 100%;
}
.main-container {
@@ -28,5 +28,5 @@ body,
}
html.dark .euler-copilot-container {
- background: url('@/assets/images/login-background-dark.jpg') no-repeat center right;
+ background: var(--login-bg-dark, url('@/assets/images/login-background-dark.jpg')) no-repeat center right;
}
diff --git a/src/styles/dataSet.scss b/src/styles/dataSet.scss
index 82bc77e70945a737a9bd088d815051f31c016c7e..86db879596073879adcf5e8f58bbc5236b88f269 100644
--- a/src/styles/dataSet.scss
+++ b/src/styles/dataSet.scss
@@ -138,7 +138,7 @@
background-repeat: no-repeat !important;
background-size: 100% !important;
display: inline-block;
- background: url('/src/assets/icons/taskLoading.png');
+ background: var(--task-loading, url('/src/assets/icons/taskLoading.png'));
}
.icon-box {
@@ -333,7 +333,7 @@
background-repeat: no-repeat !important;
background-size: 100% !important;
display: inline-block;
- background: url('/src/assets/icons/taskLoading.png');
+ background: var(--task-loading, url('/src/assets/icons/taskLoading.png'));
}
.icon-box {
diff --git a/src/styles/grouInfo.scss b/src/styles/grouInfo.scss
index ef9951de0a4b0d2b5393d225be34f5f821be765a..e8a7104ded71e23b76f706ac6c5661f60b372c6b 100644
--- a/src/styles/grouInfo.scss
+++ b/src/styles/grouInfo.scss
@@ -85,7 +85,6 @@
}
.group-info-content{
width: 100%;
- height: calc(100vh - 88px);
border-radius: 8px;
background-color: var(--o-bg-color-base);
margin-top: 24px;
diff --git a/src/styles/group.scss b/src/styles/group.scss
index cf2eb4cda137050878f2513fe7182698e6127812..b5bf4424e0db1129c477ac504318bcd67df297f5 100644
--- a/src/styles/group.scss
+++ b/src/styles/group.scss
@@ -24,7 +24,7 @@
justify-content: space-between;
.group-btn {
border-radius: 4px !important;
- width: 96px;
+ min-width: 96px;
background-color: rgb(99, 149, 253);
}
.group-right-btn {
@@ -101,8 +101,6 @@
}
.group-tabs-content {
margin-top: 16px;
- display: flex;
- justify-content: space-between;
display: grid;
grid-template-columns: repeat(auto-fill, 339px);
gap: 16px;
diff --git a/src/styles/knowledgeFile.scss b/src/styles/knowledgeFile.scss
index 044d1187a661a9687426def08c0597a1ee7bf044..e2a7f1a0a632bb57e525910aaabf5f9c75fef300 100644
--- a/src/styles/knowledgeFile.scss
+++ b/src/styles/knowledgeFile.scss
@@ -256,7 +256,7 @@
background-repeat: no-repeat !important;
background-size: 100% !important;
display: inline-block;
- background: url('/src/assets/icons/taskLoading.png');
+ background: var(--task-loading, url('/src/assets/icons/taskLoading.png'));
}
.icon-box {
diff --git a/src/styles/knowledgeForm.scss b/src/styles/knowledgeForm.scss
index e7d50e784847e2557cc32553d1baf627db65b68b..e9a2b495f3cdb116621793f0c934b7111dd97aa9 100644
--- a/src/styles/knowledgeForm.scss
+++ b/src/styles/knowledgeForm.scss
@@ -18,7 +18,7 @@
}
.deleteConfig:hover {
- color: rgb(99, 149, 253);
+ color: var(--o-color-primary);
}
}
}
@@ -36,8 +36,8 @@
}
.el-form-item {
- gap: 24px;
- margin-bottom: 24px;
+ gap: 20px;
+ margin-bottom: 20px !important; // 统一间距
display: flex;
align-items: center;
@@ -65,7 +65,7 @@
.icon-help{
margin-left: 4px;
margin-top: 0px !important;
- color: #8d98aa;
+ color: var(--o-text-color-secondary);
}
}
@@ -76,7 +76,7 @@
.el-input-number__decrease {
background: transparent;
.el-icon {
- color: #8d98aa;
+ color: var(--o-text-color-secondary);
}
}
.el-input__wrapper {
@@ -98,12 +98,13 @@
}
.el-form-item__content {
- flex: unset !important;
+ max-width: 450px; // 防止内容超出边界
.el-input,
.el-select__wrapper,
.el-textarea__inner {
width: 352px !important;
+ max-width: 352px; // 确保不会超出
font-size: 12px;
}
@@ -136,6 +137,8 @@
padding: 0 !important;
font-size: 12px !important;
color: var(--o-text-color-secondary) !important;
+ min-width: 140px; // 确保label有足够宽度,避免换行
+ white-space: nowrap; // 防止文字换行
.el-icon {
margin-top: 2px;
@@ -144,7 +147,7 @@
}
.el-icon:hover {
- color: rgb(82 163 255);
+ color: var(--o-color-primary);
}
}
@@ -198,47 +201,148 @@
margin-left: 8px;
font-size: 12px;
line-height: 22px;
- color: rgb(141 152 170);
+ color: var(--o-text-color-secondary);
}
}
.kl-ruleForm{
.el-form-item__label{
- max-width: 128px;
+ min-width: 140px; // 确保label宽度一致
+ max-width: 140px;
}
.config-form{
margin-bottom: 8px !important;
}
- & :nth-last-child(2) {
- margin-bottom: 0 !important;
+
+ // 确保选择器不超出对话框边界
+ .el-form-item__content {
+ .el-input,
+ .el-select__wrapper {
+ width: 320px !important; // 在对话框中使用更小的宽度
+ max-width: 320px !important;
+ }
}
}
.analyticMethodSelect {
box-sizing: border-box;
- .el-select-dropdown {
- // width: 100% !important;
- // max-width: unset !important;
- }
.el-select-dropdown__item.is-hovering {
color: #fff;
}
}
-.create-dialog {
- height: 600px;
- position: relative;
- padding: 0 !important;
- overflow: hidden;
+// 自适应高度对话框 - 重写CSS变量
+.adaptive-height-dialog {
+ // 覆盖所有可能的CSS变量
+ --el-dialog-height: auto !important;
+ --el-dialog-max-height: 90vh !important;
+ --o-dialog-body-max-height: none !important;
+ --el-dialog-body-max-height: none !important;
+ --o-dialog-max-height: 90vh !important;
+
+ // 强制覆盖Element Plus的内联样式和计算样式
+ .el-dialog__body {
+ max-height: none !important;
+ height: auto !important;
+ overflow: visible !important;
+ }
+}
+.el-overlay .adaptive-height-dialog,
+.adaptive-height-dialog.el-dialog,
+div.adaptive-height-dialog {
+ height: auto !important; // 强制覆盖固定高度
+ max-height: 90vh !important; // 最大高度为视口的90%
+ min-height: auto !important; // 自适应最小高度
+
.el-dialog__body {
- height: 464px !important;
- max-height: unset !important;
- min-height: unset !important;
- padding-left: 16px !important;
+ height: auto !important; // 强制覆盖固定高度
+ max-height: none !important; // 移除最大高度限制,让内容完全展开
+ min-height: auto !important;
+ padding: 16px 20px 20px 16px !important; // 增加底部padding
margin-right: 0 !important;
- padding-bottom: 0;
+ overflow: visible !important; // 让内容完全可见
+
+ // 在body层面也覆盖CSS变量
+ --o-dialog-body-max-height: none !important;
+ --el-dialog-body-max-height: none !important;
+ }
+
+ .el-dialog__header {
+ padding-bottom: 16px !important;
+ }
+}
+
+// 更强的覆盖,针对Element Plus的内部类
+.el-dialog.adaptive-height-dialog,
+.el-dialog__wrapper .adaptive-height-dialog {
+ height: auto !important;
+ max-height: 90vh !important;
+
+ .el-dialog__body {
+ max-height: none !important;
+ overflow: visible !important;
+ height: auto !important;
+ }
+}
+
+// 最强选择器 - 直接覆盖Element Plus的计算样式
+.el-overlay-dialog .adaptive-height-dialog .el-dialog__body,
+.adaptive-height-dialog .el-dialog__body,
+div[class*="adaptive-height-dialog"] .el-dialog__body {
+ max-height: none !important;
+ overflow: visible !important;
+ height: auto !important;
+
+ // 重置所有相关CSS变量
+ --o-dialog-body-max-height: none !important;
+ --el-dialog-body-max-height: none !important;
+}
+
+// 保留原有的create-dialog样式作为备用
+.create-dialog {
+ position: relative;
+ padding: 0 !important;
+
+ // 在对话框中特别处理表单布局
+ .knowledge-form-container {
+ width: 100%;
+ max-width: 100%;
+ overflow: hidden;
+
+ .kl-ruleForm {
+ .el-form-item {
+ gap: 16px; // 减少gap避免超出
+
+ .el-form-item__label {
+ min-width: 120px; // 在对话框中使用更小的label宽度
+ max-width: 120px;
+ flex-shrink: 0;
+ }
+
+ .el-form-item__content {
+ flex: 1;
+ .el-input,
+ .el-select__wrapper,
+ .el-textarea__inner {
+ width: 100% !important;
+ max-width: 300px !important; // 确保不超出对话框
+ }
+ }
+ }
+ }
+
+ // 特殊处理分块设置和向量化设置中的长标签
+ .chunk-settings,
+ .vectorization-settings {
+ .el-form-item {
+ .el-form-item__label {
+ min-width: 140px !important; // 为长标签提供更多空间
+ max-width: 140px !important;
+ }
+ }
+ }
}
.analyticMethod {
@@ -260,7 +364,7 @@
.el-input-number__decrease {
background: transparent;
.el-icon {
- color: #8d98aa;
+ color: var(--o-text-color-secondary);
}
}
@@ -269,22 +373,24 @@
}
.kl-ops-btn {
- height: 24px !important;
- margin-top: 32px;
+ height: auto !important;
+ margin-top: 24px;
margin-bottom: 0;
+ padding-top: 16px; // 增加顶部间距
+ border-top: 1px solid var(--o-border-color-light); // 添加分隔线
.el-form-item__content {
display: flex;
justify-content: center;
width: 100% !important;
- height: 24px !important;
min-height: unset !important;
margin-left: 0 !important;
- line-height: 24px !important;
+ gap: 12px; // 按钮间距
}
.resetBtn {
- height: 24px !important;
+ height: 32px !important; // 增加按钮高度使其更易点击
+ padding: 0 20px;
}
}
@@ -307,6 +413,15 @@
font-size: 12px;
}
+ .tip-message {
+ margin: 0 0 24px 0;
+ padding: 0;
+ font-size: 14px;
+ line-height: 1.5;
+ color: var(--o-text-color-primary);
+ font-weight: 400;
+ }
+
.tip-ops-btn {
display: flex;
justify-content: center;
@@ -325,9 +440,8 @@
}
.kl-create-ops-btn {
- position: absolute;
- bottom: 24px;
- left: 190px;
+ // 移除绝对定位,使用正常文档流
+ position: static;
}
.assetIdClass {
@@ -346,7 +460,7 @@
transform: rotateZ(180deg);
}
.copydocument:hover {
- color: rgb(99, 149, 253);
+ color: var(--o-color-primary);
}
}
@@ -365,3 +479,145 @@
min-width: unset !important;
padding: 8px !important;
}
+
+// Section导航样式
+.knowledge-form-container {
+ .section-navigation {
+ display: flex;
+ margin-bottom: 20px;
+ border-bottom: 1px solid var(--o-border-color-light);
+ background: var(--o-bg-color-light);
+ border-radius: 6px 6px 0 0;
+
+ .section-tab {
+ position: relative;
+ padding: 12px 16px;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ border-radius: 6px 6px 0 0;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+
+ .section-title {
+ font-size: 12px;
+ color: var(--o-text-color-secondary);
+ font-weight: 400;
+ }
+
+ .check-icon {
+ font-size: 14px;
+ color: var(--o-color-success);
+ }
+
+ &:hover {
+ background: var(--o-bg-color-base);
+
+ .section-title {
+ color: var(--o-text-color-primary);
+ }
+ }
+
+ &.active {
+ background: var(--o-bg-color-base);
+ border-bottom: 2px solid var(--o-color-primary);
+
+ .section-title {
+ color: var(--o-color-primary);
+ font-weight: 500;
+ }
+ }
+
+ &.completed:not(.active) {
+ .section-title {
+ color: var(--o-color-success);
+ }
+ }
+ }
+ }
+
+ .form-section {
+ min-height: 180px;
+ padding: 16px 0;
+
+ .el-form-item {
+ margin-bottom: 20px !important; // 统一间距
+ }
+ }
+
+ .chunk-settings,
+ .vectorization-settings {
+ margin-top: 20px;
+ padding: 16px;
+ background: var(--o-bg-color-light);
+ border-radius: 6px;
+ border: 1px solid var(--o-border-color-light);
+
+ .chunk-header,
+ .vectorization-header {
+ font-size: 13px;
+ font-weight: 500;
+ color: var(--o-text-color-primary);
+ margin-bottom: 16px;
+ padding-bottom: 8px;
+ border-bottom: 1px solid var(--o-border-color-light);
+ }
+
+ .el-form-item {
+ margin-bottom: 16px !important; // 内部统一间距
+
+ &:last-child {
+ margin-bottom: 0 !important;
+ }
+ }
+ }
+
+ .slider-input-group {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ width: 100%; // 使用100%宽度
+ max-width: 300px; // 限制最大宽度
+
+ .top-k-slider {
+ flex: 1;
+ min-width: 0; // 允许slider收缩
+ margin-right: 0;
+ max-width: 220px; // 限制slider最大宽度
+ }
+
+ .top-k-input {
+ width: 60px;
+ flex-shrink: 0; // 防止数字输入框被压缩
+
+ .el-input-number__increase,
+ .el-input-number__decrease {
+ width: 20px;
+ }
+ }
+ }
+
+ .form-right-tip {
+ margin-left: 8px;
+ font-size: 12px;
+ color: var(--o-text-color-secondary);
+ }
+
+ // 特殊处理较长的label
+ .el-form-item {
+ &:has([label*="单次文档上传个数上限"]) {
+ .el-form-item__label {
+ min-width: 160px;
+ max-width: 160px;
+ line-height: 1.2;
+ }
+ }
+
+ &:has([label*="文件分块大小"]) {
+ .el-form-item__label {
+ min-width: 120px;
+ max-width: 120px;
+ }
+ }
+ }
+}
diff --git a/src/styles/knowledgeLibrary.scss b/src/styles/knowledgeLibrary.scss
index 66374ccde47bddecfb981d10583a46dd15f15574..3557794085842d07a2479f9f5837f6124c85e214 100644
--- a/src/styles/knowledgeLibrary.scss
+++ b/src/styles/knowledgeLibrary.scss
@@ -200,14 +200,14 @@
cursor: pointer;
width: 24px;
height: 24px;
- background-image: url(@/assets/svg/more.svg);
+ background-image: var(--more-icon, url(@/assets/svg/more.svg));
background-repeat: no-repeat;
background-size: 100% 100%;
&:hover {
- background-image: url(@/assets/svg/more_hover.svg);
+ background-image: var(--more-hover-icon, url(@/assets/svg/more_hover.svg));
}
&:active,&:focus {
- background-image: url(@/assets/svg/more_active.svg);
+ background-image: var(--more-active-icon, url(@/assets/svg/more_active.svg));
}
}
}
@@ -539,7 +539,7 @@
background-repeat: no-repeat !important;
background-size: 100% !important;
display: inline-block;
- background: url('/src/assets/icons/taskLoading.png');
+ background: var(--task-loading, url('/src/assets/icons/taskLoading.png'));
}
.icon-box {
@@ -653,6 +653,15 @@
color: var(--o-text-color-secondary);
}
+ .tip-message {
+ margin: 0 0 24px 0;
+ padding: 0;
+ font-size: 14px;
+ line-height: 1.5;
+ color: #606266;
+ font-weight: 400;
+ }
+
.iconAlarmOrange {
svg {
width: 28px;
diff --git a/src/styles/reset.scss b/src/styles/reset.scss
index d3a88dbefca9db23ed5876ea264a8c87d225088a..839b47c2d40d239122dffcfad19d45cac8a9306c 100644
--- a/src/styles/reset.scss
+++ b/src/styles/reset.scss
@@ -1,8 +1,8 @@
@font-face {
font-family: 'HarmonyOS Sans SC Regular';
src:
- url(./HarmonyOS_Sans_SC/HarmonyOS_Sans_SC_Regular.woff2) format('woff2'),
- url(./HarmonyOS_Sans_SC/HarmonyOS_Sans_SC_Regular.woff) format('woff');
+ var(--font-harmony-woff2, url(./HarmonyOS_Sans_SC/HarmonyOS_Sans_SC_Regular.woff2)) format('woff2'),
+ var(--font-harmony-woff, url(./HarmonyOS_Sans_SC/HarmonyOS_Sans_SC_Regular.woff)) format('woff');
font-weight: 400;
font-style: normal;
}
@@ -285,7 +285,6 @@ div:focus {
.el-dialog{
border-radius: 8px !important;
background-color: var(--o-bg-dialog) !important;
- width: 544px !important;
}
.el-dialog__header {
.el-dialog__title {
@@ -1002,7 +1001,6 @@ div:focus {
border-radius: 4px !important;
// border: 1px solid var(--o-input-border-color) !important;
// box-shadow: 0 0 0 0 !important;
- padding: 8px 16px !important;
background-color: var(--o-bg-color-base) !important;
}
.el-select__wrapper.is-focused{
diff --git a/src/styles/theme.scss b/src/styles/theme.scss
index b1343d89d8d2ee48a88eeca67876699d7351ae18..947a1ac28bf87453b692c0be1c012a61a1de6320 100644
--- a/src/styles/theme.scss
+++ b/src/styles/theme.scss
@@ -1,6 +1,6 @@
body[theme='dark'] {
- --o-main-bg: url('/src/assets/images/dark_bg_1.webp');
+ --o-main-bg: var(--bg-dark, url('/src/assets/images/dark_bg_1.webp'));
--o-bg-dialog:var(--o-bg-color-base);
--o-button-bg:rgb(99 149 253);
--o-tag-text-color:rgb(99 149 253);
@@ -15,16 +15,16 @@ body[theme='dark'] {
--o-tag-code-bg:rgb(168 67 205 0.3);
--o-tag-qa-color:rgb(235 175 0);
--o-tag-qa-bg:rgb(66 53 0);
- --o-empty-img-pending: url('/src/assets/images/empty_pending_dark.svg');
- --o-empty-img-failed: url('/src/assets/images/empty_failed_dark.svg');
- --o-empty-img-running: url('/src/assets/images/empty_running_dark.svg');
- --o-task-list-icon: url('/src/assets/svg/dark_taskList.svg');
- --o-task-score-icon: url('/src/assets/svg/dark_taskScore.svg');
+ --o-empty-img-pending: var(--empty-pending-dark, url('/src/assets/images/empty_pending_dark.svg'));
+ --o-empty-img-failed: var(--empty-failed-dark, url('/src/assets/images/empty_failed_dark.svg'));
+ --o-empty-img-running: var(--empty-running-dark, url('/src/assets/images/empty_running_dark.svg'));
+ --o-task-list-icon: var(--task-list-dark, url('/src/assets/svg/dark_taskList.svg'));
+ --o-task-score-icon: var(--task-score-dark, url('/src/assets/svg/dark_taskScore.svg'));
--o-task-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.3);
}
body[theme='light'] {
- --o-main-bg: url('/src/assets/images/light_bg_1.webp');
+ --o-main-bg: var(--bg-light, url('/src/assets/images/light_bg_1.webp'));
--o-bg-dialog:var(--o-bg-color-base);
--o-button-bg:rgb(99 149 253);
--o-tag-text-color:rgb(99 149 253);
@@ -39,10 +39,10 @@ body[theme='light'] {
--o-tag-code-bg:rgb(189 69 232 0.3);
--o-tag-qa-color:rgb(235 175 0);
--o-tag-qa-bg:rgb(249 235 184);
- --o-empty-img-pending: url('/src/assets/images/empty_pending.svg');
- --o-empty-img-failed: url('/src/assets/images/empty_failed.svg');
- --o-empty-img-running: url('/src/assets/images/empty_running.svg');
- --o-task-list-icon: url('/src/assets/svg/light_taskList.svg');
- --o-task-score-icon: url('/src/assets/svg/light_taskScore.svg');
+ --o-empty-img-pending: var(--empty-pending-light, url('/src/assets/images/empty_pending.svg'));
+ --o-empty-img-failed: var(--empty-failed-light, url('/src/assets/images/empty_failed.svg'));
+ --o-empty-img-running: var(--empty-running-light, url('/src/assets/images/empty_running.svg'));
+ --o-task-list-icon: var(--task-list-light, url('/src/assets/svg/light_taskList.svg'));
+ --o-task-score-icon: var(--task-score-light, url('/src/assets/svg/light_taskScore.svg'));
--o-task-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.3);
}
\ No newline at end of file
diff --git a/src/styles/upload.scss b/src/styles/upload.scss
index 5e5e36a1e644046f6322ce5adaa81bc5fb63420e..17a11a44e3dab9bc7ba171a878792b27926094da 100644
--- a/src/styles/upload.scss
+++ b/src/styles/upload.scss
@@ -14,7 +14,7 @@
}
}
.el-alert--info .el-alert__icon{
- background-image: url('@/assets/svg/icon_info.svg');
+ background-image: var(--info-icon, url('@/assets/svg/icon_info.svg'));
width: 22.3px;
height: 14px;
}
diff --git a/src/types/env.d.ts b/src/types/env.d.ts
index 24247c486b94c8039bf29cc7ee511318160e78ed..8c248f32a59a07a7712047e8130f9c622560afac 100644
--- a/src/types/env.d.ts
+++ b/src/types/env.d.ts
@@ -17,6 +17,10 @@ interface ImportMetaEnv {
VITE_APP_API_URL: string;
/** 是否开启 Mock 服务 */
VITE_MOCK_DEV_SERVER: boolean;
+ /** 集成来源域名 - 用于解决 iframe 跨域静态资源访问问题 */
+ VITE_INTEGRATION_ORIGIN?: string;
+ /** 是否在 iframe 环境中运行 */
+ VITE_IS_IFRAME_MODE?: boolean;
}
interface ImportMeta {
diff --git a/src/utils/cssAssetResolver.ts b/src/utils/cssAssetResolver.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5d37d43eaffc2d7878e2af02a981bc01e6b03d7d
--- /dev/null
+++ b/src/utils/cssAssetResolver.ts
@@ -0,0 +1,72 @@
+/**
+ * CSS 静态资源动态解析工具
+ * 在运行时动态替换 CSS 变量中的静态资源路径
+ */
+import { isInIframe, getIntegrationOrigin } from './index';
+
+/**
+ * 初始化 CSS 静态资源解析
+ * 在应用启动时调用,动态设置 CSS 变量
+ */
+export function initCssAssetResolver() {
+ // 检测是否需要处理静态资源
+ const isIframeMode = String(import.meta.env.VITE_IS_IFRAME_MODE) === 'true' || isInIframe();
+
+ if (!isIframeMode) {
+ return;
+ }
+
+ const integrationOrigin = getIntegrationOrigin();
+ const basePath = import.meta.env.BASE_URL || '/witchaind/';
+
+ // 构建静态资源基础路径
+ const assetBaseUrl = `${integrationOrigin}${basePath.replace(/\/$/, '')}/assets`;
+
+ // 设置 CSS 变量
+ const root = document.documentElement;
+
+ // 设置图片资源路径
+ root.style.setProperty('--asset-base-url', assetBaseUrl);
+ root.style.setProperty('--asset-images-url', `${assetBaseUrl}/images`);
+ root.style.setProperty('--asset-svg-url', `${assetBaseUrl}/svg`);
+ root.style.setProperty('--asset-icons-url', `${assetBaseUrl}/icons`);
+
+ // 设置具体的静态资源路径
+ root.style.setProperty('--bg-light', `url('${assetBaseUrl}/images/light_bg_1.webp')`);
+ root.style.setProperty('--bg-dark', `url('${assetBaseUrl}/images/dark_bg_1.webp')`);
+
+ // 空状态图标
+ root.style.setProperty('--empty-pending-light', `url('${assetBaseUrl}/images/empty_pending.svg')`);
+ root.style.setProperty('--empty-pending-dark', `url('${assetBaseUrl}/images/empty_pending_dark.svg')`);
+ root.style.setProperty('--empty-failed-light', `url('${assetBaseUrl}/images/empty_failed.svg')`);
+ root.style.setProperty('--empty-failed-dark', `url('${assetBaseUrl}/images/empty_failed_dark.svg')`);
+ root.style.setProperty('--empty-running-light', `url('${assetBaseUrl}/images/empty_running.svg')`);
+ root.style.setProperty('--empty-running-dark', `url('${assetBaseUrl}/images/empty_running_dark.svg')`);
+
+ // 任务图标
+ root.style.setProperty('--task-list-light', `url('${assetBaseUrl}/svg/light_taskList.svg')`);
+ root.style.setProperty('--task-list-dark', `url('${assetBaseUrl}/svg/dark_taskList.svg')`);
+ root.style.setProperty('--task-score-light', `url('${assetBaseUrl}/svg/light_taskScore.svg')`);
+ root.style.setProperty('--task-score-dark', `url('${assetBaseUrl}/svg/dark_taskScore.svg')`);
+
+ // 加载图标
+ root.style.setProperty('--task-loading', `url('${assetBaseUrl}/icons/taskLoading.png')`);
+
+ // 更多操作图标
+ root.style.setProperty('--more-icon', `url('${assetBaseUrl}/svg/more.svg')`);
+ root.style.setProperty('--more-hover-icon', `url('${assetBaseUrl}/svg/more_hover.svg')`);
+ root.style.setProperty('--more-active-icon', `url('${assetBaseUrl}/svg/more_active.svg')`);
+
+ // 登录背景
+ root.style.setProperty('--login-bg-light', `url('${assetBaseUrl}/images/login-background-light.webp')`);
+ root.style.setProperty('--login-bg-dark', `url('${assetBaseUrl}/images/login-background-dark.jpg')`);
+
+ // 信息图标
+ root.style.setProperty('--info-icon', `url('${assetBaseUrl}/svg/icon_info.svg')`);
+
+ // 字体文件
+ root.style.setProperty('--font-harmony-woff2', `url('${assetBaseUrl}/fonts/HarmonyOS/HarmonyOS_Sans_SC/HarmonyOS_Sans_SC_Regular.woff2')`);
+ root.style.setProperty('--font-harmony-woff', `url('${assetBaseUrl}/fonts/HarmonyOS/HarmonyOS_Sans_SC/HarmonyOS_Sans_SC_Regular.woff')`);
+
+ console.log('CSS 静态资源路径已动态设置:', assetBaseUrl);
+}
diff --git a/src/utils/index.ts b/src/utils/index.ts
index 26e138674f723faf71f4dba659e47da2dcf962c9..3933e5a7f7ec9273d7496f7d85c5da88ec5f09a5 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -39,3 +39,71 @@ export function isExternal(path: string) {
const isExternal = /^(https?:|http?:|mailto:|tel:)/.test(path);
return isExternal;
}
+
+/**
+ * 检测是否在 iframe 环境中运行
+ * @returns {boolean}
+ */
+export function isInIframe(): boolean {
+ try {
+ return window.self !== window.top;
+ } catch (e) {
+ return true;
+ }
+}
+
+/**
+ * 获取集成来源的 origin
+ * @returns {string}
+ */
+export function getIntegrationOrigin(): string {
+ // 优先使用环境变量配置
+ const configuredOrigin = import.meta.env.VITE_INTEGRATION_ORIGIN;
+ if (configuredOrigin) {
+ return configuredOrigin;
+ }
+
+ // 如果在 iframe 中,尝试从 parent 获取
+ if (isInIframe()) {
+ try {
+ return window.parent.location.origin;
+ } catch (e) {
+ // 跨域时无法访问 parent.location,使用 referrer
+ if (document.referrer) {
+ const url = new URL(document.referrer);
+ return url.origin;
+ }
+ }
+ }
+
+ // 默认返回当前 origin
+ return window.location.origin;
+}
+
+/**
+ * 处理静态资源 URL,解决 iframe 跨域问题
+ * @param {string} assetPath - 静态资源路径
+ * @returns {string} - 处理后的完整 URL
+ */
+export function resolveAssetUrl(assetPath: string): string {
+ // 如果已经是完整 URL,直接返回
+ if (isExternal(assetPath)) {
+ return assetPath;
+ }
+
+ // 如果不在 iframe 环境中,使用默认处理
+ const isIframeMode = import.meta.env.VITE_IS_IFRAME_MODE === 'true' || isInIframe();
+ if (!isIframeMode) {
+ return assetPath;
+ }
+
+ // 在 iframe 环境中,使用集成来源的 origin
+ const integrationOrigin = getIntegrationOrigin();
+ const basePath = import.meta.env.BASE_URL || '/witchaind/';
+
+ // 确保路径以 / 开头
+ const normalizedPath = assetPath.startsWith('/') ? assetPath : `/${assetPath}`;
+
+ // 构建完整 URL
+ return `${integrationOrigin}${basePath.replace(/\/$/, '')}${normalizedPath}`;
+}
diff --git a/src/views/dataSet/craeteEvaluate.vue b/src/views/dataSet/craeteEvaluate.vue
index 15217ef643a8b0c3c7f485b856aeef17131e311e..ef8163e738a2469e341deb1112720b6bf70e2f65 100644
--- a/src/views/dataSet/craeteEvaluate.vue
+++ b/src/views/dataSet/craeteEvaluate.vue
@@ -19,7 +19,7 @@
-
+
@@ -81,9 +81,11 @@ import "@/styles/evaluate.scss"
import KbAppAPI from '@/api/kbApp';
import dataSetAPI from '@/api/dataSet';
import EvaluateAPI from '@/api/evaluate';
+import { useAssets } from '@/composables/useAssets';
import { useGroupStore } from '@/store/modules/group';
import { IconCaretDown } from '@computing/opendesign-icons';
const { t, } = useI18n();
+const { getSvgUrl } = useAssets();
const store = useGroupStore();
const { handleKnowledgeTab } = store;
const currentLlmOption = computed(() =>
diff --git a/src/views/dataSet/index.vue b/src/views/dataSet/index.vue
index 6cb85212313eb2b14dec510825982949992cea92..10b6b596c160b779ba7c090a300906e1f429ab7f 100644
--- a/src/views/dataSet/index.vue
+++ b/src/views/dataSet/index.vue
@@ -71,12 +71,12 @@
-
+
-
+
{{ $t('exportTask.exportSuccess') }}
@@ -531,8 +531,10 @@ import DataSetDrawer from './dataSetDrawer.vue';
import CreateEvaluate from '@/views/dataSet/craeteEvaluate.vue';
import dataSetAPI from '@/api/dataSet';
import CustomLoading from '@/components/CustomLoading/index.vue';
+import { useAssets } from '@/composables/useAssets';
const route = useRoute();
const { t } = useI18n();
+const { getSvgUrl } = useAssets();
import { ref } from 'vue';
import '@/styles/dataSet.scss';
diff --git a/src/views/group/index.vue b/src/views/group/index.vue
index 2071fb5eb2b03afeb55a9e41989c947c437fa85c..9d6b9b5c3e46b7d2ce5e5baf93de39c2638b1fa5 100644
--- a/src/views/group/index.vue
+++ b/src/views/group/index.vue
@@ -63,7 +63,7 @@
@{{ item.authorName }}
-
+
{{ item.memberCount }}{{ $t('group.people') }}
@@ -106,7 +106,7 @@
{{ $t('group.private') }}
-
+
{{ convertUTCToLocalTime(scope.row.createdTime)}}
@@ -143,14 +143,19 @@ import {
IconSearch,
IconThumbnail,
} from '@computing/opendesign-icons';
-import { ref } from 'vue';
+import { ref, onMounted, watch } from 'vue';
import { debounce } from 'lodash';
+import { useAssets } from '@/composables/useAssets';
import router from '@/router/index';
import { useGroupStore } from '@/store/modules/group.js';
+import { storeToRefs } from 'pinia';
+import { useI18n } from 'vue-i18n';
import CreateGroup from './createGroup.vue';
import GroupAPI from '@/api/group';
import { TabPaneName } from 'element-plus';
import { convertUTCToLocalTime } from '@/utils/convertUTCToLocalTime';
+
+const { getImageUrl } = useAssets();
const { t, locale} = useI18n();
const groupStore = useGroupStore();
diff --git a/src/views/groupDetail/index.vue b/src/views/groupDetail/index.vue
index 14738ee6221d13f55d5e2941d460fae9709dae86..d3a722c74876833650436c0ba0daba5198a4847c 100644
--- a/src/views/groupDetail/index.vue
+++ b/src/views/groupDetail/index.vue
@@ -3,6 +3,330 @@
{{ groupName }}
+
+
+
+
+
+
+
+
+
+
+ handleSelectAllMembers(!!val)"
+ />
+
+
+ handleMemberRowSelection(row, !!val)"
+ />
+
+
+
+
+
+ {{ row.userId }}
+
+
+
+
+
+
+
+ {{ getUserAvatarContent(row.userName, row.avatar) }}
+
+ {{ row.userName }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ row.roleName }}
+
+
+
+
+
+
+
+
+ {{ $t('btnText.save') }}
+
+
+ {{ $t('btnText.cancel') }}
+
+
+
+
+
+ {{ $t('groupDetail.editMember') }}
+
+
+ {{ $t('groupDetail.deleteMember') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ handleSelectAll(!!val)"
+ />
+
+
+ handleRowSelection(row, !!val)"
+ />
+
+
+
+
+
+
+
+
+
+
+ {{ row.roleName }}
+
+
+
+
+
+
+
+ handleGroupPermissionChange(row.roleNameId, row.actionType, !!val)"
+ class="permission-group-checkbox"
+ :class="{ 'disabled-checkbox': !getGroupEditable(row.roleNameId, row.actionType) }"
+ >
+ {{ row.actionType }}
+
+ handleItemPermissionChange(row.roleNameId, row.actionType, action.action, !!val)"
+ class="permission-item-checkbox"
+ :class="{ 'disabled-checkbox': !action.editable }"
+ >
+ {{ getActionDisplayName(action) }}
+
+
+
+
+
+
+
+ {{ row.created_time }}
+
+
+
+
+
+
+
+ {{ $t('groupDetail.editRole') }}
+
+
+ {{ $t('groupDetail.deleteRole') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ getUserAvatarContent(activity.user_sub, activity.avatar) }}
+
+
+
+
{{ activity.user_sub }}{{ activity.action }}
+
{{ activity.datetime }}
+
+
+
+
+
+
+
+
+
+ 加载中...
+
+
+
+
+ 没有更多数据了
+
+
+
+
@@ -18,6 +342,12 @@
{{ form.memberCount }}{{ $t('group.people') }}
+
+
+ {{ $t('groupDetail.transfer') }}
+ {{ $t('groupDetail.transferTip') }}
+
+
{{ $t('groupDetail.dissolve') }}
@@ -30,23 +360,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 确定要将成员 {{ pendingMemberChange?.userName }} 的角色从
+ {{ pendingMemberChange?.oldRoleName }} 修改为
+ {{ pendingMemberChange?.newRoleName }} 吗?
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
+
+
+
+
+
\ No newline at end of file
diff --git a/vite.config.ts b/vite.config.ts
index 971a0bae05670f3d85b201c60c4ccd8661cc656a..0dcd8e519e213c90e81c5f1f029e4e59d8fce2c8 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -25,8 +25,15 @@ const __APP_INFO__ = {
const pathSrc = path.resolve(__dirname, './src');
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
const env = loadEnv(mode, process.cwd());
+
+ // 根据环境和集成模式动态设置 base URL
+ let baseUrl = '/witchaind/';
+ if (mode === 'development') {
+ baseUrl = env.VITE_IS_IFRAME_MODE === 'true' ? '/witchaind/' : '/';
+ }
+
return {
- base: '/witchaind/', // 设置打包路径
+ base: baseUrl, // 动态设置打包路径
resolve: {
alias: {
'@': pathSrc,
@@ -42,14 +49,20 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
additionalData: `
@use "@/styles/variables.scss" as *;
`,
+ // 抑制 Sass 弃用警告
+ silenceDeprecations: ['legacy-js-api', 'global-builtin', 'new-global', 'color-functions'],
+ // 静默第三方依赖的警告
+ quietDeps: true,
+ // 忽略来自 node_modules 的 @import 警告
+ warnRuleAsWarning: false,
},
},
},
server: {
// 允许IP访问
- host: 'localhost',
- port: 3002,
- origin: 'http://localhost:3002',
+ host: env.VITE_HOST,
+ port: Number(env.VITE_PORT),
+ origin: env.VITE_ORIGIN,
// 运行是否自动打开浏览器
headers: {
'Access-control-allow-origin': '*',
@@ -57,11 +70,11 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
open: true,
proxy: {
'/witchaind/api': {
- target: 'https://euler-copilot-master.test.osinfra.cn/witchaind',
+ target: env.VITE_BASE_PROXY_URL,
changeOrigin: true,
ws: false,
secure: false,
- rewrite: (path) => path.replace(/^\/witchaind\/api/, '/api'),
+ rewrite: (path) => path.replace(/^\/witchaind\/api/, ''),
},
},
},