This commit is contained in:
2026-03-07 16:48:59 +08:00
parent 5a5af706e5
commit c2e2a64416
36 changed files with 609 additions and 1369 deletions

View File

@@ -1,285 +0,0 @@
-- Yudao 风格建表语句
-- 包含多租户概念,使用 TenantBaseDO
-- 命名规范业务模块_功能模块_功能如 muye_point_幕业积分、muye_member_幕业会员、muye_ai_幕业AI
-- ===============================================
-- 1. 积分管理模块 (muye_point_)
-- ===============================================
-- 积分兑换配置表
CREATE TABLE `muye_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 `muye_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 `muye_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 `muye_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. 会员管理模块 (muye_member_)
-- ===============================================
-- 会员用户档案表
CREATE TABLE `muye_member_user_profile` (
`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 `muye_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='充值记录表';
-- 礼包表
CREATE TABLE `muye_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='礼包表';
-- ===============================================
-- 3. AI 模块 (muye_ai_)
-- ===============================================
-- AI模型配置表
CREATE TABLE `muye_ai_model_config` (
`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模型配置表';
-- AI应用功能表
CREATE TABLE `muye_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='AI应用功能表';
-- AI智能体表
CREATE TABLE `muye_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='AI智能体表';
-- ===============================================
-- 4. 权限管理模块
-- ===============================================
-- 用户权限表
CREATE TABLE `muye_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='用户权限表';

View File

@@ -1,61 +1,64 @@
/**
* AI模型配置 API 服务
* 用于获取模型积分消耗配置
* AI第三方服务配置 API 服务
* 用于获取服务积分消耗配置
*/
import http from './http'
const BASE_URL = '/webApi/api/tik/ai-model-config'
const BASE_URL = '/webApi/api/tik/ai-service-config'
/**
* 模型配置 API 服务
* 服务配置 API 服务
*/
export const ModelConfigService = {
export const ServiceConfigService = {
/**
* 获取所有启用的模型配置列表(按平台分组)
* @returns {Promise<Object>} 按平台分组的模型配置
* 格式: { platform: [{ modelCode, modelName, consumePoints }] }
* 获取所有启用的服务配置列表(按平台分组)
* @returns {Promise<Object>} 按平台分组的服务配置
* 格式: { platform: [{ serviceCode, serviceName, consumePoints }] }
*/
async getEnabledModelConfigList() {
async getEnabledServiceConfigList() {
const { data } = await http.get(`${BASE_URL}/list-enabled`)
return data || {}
},
/**
* 根据模型代码获取积分消耗
* @param {Object} configMap - 配置映射(从 getEnabledModelConfigList 获取)
* @param {string} modelCode - 模型代码
* 根据服务代码获取积分消耗
* @param {Object} configMap - 配置映射(从 getEnabledServiceConfigList 获取)
* @param {string} serviceCode - 服务代码
* @returns {number|null} 积分消耗,未找到返回 null
*/
getConsumePoints(configMap, modelCode) {
if (!configMap || !modelCode) return null
getConsumePoints(configMap, serviceCode) {
if (!configMap || !serviceCode) return null
for (const platform of Object.values(configMap)) {
const model = platform?.find(m => m.modelCode === modelCode)
if (model) {
return model.consumePoints
const service = platform?.find(s => s.serviceCode === serviceCode)
if (service) {
return service.consumePoints
}
}
return null
},
/**
* 根据模型代码获取模型名称
* 根据服务代码获取服务名称
* @param {Object} configMap - 配置映射
* @param {string} modelCode - 模型代码
* @returns {string|null} 模型名称,未找到返回 null
* @param {string} serviceCode - 服务代码
* @returns {string|null} 服务名称,未找到返回 null
*/
getModelName(configMap, modelCode) {
if (!configMap || !modelCode) return null
getServiceName(configMap, serviceCode) {
if (!configMap || !serviceCode) return null
for (const platform of Object.values(configMap)) {
const model = platform?.find(m => m.modelCode === modelCode)
if (model) {
return model.modelName
const service = platform?.find(s => s.serviceCode === serviceCode)
if (service) {
return service.serviceName
}
}
return null
}
}
export default ModelConfigService
// 兼容旧名称(逐步废弃)
export const ModelConfigService = ServiceConfigService
export default ServiceConfigService

View File

@@ -1,18 +1,18 @@
/**
* 积分配置 Store
* 管理AI模型积分消耗配置
* 管理AI服务积分消耗配置
*/
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
import { getJSON, setJSON } from '@/utils/storage'
import ModelConfigService from '@/api/modelConfig'
import ServiceConfigService from '@/api/modelConfig'
const STORAGE_KEY = 'points_config_v1'
const CACHE_DURATION = 30 * 60 * 1000 // 30分钟缓存
export const usePointsConfigStore = defineStore('pointsConfig', () => {
// 模型配置映射(按平台分组)
// 服务配置映射(按平台分组)
const configMap = ref({})
// 是否已加载
const isLoaded = ref(false)
@@ -24,57 +24,66 @@ export const usePointsConfigStore = defineStore('pointsConfig', () => {
// 所有平台列表
const platforms = computed(() => Object.keys(configMap.value))
// 获取所有模型列表(扁平化)
const allModels = computed(() => {
const models = []
// 获取所有服务列表(扁平化)
const allServices = computed(() => {
const services = []
for (const [platform, list] of Object.entries(configMap.value)) {
if (Array.isArray(list)) {
list.forEach(model => {
models.push({ ...model, platform })
list.forEach(service => {
services.push({ ...service, platform })
})
}
}
return models
return services
})
// 兼容allModels 别名
const allModels = allServices
/**
* 根据模型代码获取积分消耗
* @param {string} modelCode - 模型代码
* 根据服务代码获取积分消耗
* @param {string} serviceCode - 服务代码
* @returns {number|null} 积分消耗
*/
const getConsumePoints = (modelCode) => {
if (!modelCode) return null
return ModelConfigService.getConsumePoints(configMap.value, modelCode)
const getConsumePoints = (serviceCode) => {
if (!serviceCode) return null
return ServiceConfigService.getConsumePoints(configMap.value, serviceCode)
}
/**
* 根据模型代码获取模型名称
* @param {string} modelCode - 模型代码
* @returns {string|null} 模型名称
* 根据服务代码获取服务名称
* @param {string} serviceCode - 服务代码
* @returns {string|null} 服务名称
*/
const getModelName = (modelCode) => {
if (!modelCode) return null
return ModelConfigService.getModelName(configMap.value, modelCode)
const getServiceName = (serviceCode) => {
if (!serviceCode) return null
return ServiceConfigService.getServiceName(configMap.value, serviceCode)
}
// 兼容getModelName 别名
const getModelName = getServiceName
/**
* 获取模型完整信息
* @param {string} modelCode - 模型代码
* @returns {Object|null} 模型信息 { modelCode, modelName, consumePoints, platform }
* 获取服务完整信息
* @param {string} serviceCode - 服务代码
* @returns {Object|null} 服务信息 { serviceCode, serviceName, consumePoints, platform }
*/
const getModelInfo = (modelCode) => {
if (!modelCode) return null
const getServiceInfo = (serviceCode) => {
if (!serviceCode) return null
for (const [platform, list] of Object.entries(configMap.value)) {
if (Array.isArray(list)) {
const model = list.find(m => m.modelCode === modelCode)
if (model) {
return { ...model, platform }
const service = list.find(s => s.serviceCode === serviceCode)
if (service) {
return { ...service, platform }
}
}
}
return null
}
// 兼容getModelInfo 别名
const getModelInfo = getServiceInfo
/**
* 从本地存储恢复
*/
@@ -98,7 +107,7 @@ export const usePointsConfigStore = defineStore('pointsConfig', () => {
}
/**
* 加载模型配置(从服务器)
* 加载服务配置(从服务器)
* @param {boolean} force - 是否强制刷新
*/
const loadConfig = async (force = false) => {
@@ -115,14 +124,14 @@ export const usePointsConfigStore = defineStore('pointsConfig', () => {
isLoading.value = true
try {
const data = await ModelConfigService.getEnabledModelConfigList()
const data = await ServiceConfigService.getEnabledServiceConfigList()
configMap.value = data || {}
lastLoadTime.value = now
isLoaded.value = true
await persistToStorage()
return configMap.value
} catch (error) {
console.error('[pointsConfig] 加载模型配置失败:', error)
console.error('[pointsConfig] 加载服务配置失败:', error)
throw error
} finally {
isLoading.value = false
@@ -149,11 +158,14 @@ export const usePointsConfigStore = defineStore('pointsConfig', () => {
isLoaded,
isLoading,
platforms,
allModels,
allServices,
allModels, // 兼容
// 方法
getConsumePoints,
getModelName,
getModelInfo,
getServiceName,
getModelName, // 兼容
getServiceInfo,
getModelInfo, // 兼容
loadConfig,
formatPoints,
}

View File

@@ -10,7 +10,7 @@ import cn.iocoder.yudao.module.tik.enums.AiModelTypeEnum;
import cn.iocoder.yudao.module.tik.enums.AiPlatformEnum;
import cn.iocoder.yudao.module.tik.muye.aiagent.dal.AiAgentDO;
import cn.iocoder.yudao.module.tik.muye.aiagent.service.AiAgentService;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.dal.AiModelConfigDO;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.dal.AiServiceConfigDO;
import cn.iocoder.yudao.module.tik.muye.points.service.PointsService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@@ -63,7 +63,7 @@ public class DifyServiceImpl implements DifyService {
AiModelTypeEnum modelTypeEnum = "standard".equals(reqVO.getModelMode())
? AiModelTypeEnum.DIFY_WRITING_STANDARD
: AiModelTypeEnum.DIFY_WRITING_PRO;
AiModelConfigDO config = pointsService.getConfig(
AiServiceConfigDO config = pointsService.getConfig(
AiPlatformEnum.DIFY.getPlatform(),
modelTypeEnum.getModelCode());
@@ -161,7 +161,7 @@ public class DifyServiceImpl implements DifyService {
AiModelTypeEnum modelTypeEnum = "forecast_pro".equals(reqVO.getModelType())
? AiModelTypeEnum.FORECAST_PRO
: AiModelTypeEnum.FORECAST_STANDARD;
AiModelConfigDO config = pointsService.getConfig(
AiServiceConfigDO config = pointsService.getConfig(
AiPlatformEnum.DIFY.getPlatform(),
modelTypeEnum.getModelCode());
@@ -277,7 +277,7 @@ public class DifyServiceImpl implements DifyService {
}
// 获取积分配置(使用标准模式的 API Key
AiModelConfigDO config = pointsService.getConfig(
AiServiceConfigDO config = pointsService.getConfig(
AiPlatformEnum.DIFY.getPlatform(),
AiModelTypeEnum.DIFY_WRITING_STANDARD.getModelCode());
@@ -296,7 +296,7 @@ public class DifyServiceImpl implements DifyService {
}
// 获取积分配置(使用标准模式的 API Key
AiModelConfigDO config = pointsService.getConfig(
AiServiceConfigDO config = pointsService.getConfig(
AiPlatformEnum.DIFY.getPlatform(),
AiModelTypeEnum.DIFY_WRITING_STANDARD.getModelCode());

View File

@@ -1,106 +0,0 @@
package cn.iocoder.yudao.module.tik.muye.aiapplication;
import cn.iocoder.yudao.module.tik.muye.aiapplication.dal.AiApplicationDO;
import cn.iocoder.yudao.module.tik.muye.aiapplication.service.AiApplicationService;
import cn.iocoder.yudao.module.tik.muye.aiapplication.vo.AiApplicationPageReqVO;
import cn.iocoder.yudao.module.tik.muye.aiapplication.vo.AiApplicationRespVO;
import cn.iocoder.yudao.module.tik.muye.aiapplication.vo.AiApplicationSaveReqVO;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.constraints.*;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - AI应用功能")
@RestController
@RequestMapping("/admin-api/muye/ai-application")
@Validated
public class AiApplicationController {
@Resource
private AiApplicationService aiApplicationService;
@PostMapping("/create")
@Operation(summary = "创建AI应用功能")
@PreAuthorize("@ss.hasPermission('muye:ai-application:create')")
public CommonResult<Long> createAiApplication(@Valid @RequestBody AiApplicationSaveReqVO createReqVO) {
return success(aiApplicationService.createAiApplication(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新AI应用功能")
@PreAuthorize("@ss.hasPermission('muye:ai-application:update')")
public CommonResult<Boolean> updateAiApplication(@Valid @RequestBody AiApplicationSaveReqVO updateReqVO) {
aiApplicationService.updateAiApplication(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除AI应用功能")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('muye:ai-application:delete')")
public CommonResult<Boolean> deleteAiApplication(@RequestParam("id") Long id) {
aiApplicationService.deleteAiApplication(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除AI应用功能")
@PreAuthorize("@ss.hasPermission('muye:ai-application:delete')")
public CommonResult<Boolean> deleteAiApplicationList(@RequestParam("ids") List<Long> ids) {
aiApplicationService.deleteAiApplicationListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得AI应用功能")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('muye:ai-application:query')")
public CommonResult<AiApplicationRespVO> getAiApplication(@RequestParam("id") Long id) {
AiApplicationDO aiApplication = aiApplicationService.getAiApplication(id);
return success(BeanUtils.toBean(aiApplication, AiApplicationRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得AI应用功能分页")
@PreAuthorize("@ss.hasPermission('muye:ai-application:query')")
public CommonResult<PageResult<AiApplicationRespVO>> getAiApplicationPage(@Valid AiApplicationPageReqVO pageReqVO) {
PageResult<AiApplicationDO> pageResult = aiApplicationService.getAiApplicationPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, AiApplicationRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出AI应用功能 Excel")
@PreAuthorize("@ss.hasPermission('muye:ai-application:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportAiApplicationExcel(@Valid AiApplicationPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<AiApplicationDO> list = aiApplicationService.getAiApplicationPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "AI应用功能.xls", "数据", AiApplicationRespVO.class,
BeanUtils.toBean(list, AiApplicationRespVO.class));
}
}

View File

@@ -1,61 +0,0 @@
package cn.iocoder.yudao.module.tik.muye.aiapplication.dal;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* AI应用功能 DO
*
* @author 芋道源码
*/
@TableName("muye_ai_application")
@KeySequence("muye_ai_application_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AiApplicationDO extends BaseDO {
/**
* 主键
*/
@TableId
private Long id;
/**
* 应用ID
*/
private String appId;
/**
* 应用名称
*/
private String appName;
/**
* 第三方API秘钥
*/
private String apiKey;
/**
* 单位消耗积分
*/
private Integer consumePoints;
/**
* 消耗单位(time-时长 count-次数)
*/
private String unitType;
/**
* 单位值(如1min、20次)
*/
private String unitValue;
/**
* 状态(0-禁用 1-启用)
*/
private Integer status;
/**
* 备注
*/
private String remark;
}

View File

@@ -1,35 +0,0 @@
package cn.iocoder.yudao.module.tik.muye.aiapplication.mapper;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.tik.muye.aiapplication.dal.AiApplicationDO;
import cn.iocoder.yudao.module.tik.muye.aiapplication.vo.AiApplicationPageReqVO;
import org.apache.ibatis.annotations.Mapper;
/**
* AI应用功能 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface AiApplicationMapper extends BaseMapperX<AiApplicationDO> {
default PageResult<AiApplicationDO> selectPage(AiApplicationPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<AiApplicationDO>()
.eqIfPresent(AiApplicationDO::getAppId, reqVO.getAppId())
.likeIfPresent(AiApplicationDO::getAppName, reqVO.getAppName())
.eqIfPresent(AiApplicationDO::getApiKey, reqVO.getApiKey())
.eqIfPresent(AiApplicationDO::getConsumePoints, reqVO.getConsumePoints())
.eqIfPresent(AiApplicationDO::getUnitType, reqVO.getUnitType())
.eqIfPresent(AiApplicationDO::getUnitValue, reqVO.getUnitValue())
.eqIfPresent(AiApplicationDO::getStatus, reqVO.getStatus())
.eqIfPresent(AiApplicationDO::getRemark, reqVO.getRemark())
.betweenIfPresent(AiApplicationDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(AiApplicationDO::getId));
}
}

View File

@@ -1,63 +0,0 @@
package cn.iocoder.yudao.module.tik.muye.aiapplication.service;
import java.util.*;
import cn.iocoder.yudao.module.tik.muye.aiapplication.dal.AiApplicationDO;
import cn.iocoder.yudao.module.tik.muye.aiapplication.vo.AiApplicationPageReqVO;
import cn.iocoder.yudao.module.tik.muye.aiapplication.vo.AiApplicationSaveReqVO;
import jakarta.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* AI应用功能 Service 接口
*
* @author 芋道源码
*/
public interface AiApplicationService {
/**
* 创建AI应用功能
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createAiApplication(@Valid AiApplicationSaveReqVO createReqVO);
/**
* 更新AI应用功能
*
* @param updateReqVO 更新信息
*/
void updateAiApplication(@Valid AiApplicationSaveReqVO updateReqVO);
/**
* 删除AI应用功能
*
* @param id 编号
*/
void deleteAiApplication(Long id);
/**
* 批量删除AI应用功能
*
* @param ids 编号
*/
void deleteAiApplicationListByIds(List<Long> ids);
/**
* 获得AI应用功能
*
* @param id 编号
* @return AI应用功能
*/
AiApplicationDO getAiApplication(Long id);
/**
* 获得AI应用功能分页
*
* @param pageReqVO 分页查询
* @return AI应用功能分页
*/
PageResult<AiApplicationDO> getAiApplicationPage(AiApplicationPageReqVO pageReqVO);
}

View File

@@ -1,80 +0,0 @@
package cn.iocoder.yudao.module.tik.muye.aiapplication.service;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.module.tik.muye.aiapplication.dal.AiApplicationDO;
import cn.iocoder.yudao.module.tik.muye.aiapplication.mapper.AiApplicationMapper;
import cn.iocoder.yudao.module.tik.muye.aiapplication.vo.AiApplicationPageReqVO;
import cn.iocoder.yudao.module.tik.muye.aiapplication.vo.AiApplicationSaveReqVO;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
/**
* AI应用功能 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class AiApplicationServiceImpl implements AiApplicationService {
@Resource
private AiApplicationMapper aiApplicationMapper;
@Override
public Long createAiApplication(AiApplicationSaveReqVO createReqVO) {
// 插入
AiApplicationDO aiApplication = BeanUtils.toBean(createReqVO, AiApplicationDO.class);
aiApplicationMapper.insert(aiApplication);
// 返回
return aiApplication.getId();
}
@Override
public void updateAiApplication(AiApplicationSaveReqVO updateReqVO) {
// 校验存在
validateAiApplicationExists(updateReqVO.getId());
// 更新
AiApplicationDO updateObj = BeanUtils.toBean(updateReqVO, AiApplicationDO.class);
aiApplicationMapper.updateById(updateObj);
}
@Override
public void deleteAiApplication(Long id) {
// 校验存在
validateAiApplicationExists(id);
// 删除
aiApplicationMapper.deleteById(id);
}
@Override
public void deleteAiApplicationListByIds(List<Long> ids) {
// 删除
aiApplicationMapper.deleteByIds(ids);
}
private void validateAiApplicationExists(Long id) {
if (aiApplicationMapper.selectById(id) == null) {
throw exception(new ErrorCode(1004, "AI应用功能不存在"));
}
}
@Override
public AiApplicationDO getAiApplication(Long id) {
return aiApplicationMapper.selectById(id);
}
@Override
public PageResult<AiApplicationDO> getAiApplicationPage(AiApplicationPageReqVO pageReqVO) {
return aiApplicationMapper.selectPage(pageReqVO);
}
}

View File

@@ -1,44 +0,0 @@
package cn.iocoder.yudao.module.tik.muye.aiapplication.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - AI应用功能分页 Request VO")
@Data
public class AiApplicationPageReqVO extends PageParam {
@Schema(description = "应用ID", example = "6241")
private String appId;
@Schema(description = "应用名称", example = "芋艿")
private String appName;
@Schema(description = "第三方API秘钥")
private String apiKey;
@Schema(description = "单位消耗积分")
private Integer consumePoints;
@Schema(description = "消耗单位(time-时长 count-次数)", example = "1")
private String unitType;
@Schema(description = "单位值(如1min、20次)")
private String unitValue;
@Schema(description = "状态(0-禁用 1-启用)", example = "1")
private Integer status;
@Schema(description = "备注", example = "你说的对")
private String remark;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@@ -1,55 +0,0 @@
package cn.iocoder.yudao.module.tik.muye.aiapplication.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import cn.idev.excel.annotation.*;
@Schema(description = "管理后台 - AI应用功能 Response VO")
@Data
@ExcelIgnoreUnannotated
public class AiApplicationRespVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "5521")
@ExcelProperty("主键")
private Long id;
@Schema(description = "应用ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "6241")
@ExcelProperty("应用ID")
private String appId;
@Schema(description = "应用名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
@ExcelProperty("应用名称")
private String appName;
@Schema(description = "第三方API秘钥", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("第三方API秘钥")
private String apiKey;
@Schema(description = "单位消耗积分", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("单位消耗积分")
private Integer consumePoints;
@Schema(description = "消耗单位(time-时长 count-次数)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("消耗单位(time-时长 count-次数)")
private String unitType;
@Schema(description = "单位值(如1min、20次)", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("单位值(如1min、20次)")
private String unitValue;
@Schema(description = "状态(0-禁用 1-启用)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("状态(0-禁用 1-启用)")
private Integer status;
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "你说的对")
@ExcelProperty("备注")
private String remark;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@@ -1,47 +0,0 @@
package cn.iocoder.yudao.module.tik.muye.aiapplication.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import jakarta.validation.constraints.*;
@Schema(description = "管理后台 - AI应用功能新增/修改 Request VO")
@Data
public class AiApplicationSaveReqVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "5521")
private Long id;
@Schema(description = "应用ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "6241")
@NotEmpty(message = "应用ID不能为空")
private String appId;
@Schema(description = "应用名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
@NotEmpty(message = "应用名称不能为空")
private String appName;
@Schema(description = "第三方API秘钥", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "第三方API秘钥不能为空")
private String apiKey;
@Schema(description = "单位消耗积分", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "单位消耗积分不能为空")
private Integer consumePoints;
@Schema(description = "消耗单位(time-时长 count-次数)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotEmpty(message = "消耗单位(time-时长 count-次数)不能为空")
private String unitType;
@Schema(description = "单位值(如1min、20次)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "单位值(如1min、20次)不能为空")
private String unitValue;
@Schema(description = "状态(0-禁用 1-启用)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态(0-禁用 1-启用)不能为空")
private Integer status;
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "你说的对")
@NotEmpty(message = "备注不能为空")
private String remark;
}

View File

@@ -1,111 +0,0 @@
package cn.iocoder.yudao.module.tik.muye.aimodelconfig;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.dal.AiModelConfigDO;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.vo.AiModelConfigPageReqVO;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.vo.AiModelConfigRespVO;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.vo.AiModelConfigSaveReqVO;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.constraints.*;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.service.AiModelConfigService;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - AI模型配置")
@RestController
@RequestMapping("/admin-api/muye/ai-model-config")
@Validated
public class AiModelConfigController {
@Resource
private AiModelConfigService aiModelConfigService;
@PostMapping("/create")
@Operation(summary = "创建AI模型配置")
@PreAuthorize("@ss.hasPermission('muye:ai-model-config:create')")
public CommonResult<Long> createAiModelConfig(@Valid @RequestBody AiModelConfigSaveReqVO createReqVO) {
return success(aiModelConfigService.createAiModelConfig(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新AI模型配置")
@PreAuthorize("@ss.hasPermission('muye:ai-model-config:update')")
public CommonResult<Boolean> updateAiModelConfig(@Valid @RequestBody AiModelConfigSaveReqVO updateReqVO) {
aiModelConfigService.updateAiModelConfig(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除AI模型配置")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('muye:ai-model-config:delete')")
public CommonResult<Boolean> deleteAiModelConfig(@RequestParam("id") Long id) {
aiModelConfigService.deleteAiModelConfig(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除AI模型配置")
@PreAuthorize("@ss.hasPermission('muye:ai-model-config:delete')")
public CommonResult<Boolean> deleteAiModelConfigList(@RequestParam("ids") List<Long> ids) {
aiModelConfigService.deleteAiModelConfigListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得AI模型配置")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('muye:ai-model-config:query')")
public CommonResult<AiModelConfigRespVO> getAiModelConfig(@RequestParam("id") Long id) {
AiModelConfigDO aiModelConfig = aiModelConfigService.getAiModelConfig(id);
return success(BeanUtils.toBean(aiModelConfig, AiModelConfigRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得AI模型配置分页")
@PreAuthorize("@ss.hasPermission('muye:ai-model-config:query')")
public CommonResult<PageResult<AiModelConfigRespVO>> getAiModelConfigPage(@Valid AiModelConfigPageReqVO pageReqVO) {
PageResult<AiModelConfigDO> pageResult = aiModelConfigService.getAiModelConfigPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, AiModelConfigRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出AI模型配置 Excel")
@PreAuthorize("@ss.hasPermission('muye:ai-model-config:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportAiModelConfigExcel(@Valid AiModelConfigPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<AiModelConfigDO> list = aiModelConfigService.getAiModelConfigPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "AI模型配置.xls", "数据", AiModelConfigRespVO.class,
BeanUtils.toBean(list, AiModelConfigRespVO.class));
}
@GetMapping("/list-enabled")
@Operation(summary = "获取所有启用的模型配置列表(前端积分显示用)")
@PreAuthorize("@ss.hasPermission('muye:ai-model-config:query')")
public CommonResult<Map<String, List<AiModelConfigService.ModelConfigSimpleVO>>> getEnabledModelConfigList() {
return success(aiModelConfigService.getEnabledModelConfigList());
}
}

View File

@@ -1,54 +0,0 @@
package cn.iocoder.yudao.module.tik.muye.aimodelconfig.mapper;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.dal.AiModelConfigDO;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.vo.AiModelConfigPageReqVO;
import org.apache.ibatis.annotations.Mapper;
/**
* AI模型配置 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface AiModelConfigMapper extends BaseMapperX<AiModelConfigDO> {
default PageResult<AiModelConfigDO> selectPage(AiModelConfigPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<AiModelConfigDO>()
.likeIfPresent(AiModelConfigDO::getModelName, reqVO.getModelName())
.eqIfPresent(AiModelConfigDO::getModelCode, reqVO.getModelCode())
.eqIfPresent(AiModelConfigDO::getPlatform, reqVO.getPlatform())
.eqIfPresent(AiModelConfigDO::getApiKey, reqVO.getApiKey())
.eqIfPresent(AiModelConfigDO::getStatus, reqVO.getStatus())
.eqIfPresent(AiModelConfigDO::getModelType, reqVO.getModelType())
.eqIfPresent(AiModelConfigDO::getConsumePoints, reqVO.getConsumePoints())
.eqIfPresent(AiModelConfigDO::getRemark, reqVO.getRemark())
.betweenIfPresent(AiModelConfigDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(AiModelConfigDO::getId));
}
/**
* 根据平台和模型标识查询配置
*/
default AiModelConfigDO selectByPlatformAndModelCode(String platform, String modelCode) {
return selectOne(new LambdaQueryWrapperX<AiModelConfigDO>()
.eq(AiModelConfigDO::getPlatform, platform)
.eq(AiModelConfigDO::getModelCode, modelCode)
.eq(AiModelConfigDO::getStatus, 1));
}
/**
* 查询所有启用的模型配置
*/
default List<AiModelConfigDO> selectEnabledList() {
return selectList(new LambdaQueryWrapperX<AiModelConfigDO>()
.eq(AiModelConfigDO::getStatus, 1)
.orderByAsc(AiModelConfigDO::getPlatform, AiModelConfigDO::getModelCode));
}
}

View File

@@ -1,81 +0,0 @@
package cn.iocoder.yudao.module.tik.muye.aimodelconfig.service;
import java.util.*;
import lombok.Data;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.dal.AiModelConfigDO;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.vo.AiModelConfigPageReqVO;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.vo.AiModelConfigSaveReqVO;
import jakarta.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* AI模型配置 Service 接口
*
* @author 芋道源码
*/
public interface AiModelConfigService {
/**
* 创建AI模型配置
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createAiModelConfig(@Valid AiModelConfigSaveReqVO createReqVO);
/**
* 更新AI模型配置
*
* @param updateReqVO 更新信息
*/
void updateAiModelConfig(@Valid AiModelConfigSaveReqVO updateReqVO);
/**
* 删除AI模型配置
*
* @param id 编号
*/
void deleteAiModelConfig(Long id);
/**
* 批量删除AI模型配置
*
* @param ids 编号
*/
void deleteAiModelConfigListByIds(List<Long> ids);
/**
* 获得AI模型配置
*
* @param id 编号
* @return AI模型配置
*/
AiModelConfigDO getAiModelConfig(Long id);
/**
* 获得AI模型配置分页
*
* @param pageReqVO 分页查询
* @return AI模型配置分页
*/
PageResult<AiModelConfigDO> getAiModelConfigPage(AiModelConfigPageReqVO pageReqVO);
/**
* 获取所有启用的模型配置列表(前端积分显示用)
*
* @return 模型配置列表(按平台分组)
*/
Map<String, List<ModelConfigSimpleVO>> getEnabledModelConfigList();
/**
* 启用的模型配置简单VO用于前端显示
*/
@Data
class ModelConfigSimpleVO {
private String modelCode;
private String modelName;
private Integer consumePoints;
}
}

View File

@@ -1,94 +0,0 @@
package cn.iocoder.yudao.module.tik.muye.aimodelconfig.service;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.dal.AiModelConfigDO;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.mapper.AiModelConfigMapper;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.vo.AiModelConfigPageReqVO;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.vo.AiModelConfigSaveReqVO;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
/**
* AI模型配置 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class AiModelConfigServiceImpl implements AiModelConfigService {
@Resource
private AiModelConfigMapper aiModelConfigMapper;
@Override
public Long createAiModelConfig(AiModelConfigSaveReqVO createReqVO) {
// 插入
AiModelConfigDO aiModelConfig = BeanUtils.toBean(createReqVO, AiModelConfigDO.class);
aiModelConfigMapper.insert(aiModelConfig);
// 返回
return aiModelConfig.getId();
}
@Override
public void updateAiModelConfig(AiModelConfigSaveReqVO updateReqVO) {
// 校验存在
validateAiModelConfigExists(updateReqVO.getId());
// 更新
AiModelConfigDO updateObj = BeanUtils.toBean(updateReqVO, AiModelConfigDO.class);
aiModelConfigMapper.updateById(updateObj);
}
@Override
public void deleteAiModelConfig(Long id) {
// 校验存在
validateAiModelConfigExists(id);
// 删除
aiModelConfigMapper.deleteById(id);
}
@Override
public void deleteAiModelConfigListByIds(List<Long> ids) {
// 删除
aiModelConfigMapper.deleteByIds(ids);
}
private void validateAiModelConfigExists(Long id) {
if (aiModelConfigMapper.selectById(id) == null) {
throw exception(new ErrorCode(1004, "AI模型配置不存在"));
}
}
@Override
public AiModelConfigDO getAiModelConfig(Long id) {
return aiModelConfigMapper.selectById(id);
}
@Override
public PageResult<AiModelConfigDO> getAiModelConfigPage(AiModelConfigPageReqVO pageReqVO) {
return aiModelConfigMapper.selectPage(pageReqVO);
}
@Override
public Map<String, List<ModelConfigSimpleVO>> getEnabledModelConfigList() {
List<AiModelConfigDO> configList = aiModelConfigMapper.selectEnabledList();
Map<String, List<ModelConfigSimpleVO>> result = new HashMap<>();
for (AiModelConfigDO config : configList) {
ModelConfigSimpleVO simpleVO = new ModelConfigSimpleVO();
simpleVO.setModelCode(config.getModelCode());
simpleVO.setModelName(config.getModelName());
simpleVO.setConsumePoints(config.getConsumePoints());
result.computeIfAbsent(config.getPlatform(), k -> new ArrayList<>()).add(simpleVO);
}
return result;
}
}

View File

@@ -0,0 +1,111 @@
package cn.iocoder.yudao.module.tik.muye.aiserviceconfig;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.dal.AiServiceConfigDO;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.vo.AiServiceConfigPageReqVO;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.vo.AiServiceConfigRespVO;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.vo.AiServiceConfigSaveReqVO;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.constraints.*;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.service.AiServiceConfigService;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - AI第三方服务配置")
@RestController
@RequestMapping("/admin-api/muye/ai-service-config")
@Validated
public class AiServiceConfigController {
@Resource
private AiServiceConfigService aiServiceConfigService;
@PostMapping("/create")
@Operation(summary = "创建AI服务配置")
@PreAuthorize("@ss.hasPermission('muye:ai-service-config:create')")
public CommonResult<Long> createAiServiceConfig(@Valid @RequestBody AiServiceConfigSaveReqVO createReqVO) {
return success(aiServiceConfigService.createAiServiceConfig(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新AI服务配置")
@PreAuthorize("@ss.hasPermission('muye:ai-service-config:update')")
public CommonResult<Boolean> updateAiServiceConfig(@Valid @RequestBody AiServiceConfigSaveReqVO updateReqVO) {
aiServiceConfigService.updateAiServiceConfig(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除AI服务配置")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('muye:ai-service-config:delete')")
public CommonResult<Boolean> deleteAiServiceConfig(@RequestParam("id") Long id) {
aiServiceConfigService.deleteAiServiceConfig(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除AI服务配置")
@PreAuthorize("@ss.hasPermission('muye:ai-service-config:delete')")
public CommonResult<Boolean> deleteAiServiceConfigList(@RequestParam("ids") List<Long> ids) {
aiServiceConfigService.deleteAiServiceConfigListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得AI服务配置")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('muye:ai-service-config:query')")
public CommonResult<AiServiceConfigRespVO> getAiServiceConfig(@RequestParam("id") Long id) {
AiServiceConfigDO aiServiceConfig = aiServiceConfigService.getAiServiceConfig(id);
return success(BeanUtils.toBean(aiServiceConfig, AiServiceConfigRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得AI服务配置分页")
@PreAuthorize("@ss.hasPermission('muye:ai-service-config:query')")
public CommonResult<PageResult<AiServiceConfigRespVO>> getAiServiceConfigPage(@Valid AiServiceConfigPageReqVO pageReqVO) {
PageResult<AiServiceConfigDO> pageResult = aiServiceConfigService.getAiServiceConfigPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, AiServiceConfigRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出AI服务配置 Excel")
@PreAuthorize("@ss.hasPermission('muye:ai-service-config:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportAiServiceConfigExcel(@Valid AiServiceConfigPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<AiServiceConfigDO> list = aiServiceConfigService.getAiServiceConfigPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "AI服务配置.xls", "数据", AiServiceConfigRespVO.class,
BeanUtils.toBean(list, AiServiceConfigRespVO.class));
}
@GetMapping("/list-enabled")
@Operation(summary = "获取所有启用的服务配置列表(前端积分显示用)")
@PreAuthorize("@ss.hasPermission('muye:ai-service-config:query')")
public CommonResult<Map<String, List<AiServiceConfigService.ServiceConfigSimpleVO>>> getEnabledServiceConfigList() {
return success(aiServiceConfigService.getEnabledServiceConfigList());
}
}

View File

@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.tik.muye.aimodelconfig;
package cn.iocoder.yudao.module.tik.muye.aiserviceconfig;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.service.AiModelConfigService;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.service.AiServiceConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
@@ -16,21 +16,21 @@ import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
/**
* 用户 App - AI模型配置
* 用户 App - AI第三方服务配置
*/
@Tag(name = "用户 App - AI模型配置")
@Tag(name = "用户 App - AI第三方服务配置")
@RestController
@RequestMapping("/api/tik/ai-model-config")
@RequestMapping("/api/tik/ai-service-config")
@Validated
public class AppAiModelConfigController {
public class AppAiServiceConfigController {
@Resource
private AiModelConfigService aiModelConfigService;
private AiServiceConfigService aiServiceConfigService;
@GetMapping("/list-enabled")
@Operation(summary = "获取所有启用的模型配置列表(前端积分显示用)")
public CommonResult<Map<String, List<AiModelConfigService.ModelConfigSimpleVO>>> getEnabledModelConfigList() {
return success(aiModelConfigService.getEnabledModelConfigList());
@Operation(summary = "获取所有启用的服务配置列表(前端积分显示用)")
public CommonResult<Map<String, List<AiServiceConfigService.ServiceConfigSimpleVO>>> getEnabledServiceConfigList() {
return success(aiServiceConfigService.getEnabledServiceConfigList());
}
}

View File

@@ -1,23 +1,23 @@
package cn.iocoder.yudao.module.tik.muye.aimodelconfig.dal;
package cn.iocoder.yudao.module.tik.muye.aiserviceconfig.dal;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* AI模型配置 DO
* AI第三方服务配置 DO
*
* @author 芋道源码
*/
@TableName("muye_ai_model_config")
@KeySequence("muye_ai_model_config_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@TableName("muye_ai_service_config")
@KeySequence("muye_ai_service_config_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AiModelConfigDO extends BaseDO {
public class AiServiceConfigDO extends BaseDO {
/**
* 主键
@@ -25,13 +25,13 @@ public class AiModelConfigDO extends BaseDO {
@TableId
private Long id;
/**
* 模型名称
* 服务名称
*/
private String modelName;
private String serviceName;
/**
* 模型标识/编码
* 服务标识
*/
private String modelCode;
private String serviceCode;
/**
* 所属平台
*/
@@ -45,7 +45,7 @@ public class AiModelConfigDO extends BaseDO {
*/
private Integer status;
/**
* 模型类型(image-图像 text-文本 video-视频 audio-音频)
* 服务类型(image-图像 text-文本 video-视频 audio-音频)
*/
private String modelType;
/**
@@ -57,5 +57,4 @@ public class AiModelConfigDO extends BaseDO {
*/
private String remark;
}

View File

@@ -0,0 +1,54 @@
package cn.iocoder.yudao.module.tik.muye.aiserviceconfig.mapper;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.dal.AiServiceConfigDO;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.vo.AiServiceConfigPageReqVO;
import org.apache.ibatis.annotations.Mapper;
/**
* AI第三方服务配置 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface AiServiceConfigMapper extends BaseMapperX<AiServiceConfigDO> {
default PageResult<AiServiceConfigDO> selectPage(AiServiceConfigPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<AiServiceConfigDO>()
.likeIfPresent(AiServiceConfigDO::getServiceName, reqVO.getServiceName())
.eqIfPresent(AiServiceConfigDO::getServiceCode, reqVO.getServiceCode())
.eqIfPresent(AiServiceConfigDO::getPlatform, reqVO.getPlatform())
.eqIfPresent(AiServiceConfigDO::getApiKey, reqVO.getApiKey())
.eqIfPresent(AiServiceConfigDO::getStatus, reqVO.getStatus())
.eqIfPresent(AiServiceConfigDO::getModelType, reqVO.getModelType())
.eqIfPresent(AiServiceConfigDO::getConsumePoints, reqVO.getConsumePoints())
.eqIfPresent(AiServiceConfigDO::getRemark, reqVO.getRemark())
.betweenIfPresent(AiServiceConfigDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(AiServiceConfigDO::getId));
}
/**
* 根据平台和服务标识查询配置
*/
default AiServiceConfigDO selectByPlatformAndServiceCode(String platform, String serviceCode) {
return selectOne(new LambdaQueryWrapperX<AiServiceConfigDO>()
.eq(AiServiceConfigDO::getPlatform, platform)
.eq(AiServiceConfigDO::getServiceCode, serviceCode)
.eq(AiServiceConfigDO::getStatus, 1));
}
/**
* 查询所有启用的服务配置
*/
default List<AiServiceConfigDO> selectEnabledList() {
return selectList(new LambdaQueryWrapperX<AiServiceConfigDO>()
.eq(AiServiceConfigDO::getStatus, 1)
.orderByAsc(AiServiceConfigDO::getPlatform, AiServiceConfigDO::getServiceCode));
}
}

View File

@@ -0,0 +1,81 @@
package cn.iocoder.yudao.module.tik.muye.aiserviceconfig.service;
import java.util.*;
import lombok.Data;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.dal.AiServiceConfigDO;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.vo.AiServiceConfigPageReqVO;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.vo.AiServiceConfigSaveReqVO;
import jakarta.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* AI第三方服务配置 Service 接口
*
* @author 芋道源码
*/
public interface AiServiceConfigService {
/**
* 创建AI服务配置
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createAiServiceConfig(@Valid AiServiceConfigSaveReqVO createReqVO);
/**
* 更新AI服务配置
*
* @param updateReqVO 更新信息
*/
void updateAiServiceConfig(@Valid AiServiceConfigSaveReqVO updateReqVO);
/**
* 删除AI服务配置
*
* @param id 编号
*/
void deleteAiServiceConfig(Long id);
/**
* 批量删除AI服务配置
*
* @param ids 编号
*/
void deleteAiServiceConfigListByIds(List<Long> ids);
/**
* 获得AI服务配置
*
* @param id 编号
* @return AI服务配置
*/
AiServiceConfigDO getAiServiceConfig(Long id);
/**
* 获得AI服务配置分页
*
* @param pageReqVO 分页查询
* @return AI服务配置分页
*/
PageResult<AiServiceConfigDO> getAiServiceConfigPage(AiServiceConfigPageReqVO pageReqVO);
/**
* 获取所有启用的服务配置列表(前端积分显示用)
*
* @return 服务配置列表(按平台分组)
*/
Map<String, List<ServiceConfigSimpleVO>> getEnabledServiceConfigList();
/**
* 启用的服务配置简单VO用于前端显示
*/
@Data
class ServiceConfigSimpleVO {
private String serviceCode;
private String serviceName;
private Integer consumePoints;
}
}

View File

@@ -0,0 +1,94 @@
package cn.iocoder.yudao.module.tik.muye.aiserviceconfig.service;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.dal.AiServiceConfigDO;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.mapper.AiServiceConfigMapper;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.vo.AiServiceConfigPageReqVO;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.vo.AiServiceConfigSaveReqVO;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
/**
* AI第三方服务配置 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class AiServiceConfigServiceImpl implements AiServiceConfigService {
@Resource
private AiServiceConfigMapper aiServiceConfigMapper;
@Override
public Long createAiServiceConfig(AiServiceConfigSaveReqVO createReqVO) {
// 插入
AiServiceConfigDO aiServiceConfig = BeanUtils.toBean(createReqVO, AiServiceConfigDO.class);
aiServiceConfigMapper.insert(aiServiceConfig);
// 返回
return aiServiceConfig.getId();
}
@Override
public void updateAiServiceConfig(AiServiceConfigSaveReqVO updateReqVO) {
// 校验存在
validateAiServiceConfigExists(updateReqVO.getId());
// 更新
AiServiceConfigDO updateObj = BeanUtils.toBean(updateReqVO, AiServiceConfigDO.class);
aiServiceConfigMapper.updateById(updateObj);
}
@Override
public void deleteAiServiceConfig(Long id) {
// 校验存在
validateAiServiceConfigExists(id);
// 删除
aiServiceConfigMapper.deleteById(id);
}
@Override
public void deleteAiServiceConfigListByIds(List<Long> ids) {
// 删除
aiServiceConfigMapper.deleteByIds(ids);
}
private void validateAiServiceConfigExists(Long id) {
if (aiServiceConfigMapper.selectById(id) == null) {
throw exception(new ErrorCode(1004, "AI服务配置不存在"));
}
}
@Override
public AiServiceConfigDO getAiServiceConfig(Long id) {
return aiServiceConfigMapper.selectById(id);
}
@Override
public PageResult<AiServiceConfigDO> getAiServiceConfigPage(AiServiceConfigPageReqVO pageReqVO) {
return aiServiceConfigMapper.selectPage(pageReqVO);
}
@Override
public Map<String, List<ServiceConfigSimpleVO>> getEnabledServiceConfigList() {
List<AiServiceConfigDO> configList = aiServiceConfigMapper.selectEnabledList();
Map<String, List<ServiceConfigSimpleVO>> result = new HashMap<>();
for (AiServiceConfigDO config : configList) {
ServiceConfigSimpleVO simpleVO = new ServiceConfigSimpleVO();
simpleVO.setServiceCode(config.getServiceCode());
simpleVO.setServiceName(config.getServiceName());
simpleVO.setConsumePoints(config.getConsumePoints());
result.computeIfAbsent(config.getPlatform(), k -> new ArrayList<>()).add(simpleVO);
}
return result;
}
}

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.tik.muye.aimodelconfig.vo;
package cn.iocoder.yudao.module.tik.muye.aiserviceconfig.vo;
import lombok.*;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -8,16 +8,16 @@ import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - AI模型配置分页 Request VO")
@Schema(description = "管理后台 - AI第三方服务配置分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
public class AiModelConfigPageReqVO extends SortablePageParam {
public class AiServiceConfigPageReqVO extends SortablePageParam {
@Schema(description = "模型名称", example = "李四")
private String modelName;
@Schema(description = "服务名称", example = "AI文案-Pro版")
private String serviceName;
@Schema(description = "模型标识/编码")
private String modelCode;
@Schema(description = "服务标识")
private String serviceCode;
@Schema(description = "所属平台")
private String platform;
@@ -25,20 +25,20 @@ public class AiModelConfigPageReqVO extends SortablePageParam {
@Schema(description = "API秘钥")
private String apiKey;
@Schema(description = "状态(0-禁用 1-启用)", example = "2")
@Schema(description = "状态(0-禁用 1-启用)", example = "1")
private Integer status;
@Schema(description = "模型类型(image-图像 text-文本 video-视频 audio-音频)", example = "2")
@Schema(description = "服务类型(image-图像 text-文本 video-视频 audio-音频)", example = "text")
private String modelType;
@Schema(description = "消耗积分")
private Integer consumePoints;
@Schema(description = "备注", example = "随便")
@Schema(description = "备注", example = "备注信息")
private String remark;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
}

View File

@@ -1,26 +1,26 @@
package cn.iocoder.yudao.module.tik.muye.aimodelconfig.vo;
package cn.iocoder.yudao.module.tik.muye.aiserviceconfig.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
import cn.idev.excel.annotation.*;
@Schema(description = "管理后台 - AI模型配置 Response VO")
@Schema(description = "管理后台 - AI第三方服务配置 Response VO")
@Data
@ExcelIgnoreUnannotated
public class AiModelConfigRespVO {
public class AiServiceConfigRespVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "29327")
@ExcelProperty("主键")
private Long id;
@Schema(description = "模型名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
@ExcelProperty("模型名称")
private String modelName;
@Schema(description = "服务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "AI文案-Pro版")
@ExcelProperty("服务名称")
private String serviceName;
@Schema(description = "模型标识/编码", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("模型标识/编码")
private String modelCode;
@Schema(description = "服务标识", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("服务标识")
private String serviceCode;
@Schema(description = "所属平台", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("所属平台")
@@ -30,19 +30,19 @@ public class AiModelConfigRespVO {
@ExcelProperty("API秘钥")
private String apiKey;
@Schema(description = "状态(0-禁用 1-启用)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@Schema(description = "状态(0-禁用 1-启用)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("状态(0-禁用 1-启用)")
private Integer status;
@Schema(description = "模型类型(image-图像 text-文本 video-视频 audio-音频)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("模型类型(image-图像 text-文本 video-视频 audio-音频)")
@Schema(description = "服务类型(image-图像 text-文本 video-视频 audio-音频)", requiredMode = Schema.RequiredMode.REQUIRED, example = "text")
@ExcelProperty("服务类型")
private String modelType;
@Schema(description = "消耗积分", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("消耗积分")
private Integer consumePoints;
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "随便")
@Schema(description = "备注", example = "备注信息")
@ExcelProperty("备注")
private String remark;

View File

@@ -1,23 +1,23 @@
package cn.iocoder.yudao.module.tik.muye.aimodelconfig.vo;
package cn.iocoder.yudao.module.tik.muye.aiserviceconfig.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import jakarta.validation.constraints.*;
@Schema(description = "管理后台 - AI模型配置新增/修改 Request VO")
@Schema(description = "管理后台 - AI第三方服务配置新增/修改 Request VO")
@Data
public class AiModelConfigSaveReqVO {
public class AiServiceConfigSaveReqVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "29327")
private Long id;
@Schema(description = "模型名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
@NotEmpty(message = "模型名称不能为空")
private String modelName;
@Schema(description = "服务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "AI文案-Pro版")
@NotEmpty(message = "服务名称不能为空")
private String serviceName;
@Schema(description = "模型标识/编码", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "模型标识/编码不能为空")
private String modelCode;
@Schema(description = "服务标识", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "服务标识不能为空")
private String serviceCode;
@Schema(description = "所属平台", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "所属平台不能为空")
@@ -26,19 +26,19 @@ public class AiModelConfigSaveReqVO {
@Schema(description = "API秘钥")
private String apiKey;
@Schema(description = "状态(0-禁用 1-启用)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@Schema(description = "状态(0-禁用 1-启用)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态不能为空")
private Integer status;
@Schema(description = "模型类型(image-图像 text-文本 video-视频 audio-音频)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotEmpty(message = "模型类型不能为空")
@Schema(description = "服务类型(image-图像 text-文本 video-视频 audio-音频)", requiredMode = Schema.RequiredMode.REQUIRED, example = "text")
@NotEmpty(message = "服务类型不能为空")
private String modelType;
@Schema(description = "消耗积分", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "消耗积分不能为空")
private Integer consumePoints;
@Schema(description = "备注", example = "随便")
@Schema(description = "备注", example = "备注信息")
private String remark;
}
}

View File

@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.tik.muye.points.service;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.dal.AiModelConfigDO;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.dal.AiServiceConfigDO;
/**
* 积分扣减公共服务
@@ -12,11 +12,11 @@ public interface PointsService {
/**
* 获取积分配置
*
* @param platform 平台标识dify/tikhub/voice/digital_human
* @param modelCode 模型标识
* @param platform 平台标识dify/tikhub/voice/digital_human
* @param serviceCode 服务标识
* @return 积分配置
*/
AiModelConfigDO getConfig(String platform, String modelCode);
AiServiceConfigDO getConfig(String platform, String serviceCode);
/**
* 预检积分(余额不足抛异常)

View File

@@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.tik.muye.points.service;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.dal.AiModelConfigDO;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.mapper.AiModelConfigMapper;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.dal.AiServiceConfigDO;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.mapper.AiServiceConfigMapper;
import cn.iocoder.yudao.module.tik.muye.memberuserprofile.dal.MemberUserProfileDO;
import cn.iocoder.yudao.module.tik.muye.memberuserprofile.mapper.MemberUserProfileMapper;
import cn.iocoder.yudao.module.tik.muye.pointrecord.dal.PointRecordDO;
@@ -37,7 +37,7 @@ public class PointsServiceImpl implements PointsService {
private static final String STATUS_CANCELED = "canceled";
@Resource
private AiModelConfigMapper aiModelConfigMapper;
private AiServiceConfigMapper aiServiceConfigMapper;
@Resource
private MemberUserProfileMapper memberUserProfileMapper;
@@ -49,8 +49,8 @@ public class PointsServiceImpl implements PointsService {
private MemberUserService memberUserService;
@Override
public AiModelConfigDO getConfig(String platform, String modelCode) {
AiModelConfigDO config = aiModelConfigMapper.selectByPlatformAndModelCode(platform, modelCode);
public AiServiceConfigDO getConfig(String platform, String serviceCode) {
AiServiceConfigDO config = aiServiceConfigMapper.selectByPlatformAndServiceCode(platform, serviceCode);
if (config == null) {
throw exception(POINTS_CONFIG_NOT_FOUND);
}

View File

@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.tik.tikhup.service;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.dal.AiModelConfigDO;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.dal.AiServiceConfigDO;
import cn.iocoder.yudao.module.tik.muye.points.service.PointsService;
import cn.iocoder.yudao.module.tik.tikhup.mapper.TikPromptMapper;
import cn.iocoder.yudao.module.tik.tikhup.mapper.TikTokenMapper;
@@ -94,7 +94,7 @@ public class TikHupServiceImpl implements TikHupService {
// 2. 获取当前用户ID并预检积分
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
String userId = loginUserId != null ? loginUserId.toString() : "1";
AiModelConfigDO config;
AiServiceConfigDO config;
try {
config = pointsService.getConfig(PLATFORM_TIKHUB, MODEL_CODE_CRAWLER);
pointsService.checkPoints(userId, config.getConsumePoints());

View File

@@ -17,7 +17,7 @@ import cn.iocoder.yudao.module.tik.file.dal.dataobject.TikUserFileDO;
import cn.iocoder.yudao.module.tik.file.dal.mysql.TikUserFileMapper;
import cn.iocoder.yudao.module.tik.file.service.TikOssInitService;
import cn.iocoder.yudao.module.tik.kling.dto.KlingLipSyncCreateResponse;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.dal.AiModelConfigDO;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.dal.AiServiceConfigDO;
import cn.iocoder.yudao.module.tik.muye.points.service.PointsService;
import cn.iocoder.yudao.module.tik.voice.dal.dataobject.TikDigitalHumanTaskDO;
import cn.iocoder.yudao.module.tik.voice.dal.dataobject.TikUserVoiceDO;
@@ -98,7 +98,7 @@ public class DigitalHumanTaskServiceImpl implements DigitalHumanTaskService {
// 2. 积分预检和预扣
String aiProvider = StrUtil.blankToDefault(reqVO.getAiProvider(), "302ai");
String modelCode = "kling".equalsIgnoreCase(aiProvider) ? MODEL_CODE_KLING : MODEL_CODE_LATENTSYNC;
AiModelConfigDO config = pointsService.getConfig(PLATFORM_DIGITAL_HUMAN, modelCode);
AiServiceConfigDO config = pointsService.getConfig(PLATFORM_DIGITAL_HUMAN, modelCode);
pointsService.checkPoints(userId.toString(), config.getConsumePoints());
Long pendingRecordId = pointsService.createPendingDeduct(
userId.toString(),

View File

@@ -25,7 +25,7 @@ import cn.iocoder.yudao.module.tik.voice.client.VoiceCloneProvider;
import cn.iocoder.yudao.module.tik.voice.client.VoiceCloneProviderFactory;
import cn.iocoder.yudao.module.tik.voice.client.dto.VoiceTtsRequest;
import cn.iocoder.yudao.module.tik.voice.client.dto.VoiceTtsResult;
import cn.iocoder.yudao.module.tik.muye.aimodelconfig.dal.AiModelConfigDO;
import cn.iocoder.yudao.module.tik.muye.aiserviceconfig.dal.AiServiceConfigDO;
import cn.iocoder.yudao.module.tik.muye.points.service.PointsService;
import cn.iocoder.yudao.module.tik.voice.dal.dataobject.TikUserVoiceDO;
import cn.iocoder.yudao.module.tik.voice.dal.mysql.TikUserVoiceMapper;
@@ -414,7 +414,7 @@ public class TikUserVoiceServiceImpl implements TikUserVoiceService {
}
// 获取积分配置并预检(缓存未命中,需要实际调用 TTS
AiModelConfigDO ttsConfig = pointsService.getConfig(PLATFORM_VOICE, MODEL_CODE_TTS);
AiServiceConfigDO ttsConfig = pointsService.getConfig(PLATFORM_VOICE, MODEL_CODE_TTS);
pointsService.checkPoints(userId.toString(), ttsConfig.getConsumePoints());
// 使用 Provider 接口进行 TTS 合成(支持前端选择供应商,不传则使用默认)

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.tik.muye.aimodelconfig.mapper.AiModelConfigMapper">
<mapper namespace="cn.iocoder.yudao.module.tik.muye.aiserviceconfig.mapper.AiServiceConfigMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。

View File

@@ -1,52 +0,0 @@
import request from '@/config/axios'
/** AI模型配置信息 */
export interface AiModelConfig {
id: number // 主键
modelName?: string // 模型名称
modelCode?: string // 模型标识/编码
platform?: string // 所属平台
apiKey?: string // API秘钥
status?: number // 状态(0-禁用 1-启用)
modelType?: string // 模型类型(image-图像 text-文本 video-视频 audio-音频)
consumePoints?: number // 消耗积分
remark?: string // 备注
}
// AI模型配置 API
export const AiModelConfigApi = {
// 查询AI模型配置分页
getAiModelConfigPage: async (params: any) => {
return await request.get({ url: `/muye/ai-model-config/page`, params })
},
// 查询AI模型配置详情
getAiModelConfig: async (id: number) => {
return await request.get({ url: `/muye/ai-model-config/get?id=` + id })
},
// 新增AI模型配置
createAiModelConfig: async (data: AiModelConfig) => {
return await request.post({ url: `/muye/ai-model-config/create`, data })
},
// 修改AI模型配置
updateAiModelConfig: async (data: AiModelConfig) => {
return await request.put({ url: `/muye/ai-model-config/update`, data })
},
// 删除AI模型配置
deleteAiModelConfig: async (id: number) => {
return await request.delete({ url: `/muye/ai-model-config/delete?id=` + id })
},
/** 批量删除AI模型配置 */
deleteAiModelConfigList: async (ids: number[]) => {
return await request.delete({ url: `/muye/ai-model-config/delete-list?ids=${ids.join(',')}` })
},
// 导出AI模型配置 Excel
exportAiModelConfig: async (params) => {
return await request.download({ url: `/muye/ai-model-config/export-excel`, params })
},
}

View File

@@ -0,0 +1,56 @@
import request from '@/config/axios'
/** AI第三方服务配置信息 */
export interface AiServiceConfig {
id: number // 主键
serviceName?: string // 服务名称
serviceCode?: string // 服务标识
platform?: string // 所属平台
apiKey?: string // API秘钥
status?: number // 状态(0-禁用 1-启用)
modelType?: string // 服务类型(image-图像 text-文本 video-视频 audio-音频)
consumePoints?: number // 消耗积分
remark?: string // 备注
}
// AI第三方服务配置 API
export const AiServiceConfigApi = {
// 查询AI服务配置分页
getAiServiceConfigPage: async (params: any) => {
return await request.get({ url: `/muye/ai-service-config/page`, params })
},
// 查询AI服务配置详情
getAiServiceConfig: async (id: number) => {
return await request.get({ url: `/muye/ai-service-config/get?id=` + id })
},
// 新增AI服务配置
createAiServiceConfig: async (data: AiServiceConfig) => {
return await request.post({ url: `/muye/ai-service-config/create`, data })
},
// 修改AI服务配置
updateAiServiceConfig: async (data: AiServiceConfig) => {
return await request.put({ url: `/muye/ai-service-config/update`, data })
},
// 删除AI服务配置
deleteAiServiceConfig: async (id: number) => {
return await request.delete({ url: `/muye/ai-service-config/delete?id=` + id })
},
/** 批量删除AI服务配置 */
deleteAiServiceConfigList: async (ids: number[]) => {
return await request.delete({ url: `/muye/ai-service-config/delete-list?ids=${ids.join(',')}` })
},
// 导出AI服务配置 Excel
exportAiServiceConfig: async (params) => {
return await request.download({ url: `/muye/ai-service-config/export-excel`, params })
},
}
// 兼容旧名称
export const AiModelConfigApi = AiServiceConfigApi
export type AiModelConfig = AiServiceConfig

View File

@@ -7,11 +7,11 @@
label-width="140px"
v-loading="formLoading"
>
<el-form-item label="模型名称" prop="modelName">
<el-input v-model="formData.modelName" placeholder="请输入模型名称" />
<el-form-item label="服务名称" prop="serviceName">
<el-input v-model="formData.serviceName" placeholder="请输入服务名称" />
</el-form-item>
<el-form-item label="模型标识" prop="modelCode">
<el-input v-model="formData.modelCode" placeholder="请输入模型标识/编码" />
<el-form-item label="服务标识" prop="serviceCode">
<el-input v-model="formData.serviceCode" placeholder="请输入服务标识" />
</el-form-item>
<el-form-item label="所属平台" prop="platform">
<el-input v-model="formData.platform" placeholder="请输入所属平台" />
@@ -21,17 +21,16 @@
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio value="1">启用</el-radio>
<el-radio value="0">禁用</el-radio>
<el-radio :value="1">启用</el-radio>
<el-radio :value="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="模型类型" prop="modelType">
<el-form-item label="服务类型" prop="modelType">
<el-radio-group v-model="formData.modelType">
<el-radio value="image">图像</el-radio>
<el-radio value="text">文本</el-radio>
<el-radio value="video">视频</el-radio>
<el-radio value="audio">音频</el-radio>
<el-radio value="third">第三方</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="消耗积分" prop="consumePoints">
@@ -48,10 +47,10 @@
</Dialog>
</template>
<script setup lang="ts">
import { AiModelConfigApi, AiModelConfig } from '@/api/muye/aimodelconfig'
import { AiServiceConfigApi, AiServiceConfig } from '@/api/muye/aiserviceconfig'
/** AI模型配置 表单 */
defineOptions({ name: 'AiModelConfigForm' })
/** AI第三方服务配置 表单 */
defineOptions({ name: 'AiServiceConfigForm' })
const { t } = useI18n() //
const message = useMessage() //
@@ -62,23 +61,22 @@ const formLoading = ref(false) // 表单的加载中1修改时的数据加
const formType = ref('') // create - update -
const formData = ref({
id: undefined,
modelName: undefined,
modelCode: undefined,
serviceName: undefined,
serviceCode: undefined,
platform: undefined,
apiKey: undefined,
status: undefined,
status: 1,
modelType: undefined,
consumePoints: undefined,
remark: undefined,
})
const formRules = reactive({
modelName: [{ required: true, message: '模型名称不能为空', trigger: 'blur' }],
modelCode: [{ required: true, message: '模型标识/编码不能为空', trigger: 'blur' }],
serviceName: [{ required: true, message: '服务名称不能为空', trigger: 'blur' }],
serviceCode: [{ required: true, message: '服务标识不能为空', trigger: 'blur' }],
platform: [{ required: true, message: '所属平台不能为空', trigger: 'blur' }],
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }],
modelType: [{ required: true, message: '模型类型不能为空', trigger: 'change' }],
modelType: [{ required: true, message: '服务类型不能为空', trigger: 'change' }],
consumePoints: [{ required: true, message: '消耗积分不能为空', trigger: 'blur' }],
remark: [{ required: true, message: '备注不能为空', trigger: 'blur' }],
})
const formRef = ref() // Ref
@@ -92,7 +90,7 @@ const open = async (type: string, id?: number) => {
if (id) {
formLoading.value = true
try {
formData.value = await AiModelConfigApi.getAiModelConfig(id)
formData.value = await AiServiceConfigApi.getAiServiceConfig(id)
} finally {
formLoading.value = false
}
@@ -108,12 +106,12 @@ const submitForm = async () => {
//
formLoading.value = true
try {
const data = formData.value as unknown as AiModelConfig
const data = formData.value as unknown as AiServiceConfig
if (formType.value === 'create') {
await AiModelConfigApi.createAiModelConfig(data)
await AiServiceConfigApi.createAiServiceConfig(data)
message.success(t('common.createSuccess'))
} else {
await AiModelConfigApi.updateAiModelConfig(data)
await AiServiceConfigApi.updateAiServiceConfig(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
@@ -128,15 +126,15 @@ const submitForm = async () => {
const resetForm = () => {
formData.value = {
id: undefined,
modelName: undefined,
modelCode: undefined,
serviceName: undefined,
serviceCode: undefined,
platform: undefined,
apiKey: undefined,
status: undefined,
status: 1,
modelType: undefined,
consumePoints: undefined,
remark: undefined,
}
formRef.value?.resetFields()
}
</script>
</script>

View File

@@ -8,19 +8,19 @@
:inline="true"
label-width="68px"
>
<el-form-item label="模型名称" prop="modelName">
<el-form-item label="服务名称" prop="serviceName">
<el-input
v-model="queryParams.modelName"
placeholder="请输入模型名称"
v-model="queryParams.serviceName"
placeholder="请输入服务名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="模型标识" prop="modelCode">
<el-form-item label="服务标识" prop="serviceCode">
<el-input
v-model="queryParams.modelCode"
placeholder="请输入模型标识"
v-model="queryParams.serviceCode"
placeholder="请输入服务标识"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
@@ -50,10 +50,10 @@
<el-option label="启用" value="1" />
</el-select>
</el-form-item>
<el-form-item label="模型类型" prop="modelType">
<el-form-item label="服务类型" prop="modelType">
<el-select
v-model="queryParams.modelType"
placeholder="请选择模型类型"
placeholder="请选择服务类型"
clearable
class="!w-240px"
>
@@ -70,7 +70,7 @@
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['muye:ai-model-config:create']"
v-hasPermi="['muye:ai-service-config:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
@@ -79,7 +79,7 @@
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['muye:ai-model-config:export']"
v-hasPermi="['muye:ai-service-config:export']"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
@@ -88,7 +88,7 @@
plain
:disabled="isEmpty(checkedIds)"
@click="handleDeleteBatch"
v-hasPermi="['muye:ai-model-config:delete']"
v-hasPermi="['muye:ai-service-config:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
@@ -107,8 +107,8 @@
@selection-change="handleRowCheckboxChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="模型名称" align="center" width="150" prop="modelName" />
<el-table-column label="模型标识" align="center" prop="modelCode" />
<el-table-column label="服务名称" align="center" width="150" prop="serviceName" />
<el-table-column label="服务标识" align="center" prop="serviceCode" />
<el-table-column label="所属平台" align="center" prop="platform" />
<el-table-column label="API秘钥" align="center" prop="apiKey" />
<el-table-column label="状态" align="center" prop="status" >
@@ -118,7 +118,7 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="模型类型" align="center" prop="modelType" />
<el-table-column label="服务类型" align="center" prop="modelType" />
<el-table-column label="消耗积分" align="center" prop="consumePoints" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" min-width="120px">
@@ -127,7 +127,7 @@
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['muye:ai-model-config:update']"
v-hasPermi="['muye:ai-service-config:update']"
>
编辑
</el-button>
@@ -135,7 +135,7 @@
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['muye:ai-model-config:delete']"
v-hasPermi="['muye:ai-service-config:delete']"
>
删除
</el-button>
@@ -152,29 +152,29 @@
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<AiModelConfigForm ref="formRef" @success="getList" />
<AiServiceConfigForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts">
import { isEmpty } from '@/utils/is'
import download from '@/utils/download'
import { AiModelConfigApi, AiModelConfig } from '@/api/muye/aimodelconfig'
import AiModelConfigForm from './AiModelConfigForm.vue'
import { AiServiceConfigApi, AiServiceConfig } from '@/api/muye/aiserviceconfig'
import AiServiceConfigForm from './AiServiceConfigForm.vue'
/** AI模型配置 列表 */
defineOptions({ name: 'AiModelConfig' })
/** AI第三方服务配置 列表 */
defineOptions({ name: 'AiServiceConfig' })
const message = useMessage() //
const { t } = useI18n() //
const loading = ref(true) //
const list = ref<AiModelConfig[]>([]) //
const list = ref<AiServiceConfig[]>([]) //
const total = ref(0) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
modelName: undefined,
modelCode: undefined,
serviceName: undefined,
serviceCode: undefined,
platform: undefined,
apiKey: undefined,
status: undefined,
@@ -187,7 +187,7 @@ const exportLoading = ref(false) // 导出的加载中
const getList = async () => {
loading.value = true
try {
const data = await AiModelConfigApi.getAiModelConfigPage(queryParams)
const data = await AiServiceConfigApi.getAiServiceConfigPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
@@ -219,19 +219,19 @@ const handleDelete = async (id: number) => {
//
await message.delConfirm()
//
await AiModelConfigApi.deleteAiModelConfig(id)
await AiServiceConfigApi.deleteAiServiceConfig(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 批量删除AI模型配置 */
/** 批量删除AI服务配置 */
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
await AiModelConfigApi.deleteAiModelConfigList(checkedIds.value);
await AiServiceConfigApi.deleteAiServiceConfigList(checkedIds.value);
checkedIds.value = [];
message.success(t('common.delSuccess'))
await getList();
@@ -239,7 +239,7 @@ const handleDeleteBatch = async () => {
}
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (records: AiModelConfig[]) => {
const handleRowCheckboxChange = (records: AiServiceConfig[]) => {
checkedIds.value = records.map((item) => item.id!);
}
@@ -250,8 +250,8 @@ const handleExport = async () => {
await message.exportConfirm()
//
exportLoading.value = true
const data = await AiModelConfigApi.exportAiModelConfig(queryParams)
download.excel(data, 'AI模型配置.xls')
const data = await AiServiceConfigApi.exportAiServiceConfig(queryParams)
download.excel(data, 'AI服务配置.xls')
} catch {
} finally {
exportLoading.value = false
@@ -262,4 +262,4 @@ const handleExport = async () => {
onMounted(() => {
getList()
})
</script>
</script>

View File

@@ -92,9 +92,9 @@
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="账户总积分" align="center" prop="totalPoints" />
<el-table-column label="账户消耗积分" align="center" prop="usedPoints" />
<el-table-column label="账户剩余积分" align="center" prop="remainingPoints" />
<el-table-column label="总积分" align="center" prop="totalPoints" />
<el-table-column label="消耗积分" align="center" prop="usedPoints" />
<el-table-column label="剩余积分" align="center" prop="remainingPoints" />
<el-table-column label="云空间总容量" align="center" prop="totalStorage" />
<el-table-column label="云空间已用容量" align="center" prop="usedStorage" />
<el-table-column label="云空间剩余容量" align="center" prop="remainingStorage" />