diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index 67459dec40..71975880b0 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -53,7 +53,12 @@
"Skill(openspec:proposal:*)",
"Bash(cmd /c:*)",
"Bash(npx oxlint:*)",
- "Bash(pnpm:*)"
+ "Bash(pnpm:*)",
+ "mcp__server-mysql__list_tables",
+ "mcp__server-mysql__connect_db",
+ "Skill(ui-ux-pro-max)",
+ "Skill(ui-ux-pro-max:*)",
+ "Bash(python:*)"
],
"deny": [],
"ask": []
diff --git a/.claude/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-312.pyc b/.claude/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-312.pyc
new file mode 100644
index 0000000000..39222d1a1a
Binary files /dev/null and b/.claude/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-312.pyc differ
diff --git a/docs/SQL建表语句.sql b/docs/SQL建表语句.sql
new file mode 100644
index 0000000000..ffb84696c4
--- /dev/null
+++ b/docs/SQL建表语句.sql
@@ -0,0 +1,296 @@
+-- Yudao 风格建表语句
+-- 包含多租户概念,使用 TenantBaseDO
+
+-- ===============================================
+-- 1. 积分管理模块
+-- ===============================================
+
+-- 积分兑换配置表
+CREATE TABLE `member_point_exchange_config` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ `exchange_rate` int NOT NULL DEFAULT 1 COMMENT '兑换比例(1元兑换多少积分)',
+ `adjust_reason` varchar(200) NOT NULL DEFAULT '' COMMENT '调整原因',
+ `operator_id` bigint NOT NULL DEFAULT 0 COMMENT '操作人用户编号',
+ `operator_name` varchar(64) NOT NULL DEFAULT '' COMMENT '操作人账号',
+ `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态(0-禁用 1-启用)',
+ `remark` varchar(500) NOT NULL DEFAULT '' COMMENT '备注',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `creator` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者',
+ `updater` varchar(64) NOT NULL DEFAULT '' COMMENT '更新者',
+ `deleted` bit NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ PRIMARY KEY (`id`) USING BTREE,
+ KEY `idx_tenant_id` (`tenant_id`) USING BTREE,
+ KEY `idx_create_time` (`create_time`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='积分兑换配置表';
+
+-- 积分签到配置表
+CREATE TABLE `member_point_signin_config` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ `daily_points` int NOT NULL DEFAULT 0 COMMENT '每日签到赠送积分',
+ `continuous_days` int NOT NULL DEFAULT 0 COMMENT '连续签到天数',
+ `bonus_points` int NOT NULL DEFAULT 0 COMMENT '连续签到奖励积分',
+ `reset_days` int NOT NULL DEFAULT 0 COMMENT '重置签到天数(0表示不重置)',
+ `adjust_reason` varchar(200) NOT NULL DEFAULT '' COMMENT '调整原因',
+ `operator_id` bigint NOT NULL DEFAULT 0 COMMENT '操作人用户编号',
+ `operator_name` varchar(64) NOT NULL DEFAULT '' COMMENT '操作人账号',
+ `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态(0-禁用 1-启用)',
+ `remark` varchar(500) NOT NULL DEFAULT '' COMMENT '备注',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `creator` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者',
+ `updater` varchar(64) NOT NULL DEFAULT '' COMMENT '更新者',
+ `deleted` bit NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ PRIMARY KEY (`id`) USING BTREE,
+ KEY `idx_tenant_id` (`tenant_id`) USING BTREE,
+ KEY `idx_continuous_days` (`continuous_days`) USING BTREE,
+ KEY `idx_create_time` (`create_time`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='积分签到配置表';
+
+-- 积分充值配置表
+CREATE TABLE `member_point_recharge_config` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ `recharge_amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '充值金额',
+ `bonus_points` int NOT NULL DEFAULT 0 COMMENT '赠送积分数',
+ `adjust_reason` varchar(200) NOT NULL DEFAULT '' COMMENT '调整原因',
+ `operator_id` bigint NOT NULL DEFAULT 0 COMMENT '操作人用户编号',
+ `operator_name` varchar(64) NOT NULL DEFAULT '' COMMENT '操作人账号',
+ `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态(0-禁用 1-启用)',
+ `remark` varchar(500) NOT NULL DEFAULT '' COMMENT '备注',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `creator` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者',
+ `updater` varchar(64) NOT NULL DEFAULT '' COMMENT '更新者',
+ `deleted` bit NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ PRIMARY KEY (`id`) USING BTREE,
+ KEY `idx_tenant_id` (`tenant_id`) USING BTREE,
+ KEY `idx_recharge_amount` (`recharge_amount`) USING BTREE,
+ KEY `idx_create_time` (`create_time`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='积分充值配置表';
+
+-- 积分记录表
+CREATE TABLE `member_point_record` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ `user_id` bigint NOT NULL DEFAULT 0 COMMENT '用户编号',
+ `mobile` varchar(20) NOT NULL DEFAULT '' COMMENT '手机号',
+ `type` varchar(20) NOT NULL DEFAULT '' COMMENT '变动类型(increase-增加 decrease-减少)',
+ `point_amount` int NOT NULL DEFAULT 0 COMMENT '变动积分数量(正数为增加,负数为减少)',
+ `balance` int NOT NULL DEFAULT 0 COMMENT '变动后余额',
+ `reason` varchar(100) NOT NULL DEFAULT '' COMMENT '变动原因',
+ `biz_type` varchar(50) NOT NULL DEFAULT '' COMMENT '业务类型(signin-签到 recharge-充值 exchange-兑换 admin-后台调整 gift-礼包赠送)',
+ `biz_id` varchar(64) NOT NULL DEFAULT '' COMMENT '业务关联ID',
+ `remark` varchar(500) NOT NULL DEFAULT '' COMMENT '备注',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `creator` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者',
+ PRIMARY KEY (`id`) USING BTREE,
+ KEY `idx_tenant_id_user_id` (`tenant_id`, `user_id`) USING BTREE,
+ KEY `idx_user_id_create_time` (`user_id`, `create_time`) USING BTREE,
+ KEY `idx_type` (`type`) USING BTREE,
+ KEY `idx_biz_type` (`biz_type`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='积分记录表';
+
+-- ===============================================
+-- 2. 客户管理模块
+-- ===============================================
+
+-- 会员用户表
+CREATE TABLE `member_user` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ `user_id` varchar(32) NOT NULL COMMENT '用户ID',
+ `mobile` varchar(20) NOT NULL COMMENT '手机号',
+ `register_time` datetime NOT NULL COMMENT '注册时间',
+ `last_login_time` datetime NOT NULL COMMENT '最后登录时间',
+ `total_points` int NOT NULL DEFAULT 0 COMMENT '账户总积分',
+ `used_points` int NOT NULL DEFAULT 0 COMMENT '账户消耗积分',
+ `remaining_points` int NOT NULL DEFAULT 0 COMMENT '账户剩余积分',
+ `total_storage` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '云空间总容量(GB)',
+ `used_storage` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '云空间已用容量(GB)',
+ `remaining_storage` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '云空间剩余容量(GB)',
+ `total_recharge` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '总充值金额',
+ `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态(0-禁用 1-启用)',
+ `remark` varchar(500) NOT NULL DEFAULT '' COMMENT '备注',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `creator` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者',
+ `updater` varchar(64) NOT NULL DEFAULT '' COMMENT '更新者',
+ `deleted` bit NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ PRIMARY KEY (`id`) USING BTREE,
+ UNIQUE KEY `uk_user_id` (`user_id`) USING BTREE,
+ UNIQUE KEY `uk_mobile` (`mobile`) USING BTREE,
+ KEY `idx_tenant_id` (`tenant_id`) USING BTREE,
+ KEY `idx_register_time` (`register_time`) USING BTREE,
+ KEY `idx_last_login_time` (`last_login_time`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='会员用户表';
+
+-- 充值记录表
+CREATE TABLE `member_recharge_record` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ `user_id` bigint NOT NULL DEFAULT 0 COMMENT '用户编号',
+ `mobile` varchar(20) NOT NULL COMMENT '手机号',
+ `recharge_amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '充值金额',
+ `recharge_type` varchar(20) NOT NULL DEFAULT '' COMMENT '充值方式(alipay-支付宝 wechat-微信 admin-人工)',
+ `order_type` varchar(50) NOT NULL DEFAULT '' COMMENT '订单类型(purchase-权限购买 exchange-积分兑换)',
+ `permission_type` varchar(100) NOT NULL DEFAULT '' COMMENT '购买权限类型',
+ `bonus_points` int NOT NULL DEFAULT 0 COMMENT '获得积分',
+ `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态(0-失败 1-成功)',
+ `remark` varchar(500) NOT NULL DEFAULT '' COMMENT '备注',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `creator` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者',
+ PRIMARY KEY (`id`) USING BTREE,
+ KEY `idx_tenant_id_user_id` (`tenant_id`, `user_id`) USING BTREE,
+ KEY `idx_user_id_create_time` (`user_id`, `create_time`) USING BTREE,
+ KEY `idx_recharge_type` (`recharge_type`) USING BTREE,
+ KEY `idx_order_type` (`order_type`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='充值记录表';
+
+-- ===============================================
+-- 3. 礼包管理模块
+-- ===============================================
+
+-- 礼包表
+CREATE TABLE `member_gift_package` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ `package_id` varchar(32) NOT NULL COMMENT '礼包ID',
+ `package_name` varchar(100) NOT NULL COMMENT '礼包名称',
+ `sort_order` int NOT NULL DEFAULT 0 COMMENT 'C端展示排序',
+ `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态(0-禁用 1-启用)',
+ `price` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '购买价格',
+ `validity_days` int NOT NULL DEFAULT 0 COMMENT '有效期(天)',
+ `bonus_points` int NOT NULL DEFAULT 0 COMMENT '赠送积分',
+ `applications` text NOT NULL COMMENT '关联应用(JSON格式)',
+ `remark` varchar(500) NOT NULL DEFAULT '' COMMENT '备注',
+ `operator_id` bigint NOT NULL DEFAULT 0 COMMENT '操作人用户编号',
+ `operator_name` varchar(64) NOT NULL DEFAULT '' COMMENT '操作人账号',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `creator` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者',
+ `updater` varchar(64) NOT NULL DEFAULT '' COMMENT '更新者',
+ `deleted` bit NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ PRIMARY KEY (`id`) USING BTREE,
+ UNIQUE KEY `uk_package_id` (`package_id`) USING BTREE,
+ KEY `idx_tenant_id` (`tenant_id`) USING BTREE,
+ KEY `idx_sort_order` (`sort_order`) USING BTREE,
+ KEY `idx_status` (`status`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='礼包表';
+
+-- ===============================================
+-- 4. 模型管理模块
+-- ===============================================
+
+-- AI模型表
+CREATE TABLE `ai_model` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ `model_name` varchar(100) NOT NULL COMMENT '模型名称',
+ `model_code` varchar(100) NOT NULL COMMENT '模型标识/编码',
+ `platform` varchar(50) NOT NULL COMMENT '所属平台',
+ `api_key` varchar(200) NOT NULL COMMENT 'API秘钥',
+ `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态(0-禁用 1-启用)',
+ `temperature` decimal(3,2) NOT NULL DEFAULT 0.70 COMMENT '温度参数',
+ `max_tokens` int NOT NULL DEFAULT 0 COMMENT '回复数Token数',
+ `daily_limit` int NOT NULL DEFAULT 0 COMMENT '每日请求次数',
+ `model_type` varchar(50) NOT NULL COMMENT '模型类型(image-图像 text-文本 video-视频 audio-音频)',
+ `consume_points` int NOT NULL DEFAULT 0 COMMENT '消耗积分',
+ `max_text_length` int NOT NULL DEFAULT 0 COMMENT '最大文本数量',
+ `max_image_size` varchar(50) NOT NULL DEFAULT '' COMMENT '图片最大像素',
+ `max_video_duration` int NOT NULL DEFAULT 0 COMMENT '视频最大时长(秒)',
+ `max_video_quality` varchar(20) NOT NULL DEFAULT '' COMMENT '视频最大质量',
+ `remark` varchar(500) NOT NULL DEFAULT '' COMMENT '备注',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `creator` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者',
+ `updater` varchar(64) NOT NULL DEFAULT '' COMMENT '更新者',
+ `deleted` bit NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ PRIMARY KEY (`id`) USING BTREE,
+ KEY `idx_tenant_id` (`tenant_id`) USING BTREE,
+ KEY `idx_platform` (`platform`) USING BTREE,
+ KEY `idx_model_type` (`model_type`) USING BTREE,
+ KEY `idx_status` (`status`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='AI模型表';
+
+-- ===============================================
+-- 5. 应用功能管理模块
+-- ===============================================
+
+-- 应用功能表
+CREATE TABLE `ai_application` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ `app_id` varchar(32) NOT NULL COMMENT '应用ID',
+ `app_name` varchar(100) NOT NULL COMMENT '应用名称',
+ `api_key` varchar(200) NOT NULL COMMENT '第三方API秘钥',
+ `consume_points` int NOT NULL DEFAULT 0 COMMENT '单位消耗积分',
+ `unit_type` varchar(20) NOT NULL COMMENT '消耗单位(time-时长 count-次数)',
+ `unit_value` varchar(50) NOT NULL COMMENT '单位值(如:1min、20次)',
+ `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态(0-禁用 1-启用)',
+ `remark` varchar(500) NOT NULL DEFAULT '' COMMENT '备注',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `creator` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者',
+ `updater` varchar(64) NOT NULL DEFAULT '' COMMENT '更新者',
+ `deleted` bit NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ PRIMARY KEY (`id`) USING BTREE,
+ UNIQUE KEY `uk_app_id` (`app_id`) USING BTREE,
+ KEY `idx_tenant_id` (`tenant_id`) USING BTREE,
+ KEY `idx_app_name` (`app_name`) USING BTREE,
+ KEY `idx_status` (`status`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='应用功能表';
+
+-- ===============================================
+-- 6. 智能体配置模块
+-- ===============================================
+
+-- 智能体表
+CREATE TABLE `ai_agent` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ `agent_id` varchar(32) NOT NULL COMMENT '智能体ID',
+ `agent_name` varchar(100) NOT NULL COMMENT '智能体名称',
+ `icon` varchar(200) NOT NULL DEFAULT '' COMMENT '图标URL',
+ `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态(0-禁用 1-启用)',
+ `description` text NOT NULL COMMENT '设定描述',
+ `system_prompt` text NOT NULL COMMENT '预置提示词',
+ `remark` varchar(500) NOT NULL DEFAULT '' COMMENT '备注',
+ `operator_id` bigint NOT NULL DEFAULT 0 COMMENT '操作人用户编号',
+ `operator_name` varchar(64) NOT NULL DEFAULT '' COMMENT '操作人账号',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `creator` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者',
+ `updater` varchar(64) NOT NULL DEFAULT '' COMMENT '更新者',
+ `deleted` bit NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ PRIMARY KEY (`id`) USING BTREE,
+ UNIQUE KEY `uk_agent_id` (`agent_id`) USING BTREE,
+ KEY `idx_tenant_id` (`tenant_id`) USING BTREE,
+ KEY `idx_agent_name` (`agent_name`) USING BTREE,
+ KEY `idx_status` (`status`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='智能体表';
+
+-- ===============================================
+-- 7. 权限管理表
+-- ===============================================
+
+-- 用户权限表
+CREATE TABLE `member_user_permission` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ `user_id` bigint NOT NULL DEFAULT 0 COMMENT '用户编号',
+ `permission_type` varchar(100) NOT NULL COMMENT '权限类型',
+ `package_id` bigint NOT NULL DEFAULT 0 COMMENT '礼包ID',
+ `validity_start` datetime NOT NULL COMMENT '有效期开始时间',
+ `validity_end` datetime NOT NULL COMMENT '有效期结束时间',
+ `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态(0-过期 1-有效)',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `creator` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者',
+ PRIMARY KEY (`id`) USING BTREE,
+ KEY `idx_tenant_id_user_id` (`tenant_id`, `user_id`) USING BTREE,
+ KEY `idx_user_id` (`user_id`) USING BTREE,
+ KEY `idx_package_id` (`package_id`) USING BTREE,
+ KEY `idx_validity_end` (`validity_end`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户权限表';
diff --git a/frontend/app/web-gold/src/App.vue b/frontend/app/web-gold/src/App.vue
index 9dda5e2600..6243dcd0b4 100644
--- a/frontend/app/web-gold/src/App.vue
+++ b/frontend/app/web-gold/src/App.vue
@@ -10,12 +10,59 @@ const themeToken = ref({
token: {
colorPrimary: '#3B82F6',
colorInfo: '#2563EB',
+ colorSuccess: '#10B981',
+ colorWarning: '#F59E0B',
+ colorError: '#EF4444',
colorBgBase: '#F8FAFC',
colorBgContainer: '#FFFFFF',
+ colorBgElevated: '#FFFFFF',
colorTextBase: '#334155',
colorTextSecondary: '#64748B',
+ colorTextTertiary: '#94A3B8',
colorBorder: '#E2E8F0',
+ colorBorderSecondary: '#F1F5F9',
borderRadius: 8,
+ borderRadiusSM: 4,
+ borderRadiusLG: 12,
+ wireframe: false,
+ fontSize: 14,
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
+ fontSizeHeading1: 32,
+ fontSizeHeading2: 24,
+ fontSizeHeading3: 20,
+ fontSizeHeading4: 16,
+ fontSizeHeading5: 14,
+ motionDurationMid: '0.15s',
+ motionEaseInOut: 'cubic-bezier(0.4, 0, 0.2, 1)',
+ boxShadow: '0 1px 2px 0 rgb(0 0 0 / 0.05)',
+ boxShadowSecondary: '0 4px 6px -1px rgb(0 0 0 / 0.1)',
+ boxShadowTertiary: '0 10px 15px -3px rgb(0 0 0 / 0.1)',
+ },
+ algorithm: undefined, // 可以设置为 theme.darkAlgorithm 用于暗色主题
+ components: {
+ Button: {
+ controlHeight: 32,
+ controlHeightSM: 24,
+ controlHeightLG: 40,
+ borderRadius: 8,
+ },
+ Card: {
+ borderRadius: 12,
+ boxShadow: '0 1px 2px 0 rgb(0 0 0 / 0.05)',
+ },
+ Input: {
+ borderRadius: 8,
+ controlHeight: 32,
+ },
+ Table: {
+ borderRadius: 8,
+ headerBg: '#F8FAFC',
+ },
+ Menu: {
+ itemHeight: 40,
+ itemMarginInline: 4,
+ itemMarginBlock: 2,
+ },
}
})
@@ -36,4 +83,34 @@ onMounted(async () => {})
text-align: center;
display: flex;
}
+
+.ant-select-selector {
+ background: var(--color-bg) !important;
+ border: 1px solid var(--color-border) !important;
+ border-radius: 4px !important;
+ transition: all 0.2s !important;
+ min-height: 32px !important;
+}
+
+.ant-select-selection-item,
+.ant-select-selection-placeholder {
+ line-height: 30px !important;
+ color: var(--color-text) !important;
+}
+
+.ant-select-focused .ant-select-selector {
+ border-color: var(--color-primary) !important;
+ box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.1) !important;
+}
+
+.ant-select:hover .ant-select-selector {
+ border-color: var(--color-primary) !important;
+}
+
+.ant-select-arrow {
+ color: var(--color-text-secondary) !important;
+}
+.ant-modal .ant-modal-footer {
+ display: flex;
+}
diff --git a/frontend/app/web-gold/src/components/GradientButton.vue b/frontend/app/web-gold/src/components/GradientButton.vue
index 455c344e63..a3cbbf4205 100644
--- a/frontend/app/web-gold/src/components/GradientButton.vue
+++ b/frontend/app/web-gold/src/components/GradientButton.vue
@@ -103,14 +103,11 @@ const buttonClass = computed(() => {
cursor: pointer;
transition: all 0.2s ease;
background: var(--color-slate-900);
- box-shadow: 0 10px 15px -3px rgba(59, 130, 246, 0.2), 0 4px 6px -2px rgba(59, 130, 246, 0.1);
user-select: none;
}
.gradient-button:hover {
background: var(--color-slate-800);
- transform: translateY(-1px);
- box-shadow: 0 20px 25px -5px rgba(59, 130, 246, 0.3), 0 10px 10px -5px rgba(59, 130, 246, 0.15);
}
.gradient-button:active {
diff --git a/frontend/app/web-gold/src/components/SidebarNav.vue b/frontend/app/web-gold/src/components/SidebarNav.vue
index 15a4c0397d..aa1cf75d4f 100644
--- a/frontend/app/web-gold/src/components/SidebarNav.vue
+++ b/frontend/app/web-gold/src/components/SidebarNav.vue
@@ -45,7 +45,6 @@ const items = computed(() => {
children: [
{ name: '素材列表', label: '素材列表', icon: 'grid' },
{ name: '智能混剪', label: '智能混剪', icon: 'scissors' },
- { name: '素材分组', label: '素材分组', icon: 'folder' },
]
},
{
diff --git a/frontend/app/web-gold/src/layouts/LayoutExamples.vue b/frontend/app/web-gold/src/layouts/LayoutExamples.vue
new file mode 100644
index 0000000000..a68f616981
--- /dev/null
+++ b/frontend/app/web-gold/src/layouts/LayoutExamples.vue
@@ -0,0 +1,237 @@
+
+
+
+
+
布局组件使用示例
+
+
+
1. BasicLayout - 基础布局
+
+
+ 额外操作
+
+
+
+
+
+
+
2. CardLayout - 卡片布局
+
+
+ 操作
+
+
+
+
+
+
+
3. TabLayout - 标签页布局
+
+
+ 标签页操作
+
+
+
+
+
标签页1的内容
+
这是第一个标签页的内容...
+
+
+
+
+
+
标签页2的内容
+
这是第二个标签页的内容...
+
+
+
+
+
+
标签页3的内容
+
这是第三个标签页的内容...
+
+
+
+
+
+
4. FullWidthLayout - 全宽布局
+
+
+
+
+
+
+ 全宽操作
+
+
+
+
+
+
+
5. FormLayout - 表单布局
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/app/web-gold/src/layouts/MainLayout.vue b/frontend/app/web-gold/src/layouts/MainLayout.vue
index 9689ad207d..660dbd4587 100644
--- a/frontend/app/web-gold/src/layouts/MainLayout.vue
+++ b/frontend/app/web-gold/src/layouts/MainLayout.vue
@@ -42,6 +42,6 @@ import SidebarNav from '@/components/SidebarNav.vue'
.content-scroll {
flex: 1 1 auto;
overflow: auto; /* 右侧内容区域滚动 */
- padding: 0 16px 0 16px;
+ padding: 16px 0px 16px 16px;
}
diff --git a/frontend/app/web-gold/src/layouts/README.md b/frontend/app/web-gold/src/layouts/README.md
new file mode 100644
index 0000000000..ead4b13832
--- /dev/null
+++ b/frontend/app/web-gold/src/layouts/README.md
@@ -0,0 +1,297 @@
+# 统一布局组件
+
+为项目提供5种不同类型的布局组件,保持设计一致性和代码复用性。
+
+## 布局组件类型
+
+### 1. BasicLayout - 基础布局
+最通用的布局组件,适用于大多数页面。
+
+**特点:**
+- 标准页面头部(标题 + 副标题)
+- 灵活的内容区域
+- 支持返回按钮和额外操作
+
+**使用场景:**
+- 列表页面
+- 详情页面
+- 数据统计页面
+
+**示例:**
+```vue
+
+
+
+ 新增用户
+
+
+
+
+
+```
+
+### 2. CardLayout - 卡片布局
+内容包装在卡片中,提供更好的视觉层次。
+
+**特点:**
+- Ant Design Card 容器
+- 可配置的边距
+- 灵活的标题栏
+
+**使用场景:**
+- 表单页面
+- 配置页面
+- 详情展示页面
+
+**示例:**
+```vue
+
+
+
+ 编辑
+
+
+
+
+
+
+
+
+
+```
+
+### 3. TabLayout - 标签页布局
+多标签页内容组织。
+
+**特点:**
+- 动态标签页
+- 支持懒加载
+- 自定义标签页内容
+
+**使用场景:**
+- 设置页面
+- 数据对比
+- 多模块内容
+
+**示例:**
+```vue
+
+
+
+ 标签页1内容
+
+
+
+ 标签页2内容
+
+
+
+
+
+```
+
+### 4. FullWidthLayout - 全宽布局
+充分利用屏幕宽度的布局。
+
+**特点:**
+- 全宽度内容
+- 自定义头部
+- 无卡片包装
+
+**使用场景:**
+- 数据可视化
+- 宽屏内容展示
+- 全屏应用
+
+**示例:**
+```vue
+
+
+
+ 数据分析仪表板
+
+
+
+
+ 导出
+ 刷新
+
+
+
+
+
+
+
+
+```
+
+### 5. FormLayout - 表单布局
+专门用于表单页面。
+
+**特点:**
+- 居中的表单容器
+- 内置提交/取消按钮
+- 加载状态管理
+
+**使用场景:**
+- 创建/编辑页面
+- 复杂表单
+- 向导式表单
+
+**示例:**
+```vue
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+## 设计特色
+
+### 1. 统一的设计语言
+- 使用项目的设计令牌(Design Tokens)
+- 一致的颜色、字体、间距
+- Notion 风格的标签页设计
+
+### 2. 响应式设计
+- 移动端友好
+- 自适应布局
+- 弹性内容区域
+
+### 3. 可访问性
+- 语义化 HTML
+- 键盘导航支持
+- 屏幕阅读器友好
+
+### 4. 性能优化
+- 懒加载支持
+- keep-alive 兼容
+- 轻量级实现
+
+## 导入方式
+
+```javascript
+// 单独导入
+import BasicLayout from '@/layouts/components/BasicLayout.vue'
+import CardLayout from '@/layouts/components/CardLayout.vue'
+import TabLayout from '@/layouts/components/TabLayout.vue'
+import FullWidthLayout from '@/layouts/components/FullWidthLayout.vue'
+import FormLayout from '@/layouts/components/FormLayout.vue'
+
+// 批量导入
+import {
+ BasicLayout,
+ CardLayout,
+ TabLayout,
+ FullWidthLayout,
+ FormLayout
+} from '@/layouts/components'
+```
+
+## Props 说明
+
+### 通用 Props
+
+| 属性 | 类型 | 默认值 | 说明 |
+|------|------|--------|------|
+| showBack | Boolean | false | 是否显示返回按钮 |
+| title | String | '' | 页面标题 |
+| subtitle | String | '' | 页面副标题 |
+
+### TabLayout 特有 Props
+
+| 属性 | 类型 | 必需 | 说明 |
+|------|------|------|------|
+| tabs | Array | 是 | 标签页配置数组 |
+| activeKey | String | 否 | 当前激活的标签页 |
+
+### FormLayout 特有 Props
+
+| 属性 | 类型 | 默认值 | 说明 |
+|------|------|--------|------|
+| submitText | String | '提交' | 提交按钮文字 |
+| cancelText | String | '取消' | 取消按钮文字 |
+| showCancel | Boolean | true | 是否显示取消按钮 |
+| submitLoading | Boolean | false | 提交按钮加载状态 |
+
+## 插槽(Slots)
+
+### 通用插槽
+
+- `#extra` - 头部右侧额外操作区域
+- `#header` - 自定义头部内容(某些布局)
+
+### TabLayout 插槽
+
+- `#tab1`, `#tab2`, ... - 标签页内容,名称为 tabs 中的 key
+
+## 事件(Events)
+
+### 通用事件
+
+- `@back` - 点击返回按钮时触发
+
+### TabLayout 事件
+
+- `@change(key)` - 标签页切换时触发
+
+### FormLayout 事件
+
+- `@submit` - 点击提交按钮时触发
+- `@cancel` - 点击取消按钮时触发
+
+## 最佳实践
+
+1. **选择合适的布局**
+ - 简单内容 → BasicLayout
+ - 需要卡片容器 → CardLayout
+ - 多标签内容 → TabLayout
+ - 宽屏内容 → FullWidthLayout
+ - 表单页面 → FormLayout
+
+2. **保持一致性**
+ - 使用统一的设计令牌
+ - 遵循项目的设计规范
+ - 保持交互行为一致
+
+3. **性能优化**
+ - 设置合适的 `forceRender` 属性
+ - 使用 `keep-alive` 缓存组件
+ - 避免不必要的重渲染
+
+4. **可访问性**
+ - 为所有交互元素添加适当的标签
+ - 确保键盘导航正常工作
+ - 提供适当的焦点管理
diff --git a/frontend/app/web-gold/src/layouts/components/BasicLayout.vue b/frontend/app/web-gold/src/layouts/components/BasicLayout.vue
new file mode 100644
index 0000000000..0589564f6c
--- /dev/null
+++ b/frontend/app/web-gold/src/layouts/components/BasicLayout.vue
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
diff --git a/frontend/app/web-gold/src/layouts/components/CardLayout.vue b/frontend/app/web-gold/src/layouts/components/CardLayout.vue
new file mode 100644
index 0000000000..8845e8a428
--- /dev/null
+++ b/frontend/app/web-gold/src/layouts/components/CardLayout.vue
@@ -0,0 +1,155 @@
+
+
+
+
+
+
+
diff --git a/frontend/app/web-gold/src/layouts/components/FormLayout.vue b/frontend/app/web-gold/src/layouts/components/FormLayout.vue
new file mode 100644
index 0000000000..81ff17c468
--- /dev/null
+++ b/frontend/app/web-gold/src/layouts/components/FormLayout.vue
@@ -0,0 +1,194 @@
+
+
+
+
+
+
+
diff --git a/frontend/app/web-gold/src/layouts/components/FullWidthLayout.vue b/frontend/app/web-gold/src/layouts/components/FullWidthLayout.vue
new file mode 100644
index 0000000000..21cfb71813
--- /dev/null
+++ b/frontend/app/web-gold/src/layouts/components/FullWidthLayout.vue
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
diff --git a/frontend/app/web-gold/src/layouts/components/TabLayout.vue b/frontend/app/web-gold/src/layouts/components/TabLayout.vue
new file mode 100644
index 0000000000..877d928e51
--- /dev/null
+++ b/frontend/app/web-gold/src/layouts/components/TabLayout.vue
@@ -0,0 +1,182 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/app/web-gold/src/layouts/components/index.js b/frontend/app/web-gold/src/layouts/components/index.js
new file mode 100644
index 0000000000..627b51137b
--- /dev/null
+++ b/frontend/app/web-gold/src/layouts/components/index.js
@@ -0,0 +1,6 @@
+// 布局组件统一导出
+export { default as BasicLayout } from './BasicLayout.vue'
+export { default as CardLayout } from './CardLayout.vue'
+export { default as TabLayout } from './TabLayout.vue'
+export { default as FullWidthLayout } from './FullWidthLayout.vue'
+export { default as FormLayout } from './FormLayout.vue'
diff --git a/frontend/app/web-gold/src/style.less b/frontend/app/web-gold/src/style.less
index 6dd30fa1eb..679d5a60af 100644
--- a/frontend/app/web-gold/src/style.less
+++ b/frontend/app/web-gold/src/style.less
@@ -48,7 +48,7 @@
--color-gray-400: #9ca3af;
--color-gray-700: #374151;
- /* 主题设计令牌 */
+ /* 主题设计令牌 - 现代化风格 */
--color-bg: var(--color-slate-50);
--color-surface: #ffffff;
--color-header: var(--color-slate-900);
@@ -61,6 +61,24 @@
--color-primary: var(--color-blue-500);
--color-primary-hover: var(--color-blue-600);
+ /* 新增:现代化的功能色 */
+ --color-success: #10b981;
+ --color-success-bg: #ecfdf5;
+ --color-warning: #f59e0b;
+ --color-warning-bg: #fffbeb;
+ --color-error: #ef4444;
+ --color-error-bg: #fef2f2;
+
+ /* 新增:Ant Design Vue 主题覆盖 */
+ --ant-primary-color: var(--color-primary);
+ --ant-primary-color-hover: var(--color-primary-hover);
+ --ant-primary-color-active: var(--color-blue-700);
+ --ant-success-color: var(--color-success);
+ --ant-warning-color: var(--color-warning);
+ --ant-error-color: var(--color-error);
+ --ant-border-radius-base: var(--radius-button);
+ --ant-border-radius-sm: 4px;
+
/* 尺寸系统 */
--radius-card: 12px;
--radius-button: 8px;
@@ -81,6 +99,41 @@
--space-5: 20px;
--space-6: 24px;
--space-8: 32px;
+
+ /* ================================
+ Notion 风格设计变量
+ ================================ */
+ /* 极简配色 */
+ --bg-primary: #ffffff;
+ --bg-secondary: #fafafa;
+ --bg-hover: #f7f6f3;
+ --bg-selected: #e9e9e7;
+
+ /* 文字颜色 */
+ --text-primary: #37352f;
+ --text-secondary: #787774;
+ --text-tertiary: #9b9a97;
+ --text-quaternary: #c1c0bd;
+
+ /* 边框和分割线 */
+ --border-light: #e9e9e7;
+ --border-medium: #d3d3d1;
+ --border-strong: #c1c0bd;
+
+ /* 圆角 */
+ --radius-none: 0;
+ --radius-sm: 3px;
+ --radius-md: 6px;
+ --radius-lg: 8px;
+
+ /* 间距 */
+ --space-xs: 4px;
+ --space-sm: 8px;
+ --space-md: 16px;
+ --space-lg: 24px;
+ --space-xl: 32px;
+ --space-2xl: 48px;
+ --space-3xl: 64px;
}
/* ================================
diff --git a/frontend/app/web-gold/src/views/content-style/Benchmark.vue b/frontend/app/web-gold/src/views/content-style/Benchmark.vue
index b7f3dc9925..3154be4241 100644
--- a/frontend/app/web-gold/src/views/content-style/Benchmark.vue
+++ b/frontend/app/web-gold/src/views/content-style/Benchmark.vue
@@ -23,7 +23,6 @@ const promptStore = usePromptStore()
const {
data,
selectedRowKeys,
- expandedRowKeys,
saveTableDataToSession,
loadTableDataFromSession,
processApiResponse,
@@ -36,10 +35,9 @@ const {
batchAnalyzeLoading,
globalLoading,
globalLoadingText,
- analyzeVideo,
batchAnalyze,
getVoiceText,
-} = useBenchmarkAnalysis(data, expandedRowKeys, saveTableDataToSession)
+} = useBenchmarkAnalysis(data, saveTableDataToSession)
// ==================== 表单状态 ====================
const form = ref({
@@ -110,8 +108,8 @@ async function handleExportToExcel() {
return
}
- if (selectedRowKeys.value.length > 10) {
- message.warning('最多只能导出10条数据,请重新选择')
+ if (selectedRowKeys.value.length > 20) {
+ message.warning('最多只能导出20条数据,请重新选择')
return
}
@@ -189,26 +187,13 @@ async function handleResetForm() {
await clearData()
}
-// ==================== 提示词操作函数 ====================
-function handleCopyPrompt(row) {
- if (!row.prompt) {
- message.warning('没有提示词可复制')
- return
- }
-
- navigator.clipboard.writeText(row.prompt).then(() => {
- message.success('提示词已复制到剪贴板')
- }).catch(() => {
- message.error('复制失败')
- })
-}
-
+// ==================== 批量提示词操作函数 ====================
function handleCopyBatchPrompt(prompt) {
if (!prompt || !prompt.trim()) {
message.warning('没有提示词可复制')
return
}
-
+
navigator.clipboard.writeText(prompt).then(() => {
message.success('提示词已复制到剪贴板')
}).catch(() => {
@@ -216,40 +201,25 @@ function handleCopyBatchPrompt(prompt) {
})
}
-// ==================== 创作相关函数 ====================
-function handleCreateContent(row) {
- promptStore.setPrompt(row.prompt, row)
- router.push('/content-style/copywriting')
-}
-
function handleUseBatchPrompt(prompt) {
if (!prompt || !prompt.trim()) {
message.warning('暂无批量生成的提示词')
return
}
-
+
promptStore.setPrompt(prompt, { batch: true })
router.push('/content-style/copywriting')
}
// ==================== 保存提示词到服务器 ====================
-function handleOpenSavePromptModal(row, batchPrompt = null) {
- if (row) {
- // 单个视频的提示词
- if (!row.prompt || !row.prompt.trim()) {
- message.warning('没有提示词可保存')
- return
- }
- savePromptContent.value = row.prompt
- } else {
- // 批量提示词:使用传入的 batchPrompt(AI 生成的内容),而不是原始的 mergedText
- const promptToSave = batchPrompt || batchPromptMergedText.value
- if (!promptToSave || !promptToSave.trim()) {
- message.warning('没有提示词可保存')
- return
- }
- savePromptContent.value = promptToSave
+function handleOpenSavePromptModal(batchPrompt = null) {
+ // 批量提示词:使用传入的 batchPrompt(AI 生成的内容),而不是原始的 mergedText
+ const promptToSave = batchPrompt || batchPromptMergedText.value
+ if (!promptToSave || !promptToSave.trim()) {
+ message.warning('没有提示词可保存')
+ return
}
+ savePromptContent.value = promptToSave
savePromptModalVisible.value = true
}
@@ -277,14 +247,9 @@ defineOptions({ name: 'ContentStyleBenchmark' })
@@ -312,7 +277,7 @@ defineOptions({ name: 'ContentStyleBenchmark' })
:merged-text="batchPromptMergedText"
:text-count="batchPromptTextCount"
@copy="handleCopyBatchPrompt"
- @save="(prompt) => handleOpenSavePromptModal(null, prompt)"
+ @save="(prompt) => handleOpenSavePromptModal(prompt)"
@use="handleUseBatchPrompt"
/>
diff --git a/frontend/app/web-gold/src/views/content-style/components/BenchmarkTable.vue b/frontend/app/web-gold/src/views/content-style/components/BenchmarkTable.vue
index eb39c2666e..4e7fe094d3 100644
--- a/frontend/app/web-gold/src/views/content-style/components/BenchmarkTable.vue
+++ b/frontend/app/web-gold/src/views/content-style/components/BenchmarkTable.vue
@@ -1,8 +1,6 @@
-
-
- $emit('analyze', row)"
- @copy="(row) => $emit('copy', row)"
- @save-to-server="(row) => $emit('saveToServer', row)"
- @create-content="(row) => $emit('createContent', row)"
- />
-
打开
-
-
-
-
-
-
@@ -184,15 +139,10 @@ function onExpandedRowKeysChange(keys) {
margin-bottom: 12px;
}
-.section-header .ant-space {
+.button-group {
display: flex;
align-items: center;
-}
-
-.section-header .ant-btn {
- display: inline-flex;
- align-items: center;
- justify-content: center;
+ gap: 12px;
}
.section-title {
diff --git a/frontend/app/web-gold/src/views/dh/VoiceCopy.vue b/frontend/app/web-gold/src/views/dh/VoiceCopy.vue
index 99728bb827..2e7fb472d8 100644
--- a/frontend/app/web-gold/src/views/dh/VoiceCopy.vue
+++ b/frontend/app/web-gold/src/views/dh/VoiceCopy.vue
@@ -1,17 +1,15 @@
-
-
-
-
+
+
+
+ 新建配音
+
- 查询
+ 查询
重置
@@ -101,7 +99,7 @@
-
+
-
diff --git a/frontend/app/web-gold/src/views/material/MaterialListNew.vue b/frontend/app/web-gold/src/views/material/MaterialListNew.vue
index 84a50b410f..984adfc6c6 100644
--- a/frontend/app/web-gold/src/views/material/MaterialListNew.vue
+++ b/frontend/app/web-gold/src/views/material/MaterialListNew.vue
@@ -465,11 +465,10 @@ onMounted(() => {
.category-tabs {
display: flex;
- background: #f5f5f5;
- border-radius: 8px;
- padding: 3px;
+ background: transparent;
+ border-bottom: 1px solid #e5e7eb;
+ padding-bottom: 0;
margin-bottom: 16px;
- border: 1px solid #e8e8e8;
}
.category-tab {
@@ -478,21 +477,22 @@ onMounted(() => {
text-align: center;
cursor: pointer;
background: transparent;
- border-radius: 6px;
font-weight: 400;
- font-size: 13px;
- color: #666;
- border: 1px solid transparent;
+ font-size: 14px;
+ color: #6b7280;
+ border-bottom: 2px solid transparent;
+ transition: all 0.15s ease;
+ margin-bottom: -1px;
+
&:hover {
- color: #1890ff;
- background: rgba(24, 144, 255, 0.05);
+ color: #374151;
+ background: rgba(243, 244, 246, 0.5);
}
&--active {
- background: #fff;
- color: #1890ff;
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
- border: 1px solid #d9d9d9;
+ color: #2563eb;
+ border-bottom-color: #2563eb;
+ font-weight: 500;
}
}
@@ -536,8 +536,6 @@ onMounted(() => {
}
.sidebar-section {
- margin-top: 16px;
-
&__header {
padding: 8px 12px;
font-weight: 500;
diff --git a/frontend/app/web-gold/src/views/trends/Forecast.vue b/frontend/app/web-gold/src/views/trends/Forecast.vue
index 9709958c9b..6ab3bc8e16 100644
--- a/frontend/app/web-gold/src/views/trends/Forecast.vue
+++ b/frontend/app/web-gold/src/views/trends/Forecast.vue
@@ -1,6 +1,6 @@