From c7334ab7d97c96fc555c1fe918cf9061badc1faf Mon Sep 17 00:00:00 2001 From: old burden Date: Mon, 20 Apr 2026 16:28:27 +0800 Subject: [PATCH 1/8] =?UTF-8?q?fix=EF=BC=9A=E7=B3=BB=E7=BB=9F=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=A1=A8=E5=AE=9E=E7=8E=B0=E9=80=9A=E8=BF=87=E9=83=A8?= =?UTF-8?q?=E9=97=A8=E5=85=B3=E8=81=94ai=5Fuser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/controller/ai/AiOrderController.java | 2 +- .../ai/service/impl/AiOrderServiceImpl.java | 18 ++++++++++++++++++ .../ai/service/impl/AiUserServiceImpl.java | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/ai/AiOrderController.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/ai/AiOrderController.java index eeea47d..bcb817e 100644 --- a/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/ai/AiOrderController.java +++ b/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/ai/AiOrderController.java @@ -24,7 +24,7 @@ import java.util.List; * @date 2025-11-13 */ @RestController -@RequestMapping("/ai/order") +@RequestMapping("/ai/video/order") public class AiOrderController extends BaseController { @Autowired diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiOrderServiceImpl.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiOrderServiceImpl.java index d06659b..46a12d7 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiOrderServiceImpl.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiOrderServiceImpl.java @@ -59,6 +59,9 @@ public class AiOrderServiceImpl implements IAiOrderService { @Autowired private IByteDeptApiKeyService byteDeptApiKeyService; + @Autowired + private IAiVideoReportDataService aiVideoReportDataService; + // 流水表:任务成功时回补 private static final String TASK_SUCCESS_BACK_FILL_REMARK = "order.number.generation.successbackfill"; @@ -244,6 +247,7 @@ public class AiOrderServiceImpl implements IAiOrderService { public void orderSuccess(AiOrder aiOrder) { aiOrder.setStatus(1); aiOrderMapper.updateById(aiOrder); + syncVideoReportData(aiOrder); AiStatistics aiStatistics = new AiStatistics(); aiStatistics.setSource(aiOrder.getSource()); aiStatistics.setGenerateCount(1L); @@ -349,4 +353,18 @@ public class AiOrderServiceImpl implements IAiOrderService { // BalanceChangerConstants.QUICK_VIDEO_GENERATION, TASK_SUCCESS_BALANCE_REMARK); return AjaxResult.success("callback success"); } + + /** + * 任务成功后按“提交时间”写入团队消耗统计来源表。 + * + * @param aiOrder 已成功订单 + */ + private void syncVideoReportData(AiOrder aiOrder) { + if (aiOrder == null || aiOrder.getCreateTime() == null || aiOrder.getDeptId() == null || aiOrder.getUserId() == null) { + return; + } + BigDecimal score = aiOrder.getAmount() != null ? aiOrder.getAmount() : BigDecimal.ZERO; + Long useTokens = aiOrder.getTotalUsage() != null ? aiOrder.getTotalUsage().longValue() : 0L; + aiVideoReportDataService.syncVideoConsumeIncrement(aiOrder.getCreateTime(), aiOrder.getDeptId(), aiOrder.getUserId(), score, useTokens); + } } diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiUserServiceImpl.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiUserServiceImpl.java index 432c927..1b12ca5 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiUserServiceImpl.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiUserServiceImpl.java @@ -303,7 +303,7 @@ public class AiUserServiceImpl implements IAiUserService { private AiUser getUserByInvitationCode(String invitationCode) { LambdaQueryWrapper query = Wrappers.lambdaQuery(); query.eq(AiUser::getInvitationCode, invitationCode); - query.eq(AiUser::getDelFlag, 0); + query.eq(AiUser::getDelFlag, "0"); return aiUserMapper.selectOne(query); } From bfa30bb543271ca437c181b9d0d3e102512b190a Mon Sep 17 00:00:00 2001 From: old burden Date: Mon, 20 Apr 2026 16:33:43 +0800 Subject: [PATCH 2/8] =?UTF-8?q?fix=EF=BC=9A=E6=96=B0=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin-ui/src/api/ai/config.js | 0 admin-ui/src/api/ai/data.js | 0 admin-ui/src/api/ai/order.js | 29 +- admin-ui/src/api/ai/record.js | 0 admin-ui/src/api/subteam.js | 0 admin-ui/src/views/ai/config/index.vue | 270 +++++++ admin-ui/src/views/ai/data/index.vue | 0 admin-ui/src/views/ai/order/index.vue | 737 +++++------------- admin-ui/src/views/ai/record/index.vue | 312 ++++++++ .../src/views/subteam/chargeOrder/index.vue | 0 .../src/views/subteam/consumeStat/index.vue | 0 .../src/views/subteam/groupBalance/index.vue | 0 admin-ui/src/views/subteam/overview/index.vue | 0 admin-ui/src/views/subteam/user/index.vue | 0 .../src/views/subteam/userBalance/index.vue | 0 .../src/views/subteam/videoOrder/index.vue | 0 .../AiChargeRefundOrderController.java | 104 +++ .../controller/AiDeptArkConfigController.java | 104 +++ .../AiGroupBalanceChangeRecordController.java | 104 +++ .../AiVideoReportDataController.java | 110 +++ .../com/ruoyi/api/PortalVideoController.java | 4 +- .../ruoyi/config/PortalVideoProperties.java | 171 ++-- .../subteam/SubteamChargeOrderController.java | 0 .../subteam/SubteamConsumeStatController.java | 0 .../SubteamGroupBalanceController.java | 0 .../subteam/SubteamOverviewController.java | 0 .../subteam/SubteamUserBalanceController.java | 0 .../subteam/SubteamUserController.java | 118 +++ .../subteam/SubteamVideoOrderController.java | 45 ++ .../domain/subteam/SubteamOverviewVO.java | 30 + .../domain/subteam/SubteamVideoMetrics.java | 18 + .../subteam/ISubteamDataQueryService.java | 21 + .../subteam/ISubteamOverviewService.java | 8 + .../service/subteam/ISubteamScopeService.java | 24 + .../impl/SubteamDataQueryServiceImpl.java | 78 ++ .../impl/SubteamOverviewServiceImpl.java | 72 ++ .../subteam/impl/SubteamScopeServiceImpl.java | 0 .../mapper/ai/AiChargeRefundOrderMapper.xml | 113 +++ .../mapper/ai/AiDeptArkConfigMapper.xml | 87 +++ .../ai/AiGroupBalanceChangeRecordMapper.xml | 88 +++ .../mapper/ai/AiVideoReportDataMapper.xml | 161 ++++ 41 files changed, 2169 insertions(+), 639 deletions(-) create mode 100644 admin-ui/src/api/ai/config.js create mode 100644 admin-ui/src/api/ai/data.js create mode 100644 admin-ui/src/api/ai/record.js create mode 100644 admin-ui/src/api/subteam.js create mode 100644 admin-ui/src/views/ai/config/index.vue create mode 100644 admin-ui/src/views/ai/data/index.vue create mode 100644 admin-ui/src/views/ai/record/index.vue create mode 100644 admin-ui/src/views/subteam/chargeOrder/index.vue create mode 100644 admin-ui/src/views/subteam/consumeStat/index.vue create mode 100644 admin-ui/src/views/subteam/groupBalance/index.vue create mode 100644 admin-ui/src/views/subteam/overview/index.vue create mode 100644 admin-ui/src/views/subteam/user/index.vue create mode 100644 admin-ui/src/views/subteam/userBalance/index.vue create mode 100644 admin-ui/src/views/subteam/videoOrder/index.vue create mode 100644 web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiChargeRefundOrderController.java create mode 100644 web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiDeptArkConfigController.java create mode 100644 web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiGroupBalanceChangeRecordController.java create mode 100644 web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiVideoReportDataController.java create mode 100644 web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamChargeOrderController.java create mode 100644 web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamConsumeStatController.java create mode 100644 web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamGroupBalanceController.java create mode 100644 web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamOverviewController.java create mode 100644 web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamUserBalanceController.java create mode 100644 web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamUserController.java create mode 100644 web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamVideoOrderController.java create mode 100644 web-api/ruoyi-system/src/main/java/com/ruoyi/system/domain/subteam/SubteamOverviewVO.java create mode 100644 web-api/ruoyi-system/src/main/java/com/ruoyi/system/domain/subteam/SubteamVideoMetrics.java create mode 100644 web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/ISubteamDataQueryService.java create mode 100644 web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/ISubteamOverviewService.java create mode 100644 web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/ISubteamScopeService.java create mode 100644 web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/impl/SubteamDataQueryServiceImpl.java create mode 100644 web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/impl/SubteamOverviewServiceImpl.java create mode 100644 web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/impl/SubteamScopeServiceImpl.java create mode 100644 web-api/ruoyi-system/src/main/resources/mapper/ai/AiChargeRefundOrderMapper.xml create mode 100644 web-api/ruoyi-system/src/main/resources/mapper/ai/AiDeptArkConfigMapper.xml create mode 100644 web-api/ruoyi-system/src/main/resources/mapper/ai/AiGroupBalanceChangeRecordMapper.xml create mode 100644 web-api/ruoyi-system/src/main/resources/mapper/ai/AiVideoReportDataMapper.xml diff --git a/admin-ui/src/api/ai/config.js b/admin-ui/src/api/ai/config.js new file mode 100644 index 0000000..e69de29 diff --git a/admin-ui/src/api/ai/data.js b/admin-ui/src/api/ai/data.js new file mode 100644 index 0000000..e69de29 diff --git a/admin-ui/src/api/ai/order.js b/admin-ui/src/api/ai/order.js index d54a66b..c964878 100644 --- a/admin-ui/src/api/ai/order.js +++ b/admin-ui/src/api/ai/order.js @@ -1,6 +1,6 @@ import request from '@/utils/request' -// 查询订单管理列表 +// 查询团队(部门)充值退款订单列表 export function listOrder(query) { return request({ url: '/ai/order/list', @@ -9,7 +9,7 @@ export function listOrder(query) { }) } -// 查询订单管理详细 +// 查询团队(部门)充值退款订单详细 export function getOrder(id) { return request({ url: '/ai/order/' + id, @@ -17,7 +17,7 @@ export function getOrder(id) { }) } -// 新增订单管理 +// 新增团队(部门)充值退款订单 export function addOrder(data) { return request({ url: '/ai/order', @@ -26,7 +26,7 @@ export function addOrder(data) { }) } -// 修改订单管理 +// 修改团队(部门)充值退款订单 export function updateOrder(data) { return request({ url: '/ai/order', @@ -35,29 +35,10 @@ export function updateOrder(data) { }) } -export function changeIsTop(id, isTop) { - const data = { - id, - isTop - } - return request({ - url: '/ai/order', - method: 'put', - data: data - }) -} - -// 删除订单管理 +// 删除团队(部门)充值退款订单 export function delOrder(id) { return request({ url: '/ai/order/' + id, method: 'delete' }) } - -export function downloadVideo(id) { - return request({ - url: '/api/ai/' + id, - method: 'get' - }) -} diff --git a/admin-ui/src/api/ai/record.js b/admin-ui/src/api/ai/record.js new file mode 100644 index 0000000..e69de29 diff --git a/admin-ui/src/api/subteam.js b/admin-ui/src/api/subteam.js new file mode 100644 index 0000000..e69de29 diff --git a/admin-ui/src/views/ai/config/index.vue b/admin-ui/src/views/ai/config/index.vue new file mode 100644 index 0000000..dc0830b --- /dev/null +++ b/admin-ui/src/views/ai/config/index.vue @@ -0,0 +1,270 @@ + + + diff --git a/admin-ui/src/views/ai/data/index.vue b/admin-ui/src/views/ai/data/index.vue new file mode 100644 index 0000000..e69de29 diff --git a/admin-ui/src/views/ai/order/index.vue b/admin-ui/src/views/ai/order/index.vue index 33c7281..5dd6c22 100644 --- a/admin-ui/src/views/ai/order/index.vue +++ b/admin-ui/src/views/ai/order/index.vue @@ -1,79 +1,59 @@ - - diff --git a/admin-ui/src/views/ai/record/index.vue b/admin-ui/src/views/ai/record/index.vue new file mode 100644 index 0000000..9027035 --- /dev/null +++ b/admin-ui/src/views/ai/record/index.vue @@ -0,0 +1,312 @@ + + + diff --git a/admin-ui/src/views/subteam/chargeOrder/index.vue b/admin-ui/src/views/subteam/chargeOrder/index.vue new file mode 100644 index 0000000..e69de29 diff --git a/admin-ui/src/views/subteam/consumeStat/index.vue b/admin-ui/src/views/subteam/consumeStat/index.vue new file mode 100644 index 0000000..e69de29 diff --git a/admin-ui/src/views/subteam/groupBalance/index.vue b/admin-ui/src/views/subteam/groupBalance/index.vue new file mode 100644 index 0000000..e69de29 diff --git a/admin-ui/src/views/subteam/overview/index.vue b/admin-ui/src/views/subteam/overview/index.vue new file mode 100644 index 0000000..e69de29 diff --git a/admin-ui/src/views/subteam/user/index.vue b/admin-ui/src/views/subteam/user/index.vue new file mode 100644 index 0000000..e69de29 diff --git a/admin-ui/src/views/subteam/userBalance/index.vue b/admin-ui/src/views/subteam/userBalance/index.vue new file mode 100644 index 0000000..e69de29 diff --git a/admin-ui/src/views/subteam/videoOrder/index.vue b/admin-ui/src/views/subteam/videoOrder/index.vue new file mode 100644 index 0000000..e69de29 diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiChargeRefundOrderController.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiChargeRefundOrderController.java new file mode 100644 index 0000000..422d40e --- /dev/null +++ b/web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiChargeRefundOrderController.java @@ -0,0 +1,104 @@ +package com.ruoyi.ai.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.ai.domain.AiChargeRefundOrder; +import com.ruoyi.ai.service.IAiChargeRefundOrderService; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * 团队(部门)充值退款订单Controller + * + * @author shi + * @date 2026-04-17 + */ +@RestController +@RequestMapping("/ai/order") +public class AiChargeRefundOrderController extends BaseController +{ + @Autowired + private IAiChargeRefundOrderService aiChargeRefundOrderService; + + /** + * 查询团队(部门)充值退款订单列表 + */ + @PreAuthorize("@ss.hasPermi('ai:order:list')") + @GetMapping("/list") + public TableDataInfo list(AiChargeRefundOrder aiChargeRefundOrder) + { + startPage(); + List list = aiChargeRefundOrderService.selectAiChargeRefundOrderList(aiChargeRefundOrder); + return getDataTable(list); + } + + /** + * 导出团队(部门)充值退款订单列表 + */ + @PreAuthorize("@ss.hasPermi('ai:order:export')") + @Log(title = "团队(部门)充值退款订单", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, AiChargeRefundOrder aiChargeRefundOrder) + { + List list = aiChargeRefundOrderService.selectAiChargeRefundOrderList(aiChargeRefundOrder); + ExcelUtil util = new ExcelUtil(AiChargeRefundOrder.class); + util.exportExcel(response, list, "团队(部门)充值退款订单数据"); + } + + /** + * 获取团队(部门)充值退款订单详细信息 + */ + @PreAuthorize("@ss.hasPermi('ai:order:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(aiChargeRefundOrderService.selectAiChargeRefundOrderById(id)); + } + + /** + * 新增团队(部门)充值退款订单 + */ + @PreAuthorize("@ss.hasPermi('ai:order:add')") + @Log(title = "团队(部门)充值退款订单", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody AiChargeRefundOrder aiChargeRefundOrder) + { + return toAjax(aiChargeRefundOrderService.insertAiChargeRefundOrder(aiChargeRefundOrder)); + } + + /** + * 修改团队(部门)充值退款订单 + */ + @PreAuthorize("@ss.hasPermi('ai:order:edit')") + @Log(title = "团队(部门)充值退款订单", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody AiChargeRefundOrder aiChargeRefundOrder) + { + return toAjax(aiChargeRefundOrderService.updateAiChargeRefundOrder(aiChargeRefundOrder)); + } + + /** + * 删除团队(部门)充值退款订单 + */ + @PreAuthorize("@ss.hasPermi('ai:order:remove')") + @Log(title = "团队(部门)充值退款订单", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(aiChargeRefundOrderService.deleteAiChargeRefundOrderByIds(ids)); + } +} diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiDeptArkConfigController.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiDeptArkConfigController.java new file mode 100644 index 0000000..aef8ced --- /dev/null +++ b/web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiDeptArkConfigController.java @@ -0,0 +1,104 @@ +package com.ruoyi.ai.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.ai.domain.AiDeptArkConfig; +import com.ruoyi.ai.service.IAiDeptArkConfigService; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * 团队(部门)对应火山引擎配置Controller + * + * @author shi + * @date 2026-04-17 + */ +@RestController +@RequestMapping("/ai/config") +public class AiDeptArkConfigController extends BaseController +{ + @Autowired + private IAiDeptArkConfigService aiDeptArkConfigService; + + /** + * 查询团队(部门)对应火山引擎配置列表 + */ + @PreAuthorize("@ss.hasPermi('ai:config:list')") + @GetMapping("/list") + public TableDataInfo list(AiDeptArkConfig aiDeptArkConfig) + { + startPage(); + List list = aiDeptArkConfigService.selectAiDeptArkConfigList(aiDeptArkConfig); + return getDataTable(list); + } + + /** + * 导出团队(部门)对应火山引擎配置列表 + */ + @PreAuthorize("@ss.hasPermi('ai:config:export')") + @Log(title = "团队(部门)对应火山引擎配置", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, AiDeptArkConfig aiDeptArkConfig) + { + List list = aiDeptArkConfigService.selectAiDeptArkConfigList(aiDeptArkConfig); + ExcelUtil util = new ExcelUtil(AiDeptArkConfig.class); + util.exportExcel(response, list, "团队(部门)对应火山引擎配置数据"); + } + + /** + * 获取团队(部门)对应火山引擎配置详细信息 + */ + @PreAuthorize("@ss.hasPermi('ai:config:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") String id) + { + return success(aiDeptArkConfigService.selectAiDeptArkConfigById(id)); + } + + /** + * 新增团队(部门)对应火山引擎配置 + */ + @PreAuthorize("@ss.hasPermi('ai:config:add')") + @Log(title = "团队(部门)对应火山引擎配置", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody AiDeptArkConfig aiDeptArkConfig) + { + return toAjax(aiDeptArkConfigService.insertAiDeptArkConfig(aiDeptArkConfig)); + } + + /** + * 修改团队(部门)对应火山引擎配置 + */ + @PreAuthorize("@ss.hasPermi('ai:config:edit')") + @Log(title = "团队(部门)对应火山引擎配置", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody AiDeptArkConfig aiDeptArkConfig) + { + return toAjax(aiDeptArkConfigService.updateAiDeptArkConfig(aiDeptArkConfig)); + } + + /** + * 删除团队(部门)对应火山引擎配置 + */ + @PreAuthorize("@ss.hasPermi('ai:config:remove')") + @Log(title = "团队(部门)对应火山引擎配置", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable String[] ids) + { + return toAjax(aiDeptArkConfigService.deleteAiDeptArkConfigByIds(ids)); + } +} diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiGroupBalanceChangeRecordController.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiGroupBalanceChangeRecordController.java new file mode 100644 index 0000000..dfc1337 --- /dev/null +++ b/web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiGroupBalanceChangeRecordController.java @@ -0,0 +1,104 @@ +package com.ruoyi.ai.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.ai.domain.AiGroupBalanceChangeRecord; +import com.ruoyi.ai.service.IAiGroupBalanceChangeRecordService; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * 团队(部门)余额变动Controller + * + * @author shi + * @date 2026-04-17 + */ +@RestController +@RequestMapping("/ai/record") +public class AiGroupBalanceChangeRecordController extends BaseController +{ + @Autowired + private IAiGroupBalanceChangeRecordService aiGroupBalanceChangeRecordService; + + /** + * 查询团队(部门)余额变动列表 + */ + @PreAuthorize("@ss.hasPermi('ai:record:list')") + @GetMapping("/list") + public TableDataInfo list(AiGroupBalanceChangeRecord aiGroupBalanceChangeRecord) + { + startPage(); + List list = aiGroupBalanceChangeRecordService.selectAiGroupBalanceChangeRecordList(aiGroupBalanceChangeRecord); + return getDataTable(list); + } + + /** + * 导出团队(部门)余额变动列表 + */ + @PreAuthorize("@ss.hasPermi('ai:record:export')") + @Log(title = "团队(部门)余额变动", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, AiGroupBalanceChangeRecord aiGroupBalanceChangeRecord) + { + List list = aiGroupBalanceChangeRecordService.selectAiGroupBalanceChangeRecordList(aiGroupBalanceChangeRecord); + ExcelUtil util = new ExcelUtil(AiGroupBalanceChangeRecord.class); + util.exportExcel(response, list, "团队(部门)余额变动数据"); + } + + /** + * 获取团队(部门)余额变动详细信息 + */ + @PreAuthorize("@ss.hasPermi('ai:record:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") String id) + { + return success(aiGroupBalanceChangeRecordService.selectAiGroupBalanceChangeRecordById(id)); + } + + /** + * 新增团队(部门)余额变动 + */ + @PreAuthorize("@ss.hasPermi('ai:record:add')") + @Log(title = "团队(部门)余额变动", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody AiGroupBalanceChangeRecord aiGroupBalanceChangeRecord) + { + return toAjax(aiGroupBalanceChangeRecordService.insertAiGroupBalanceChangeRecord(aiGroupBalanceChangeRecord)); + } + + /** + * 修改团队(部门)余额变动 + */ + @PreAuthorize("@ss.hasPermi('ai:record:edit')") + @Log(title = "团队(部门)余额变动", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody AiGroupBalanceChangeRecord aiGroupBalanceChangeRecord) + { + return toAjax(aiGroupBalanceChangeRecordService.updateAiGroupBalanceChangeRecord(aiGroupBalanceChangeRecord)); + } + + /** + * 删除团队(部门)余额变动 + */ + @PreAuthorize("@ss.hasPermi('ai:record:remove')") + @Log(title = "团队(部门)余额变动", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable String[] ids) + { + return toAjax(aiGroupBalanceChangeRecordService.deleteAiGroupBalanceChangeRecordByIds(ids)); + } +} diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiVideoReportDataController.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiVideoReportDataController.java new file mode 100644 index 0000000..e3a4c7b --- /dev/null +++ b/web-api/ruoyi-admin/src/main/java/com/ruoyi/ai/controller/AiVideoReportDataController.java @@ -0,0 +1,110 @@ +package com.ruoyi.ai.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.ai.domain.AiVideoReportData; +import com.ruoyi.ai.service.IAiVideoReportDataService; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.StringUtils; + +/** + * AI视频生成统计数据,作为其他统计报的数据源Controller + * + * @author shi + * @date 2026-04-17 + */ +@RestController +@RequestMapping("/ai/data") +public class AiVideoReportDataController extends BaseController +{ + @Autowired + private IAiVideoReportDataService aiVideoReportDataService; + + /** + * 查询AI视频生成统计数据,作为其他统计报的数据源列表 + */ + @PreAuthorize("@ss.hasPermi('ai:data:list')") + @GetMapping("/list") + public TableDataInfo list(AiVideoReportData aiVideoReportData) + { + if (StringUtils.isEmpty(aiVideoReportData.getStatDate()) || StringUtils.isEmpty(aiVideoReportData.getDeptName())) + { + return getDataTable(java.util.Collections.emptyList()); + } + startPage(); + List list = aiVideoReportDataService.selectTeamDailyConsumeList( + aiVideoReportData.getStatDate(), aiVideoReportData.getDeptName()); + return getDataTable(list); + } + + /** + * 导出AI视频生成统计数据,作为其他统计报的数据源列表 + */ + @PreAuthorize("@ss.hasPermi('ai:data:export')") + @Log(title = "AI视频生成统计数据,作为其他统计报的数据源", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, AiVideoReportData aiVideoReportData) + { + List list = aiVideoReportDataService.selectAiVideoReportDataList(aiVideoReportData); + ExcelUtil util = new ExcelUtil(AiVideoReportData.class); + util.exportExcel(response, list, "AI视频生成统计数据,作为其他统计报的数据源数据"); + } + + /** + * 获取AI视频生成统计数据,作为其他统计报的数据源详细信息 + */ + @PreAuthorize("@ss.hasPermi('ai:data:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") String id) + { + return success(aiVideoReportDataService.selectAiVideoReportDataById(id)); + } + + /** + * 新增AI视频生成统计数据,作为其他统计报的数据源 + */ + @PreAuthorize("@ss.hasPermi('ai:data:add')") + @Log(title = "AI视频生成统计数据,作为其他统计报的数据源", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody AiVideoReportData aiVideoReportData) + { + return toAjax(aiVideoReportDataService.insertAiVideoReportData(aiVideoReportData)); + } + + /** + * 修改AI视频生成统计数据,作为其他统计报的数据源 + */ + @PreAuthorize("@ss.hasPermi('ai:data:edit')") + @Log(title = "AI视频生成统计数据,作为其他统计报的数据源", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody AiVideoReportData aiVideoReportData) + { + return toAjax(aiVideoReportDataService.updateAiVideoReportData(aiVideoReportData)); + } + + /** + * 删除AI视频生成统计数据,作为其他统计报的数据源 + */ + @PreAuthorize("@ss.hasPermi('ai:data:remove')") + @Log(title = "AI视频生成统计数据,作为其他统计报的数据源", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable String[] ids) + { + return toAjax(aiVideoReportDataService.deleteAiVideoReportDataByIds(ids)); + } +} diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/PortalVideoController.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/PortalVideoController.java index 42ed67a..052ae25 100644 --- a/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/PortalVideoController.java +++ b/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/PortalVideoController.java @@ -162,7 +162,7 @@ public class PortalVideoController extends BaseController { List allowed = loadModelOptionsForAiUser(uid, secondDeptId); String modelId = StringUtils.isNotEmpty(req.getModel()) ? req.getModel() : resolveDefaultModelForAiUser(uid, secondDeptId, allowed); if (StringUtils.isEmpty(modelId)) { - throw new ServiceException("未配置门户视频模型:请在后台为该用户所属二级部门配置 model_parm,或在 portal.video.models 中配置全局列表"); + throw new ServiceException("未配置门户视频模型:请在后台为该用户所属二级部门配置"); } if (StringUtils.isNotEmpty(req.getModel()) && !isModelInOptions(modelId, allowed)) { throw new ServiceException("所选模型对当前部门不可用"); @@ -517,7 +517,7 @@ public class PortalVideoController extends BaseController { } @GetMapping("/options") - @ApiOperation("门户视频生成可选参数(模型/比例/时长等,来自配置)") + @ApiOperation("门户视频生成可选参数(模型/比例/时长等,来自系统参数)") public AjaxResult videoParamOptions() { Long uid = SecurityUtils.getAiUserId(); Long secondDeptId = byteDeptApiKeyService.resolveSecondLevelDeptId(uid); diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/config/PortalVideoProperties.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/config/PortalVideoProperties.java index 81241ca..0cf4d70 100644 --- a/web-api/ruoyi-admin/src/main/java/com/ruoyi/config/PortalVideoProperties.java +++ b/web-api/ruoyi-admin/src/main/java/com/ruoyi/config/PortalVideoProperties.java @@ -1,115 +1,102 @@ package com.ruoyi.config; -import org.springframework.boot.context.properties.ConfigurationProperties; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.service.ISysConfigService; import org.springframework.stereotype.Component; import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import javax.annotation.Resource; + /** - * 门户视频生成参数(模型、比例、时长、分辨率等从配置读取,不在代码中写死业务默认值)。 + * 门户视频生成参数(从 sys_config 读取)。 */ @Component -@ConfigurationProperties(prefix = "portal.video") public class PortalVideoProperties { - private Defaults defaults = new Defaults(); + private static final ObjectMapper OM = new ObjectMapper(); - private List models = new ArrayList<>(); + /** 默认值:{"model":"...","duration":5,"resolution":"720p","ratio":"16:9"} */ + private static final String CFG_DEFAULTS = "portal.video.defaults"; + /** 模型列表:[{"label":"Seedance 2.0","value":"ep-xxx"}] */ + private static final String CFG_MODELS = "portal.video.models"; + /** 二级部门模型映射:{"101":[{"label":"...","value":"..."}]} */ + private static final String CFG_MODELS_BY_SECOND_DEPT = "portal.video.modelsBySecondDept"; + /** 二级部门默认值覆盖:{"101":{"duration":5,"resolution":"720p"}} */ + private static final String CFG_DEFAULTS_BY_SECOND_DEPT = "portal.video.defaultsBySecondDept"; + /** 比例列表:["16:9","9:16"] */ + private static final String CFG_RATIOS = "portal.video.ratios"; + /** 时长列表:[5,10] */ + private static final String CFG_DURATIONS = "portal.video.durations"; + /** 分辨率列表:["720p","1080p"] */ + private static final String CFG_RESOLUTIONS = "portal.video.resolutions"; + /** 功能类型:与 ai_manager.type 对应 */ + private static final String CFG_FUNCTION_TYPE = "portal.video.functionType"; + private static final String DEFAULT_FUNCTION_TYPE = "21"; - /** - * 按二级部门 {@code dept_id}(字符串,如 {@code "101"})配置专属模型列表;未命中时使用全局 {@link #models}。 - */ - private Map> modelsBySecondDept = new LinkedHashMap<>(); - - /** - * 按二级部门覆盖 {@link #defaults} 中的字段;仅配置需要覆盖的项即可。 - */ - private Map defaultsBySecondDept = new LinkedHashMap<>(); - - private List ratios = new ArrayList<>(); - - private List durations = new ArrayList<>(); - - private List resolutions = new ArrayList<>(); - - /** - * 与 ai_manager.type 一致,用于扣费与订单;库中需存在对应记录且 status=0、del_flag=0 - */ - private String functionType = "21"; + @Resource + private ISysConfigService sysConfigService; public String getFunctionType() { - return functionType; - } - - public void setFunctionType(String functionType) { - this.functionType = functionType != null ? functionType : "21"; + String functionType = trimToNull(sysConfigService.selectConfigByKey(CFG_FUNCTION_TYPE)); + return functionType != null ? functionType : DEFAULT_FUNCTION_TYPE; } public Defaults getDefaults() { - return defaults; - } - - public void setDefaults(Defaults defaults) { - if (defaults != null) { - this.defaults = defaults; - } + Defaults defaults = parseObjectConfig(CFG_DEFAULTS, Defaults.class); + return defaults != null ? defaults : new Defaults(); } public List getModels() { - return models; - } - - public void setModels(List models) { - this.models = models != null ? models : new ArrayList<>(); + List models = parseListConfig(CFG_MODELS, new TypeReference>() { + }); + return models != null ? models : new ArrayList<>(); } public Map> getModelsBySecondDept() { - return modelsBySecondDept; - } - - public void setModelsBySecondDept(Map> modelsBySecondDept) { - this.modelsBySecondDept = modelsBySecondDept != null ? modelsBySecondDept : new LinkedHashMap<>(); + Map> map = parseObjectConfig(CFG_MODELS_BY_SECOND_DEPT, + new TypeReference>>() { + }); + return map != null ? map : new LinkedHashMap<>(); } public Map getDefaultsBySecondDept() { - return defaultsBySecondDept; - } - - public void setDefaultsBySecondDept(Map defaultsBySecondDept) { - this.defaultsBySecondDept = defaultsBySecondDept != null ? defaultsBySecondDept : new LinkedHashMap<>(); + Map map = parseObjectConfig(CFG_DEFAULTS_BY_SECOND_DEPT, + new TypeReference>() { + }); + return map != null ? map : new LinkedHashMap<>(); } public List getRatios() { - return ratios; - } - - public void setRatios(List ratios) { - this.ratios = ratios != null ? ratios : new ArrayList<>(); + List ratios = parseListConfig(CFG_RATIOS, new TypeReference>() { + }); + return ratios != null ? ratios : Collections.emptyList(); } public List getDurations() { - return durations; - } - - public void setDurations(List durations) { - this.durations = durations != null ? durations : new ArrayList<>(); + List durations = parseListConfig(CFG_DURATIONS, new TypeReference>() { + }); + return durations != null ? durations : Collections.emptyList(); } public List getResolutions() { - return resolutions; - } - - public void setResolutions(List resolutions) { - this.resolutions = resolutions != null ? resolutions : new ArrayList<>(); + List resolutions = parseListConfig(CFG_RESOLUTIONS, new TypeReference>() { + }); + return resolutions != null ? resolutions : Collections.emptyList(); } /** * defaults.model 为空时,取 models 第一项的 value。 */ public String resolveDefaultModelId() { + Defaults defaults = getDefaults(); + List models = getModels(); if (defaults.getModel() != null && !defaults.getModel().isEmpty()) { return defaults.getModel(); } @@ -120,6 +107,8 @@ public class PortalVideoProperties { } public List resolveModelsForSecondDept(Long secondDeptId) { + Map> modelsBySecondDept = getModelsBySecondDept(); + List models = getModels(); if (secondDeptId != null) { List byDept = modelsBySecondDept.get(String.valueOf(secondDeptId)); if (byDept != null && !byDept.isEmpty()) { @@ -131,12 +120,13 @@ public class PortalVideoProperties { public Defaults resolveEffectiveDefaults(Long secondDeptId) { Defaults out = new Defaults(); - Defaults g = this.defaults; + Defaults g = this.getDefaults(); out.setModel(g.getModel()); out.setDuration(g.getDuration()); out.setResolution(g.getResolution()); out.setRatio(g.getRatio()); if (secondDeptId != null) { + Map defaultsBySecondDept = getDefaultsBySecondDept(); Defaults o = defaultsBySecondDept.get(String.valueOf(secondDeptId)); if (o != null) { if (o.getModel() != null && !o.getModel().isEmpty()) { @@ -183,6 +173,51 @@ public class PortalVideoProperties { return false; } + private T parseObjectConfig(String key, Class clazz) { + String raw = trimToNull(sysConfigService.selectConfigByKey(key)); + if (raw == null) { + return null; + } + try { + return OM.readValue(raw, clazz); + } catch (Exception e) { + return null; + } + } + + private T parseObjectConfig(String key, TypeReference typeReference) { + String raw = trimToNull(sysConfigService.selectConfigByKey(key)); + if (raw == null) { + return null; + } + try { + return OM.readValue(raw, typeReference); + } catch (Exception e) { + return null; + } + } + + private List parseListConfig(String key, TypeReference> typeReference) { + String raw = trimToNull(sysConfigService.selectConfigByKey(key)); + if (raw == null) { + return null; + } + try { + List list = OM.readValue(raw, typeReference); + return list != null ? list : new ArrayList<>(); + } catch (Exception e) { + return null; + } + } + + private String trimToNull(String value) { + if (StringUtils.isEmpty(value)) { + return null; + } + String out = value.trim(); + return out.isEmpty() ? null : out; + } + public static class Defaults { private String model; private Integer duration; diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamChargeOrderController.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamChargeOrderController.java new file mode 100644 index 0000000..e69de29 diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamConsumeStatController.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamConsumeStatController.java new file mode 100644 index 0000000..e69de29 diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamGroupBalanceController.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamGroupBalanceController.java new file mode 100644 index 0000000..e69de29 diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamOverviewController.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamOverviewController.java new file mode 100644 index 0000000..e69de29 diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamUserBalanceController.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamUserBalanceController.java new file mode 100644 index 0000000..e69de29 diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamUserController.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamUserController.java new file mode 100644 index 0000000..67a2a5e --- /dev/null +++ b/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamUserController.java @@ -0,0 +1,118 @@ +package com.ruoyi.web.controller.subteam; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.AiUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.ai.service.IAiUserService; +import com.ruoyi.system.service.subteam.ISubteamScopeService; + +@RestController +@RequestMapping("/subteam/user") +public class SubteamUserController extends BaseController { + + @Autowired + private IAiUserService aiUserService; + + @Autowired + private ISubteamScopeService subteamScopeService; + + @PreAuthorize("@ss.hasPermi('subteam:user:list')") + @GetMapping("/list") + public TableDataInfo list(AiUser aiUser) { + aiUser.setDeptId(subteamScopeService.currentTeamDeptId()); + startPage(); + List list = aiUserService.selectAiUserList(aiUser); + return getDataTable(list); + } + + @PreAuthorize("@ss.hasPermi('subteam:user:query')") + @GetMapping(value = {"/", "/{userId}"}) + public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) { + if (StringUtils.isNotNull(userId)) { + subteamScopeService.assertAiUserInTeam(userId); + return success(aiUserService.selectAiUserById(userId)); + } + return success(); + } + + @PreAuthorize("@ss.hasPermi('subteam:user:add')") + @Log(title = "团队后台用户", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody AiUser aiUser) { + if (StringUtils.isEmpty(aiUser.getUsername())) { + return error("登录账号不能为空"); + } + if (StringUtils.isEmpty(aiUser.getPassword())) { + return error("密码不能为空"); + } + aiUser.setDeptId(subteamScopeService.currentTeamDeptId()); + aiUser.setCreateBy(getUsername()); + return toAjax(aiUserService.insertAiUser(aiUser)); + } + + @PreAuthorize("@ss.hasPermi('subteam:user:edit')") + @Log(title = "团队后台用户", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody AiUser aiUser) { + if (aiUser.getId() == null) { + return error("用户主键不能为空"); + } + subteamScopeService.assertAiUserInTeam(aiUser.getId()); + aiUser.setDeptId(subteamScopeService.currentTeamDeptId()); + aiUser.setUpdateBy(getUsername()); + return toAjax(aiUserService.updateAiUser(aiUser)); + } + + @PreAuthorize("@ss.hasPermi('subteam:user:remove')") + @Log(title = "团队后台用户", businessType = BusinessType.DELETE) + @DeleteMapping("/{userIds}") + public AjaxResult remove(@PathVariable Long[] userIds) { + for (Long userId : userIds) { + subteamScopeService.assertAiUserInTeam(userId); + } + return toAjax(aiUserService.deleteAiUserByIds(userIds)); + } + + @PreAuthorize("@ss.hasPermi('subteam:user:resetPwd')") + @Log(title = "团队后台用户", businessType = BusinessType.UPDATE) + @PutMapping("/resetPwd") + public AjaxResult resetPwd(@RequestBody AiUser aiUser) { + if (aiUser.getId() == null) { + return error("用户主键不能为空"); + } + if (StringUtils.isEmpty(aiUser.getPassword())) { + return error("新密码不能为空"); + } + subteamScopeService.assertAiUserInTeam(aiUser.getId()); + aiUser.setNewPassword(aiUser.getPassword()); + return toAjax(aiUserService.updatePassword(aiUser)); + } + + @PreAuthorize("@ss.hasPermi('subteam:user:edit')") + @Log(title = "团队后台用户", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody AiUser aiUser) { + if (aiUser.getId() == null) { + return error("用户主键不能为空"); + } + subteamScopeService.assertAiUserInTeam(aiUser.getId()); + aiUser.setUpdateBy(getUsername()); + return toAjax(aiUserService.updateUserStatus(aiUser)); + } +} diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamVideoOrderController.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamVideoOrderController.java new file mode 100644 index 0000000..fcb22f4 --- /dev/null +++ b/web-api/ruoyi-admin/src/main/java/com/ruoyi/web/controller/subteam/SubteamVideoOrderController.java @@ -0,0 +1,45 @@ +package com.ruoyi.web.controller.subteam; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.ai.domain.AiOrder; +import com.ruoyi.ai.service.IAiOrderService; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.system.service.subteam.ISubteamDataQueryService; +import com.ruoyi.system.service.subteam.ISubteamScopeService; + +@RestController +@RequestMapping("/subteam/video-order") +public class SubteamVideoOrderController extends BaseController { + + @Autowired + private ISubteamDataQueryService subteamDataQueryService; + + @Autowired + private ISubteamScopeService subteamScopeService; + + @Autowired + private IAiOrderService aiOrderService; + + @PreAuthorize("@ss.hasPermi('subteam:videoOrder:list')") + @GetMapping("/list") + public TableDataInfo list(AiOrder query) { + startPage(); + List list = subteamDataQueryService.selectVideoOrders(query); + return getDataTable(list); + } + + @PreAuthorize("@ss.hasPermi('subteam:videoOrder:query')") + @GetMapping("/{id}") + public AjaxResult getInfo(@PathVariable Long id) { + subteamScopeService.assertAiOrderBelongsToTeam(id); + return success(aiOrderService.selectAiOrderById(id)); + } +} diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/system/domain/subteam/SubteamOverviewVO.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/domain/subteam/SubteamOverviewVO.java new file mode 100644 index 0000000..69a2c0b --- /dev/null +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/domain/subteam/SubteamOverviewVO.java @@ -0,0 +1,30 @@ +package com.ruoyi.system.domain.subteam; + +import java.io.Serializable; +import java.math.BigDecimal; +import lombok.Data; + +/** + * 团队后台首页概览 + */ +@Data +public class SubteamOverviewVO implements Serializable { + + private static final long serialVersionUID = 1L; + + private Long deptId; + + private String deptName; + + /** 团队积分余额(sys_dept.balance) */ + private BigDecimal balance; + + /** AI 用户数量(ai_user,实时) */ + private Integer aiUserCount; + + /** 近七日消耗积分(ai_video_report_data,可能来自缓存) */ + private BigDecimal last7DaysConsumeScore; + + /** 近七日成功订单数(ai_video_report_data,可能来自缓存) */ + private Long last7DaysOrderCount; +} diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/system/domain/subteam/SubteamVideoMetrics.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/domain/subteam/SubteamVideoMetrics.java new file mode 100644 index 0000000..cf04988 --- /dev/null +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/domain/subteam/SubteamVideoMetrics.java @@ -0,0 +1,18 @@ +package com.ruoyi.system.domain.subteam; + +import java.io.Serializable; +import java.math.BigDecimal; +import lombok.Data; + +/** + * 团队视频统计汇总(近七日消耗/订单数) + */ +@Data +public class SubteamVideoMetrics implements Serializable { + + private static final long serialVersionUID = 1L; + + private BigDecimal consumeScore; + + private Long orderCount; +} diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/ISubteamDataQueryService.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/ISubteamDataQueryService.java new file mode 100644 index 0000000..f841ddc --- /dev/null +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/ISubteamDataQueryService.java @@ -0,0 +1,21 @@ +package com.ruoyi.system.service.subteam; + +import java.util.List; +import com.ruoyi.ai.domain.AiBalanceChangeRecord; +import com.ruoyi.ai.domain.AiChargeRefundOrder; +import com.ruoyi.ai.domain.AiGroupBalanceChangeRecord; +import com.ruoyi.ai.domain.AiOrder; +import com.ruoyi.ai.domain.AiVideoReportData; + +public interface ISubteamDataQueryService { + + List selectVideoOrders(AiOrder query); + + List selectChargeRefundOrders(AiChargeRefundOrder query); + + List selectUserBalanceRecords(AiBalanceChangeRecord query); + + List selectGroupBalanceRecords(AiGroupBalanceChangeRecord query); + + List selectTeamDailyConsume(String statDate); +} diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/ISubteamOverviewService.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/ISubteamOverviewService.java new file mode 100644 index 0000000..589f93f --- /dev/null +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/ISubteamOverviewService.java @@ -0,0 +1,8 @@ +package com.ruoyi.system.service.subteam; + +import com.ruoyi.system.domain.subteam.SubteamOverviewVO; + +public interface ISubteamOverviewService { + + SubteamOverviewVO loadOverview(); +} diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/ISubteamScopeService.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/ISubteamScopeService.java new file mode 100644 index 0000000..676fc29 --- /dev/null +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/ISubteamScopeService.java @@ -0,0 +1,24 @@ +package com.ruoyi.system.service.subteam; + +/** + * 团队后台数据范围:当前登录人所属部门(团队) + */ +public interface ISubteamScopeService { + + /** + * 当前账号所属团队部门 ID(sys_user.dept_id) + */ + Long currentTeamDeptId(); + + void assertSysUserInTeam(Long sysUserId); + + void assertAiUserInTeam(Long aiUserId); + + void assertAiOrderBelongsToTeam(Long orderId); + + void assertChargeRefundBelongsToTeam(Long orderPkId); + + void assertGroupBalanceRecordBelongsToTeam(String recordId); + + void assertAiBalanceRecordVisible(Long recordId, Long teamDeptId); +} diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/impl/SubteamDataQueryServiceImpl.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/impl/SubteamDataQueryServiceImpl.java new file mode 100644 index 0000000..6cc7ff2 --- /dev/null +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/impl/SubteamDataQueryServiceImpl.java @@ -0,0 +1,78 @@ +package com.ruoyi.system.service.subteam.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ruoyi.ai.domain.AiBalanceChangeRecord; +import com.ruoyi.ai.domain.AiChargeRefundOrder; +import com.ruoyi.ai.domain.AiGroupBalanceChangeRecord; +import com.ruoyi.ai.domain.AiOrder; +import com.ruoyi.ai.domain.AiVideoReportData; +import com.ruoyi.ai.mapper.AiBalanceChangeRecordMapper; +import com.ruoyi.ai.mapper.AiChargeRefundOrderMapper; +import com.ruoyi.ai.mapper.AiGroupBalanceChangeRecordMapper; +import com.ruoyi.ai.mapper.AiOrderMapper; +import com.ruoyi.ai.service.IAiVideoReportDataService; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.service.subteam.ISubteamDataQueryService; +import com.ruoyi.system.service.subteam.ISubteamScopeService; + +@Service +public class SubteamDataQueryServiceImpl implements ISubteamDataQueryService { + + @Autowired + private ISubteamScopeService subteamScopeService; + + @Autowired + private AiOrderMapper aiOrderMapper; + + @Autowired + private AiChargeRefundOrderMapper aiChargeRefundOrderMapper; + + @Autowired + private AiBalanceChangeRecordMapper aiBalanceChangeRecordMapper; + + @Autowired + private AiGroupBalanceChangeRecordMapper aiGroupBalanceChangeRecordMapper; + + @Autowired + private IAiVideoReportDataService aiVideoReportDataService; + + @Override + public List selectVideoOrders(AiOrder query) { + Long deptId = subteamScopeService.currentTeamDeptId(); + query.setDeptId(deptId); + return aiOrderMapper.selectAiOrderList(query); + } + + @Override + public List selectChargeRefundOrders(AiChargeRefundOrder query) { + Long deptId = subteamScopeService.currentTeamDeptId(); + query.setDeptId(deptId); + return aiChargeRefundOrderMapper.selectAiChargeRefundOrderList(query); + } + + @Override + public List selectUserBalanceRecords(AiBalanceChangeRecord query) { + Long deptId = subteamScopeService.currentTeamDeptId(); + return aiBalanceChangeRecordMapper.selectAiBalanceChangeRecordListByAiUserDept(query, deptId); + } + + @Override + public List selectGroupBalanceRecords(AiGroupBalanceChangeRecord query) { + Long deptId = subteamScopeService.currentTeamDeptId(); + query.setDeptId(deptId); + return aiGroupBalanceChangeRecordMapper.selectList( + Wrappers.lambdaQuery(query).orderByDesc(AiGroupBalanceChangeRecord::getId)); + } + + @Override + public List selectTeamDailyConsume(String statDate) { + if (StringUtils.isEmpty(statDate)) { + return java.util.Collections.emptyList(); + } + Long deptId = subteamScopeService.currentTeamDeptId(); + return aiVideoReportDataService.selectTeamDailyConsumeByDeptId(statDate, deptId); + } +} diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/impl/SubteamOverviewServiceImpl.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/impl/SubteamOverviewServiceImpl.java new file mode 100644 index 0000000..0edd0c6 --- /dev/null +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/impl/SubteamOverviewServiceImpl.java @@ -0,0 +1,72 @@ +package com.ruoyi.system.service.subteam.impl; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.ai.mapper.AiVideoReportDataMapper; +import com.ruoyi.ai.service.IAiUserService; +import com.ruoyi.common.core.domain.entity.SysDept; +import com.ruoyi.system.domain.subteam.SubteamOverviewVO; +import com.ruoyi.system.domain.subteam.SubteamVideoMetrics; +import com.ruoyi.system.mapper.SysDeptMapper; +import com.ruoyi.system.service.subteam.ISubteamOverviewService; +import com.ruoyi.system.service.subteam.ISubteamScopeService; +import com.ruoyi.common.core.redis.RedisCache; + +@Service +public class SubteamOverviewServiceImpl implements ISubteamOverviewService { + + private static final int METRICS_CACHE_MINUTES = 5; + + @Autowired + private ISubteamScopeService subteamScopeService; + + @Autowired + private SysDeptMapper sysDeptMapper; + + @Autowired + private IAiUserService aiUserService; + + @Autowired + private AiVideoReportDataMapper aiVideoReportDataMapper; + + @Autowired + private RedisCache redisCache; + + @Override + public SubteamOverviewVO loadOverview() { + Long deptId = subteamScopeService.currentTeamDeptId(); + SysDept dept = sysDeptMapper.selectDeptById(deptId); + SubteamOverviewVO vo = new SubteamOverviewVO(); + vo.setDeptId(deptId); + vo.setDeptName(dept != null ? dept.getDeptName() : ""); + vo.setBalance(dept != null && dept.getBalance() != null ? dept.getBalance() : BigDecimal.ZERO); + vo.setAiUserCount(aiUserService.countAiUserByDeptId(deptId)); + + LocalDate end = LocalDate.now(); + LocalDate start = end.minusDays(6); + String startDay = start.format(DateTimeFormatter.BASIC_ISO_DATE); + String endDay = end.format(DateTimeFormatter.BASIC_ISO_DATE); + String cacheKey = "subteam:videoMetrics:" + deptId + ":" + startDay + ":" + endDay; + SubteamVideoMetrics metrics = redisCache.getCacheObject(cacheKey); + if (metrics == null) { + metrics = aiVideoReportDataMapper.selectDeptVideoMetricsBetween(deptId, startDay, endDay); + if (metrics == null) { + metrics = new SubteamVideoMetrics(); + } + if (metrics.getConsumeScore() == null) { + metrics.setConsumeScore(BigDecimal.ZERO); + } + if (metrics.getOrderCount() == null) { + metrics.setOrderCount(0L); + } + redisCache.setCacheObject(cacheKey, metrics, METRICS_CACHE_MINUTES, TimeUnit.MINUTES); + } + vo.setLast7DaysConsumeScore(metrics.getConsumeScore()); + vo.setLast7DaysOrderCount(metrics.getOrderCount()); + return vo; + } +} diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/impl/SubteamScopeServiceImpl.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/system/service/subteam/impl/SubteamScopeServiceImpl.java new file mode 100644 index 0000000..e69de29 diff --git a/web-api/ruoyi-system/src/main/resources/mapper/ai/AiChargeRefundOrderMapper.xml b/web-api/ruoyi-system/src/main/resources/mapper/ai/AiChargeRefundOrderMapper.xml new file mode 100644 index 0000000..a23253a --- /dev/null +++ b/web-api/ruoyi-system/src/main/resources/mapper/ai/AiChargeRefundOrderMapper.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + select o.id, o.del_flag, o.create_by, o.create_time, o.update_time, o.order_num, o.third_party_order_num, o.dept_id, + d.dept_name as dept_name, o.order_type, o.money, o.amount, o.remark, o.status + from ai_charge_refund_order o + left join sys_dept d on d.dept_id = o.dept_id and d.del_flag = '0' + + + + + + + + insert into ai_charge_refund_order + + del_flag, + create_by, + create_time, + update_time, + order_num, + third_party_order_num, + dept_id, + order_type, + money, + amount, + remark, + status, + + + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateTime}, + #{orderNum}, + #{thirdPartyOrderNum}, + #{deptId}, + #{orderType}, + #{money}, + #{amount}, + #{remark}, + #{status}, + + + + + update ai_charge_refund_order + + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_time = #{updateTime}, + order_num = #{orderNum}, + third_party_order_num = #{thirdPartyOrderNum}, + dept_id = #{deptId}, + order_type = #{orderType}, + money = #{money}, + amount = #{amount}, + remark = #{remark}, + status = #{status}, + + where id = #{id} + + + + delete from ai_charge_refund_order where id = #{id} + + + + delete from ai_charge_refund_order where id in + + #{id} + + + \ No newline at end of file diff --git a/web-api/ruoyi-system/src/main/resources/mapper/ai/AiDeptArkConfigMapper.xml b/web-api/ruoyi-system/src/main/resources/mapper/ai/AiDeptArkConfigMapper.xml new file mode 100644 index 0000000..2c68fcd --- /dev/null +++ b/web-api/ruoyi-system/src/main/resources/mapper/ai/AiDeptArkConfigMapper.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + select id, dept_id, model_parm, project, byte_api_key, create_by, create_time, update_by, update_time from ai_dept_ark_config + + + + + + + + insert into ai_dept_ark_config + + dept_id, + model_parm, + project, + byte_api_key, + create_by, + create_time, + update_by, + update_time, + + + #{deptId}, + #{modelParm}, + #{project}, + #{byteApiKey}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ai_dept_ark_config + + dept_id = #{deptId}, + model_parm = #{modelParm}, + project = #{project}, + byte_api_key = #{byteApiKey}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ai_dept_ark_config where id = #{id} + + + + delete from ai_dept_ark_config where id in + + #{id} + + + \ No newline at end of file diff --git a/web-api/ruoyi-system/src/main/resources/mapper/ai/AiGroupBalanceChangeRecordMapper.xml b/web-api/ruoyi-system/src/main/resources/mapper/ai/AiGroupBalanceChangeRecordMapper.xml new file mode 100644 index 0000000..56d25b8 --- /dev/null +++ b/web-api/ruoyi-system/src/main/resources/mapper/ai/AiGroupBalanceChangeRecordMapper.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + select id, relation_order_no, dept_id, type, change_amount, result_amount, remark, create_time, update_time from ai_group_balance_change_record + + + + + + + + insert into ai_group_balance_change_record + + relation_order_no, + dept_id, + type, + change_amount, + result_amount, + remark, + create_time, + update_time, + + + #{relationOrderNo}, + #{deptId}, + #{type}, + #{changeAmount}, + #{resultAmount}, + #{remark}, + #{createTime}, + #{updateTime}, + + + + + update ai_group_balance_change_record + + relation_order_no = #{relationOrderNo}, + dept_id = #{deptId}, + type = #{type}, + change_amount = #{changeAmount}, + result_amount = #{resultAmount}, + remark = #{remark}, + create_time = #{createTime}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ai_group_balance_change_record where id = #{id} + + + + delete from ai_group_balance_change_record where id in + + #{id} + + + \ No newline at end of file diff --git a/web-api/ruoyi-system/src/main/resources/mapper/ai/AiVideoReportDataMapper.xml b/web-api/ruoyi-system/src/main/resources/mapper/ai/AiVideoReportDataMapper.xml new file mode 100644 index 0000000..a2daca5 --- /dev/null +++ b/web-api/ruoyi-system/src/main/resources/mapper/ai/AiVideoReportDataMapper.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + select id, date_key, dept_id, user_id, score, order_count, use_tokens, recharge_score, create_time, update_time from ai_video_report_data + + + + + + + + insert into ai_video_report_data + + date_key, + dept_id, + user_id, + score, + order_count, + use_tokens, + recharge_score, + create_time, + update_time, + + + #{dateKey}, + #{deptId}, + #{userId}, + #{score}, + #{orderCount}, + #{useTokens}, + #{rechargeScore}, + #{createTime}, + #{updateTime}, + + + + + update ai_video_report_data + + date_key = #{dateKey}, + dept_id = #{deptId}, + user_id = #{userId}, + score = #{score}, + order_count = #{orderCount}, + use_tokens = #{useTokens}, + recharge_score = #{rechargeScore}, + create_time = #{createTime}, + update_time = #{updateTime}, + + where id = #{id} + + + + + + + + + + insert into ai_video_report_data + (date_key, dept_id, user_id, score, order_count, use_tokens, recharge_score, create_time, update_time) + values + (#{dateKey}, #{deptId}, #{userId}, #{score}, #{orderCount}, #{useTokens}, 0, now(), now()) + on duplicate key update + score = score + values(score), + order_count = order_count + values(order_count), + use_tokens = use_tokens + values(use_tokens), + update_time = now() + + + + insert into ai_video_report_data + (date_key, dept_id, user_id, score, order_count, use_tokens, recharge_score, create_time, update_time) + values + (#{dateKey}, #{deptId}, 0, 0, 0, 0, #{rechargeScore}, now(), now()) + on duplicate key update + recharge_score = recharge_score + values(recharge_score), + update_time = now() + + + + delete from ai_video_report_data where id = #{id} + + + + delete from ai_video_report_data where id in + + #{id} + + + \ No newline at end of file From 6600f4f1f95b3808997ece6eaa88237a2bc7e8c8 Mon Sep 17 00:00:00 2001 From: old burden Date: Mon, 20 Apr 2026 16:55:10 +0800 Subject: [PATCH 3/8] =?UTF-8?q?fix=EF=BC=9A=E6=96=B0=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/subteam/chargeOrder/index.vue | 64 +++++++ .../src/views/subteam/consumeStat/index.vue | 66 +++++++ .../src/views/subteam/groupBalance/index.vue | 55 ++++++ admin-ui/src/views/subteam/overview/index.vue | 58 ++++++ admin-ui/src/views/subteam/user/index.vue | 179 ++++++++++++++++++ .../src/views/subteam/userBalance/index.vue | 56 ++++++ .../src/views/subteam/videoOrder/index.vue | 138 ++++++++++++++ .../ruoyi/ai/domain/AiVideoReportData.java | 9 + .../mapper/AiBalanceChangeRecordMapper.java | 12 ++ .../ai/mapper/AiChargeRefundOrderMapper.java | 8 + .../ai/mapper/AiDeptArkConfigMapper.java | 10 + .../AiGroupBalanceChangeRecordMapper.java | 11 ++ .../ai/mapper/AiVideoReportDataMapper.java | 33 ++++ .../service/IAiChargeRefundOrderService.java | 11 ++ .../ai/service/IAiDeptArkConfigService.java | 11 ++ .../IAiGroupBalanceChangeRecordService.java | 12 ++ .../ai/service/IAiVideoReportDataService.java | 34 ++++ .../impl/AiChargeRefundOrderServiceImpl.java | 33 ++++ .../impl/AiDeptArkConfigServiceImpl.java | 26 +++ ...AiGroupBalanceChangeRecordServiceImpl.java | 27 +++ .../impl/AiVideoReportDataServiceImpl.java | 53 ++++++ .../system/AiBalanceChangeRecordMapper.xml | 20 ++ 22 files changed, 926 insertions(+) diff --git a/admin-ui/src/views/subteam/chargeOrder/index.vue b/admin-ui/src/views/subteam/chargeOrder/index.vue index e69de29..ef23826 100644 --- a/admin-ui/src/views/subteam/chargeOrder/index.vue +++ b/admin-ui/src/views/subteam/chargeOrder/index.vue @@ -0,0 +1,64 @@ + + + diff --git a/admin-ui/src/views/subteam/consumeStat/index.vue b/admin-ui/src/views/subteam/consumeStat/index.vue index e69de29..8f35d93 100644 --- a/admin-ui/src/views/subteam/consumeStat/index.vue +++ b/admin-ui/src/views/subteam/consumeStat/index.vue @@ -0,0 +1,66 @@ + + + + + diff --git a/admin-ui/src/views/subteam/groupBalance/index.vue b/admin-ui/src/views/subteam/groupBalance/index.vue index e69de29..0638a08 100644 --- a/admin-ui/src/views/subteam/groupBalance/index.vue +++ b/admin-ui/src/views/subteam/groupBalance/index.vue @@ -0,0 +1,55 @@ + + + diff --git a/admin-ui/src/views/subteam/overview/index.vue b/admin-ui/src/views/subteam/overview/index.vue index e69de29..47ea8d9 100644 --- a/admin-ui/src/views/subteam/overview/index.vue +++ b/admin-ui/src/views/subteam/overview/index.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/admin-ui/src/views/subteam/user/index.vue b/admin-ui/src/views/subteam/user/index.vue index e69de29..6e3fe75 100644 --- a/admin-ui/src/views/subteam/user/index.vue +++ b/admin-ui/src/views/subteam/user/index.vue @@ -0,0 +1,179 @@ + + + diff --git a/admin-ui/src/views/subteam/userBalance/index.vue b/admin-ui/src/views/subteam/userBalance/index.vue index e69de29..236bd65 100644 --- a/admin-ui/src/views/subteam/userBalance/index.vue +++ b/admin-ui/src/views/subteam/userBalance/index.vue @@ -0,0 +1,56 @@ + + + diff --git a/admin-ui/src/views/subteam/videoOrder/index.vue b/admin-ui/src/views/subteam/videoOrder/index.vue index e69de29..b06d72b 100644 --- a/admin-ui/src/views/subteam/videoOrder/index.vue +++ b/admin-ui/src/views/subteam/videoOrder/index.vue @@ -0,0 +1,138 @@ + + + diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/domain/AiVideoReportData.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/domain/AiVideoReportData.java index dcb1a6d..e9b710e 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/domain/AiVideoReportData.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/domain/AiVideoReportData.java @@ -27,6 +27,9 @@ public class AiVideoReportData implements Serializable { /** 统计日期键(varchar) */ private String dateKey; + /** 查询参数:统计日期(yyyyMMdd) */ + private String statDate; + /** 部门ID */ private Long deptId; @@ -42,6 +45,12 @@ public class AiVideoReportData implements Serializable { /** 消耗 tokens */ private Long useTokens; + /** 充值积分 */ + private BigDecimal rechargeScore; + + /** 部门名称(联表字段) */ + private String deptName; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiBalanceChangeRecordMapper.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiBalanceChangeRecordMapper.java index 64b6199..fab0dcc 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiBalanceChangeRecordMapper.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiBalanceChangeRecordMapper.java @@ -4,6 +4,7 @@ import java.util.List; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.ai.domain.AiBalanceChangeRecord; +import org.apache.ibatis.annotations.Param; /** * 余额使用记录Mapper接口 @@ -17,4 +18,15 @@ public interface AiBalanceChangeRecordMapper extends BaseMapper selectAiBalanceChangeRecordList(AiBalanceChangeRecord aiBalanceChangeRecord); + + /** + * 按 AI 用户所属部门查询余额流水 + * + * @param aiBalanceChangeRecord 查询条件 + * @param deptId 部门ID + * @return 余额流水列表 + */ + List selectAiBalanceChangeRecordListByAiUserDept( + @Param("query") AiBalanceChangeRecord aiBalanceChangeRecord, + @Param("deptId") Long deptId); } diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiChargeRefundOrderMapper.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiChargeRefundOrderMapper.java index 46c0ff2..39ae280 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiChargeRefundOrderMapper.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiChargeRefundOrderMapper.java @@ -2,9 +2,17 @@ package com.ruoyi.ai.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.ai.domain.AiChargeRefundOrder; +import java.util.List; /** * 充值/退款订单 Mapper */ public interface AiChargeRefundOrderMapper extends BaseMapper { + /** + * 查询充值/退款订单列表 + * + * @param aiChargeRefundOrder 查询条件 + * @return 订单列表 + */ + List selectAiChargeRefundOrderList(AiChargeRefundOrder aiChargeRefundOrder); } diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiDeptArkConfigMapper.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiDeptArkConfigMapper.java index 7aa7833..7da858a 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiDeptArkConfigMapper.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiDeptArkConfigMapper.java @@ -2,9 +2,19 @@ package com.ruoyi.ai.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.ai.domain.AiDeptArkConfig; +import java.util.List; /** * 部门方舟配置 Mapper */ public interface AiDeptArkConfigMapper extends BaseMapper { + List selectAiDeptArkConfigList(AiDeptArkConfig aiDeptArkConfig); + + AiDeptArkConfig selectAiDeptArkConfigById(String id); + + int insertAiDeptArkConfig(AiDeptArkConfig aiDeptArkConfig); + + int updateAiDeptArkConfig(AiDeptArkConfig aiDeptArkConfig); + + int deleteAiDeptArkConfigByIds(String[] ids); } diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiGroupBalanceChangeRecordMapper.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiGroupBalanceChangeRecordMapper.java index 8f4fbf6..75b7257 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiGroupBalanceChangeRecordMapper.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiGroupBalanceChangeRecordMapper.java @@ -2,9 +2,20 @@ package com.ruoyi.ai.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.ai.domain.AiGroupBalanceChangeRecord; +import java.util.List; /** * 集团余额变动记录 Mapper */ public interface AiGroupBalanceChangeRecordMapper extends BaseMapper { + List selectAiGroupBalanceChangeRecordList( + AiGroupBalanceChangeRecord aiGroupBalanceChangeRecord); + + AiGroupBalanceChangeRecord selectAiGroupBalanceChangeRecordById(String id); + + int insertAiGroupBalanceChangeRecord(AiGroupBalanceChangeRecord aiGroupBalanceChangeRecord); + + int updateAiGroupBalanceChangeRecord(AiGroupBalanceChangeRecord aiGroupBalanceChangeRecord); + + int deleteAiGroupBalanceChangeRecordByIds(String[] ids); } diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiVideoReportDataMapper.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiVideoReportDataMapper.java index 40fae7a..dcc8ece 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiVideoReportDataMapper.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/mapper/AiVideoReportDataMapper.java @@ -3,6 +3,10 @@ package com.ruoyi.ai.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.ai.domain.AiVideoReportData; import com.ruoyi.common.core.dto.DeptSummaryDTO; +import com.ruoyi.system.domain.subteam.SubteamVideoMetrics; +import java.math.BigDecimal; +import java.util.List; +import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; /** @@ -12,4 +16,33 @@ public interface AiVideoReportDataMapper extends BaseMapper { @Select("SELECT SUM(order_count) as order_count,SUM(score) as score FROM ai_video_report_data " + " where dept_id=#{deptId} and date_key>=#{startHour} and date_key<=#{endHour}") DeptSummaryDTO selectOneDeptSummaryData(Long deptId, String startHour, String endHour); + + List selectTeamDailyConsumeByDeptId(@Param("statDate") String statDate, @Param("deptId") Long deptId); + + SubteamVideoMetrics selectDeptVideoMetricsBetween( + @Param("deptId") Long deptId, + @Param("startDay") String startDay, + @Param("endDay") String endDay); + + int upsertVideoConsumeIncrement( + @Param("dateKey") String dateKey, + @Param("deptId") Long deptId, + @Param("userId") Long userId, + @Param("score") BigDecimal score, + @Param("orderCount") Long orderCount, + @Param("useTokens") Long useTokens); + + List selectTeamDailyConsumeList( + @Param("statDate") String statDate, + @Param("deptName") String deptName); + + List selectAiVideoReportDataList(AiVideoReportData aiVideoReportData); + + AiVideoReportData selectAiVideoReportDataById(String id); + + int insertAiVideoReportData(AiVideoReportData aiVideoReportData); + + int updateAiVideoReportData(AiVideoReportData aiVideoReportData); + + int deleteAiVideoReportDataByIds(String[] ids); } diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiChargeRefundOrderService.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiChargeRefundOrderService.java index 1879a67..cd647f6 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiChargeRefundOrderService.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiChargeRefundOrderService.java @@ -1,6 +1,7 @@ package com.ruoyi.ai.service; import com.ruoyi.ai.domain.AiChargeRefundOrder; +import java.util.List; /** * 充值/退款订单 Service @@ -14,4 +15,14 @@ public interface IAiChargeRefundOrderService { int updateById(AiChargeRefundOrder entity); int deleteById(Long id); + + List selectAiChargeRefundOrderList(AiChargeRefundOrder aiChargeRefundOrder); + + AiChargeRefundOrder selectAiChargeRefundOrderById(Long id); + + int insertAiChargeRefundOrder(AiChargeRefundOrder aiChargeRefundOrder); + + int updateAiChargeRefundOrder(AiChargeRefundOrder aiChargeRefundOrder); + + int deleteAiChargeRefundOrderByIds(Long[] ids); } diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiDeptArkConfigService.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiDeptArkConfigService.java index aea396d..962af62 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiDeptArkConfigService.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiDeptArkConfigService.java @@ -1,6 +1,7 @@ package com.ruoyi.ai.service; import com.ruoyi.ai.domain.AiDeptArkConfig; +import java.util.List; /** * 部门方舟配置 Service @@ -14,4 +15,14 @@ public interface IAiDeptArkConfigService { int updateById(AiDeptArkConfig entity); int deleteById(Long id); + + List selectAiDeptArkConfigList(AiDeptArkConfig aiDeptArkConfig); + + AiDeptArkConfig selectAiDeptArkConfigById(String id); + + int insertAiDeptArkConfig(AiDeptArkConfig aiDeptArkConfig); + + int updateAiDeptArkConfig(AiDeptArkConfig aiDeptArkConfig); + + int deleteAiDeptArkConfigByIds(String[] ids); } diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiGroupBalanceChangeRecordService.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiGroupBalanceChangeRecordService.java index 77db2c0..a3846a7 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiGroupBalanceChangeRecordService.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiGroupBalanceChangeRecordService.java @@ -1,6 +1,7 @@ package com.ruoyi.ai.service; import com.ruoyi.ai.domain.AiGroupBalanceChangeRecord; +import java.util.List; /** * 集团余额变动记录 Service @@ -14,4 +15,15 @@ public interface IAiGroupBalanceChangeRecordService { int updateById(AiGroupBalanceChangeRecord entity); int deleteById(Long id); + + List selectAiGroupBalanceChangeRecordList( + AiGroupBalanceChangeRecord aiGroupBalanceChangeRecord); + + AiGroupBalanceChangeRecord selectAiGroupBalanceChangeRecordById(String id); + + int insertAiGroupBalanceChangeRecord(AiGroupBalanceChangeRecord aiGroupBalanceChangeRecord); + + int updateAiGroupBalanceChangeRecord(AiGroupBalanceChangeRecord aiGroupBalanceChangeRecord); + + int deleteAiGroupBalanceChangeRecordByIds(String[] ids); } diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiVideoReportDataService.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiVideoReportDataService.java index 715d689..4b5d12e 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiVideoReportDataService.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IAiVideoReportDataService.java @@ -2,6 +2,8 @@ package com.ruoyi.ai.service; import com.ruoyi.ai.domain.AiVideoReportData; import com.ruoyi.common.core.dto.DeptSummaryDTO; +import java.math.BigDecimal; +import java.util.List; import java.util.Date; @@ -14,4 +16,36 @@ public interface IAiVideoReportDataService { int insert(AiVideoReportData entity); DeptSummaryDTO getSevenDayDeptSummaryData(Long deptId); + + /** + * 按部门查询团队每日消耗 + * + * @param statDate 统计日期(yyyyMMdd) + * @param deptId 部门ID + * @return 每日消耗列表 + */ + List selectTeamDailyConsumeByDeptId(String statDate, Long deptId); + + /** + * 同步视频消耗增量 + * + * @param createTime 订单创建时间 + * @param deptId 部门ID + * @param userId 用户ID + * @param score 消耗积分 + * @param useTokens 消耗token + */ + void syncVideoConsumeIncrement(Date createTime, Long deptId, Long userId, BigDecimal score, Long useTokens); + + List selectTeamDailyConsumeList(String statDate, String deptName); + + List selectAiVideoReportDataList(AiVideoReportData aiVideoReportData); + + AiVideoReportData selectAiVideoReportDataById(String id); + + int insertAiVideoReportData(AiVideoReportData aiVideoReportData); + + int updateAiVideoReportData(AiVideoReportData aiVideoReportData); + + int deleteAiVideoReportDataByIds(String[] ids); } diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiChargeRefundOrderServiceImpl.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiChargeRefundOrderServiceImpl.java index 5262731..a537088 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiChargeRefundOrderServiceImpl.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiChargeRefundOrderServiceImpl.java @@ -6,6 +6,7 @@ import org.springframework.stereotype.Service; import com.ruoyi.ai.domain.AiChargeRefundOrder; import com.ruoyi.ai.mapper.AiChargeRefundOrderMapper; import com.ruoyi.ai.service.IAiChargeRefundOrderService; +import java.util.List; /** * 充值/退款订单 Service 实现 @@ -35,4 +36,36 @@ public class AiChargeRefundOrderServiceImpl implements IAiChargeRefundOrderServi public int deleteById(Long id) { return aiChargeRefundOrderMapper.deleteById(id); } + + @Override + public List selectAiChargeRefundOrderList(AiChargeRefundOrder aiChargeRefundOrder) { + return aiChargeRefundOrderMapper.selectAiChargeRefundOrderList(aiChargeRefundOrder); + } + + @Override + public AiChargeRefundOrder selectAiChargeRefundOrderById(Long id) { + return aiChargeRefundOrderMapper.selectById(id); + } + + @Override + public int insertAiChargeRefundOrder(AiChargeRefundOrder aiChargeRefundOrder) { + return aiChargeRefundOrderMapper.insert(aiChargeRefundOrder); + } + + @Override + public int updateAiChargeRefundOrder(AiChargeRefundOrder aiChargeRefundOrder) { + return aiChargeRefundOrderMapper.updateById(aiChargeRefundOrder); + } + + @Override + public int deleteAiChargeRefundOrderByIds(Long[] ids) { + int rows = 0; + if (ids == null) { + return rows; + } + for (Long id : ids) { + rows += aiChargeRefundOrderMapper.deleteById(id); + } + return rows; + } } diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiDeptArkConfigServiceImpl.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiDeptArkConfigServiceImpl.java index bc2a2f3..e470264 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiDeptArkConfigServiceImpl.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiDeptArkConfigServiceImpl.java @@ -6,6 +6,7 @@ import org.springframework.stereotype.Service; import com.ruoyi.ai.domain.AiDeptArkConfig; import com.ruoyi.ai.mapper.AiDeptArkConfigMapper; import com.ruoyi.ai.service.IAiDeptArkConfigService; +import java.util.List; /** * 部门方舟配置 Service 实现 @@ -35,4 +36,29 @@ public class AiDeptArkConfigServiceImpl implements IAiDeptArkConfigService { public int deleteById(Long id) { return aiDeptArkConfigMapper.deleteById(id); } + + @Override + public List selectAiDeptArkConfigList(AiDeptArkConfig aiDeptArkConfig) { + return aiDeptArkConfigMapper.selectAiDeptArkConfigList(aiDeptArkConfig); + } + + @Override + public AiDeptArkConfig selectAiDeptArkConfigById(String id) { + return aiDeptArkConfigMapper.selectAiDeptArkConfigById(id); + } + + @Override + public int insertAiDeptArkConfig(AiDeptArkConfig aiDeptArkConfig) { + return aiDeptArkConfigMapper.insertAiDeptArkConfig(aiDeptArkConfig); + } + + @Override + public int updateAiDeptArkConfig(AiDeptArkConfig aiDeptArkConfig) { + return aiDeptArkConfigMapper.updateAiDeptArkConfig(aiDeptArkConfig); + } + + @Override + public int deleteAiDeptArkConfigByIds(String[] ids) { + return aiDeptArkConfigMapper.deleteAiDeptArkConfigByIds(ids); + } } diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiGroupBalanceChangeRecordServiceImpl.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiGroupBalanceChangeRecordServiceImpl.java index d4268dc..7ec6279 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiGroupBalanceChangeRecordServiceImpl.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiGroupBalanceChangeRecordServiceImpl.java @@ -6,6 +6,7 @@ import org.springframework.stereotype.Service; import com.ruoyi.ai.domain.AiGroupBalanceChangeRecord; import com.ruoyi.ai.mapper.AiGroupBalanceChangeRecordMapper; import com.ruoyi.ai.service.IAiGroupBalanceChangeRecordService; +import java.util.List; /** * 集团余额变动记录 Service 实现 @@ -35,4 +36,30 @@ public class AiGroupBalanceChangeRecordServiceImpl implements IAiGroupBalanceCha public int deleteById(Long id) { return aiGroupBalanceChangeRecordMapper.deleteById(id); } + + @Override + public List selectAiGroupBalanceChangeRecordList( + AiGroupBalanceChangeRecord aiGroupBalanceChangeRecord) { + return aiGroupBalanceChangeRecordMapper.selectAiGroupBalanceChangeRecordList(aiGroupBalanceChangeRecord); + } + + @Override + public AiGroupBalanceChangeRecord selectAiGroupBalanceChangeRecordById(String id) { + return aiGroupBalanceChangeRecordMapper.selectAiGroupBalanceChangeRecordById(id); + } + + @Override + public int insertAiGroupBalanceChangeRecord(AiGroupBalanceChangeRecord aiGroupBalanceChangeRecord) { + return aiGroupBalanceChangeRecordMapper.insertAiGroupBalanceChangeRecord(aiGroupBalanceChangeRecord); + } + + @Override + public int updateAiGroupBalanceChangeRecord(AiGroupBalanceChangeRecord aiGroupBalanceChangeRecord) { + return aiGroupBalanceChangeRecordMapper.updateAiGroupBalanceChangeRecord(aiGroupBalanceChangeRecord); + } + + @Override + public int deleteAiGroupBalanceChangeRecordByIds(String[] ids) { + return aiGroupBalanceChangeRecordMapper.deleteAiGroupBalanceChangeRecordByIds(ids); + } } diff --git a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiVideoReportDataServiceImpl.java b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiVideoReportDataServiceImpl.java index 8a957b1..d14631e 100644 --- a/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiVideoReportDataServiceImpl.java +++ b/web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/AiVideoReportDataServiceImpl.java @@ -6,6 +6,7 @@ import com.ruoyi.ai.service.IAiVideoReportDataService; import com.ruoyi.common.constant.RedisKey; import com.ruoyi.common.core.dto.DeptSummaryDTO; import com.ruoyi.common.utils.DateUtils; +import java.math.BigDecimal; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @@ -15,6 +16,7 @@ import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; +import java.util.List; /** * 视频报表数据 Service 实现 @@ -54,6 +56,57 @@ public class AiVideoReportDataServiceImpl implements IAiVideoReportDataService { return videoReportDataMapper.selectOneDeptSummaryData(deptId, startHour, endHour); } + @Override + public List selectTeamDailyConsumeByDeptId(String statDate, Long deptId) { + return videoReportDataMapper.selectTeamDailyConsumeByDeptId(statDate, deptId); + } + + @Override + public void syncVideoConsumeIncrement(Date createTime, Long deptId, Long userId, BigDecimal score, Long useTokens) { + if (createTime == null || deptId == null || userId == null) { + return; + } + BigDecimal scoreSafe = score != null ? score : BigDecimal.ZERO; + Long useTokensSafe = useTokens != null ? useTokens : 0L; + videoReportDataMapper.upsertVideoConsumeIncrement( + formatDateKey(createTime), + deptId, + userId, + scoreSafe, + 1L, + useTokensSafe); + } + + @Override + public List selectTeamDailyConsumeList(String statDate, String deptName) { + return videoReportDataMapper.selectTeamDailyConsumeList(statDate, deptName); + } + + @Override + public List selectAiVideoReportDataList(AiVideoReportData aiVideoReportData) { + return videoReportDataMapper.selectAiVideoReportDataList(aiVideoReportData); + } + + @Override + public AiVideoReportData selectAiVideoReportDataById(String id) { + return videoReportDataMapper.selectAiVideoReportDataById(id); + } + + @Override + public int insertAiVideoReportData(AiVideoReportData aiVideoReportData) { + return videoReportDataMapper.insertAiVideoReportData(aiVideoReportData); + } + + @Override + public int updateAiVideoReportData(AiVideoReportData aiVideoReportData) { + return videoReportDataMapper.updateAiVideoReportData(aiVideoReportData); + } + + @Override + public int deleteAiVideoReportDataByIds(String[] ids) { + return videoReportDataMapper.deleteAiVideoReportDataByIds(ids); + } + private static String formatDateKey(Date date) { LocalDateTime ldt = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); return DATE_KEY_FORMAT.format(ldt); diff --git a/web-api/ruoyi-system/src/main/resources/mapper/system/AiBalanceChangeRecordMapper.xml b/web-api/ruoyi-system/src/main/resources/mapper/system/AiBalanceChangeRecordMapper.xml index d43f1bf..4d1d8d6 100644 --- a/web-api/ruoyi-system/src/main/resources/mapper/system/AiBalanceChangeRecordMapper.xml +++ b/web-api/ruoyi-system/src/main/resources/mapper/system/AiBalanceChangeRecordMapper.xml @@ -43,6 +43,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" order by r.id desc + +