fix:新功能提交
This commit is contained in:
parent
c7334ab7d9
commit
bfa30bb543
|
|
@ -1,6 +1,6 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
|
||||||
// 查询订单管理列表
|
// 查询团队(部门)充值退款订单列表
|
||||||
export function listOrder(query) {
|
export function listOrder(query) {
|
||||||
return request({
|
return request({
|
||||||
url: '/ai/order/list',
|
url: '/ai/order/list',
|
||||||
|
|
@ -9,7 +9,7 @@ export function listOrder(query) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询订单管理详细
|
// 查询团队(部门)充值退款订单详细
|
||||||
export function getOrder(id) {
|
export function getOrder(id) {
|
||||||
return request({
|
return request({
|
||||||
url: '/ai/order/' + id,
|
url: '/ai/order/' + id,
|
||||||
|
|
@ -17,7 +17,7 @@ export function getOrder(id) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增订单管理
|
// 新增团队(部门)充值退款订单
|
||||||
export function addOrder(data) {
|
export function addOrder(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/ai/order',
|
url: '/ai/order',
|
||||||
|
|
@ -26,7 +26,7 @@ export function addOrder(data) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改订单管理
|
// 修改团队(部门)充值退款订单
|
||||||
export function updateOrder(data) {
|
export function updateOrder(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/ai/order',
|
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) {
|
export function delOrder(id) {
|
||||||
return request({
|
return request({
|
||||||
url: '/ai/order/' + id,
|
url: '/ai/order/' + id,
|
||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function downloadVideo(id) {
|
|
||||||
return request({
|
|
||||||
url: '/api/ai/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,270 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="部门ID" prop="deptId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.deptId"
|
||||||
|
placeholder="请输入部门ID"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="el-icon-plus"
|
||||||
|
size="mini"
|
||||||
|
@click="handleAdd"
|
||||||
|
v-hasPermi="['ai:config:add']"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
icon="el-icon-edit"
|
||||||
|
size="mini"
|
||||||
|
:disabled="single"
|
||||||
|
@click="handleUpdate"
|
||||||
|
v-hasPermi="['ai:config:edit']"
|
||||||
|
>修改</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
icon="el-icon-delete"
|
||||||
|
size="mini"
|
||||||
|
:disabled="multiple"
|
||||||
|
@click="handleDelete"
|
||||||
|
v-hasPermi="['ai:config:remove']"
|
||||||
|
>删除</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="el-icon-download"
|
||||||
|
size="mini"
|
||||||
|
@click="handleExport"
|
||||||
|
v-hasPermi="['ai:config:export']"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="ID" align="center" prop="id" />
|
||||||
|
<el-table-column label="部门ID" align="center" prop="deptId" />
|
||||||
|
<el-table-column label="视频模型列表JSON(label+value)" align="center" prop="modelParm" />
|
||||||
|
<el-table-column label="Byte project,加密" align="center" prop="project" />
|
||||||
|
<el-table-column label="Byte API Key,加密" align="center" prop="byteApiKey" />
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-edit"
|
||||||
|
@click="handleUpdate(scope.row)"
|
||||||
|
v-hasPermi="['ai:config:edit']"
|
||||||
|
>修改</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
@click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['ai:config:remove']"
|
||||||
|
>删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-show="total>0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNum"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 添加或修改团队(部门)对应火山引擎配置对话框 -->
|
||||||
|
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||||
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="部门ID" prop="deptId">
|
||||||
|
<el-input v-model="form.deptId" placeholder="请输入部门ID" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="视频模型列表JSON(label+value)" prop="modelParm">
|
||||||
|
<el-input v-model="form.modelParm" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="Byte project,加密" prop="project">
|
||||||
|
<el-input v-model="form.project" placeholder="请输入Byte project,加密" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="Byte API Key,加密" prop="byteApiKey">
|
||||||
|
<el-input v-model="form.byteApiKey" placeholder="请输入Byte API Key,加密" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { listConfig, getConfig, delConfig, addConfig, updateConfig } from "@/api/ai/config"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Config",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 选中数组
|
||||||
|
ids: [],
|
||||||
|
// 非单个禁用
|
||||||
|
single: true,
|
||||||
|
// 非多个禁用
|
||||||
|
multiple: true,
|
||||||
|
// 显示搜索条件
|
||||||
|
showSearch: true,
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
// 团队(部门)对应火山引擎配置表格数据
|
||||||
|
configList: [],
|
||||||
|
// 弹出层标题
|
||||||
|
title: "",
|
||||||
|
// 是否显示弹出层
|
||||||
|
open: false,
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
deptId: null,
|
||||||
|
modelParm: null,
|
||||||
|
project: null,
|
||||||
|
byteApiKey: null,
|
||||||
|
},
|
||||||
|
// 表单参数
|
||||||
|
form: {},
|
||||||
|
// 表单校验
|
||||||
|
rules: {
|
||||||
|
deptId: [
|
||||||
|
{ required: true, message: "部门ID不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询团队(部门)对应火山引擎配置列表 */
|
||||||
|
getList() {
|
||||||
|
this.loading = true
|
||||||
|
listConfig(this.queryParams).then(response => {
|
||||||
|
this.configList = response.rows
|
||||||
|
this.total = response.total
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 取消按钮
|
||||||
|
cancel() {
|
||||||
|
this.open = false
|
||||||
|
this.reset()
|
||||||
|
},
|
||||||
|
// 表单重置
|
||||||
|
reset() {
|
||||||
|
this.form = {
|
||||||
|
id: null,
|
||||||
|
deptId: null,
|
||||||
|
modelParm: null,
|
||||||
|
project: null,
|
||||||
|
byteApiKey: null,
|
||||||
|
createBy: null,
|
||||||
|
createTime: null,
|
||||||
|
updateBy: null,
|
||||||
|
updateTime: null
|
||||||
|
}
|
||||||
|
this.resetForm("form")
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNum = 1
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.resetForm("queryForm")
|
||||||
|
this.handleQuery()
|
||||||
|
},
|
||||||
|
// 多选框选中数据
|
||||||
|
handleSelectionChange(selection) {
|
||||||
|
this.ids = selection.map(item => item.id)
|
||||||
|
this.single = selection.length!==1
|
||||||
|
this.multiple = !selection.length
|
||||||
|
},
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
handleAdd() {
|
||||||
|
this.reset()
|
||||||
|
this.open = true
|
||||||
|
this.title = "添加团队(部门)对应火山引擎配置"
|
||||||
|
},
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
handleUpdate(row) {
|
||||||
|
this.reset()
|
||||||
|
const id = row.id || this.ids
|
||||||
|
getConfig(id).then(response => {
|
||||||
|
this.form = response.data
|
||||||
|
this.open = true
|
||||||
|
this.title = "修改团队(部门)对应火山引擎配置"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/** 提交按钮 */
|
||||||
|
submitForm() {
|
||||||
|
this.$refs["form"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (this.form.id != null) {
|
||||||
|
updateConfig(this.form).then(response => {
|
||||||
|
this.$modal.msgSuccess("修改成功")
|
||||||
|
this.open = false
|
||||||
|
this.getList()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
addConfig(this.form).then(response => {
|
||||||
|
this.$modal.msgSuccess("新增成功")
|
||||||
|
this.open = false
|
||||||
|
this.getList()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
handleDelete(row) {
|
||||||
|
const ids = row.id || this.ids
|
||||||
|
this.$modal.confirm('是否确认删除团队(部门)对应火山引擎配置编号为"' + ids + '"的数据项?').then(function() {
|
||||||
|
return delConfig(ids)
|
||||||
|
}).then(() => {
|
||||||
|
this.getList()
|
||||||
|
this.$modal.msgSuccess("删除成功")
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
handleExport() {
|
||||||
|
this.download('ai/config/export', {
|
||||||
|
...this.queryParams
|
||||||
|
}, `config_${new Date().getTime()}.xlsx`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -1,79 +1,59 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-form
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="88px">
|
||||||
:model="queryParams"
|
<el-form-item label="团队名称" prop="deptName">
|
||||||
ref="queryForm"
|
|
||||||
size="small"
|
|
||||||
:inline="true"
|
|
||||||
v-show="showSearch"
|
|
||||||
label-width="68px"
|
|
||||||
>
|
|
||||||
<el-form-item label="订单编号" prop="orderNum">
|
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.orderNum"
|
v-model="queryParams.deptName"
|
||||||
placeholder="请输入订单编号"
|
placeholder="支持模糊搜索"
|
||||||
clearable
|
clearable
|
||||||
@keyup.enter.native="handleQuery"
|
@keyup.enter.native="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="用户ID" prop="uuid">
|
<el-form-item label="类型" prop="orderType">
|
||||||
<el-input
|
<el-select v-model="queryParams.orderType" placeholder="全部" clearable style="width: 140px">
|
||||||
v-model="queryParams.uuid"
|
<el-option v-for="item in orderTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
placeholder="请输入用户ID"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="操作类型" prop="type">
|
|
||||||
<el-select v-model="queryParams.type" placeholder="请选择操作类型" clearable>
|
|
||||||
<el-option
|
|
||||||
v-for="dict in dict.type.ai_function_type"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="是否置顶" prop="isTop">
|
|
||||||
<el-select v-model="queryParams.isTop" placeholder="请选择" clearable>
|
|
||||||
<el-option
|
|
||||||
v-for="dict in dict.type.sys_yes_no"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="状态" prop="status">
|
|
||||||
<el-select
|
|
||||||
v-model="queryParams.status"
|
|
||||||
placeholder="请选择状态"
|
|
||||||
filterable
|
|
||||||
clearable
|
|
||||||
style="width: 200px; margin-bottom: 16px;"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(label, value) in statusMap"
|
|
||||||
:key="value"
|
|
||||||
:label="label"
|
|
||||||
:value="Number(value)"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="创建时间">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="dateRange"
|
|
||||||
style="width: 240px"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="-"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="el-icon-plus"
|
||||||
|
size="mini"
|
||||||
|
@click="handleAdd"
|
||||||
|
v-hasPermi="['ai:order:add']"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
icon="el-icon-edit"
|
||||||
|
size="mini"
|
||||||
|
:disabled="single"
|
||||||
|
@click="handleUpdate"
|
||||||
|
v-hasPermi="['ai:order:edit']"
|
||||||
|
>修改</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
icon="el-icon-delete"
|
||||||
|
size="mini"
|
||||||
|
:disabled="multiple"
|
||||||
|
@click="handleDelete"
|
||||||
|
v-hasPermi="['ai:order:remove']"
|
||||||
|
>删除</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button
|
||||||
type="warning"
|
type="warning"
|
||||||
plain
|
plain
|
||||||
|
|
@ -82,113 +62,45 @@
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
v-hasPermi="['ai:order:export']"
|
v-hasPermi="['ai:order:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-form>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
</el-row>
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="orderList" @selection-change="handleSelectionChange">
|
<el-table v-loading="loading" :data="orderList" @selection-change="handleSelectionChange">
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<el-table-column label="主键ID" align="center" prop="id" width="60" />
|
<el-table-column label="ID" align="center" prop="id" width="72" />
|
||||||
<!-- <el-table-column label="备注" align="center" prop="remark" /> -->
|
<el-table-column label="团队名称" align="center" prop="deptName" min-width="120" show-overflow-tooltip />
|
||||||
<el-table-column label="订单编号" align="center" prop="orderNum" width="150"/>
|
<el-table-column label="类型" align="center" width="100">
|
||||||
<el-table-column label="用户ID" align="center" prop="uuid" width="100" />
|
|
||||||
<el-table-column label="操作类型" align="center" prop="type" width="90" >
|
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<dict-tag :options="dict.type.ai_function_type" :value="scope.row.type" />
|
<span>{{ orderTypeLabel(scope.row.orderType) }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="金额" align="center" prop="amount" width="100" />
|
<el-table-column label="金额(元)" align="center" prop="money" width="100" />
|
||||||
<el-table-column label="生成结果" align="center" width="200">
|
<el-table-column label="积分" align="center" prop="amount" width="100" />
|
||||||
|
<el-table-column label="时间" align="center" prop="createTime" width="160">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<!-- 判断是否为链接 -->
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
<template v-if="isUrl(scope.row.result)">
|
|
||||||
<!-- 图片链接 -->
|
|
||||||
<img
|
|
||||||
v-if="isImage(scope.row.result)"
|
|
||||||
:src="scope.row.result"
|
|
||||||
class="preview-img"
|
|
||||||
@click="viewImage(scope.row.result)"
|
|
||||||
alt="预览图片"
|
|
||||||
/>
|
|
||||||
<!-- 视频链接 -->
|
|
||||||
<video
|
|
||||||
v-else-if="isVideo(scope.row.result)"
|
|
||||||
:src="scope.row.result"
|
|
||||||
class="preview-video"
|
|
||||||
@click="playVideo(scope.row.result)"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<!-- 视频任务失败等场景:result 为 VideoTaskError JSON(表格内简短,悬停看全文) -->
|
|
||||||
<template v-else-if="parseVolcTaskErrorJson(scope.row.result)">
|
|
||||||
<span
|
|
||||||
v-for="err in [parseVolcTaskErrorJson(scope.row.result)]"
|
|
||||||
:key="'oe-' + scope.row.id"
|
|
||||||
class="order-result-error-wrap"
|
|
||||||
>
|
|
||||||
<el-tooltip
|
|
||||||
placement="top-start"
|
|
||||||
effect="dark"
|
|
||||||
:open-delay="200"
|
|
||||||
popper-class="order-result-error-tooltip-popper"
|
|
||||||
>
|
|
||||||
<div slot="content" class="order-result-error-tooltip-body">
|
|
||||||
<div class="order-result-error-tooltip-row">
|
|
||||||
<span class="order-result-error-tooltip-k">错误编号:</span>
|
|
||||||
<span class="order-result-error-tooltip-v">{{ err.code || '—' }}</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="volcTaskErrorHintForCode(err.code)"
|
|
||||||
class="order-result-error-tooltip-row"
|
|
||||||
>
|
|
||||||
<span class="order-result-error-tooltip-k">中文说明:</span>
|
|
||||||
<span class="order-result-error-tooltip-v">{{
|
|
||||||
volcTaskErrorHintForCode(err.code)
|
|
||||||
}}</span>
|
|
||||||
</div>
|
|
||||||
<div class="order-result-error-tooltip-row order-result-error-tooltip-row--msg">
|
|
||||||
<span class="order-result-error-tooltip-k">信息:</span>
|
|
||||||
<span class="order-result-error-tooltip-v">{{ err.message || '—' }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span class="order-result-error-compact">{{ volcTaskErrorCellSummary(err) }}</span>
|
|
||||||
</el-tooltip>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<!-- 非链接内容(如任务 id,可点击尝试拉取视频) -->
|
|
||||||
<span v-else @click="handleOtherEvent(scope.row)">{{ scope.row.result }}</span>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="文字描述" align="center" prop="text">
|
<el-table-column label="备注" align="center" prop="remark" min-width="140" show-overflow-tooltip />
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="140">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<!-- 核心:给 popover 加 ref,触发元素绑定 v-popover -->
|
<el-button
|
||||||
<el-popover
|
size="mini"
|
||||||
ref="promptPopover"
|
type="text"
|
||||||
placement="top"
|
icon="el-icon-edit"
|
||||||
width="400"
|
@click="handleUpdate(scope.row)"
|
||||||
trigger="hover"
|
v-hasPermi="['ai:order:edit']"
|
||||||
:content="scope.row.text || '无提示词'"
|
>修改</el-button>
|
||||||
></el-popover>
|
<el-button
|
||||||
<!-- 触发元素:绑定 v-popover 到 popover 的 ref -->
|
size="mini"
|
||||||
<div
|
type="text"
|
||||||
class="text-ellipsis-two-lines"
|
icon="el-icon-delete"
|
||||||
v-popover:promptPopover
|
@click="handleDelete(scope.row)"
|
||||||
style="cursor: pointer;"
|
v-hasPermi="['ai:order:remove']"
|
||||||
>{{ scope.row.text}}</div>
|
>删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="置顶" align="center" key="status" width="60">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-switch
|
|
||||||
v-model="scope.row.isTop"
|
|
||||||
active-value="Y"
|
|
||||||
inactive-value="N"
|
|
||||||
@change="handleIsTopChange(scope.row)"
|
|
||||||
></el-switch>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="创建时间" align="center" prop="createTime" width="150"/>
|
|
||||||
<el-table-column label="状态" align="center" prop="status" :formatter="formatStatus" width="70"/>
|
|
||||||
<el-table-column label="来源" align="center" prop="source" width="70"/>
|
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<pagination
|
<pagination
|
||||||
|
|
@ -199,39 +111,40 @@
|
||||||
@pagination="getList"
|
@pagination="getList"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 添加或修改订单管理对话框 -->
|
<el-dialog :title="title" :visible.sync="open" width="560px" append-to-body>
|
||||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
<el-form-item label="团队" prop="deptId">
|
||||||
<el-form-item label="订单编号" prop="orderNum">
|
<treeselect
|
||||||
<el-input v-model="form.orderNum" placeholder="请输入订单编号" />
|
v-model="form.deptId"
|
||||||
|
:options="deptOptions"
|
||||||
|
:normalizer="normalizer"
|
||||||
|
:show-count="true"
|
||||||
|
placeholder="请选择团队(二级部门)"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="用户ID" prop="userId">
|
<el-form-item label="类型" prop="orderType">
|
||||||
<el-input v-model="form.userId" placeholder="请输入用户ID" />
|
<el-select v-model="form.orderType" placeholder="请选择" style="width: 100%">
|
||||||
</el-form-item>
|
<el-option v-for="item in orderTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
<el-form-item label="状态" prop="status">
|
|
||||||
<el-select
|
|
||||||
v-model="form.status"
|
|
||||||
placeholder="请选择状态"
|
|
||||||
filterable
|
|
||||||
clearable
|
|
||||||
style="width: 200px;"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(label, value) in statusMap"
|
|
||||||
:key="value"
|
|
||||||
:label="label"
|
|
||||||
:value="Number(value)"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="金额" prop="amount">
|
<el-form-item label="金额(元)" prop="money">
|
||||||
<el-input v-model="form.amount" placeholder="请输入金额" />
|
<el-input v-model="form.money" placeholder="可选,对账用金额" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="生成结果" prop="result">
|
<el-form-item label="积分" prop="amount">
|
||||||
<el-input v-model="form.result" placeholder="请输入生成结果" />
|
<el-input v-model="form.amount" placeholder="充值/退款填正数;手动修改可填负数表示扣减" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态" prop="status">
|
||||||
|
<el-select v-model="form.status" placeholder="请选择" style="width: 100%">
|
||||||
|
<el-option label="进行中" :value="0" />
|
||||||
|
<el-option label="已完成" :value="1" />
|
||||||
|
<el-option label="失败" :value="2" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="订单编号" prop="orderNum" v-if="form.id != null">
|
||||||
|
<el-input v-model="form.orderNum" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="备注" prop="remark">
|
||||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="对账说明、打款信息等" maxlength="500" show-word-limit />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
|
|
@ -239,424 +152,158 @@
|
||||||
<el-button @click="cancel">取 消</el-button>
|
<el-button @click="cancel">取 消</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 图片预览弹窗 -->
|
|
||||||
<el-dialog :visible.sync="imageDialogVisible" title="图片预览" width="60%">
|
|
||||||
<img :src="previewImageUrl" class="dialog-img" alt="大图预览" />
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 新增视频弹窗 -->
|
|
||||||
<el-dialog :visible.sync="videoDialogVisible" title="视频播放" width="60%">
|
|
||||||
<video :src="previewVideoUrl" controls class="dialog-video"></video>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { listOrder, getOrder, delOrder, addOrder, updateOrder } from "@/api/ai/order"
|
||||||
listOrder,
|
import { deptTreeSelect } from "@/api/system/user"
|
||||||
getOrder,
|
import Treeselect from "@riophae/vue-treeselect"
|
||||||
delOrder,
|
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
|
||||||
addOrder,
|
|
||||||
downloadVideo,
|
|
||||||
changeIsTop,
|
|
||||||
updateOrder
|
|
||||||
} from "@/api/ai/order";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Order",
|
name: "TeamChargeOrder",
|
||||||
dicts: ["ai_function_type", "sys_yes_no"],
|
components: { Treeselect },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
imageDialogVisible: false,
|
|
||||||
videoDialogVisible: false,
|
|
||||||
previewVideoUrl: "",
|
|
||||||
previewImageUrl: "",
|
|
||||||
dateRange: [],
|
|
||||||
statusMap: {
|
|
||||||
0: "进行中",
|
|
||||||
1: "已完成",
|
|
||||||
2: "已失败"
|
|
||||||
},
|
|
||||||
// 遮罩层
|
|
||||||
loading: true,
|
loading: true,
|
||||||
// 选中数组
|
|
||||||
ids: [],
|
ids: [],
|
||||||
// 非单个禁用
|
|
||||||
single: true,
|
single: true,
|
||||||
// 非多个禁用
|
|
||||||
multiple: true,
|
multiple: true,
|
||||||
// 显示搜索条件
|
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
// 总条数
|
|
||||||
total: 0,
|
total: 0,
|
||||||
// 订单管理表格数据
|
|
||||||
orderList: [],
|
orderList: [],
|
||||||
// 弹出层标题
|
|
||||||
title: "",
|
title: "",
|
||||||
// 是否显示弹出层
|
|
||||||
open: false,
|
open: false,
|
||||||
// 查询参数
|
deptOptions: [],
|
||||||
|
orderTypeOptions: [
|
||||||
|
{ label: "充值", value: 0 },
|
||||||
|
{ label: "退款", value: 1 },
|
||||||
|
{ label: "手动修改", value: 2 }
|
||||||
|
],
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
orderNum: null,
|
deptName: null,
|
||||||
userId: null,
|
orderType: null
|
||||||
type: null,
|
|
||||||
amount: null,
|
|
||||||
result: null,
|
|
||||||
status: null
|
|
||||||
},
|
},
|
||||||
// 表单参数
|
|
||||||
form: {},
|
form: {},
|
||||||
// 表单校验
|
|
||||||
rules: {
|
rules: {
|
||||||
delFlag: [
|
deptId: [{ required: true, message: "请选择团队", trigger: "change" }],
|
||||||
{ required: true, message: "删除标志不能为空", trigger: "blur" }
|
orderType: [{ required: true, message: "请选择类型", trigger: "change" }],
|
||||||
]
|
amount: [{ required: true, message: "请填写积分", trigger: "blur" }],
|
||||||
|
status: [{ required: true, message: "请选择状态", trigger: "change" }]
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getList();
|
this.getDeptTree()
|
||||||
|
this.getList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleIsTopChange(row) {
|
orderTypeLabel(orderType) {
|
||||||
let text = row.isTop === "Y" ? "置顶" : "取消置顶";
|
const n = orderType !== undefined && orderType !== null ? Number(orderType) : null
|
||||||
this.$modal
|
const hit = this.orderTypeOptions.find(o => o.value === n)
|
||||||
.confirm('确认要"' + text + '""' + row.id + '"作品吗?')
|
return hit ? hit.label : "—"
|
||||||
.then(function() {
|
|
||||||
return changeIsTop(row.id, row.isTop);
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.$modal.msgSuccess(text + "成功");
|
|
||||||
})
|
|
||||||
.catch(function() {
|
|
||||||
row.isTop = row.isTop === "Y" ? "N" : "Y";
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
// 判断是否为 http(s) URL(与 portal-ui 生成视频模块一致)
|
getDeptTree() {
|
||||||
isUrl(str) {
|
deptTreeSelect().then(response => {
|
||||||
const value = String(str || "").trim();
|
this.deptOptions = response.data || []
|
||||||
return /^https?:\/\//i.test(value);
|
})
|
||||||
},
|
},
|
||||||
/** 已知错误码对应中文说明(与门户 VideoGen 一致) */
|
normalizer(node) {
|
||||||
volcTaskErrorHintForCode(code) {
|
if (node.children && !node.children.length) {
|
||||||
const c = String(code || "").trim();
|
delete node.children
|
||||||
const hints = {
|
|
||||||
OutputVideoSensitiveContentDetected: "输出视频可能包含敏感信息",
|
|
||||||
InvalidParameter: "请求参数无效"
|
|
||||||
};
|
|
||||||
return hints[c] || "";
|
|
||||||
},
|
|
||||||
/** 表格内摘要:已知码只显示中文,未知码显示 code */
|
|
||||||
volcTaskErrorCellSummary(err) {
|
|
||||||
if (!err) return "—";
|
|
||||||
const code = String(err.code || "").trim();
|
|
||||||
const hint = this.volcTaskErrorHintForCode(code);
|
|
||||||
if (hint) return hint;
|
|
||||||
if (code) return code;
|
|
||||||
const msg = String(err.message || "").trim();
|
|
||||||
return msg ? msg.slice(0, 32) + (msg.length > 32 ? "…" : "") : "—";
|
|
||||||
},
|
|
||||||
/** 已知火山错误码后附中文说明(括号),导出等场景可用 */
|
|
||||||
volcFailureCodeWithHint(code) {
|
|
||||||
const c = String(code || "").trim();
|
|
||||||
if (!c) return "";
|
|
||||||
const hint = this.volcTaskErrorHintForCode(c);
|
|
||||||
return hint ? `${c}(${hint})` : c;
|
|
||||||
},
|
|
||||||
/** result 为火山回调失败写入的 VideoTaskError JSON 时解析为 { code, message } */
|
|
||||||
parseVolcTaskErrorJson(str) {
|
|
||||||
const s = String(str || "").trim();
|
|
||||||
if (!s || s[0] !== "{") return null;
|
|
||||||
try {
|
|
||||||
const o = JSON.parse(s);
|
|
||||||
if (
|
|
||||||
o &&
|
|
||||||
typeof o === "object" &&
|
|
||||||
!Array.isArray(o) &&
|
|
||||||
("code" in o || "message" in o)
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
code: o.code != null ? String(o.code) : "",
|
|
||||||
message: o.message != null ? String(o.message) : ""
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} catch (_) {
|
|
||||||
/* ignore */
|
|
||||||
}
|
}
|
||||||
return null;
|
return {
|
||||||
},
|
id: node.id,
|
||||||
// 判断是否为图片结果(与 portal-ui GeneratedAssets 一致)
|
label: node.label,
|
||||||
isImage(url) {
|
children: node.children
|
||||||
const value = String(url || "").trim();
|
|
||||||
if (!value) return false;
|
|
||||||
return /\.(jpeg|jpg|png|gif|webp|bmp)(\?.*)?$/i.test(value);
|
|
||||||
},
|
|
||||||
// 判断是否为视频结果(与 portal-ui VideoGen/GeneratedAssets 一致)
|
|
||||||
isVideo(url) {
|
|
||||||
const value = String(url || "").trim();
|
|
||||||
if (!value) return false;
|
|
||||||
return /\.(mp4|mov|webm|ogg|m4v|avi|mkv)(\?.*)?$/i.test(value);
|
|
||||||
},
|
|
||||||
// 查看图片
|
|
||||||
viewImage(url) {
|
|
||||||
this.previewImageUrl = url;
|
|
||||||
this.imageDialogVisible = true;
|
|
||||||
},
|
|
||||||
// 播放视频
|
|
||||||
playVideo(url) {
|
|
||||||
this.previewVideoUrl = url;
|
|
||||||
this.videoDialogVisible = true;
|
|
||||||
},
|
|
||||||
// 非链接内容点击事件
|
|
||||||
async handleOtherEvent(row) {
|
|
||||||
if (this.parseVolcTaskErrorJson(row.result)) return;
|
|
||||||
// 防止重复点击
|
|
||||||
if (row.isDownloading) return;
|
|
||||||
const originalResult = row.result;
|
|
||||||
try {
|
|
||||||
// 标记为下载中状态
|
|
||||||
row.isDownloading = true;
|
|
||||||
// 保存原始内容
|
|
||||||
|
|
||||||
// 修改显示内容为“下载中...”
|
|
||||||
row.result = "下载中...";
|
|
||||||
|
|
||||||
// 执行下载操作
|
|
||||||
const resultId = originalResult; // 假设result存储的是ID
|
|
||||||
var res = await downloadVideo(resultId);
|
|
||||||
if (res.status === "succeeded") {
|
|
||||||
row.result = res.content.video_url;
|
|
||||||
} else {
|
|
||||||
row.result = "视频生成中"
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('下载失败:', error);
|
|
||||||
// 失败后恢复原始内容
|
|
||||||
row.result = originalResult || row.result.replace("下载中...", "");
|
|
||||||
this.$message.error('下载失败,请重试');
|
|
||||||
} finally {
|
|
||||||
// 重置下载状态
|
|
||||||
row.isDownloading = false;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
formatStatus(row) {
|
|
||||||
// 如果有匹配的类型则显示对应文字,否则显示"未知"
|
|
||||||
return this.statusMap[row.status] || "未知";
|
|
||||||
},
|
|
||||||
/** 查询订单管理列表 */
|
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
listOrder(this.addDateRange(this.queryParams, this.dateRange)).then(
|
listOrder(this.queryParams).then(response => {
|
||||||
response => {
|
this.orderList = response.rows
|
||||||
this.orderList = response.rows;
|
this.total = response.total
|
||||||
this.total = response.total;
|
this.loading = false
|
||||||
this.loading = false;
|
})
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
// 取消按钮
|
|
||||||
cancel() {
|
cancel() {
|
||||||
this.open = false;
|
this.open = false
|
||||||
this.reset();
|
this.reset()
|
||||||
},
|
},
|
||||||
// 表单重置
|
|
||||||
reset() {
|
reset() {
|
||||||
this.form = {
|
this.form = {
|
||||||
id: null,
|
id: null,
|
||||||
delFlag: null,
|
deptId: undefined,
|
||||||
createBy: null,
|
orderType: 0,
|
||||||
createTime: null,
|
money: undefined,
|
||||||
updateBy: null,
|
amount: undefined,
|
||||||
updateTime: null,
|
remark: undefined,
|
||||||
remark: null,
|
status: 1,
|
||||||
orderNum: null,
|
orderNum: undefined
|
||||||
userId: null,
|
}
|
||||||
type: null,
|
this.resetForm("form")
|
||||||
amount: null,
|
|
||||||
result: null,
|
|
||||||
status: null
|
|
||||||
};
|
|
||||||
this.resetForm("form");
|
|
||||||
},
|
},
|
||||||
/** 搜索按钮操作 */
|
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
this.queryParams.pageNum = 1;
|
this.queryParams.pageNum = 1
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
/** 重置按钮操作 */
|
|
||||||
resetQuery() {
|
resetQuery() {
|
||||||
this.dateRange = [];
|
this.resetForm("queryForm")
|
||||||
this.resetForm("queryForm");
|
this.handleQuery()
|
||||||
this.handleQuery();
|
|
||||||
},
|
},
|
||||||
// 多选框选中数据
|
|
||||||
handleSelectionChange(selection) {
|
handleSelectionChange(selection) {
|
||||||
this.ids = selection.map(item => item.id);
|
this.ids = selection.map(item => item.id)
|
||||||
this.single = selection.length !== 1;
|
this.single = selection.length !== 1
|
||||||
this.multiple = !selection.length;
|
this.multiple = !selection.length
|
||||||
},
|
},
|
||||||
/** 新增按钮操作 */
|
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
this.reset();
|
this.reset()
|
||||||
this.open = true;
|
this.open = true
|
||||||
this.title = "添加订单管理";
|
this.title = "新增团队订单"
|
||||||
},
|
},
|
||||||
/** 修改按钮操作 */
|
|
||||||
handleUpdate(row) {
|
handleUpdate(row) {
|
||||||
this.reset();
|
this.reset()
|
||||||
const id = row.id || this.ids;
|
const id = row.id || this.ids[0]
|
||||||
getOrder(id).then(response => {
|
getOrder(id).then(response => {
|
||||||
this.form = response.data;
|
this.form = response.data
|
||||||
this.open = true;
|
this.open = true
|
||||||
this.title = "修改订单管理";
|
this.title = "修改团队订单"
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
/** 提交按钮 */
|
|
||||||
submitForm() {
|
submitForm() {
|
||||||
this.$refs["form"].validate(valid => {
|
this.$refs["form"].validate(valid => {
|
||||||
if (valid) {
|
if (!valid) {
|
||||||
if (this.form.id != null) {
|
return
|
||||||
updateOrder(this.form).then(response => {
|
|
||||||
this.$modal.msgSuccess("修改成功");
|
|
||||||
this.open = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
addOrder(this.form).then(response => {
|
|
||||||
this.$modal.msgSuccess("新增成功");
|
|
||||||
this.open = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
const payload = { ...this.form }
|
||||||
|
if (payload.id == null) {
|
||||||
|
addOrder(payload).then(() => {
|
||||||
|
this.$modal.msgSuccess("新增成功")
|
||||||
|
this.open = false
|
||||||
|
this.getList()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
updateOrder(payload).then(() => {
|
||||||
|
this.$modal.msgSuccess("修改成功")
|
||||||
|
this.open = false
|
||||||
|
this.getList()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
/** 删除按钮操作 */
|
|
||||||
handleDelete(row) {
|
handleDelete(row) {
|
||||||
const ids = row.id || this.ids;
|
const ids = row.id || this.ids
|
||||||
this.$modal
|
this.$modal.confirm("是否确认删除所选团队订单?").then(() => delOrder(ids)).then(() => {
|
||||||
.confirm('是否确认删除订单管理编号为"' + ids + '"的数据项?')
|
this.getList()
|
||||||
.then(function() {
|
this.$modal.msgSuccess("删除成功")
|
||||||
return delOrder(ids);
|
}).catch(() => {})
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.getList();
|
|
||||||
this.$modal.msgSuccess("删除成功");
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
|
||||||
handleExport() {
|
handleExport() {
|
||||||
this.download(
|
this.download("ai/order/export", { ...this.queryParams }, `team_orders_${new Date().getTime()}.xlsx`)
|
||||||
"ai/order/export",
|
|
||||||
{
|
|
||||||
...this.queryParams
|
|
||||||
},
|
|
||||||
`order_${new Date().getTime()}.xlsx`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
.dialog-video {
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-img {
|
|
||||||
width: 80px;
|
|
||||||
height: 60px;
|
|
||||||
object-fit: cover;
|
|
||||||
cursor: pointer;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-video {
|
|
||||||
width: 120px;
|
|
||||||
height: 80px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-img {
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.order-result-error-wrap {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.order-result-error-compact {
|
|
||||||
display: inline-block;
|
|
||||||
max-width: 200px;
|
|
||||||
margin: 0 auto;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.35;
|
|
||||||
color: #c45656;
|
|
||||||
cursor: help;
|
|
||||||
text-align: center;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.order-result-error-tooltip-body {
|
|
||||||
max-width: 420px;
|
|
||||||
text-align: left;
|
|
||||||
line-height: 1.5;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.order-result-error-tooltip-row {
|
|
||||||
margin-bottom: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.order-result-error-tooltip-row:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.order-result-error-tooltip-row--msg .order-result-error-tooltip-v {
|
|
||||||
display: block;
|
|
||||||
margin-top: 2px;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
.order-result-error-tooltip-k {
|
|
||||||
font-weight: 600;
|
|
||||||
color: #fde2e2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.order-result-error-tooltip-v {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-ellipsis-two-lines {
|
|
||||||
/* 必须设置宽度(继承表格列宽,也可手动指定) */
|
|
||||||
width: 100%;
|
|
||||||
/* 核心属性:多行文本溢出隐藏 */
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-line-clamp: 2; /* 显示2行 */
|
|
||||||
line-clamp: 2; /* 标准属性,兼容现代浏览器 */
|
|
||||||
overflow: hidden;
|
|
||||||
/* 可选:调整行高,优化显示 */
|
|
||||||
line-height: 1.5;
|
|
||||||
max-height: 3em; /* 行高1.5 × 2行 = 3em,防止高度溢出 */
|
|
||||||
/* 可选:文本对齐 */
|
|
||||||
text-align: center;
|
|
||||||
/* 解决scoped样式穿透(如果需要) */
|
|
||||||
/deep/ & {
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 0 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,312 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="订单号" prop="relationOrderNo">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.relationOrderNo"
|
||||||
|
placeholder="请输入关联(充值/退款)订单号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="部门ID" prop="deptId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.deptId"
|
||||||
|
placeholder="请输入部门ID"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="变更金额" prop="changeAmount">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.changeAmount"
|
||||||
|
placeholder="请输入变更金额"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="变更后金额" prop="resultAmount">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.resultAmount"
|
||||||
|
placeholder="请输入变更后金额"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="el-icon-plus"
|
||||||
|
size="mini"
|
||||||
|
@click="handleAdd"
|
||||||
|
v-hasPermi="['ai:record:add']"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
icon="el-icon-edit"
|
||||||
|
size="mini"
|
||||||
|
:disabled="single"
|
||||||
|
@click="handleUpdate"
|
||||||
|
v-hasPermi="['ai:record:edit']"
|
||||||
|
>修改</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
icon="el-icon-delete"
|
||||||
|
size="mini"
|
||||||
|
:disabled="multiple"
|
||||||
|
@click="handleDelete"
|
||||||
|
v-hasPermi="['ai:record:remove']"
|
||||||
|
>删除</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="el-icon-download"
|
||||||
|
size="mini"
|
||||||
|
@click="handleExport"
|
||||||
|
v-hasPermi="['ai:record:export']"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="recordList" @selection-change="handleSelectionChange">
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="ID" align="center" prop="id" />
|
||||||
|
<el-table-column label="订单号" align="center" prop="relationOrderNo" />
|
||||||
|
<el-table-column label="部门ID" align="center" prop="deptId" />
|
||||||
|
<el-table-column label="操作类型" align="center" prop="type" />
|
||||||
|
<el-table-column label="变更金额" align="center" prop="changeAmount" />
|
||||||
|
<el-table-column label="变更后金额" align="center" prop="resultAmount" />
|
||||||
|
<el-table-column label="备注" align="center" prop="remark" />
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-edit"
|
||||||
|
@click="handleUpdate(scope.row)"
|
||||||
|
v-hasPermi="['ai:record:edit']"
|
||||||
|
>修改</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
@click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['ai:record:remove']"
|
||||||
|
>删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-show="total>0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNum"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 添加或修改团队(部门)余额变动对话框 -->
|
||||||
|
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||||
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="订单号" prop="relationOrderNo">
|
||||||
|
<el-input v-model="form.relationOrderNo" placeholder="请输入关联(充值/退款)订单号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="部门ID" prop="deptId">
|
||||||
|
<el-input v-model="form.deptId" placeholder="请输入部门ID" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="变更金额" prop="changeAmount">
|
||||||
|
<el-input v-model="form.changeAmount" placeholder="请输入变更金额" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="变更后金额" prop="resultAmount">
|
||||||
|
<el-input v-model="form.resultAmount" placeholder="请输入变更后金额" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input v-model="form.remark" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { listRecord, getRecord, delRecord, addRecord, updateRecord } from "@/api/ai/record"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Record",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 选中数组
|
||||||
|
ids: [],
|
||||||
|
// 非单个禁用
|
||||||
|
single: true,
|
||||||
|
// 非多个禁用
|
||||||
|
multiple: true,
|
||||||
|
// 显示搜索条件
|
||||||
|
showSearch: true,
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
// 团队(部门)余额变动表格数据
|
||||||
|
recordList: [],
|
||||||
|
// 弹出层标题
|
||||||
|
title: "",
|
||||||
|
// 是否显示弹出层
|
||||||
|
open: false,
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
relationOrderNo: null,
|
||||||
|
deptId: null,
|
||||||
|
type: null,
|
||||||
|
changeAmount: null,
|
||||||
|
resultAmount: null,
|
||||||
|
},
|
||||||
|
// 表单参数
|
||||||
|
form: {},
|
||||||
|
// 表单校验
|
||||||
|
rules: {
|
||||||
|
deptId: [
|
||||||
|
{ required: true, message: "部门ID不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
type: [
|
||||||
|
{ required: true, message: "操作类型不能为空", trigger: "change" }
|
||||||
|
],
|
||||||
|
changeAmount: [
|
||||||
|
{ required: true, message: "变更金额不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
resultAmount: [
|
||||||
|
{ required: true, message: "变更后金额不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
createTime: [
|
||||||
|
{ required: true, message: "创建时间不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询团队(部门)余额变动列表 */
|
||||||
|
getList() {
|
||||||
|
this.loading = true
|
||||||
|
listRecord(this.queryParams).then(response => {
|
||||||
|
this.recordList = response.rows
|
||||||
|
this.total = response.total
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 取消按钮
|
||||||
|
cancel() {
|
||||||
|
this.open = false
|
||||||
|
this.reset()
|
||||||
|
},
|
||||||
|
// 表单重置
|
||||||
|
reset() {
|
||||||
|
this.form = {
|
||||||
|
id: null,
|
||||||
|
relationOrderNo: null,
|
||||||
|
deptId: null,
|
||||||
|
type: null,
|
||||||
|
changeAmount: null,
|
||||||
|
resultAmount: null,
|
||||||
|
remark: null,
|
||||||
|
createTime: null,
|
||||||
|
updateTime: null
|
||||||
|
}
|
||||||
|
this.resetForm("form")
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNum = 1
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.resetForm("queryForm")
|
||||||
|
this.handleQuery()
|
||||||
|
},
|
||||||
|
// 多选框选中数据
|
||||||
|
handleSelectionChange(selection) {
|
||||||
|
this.ids = selection.map(item => item.id)
|
||||||
|
this.single = selection.length!==1
|
||||||
|
this.multiple = !selection.length
|
||||||
|
},
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
handleAdd() {
|
||||||
|
this.reset()
|
||||||
|
this.open = true
|
||||||
|
this.title = "添加团队(部门)余额变动"
|
||||||
|
},
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
handleUpdate(row) {
|
||||||
|
this.reset()
|
||||||
|
const id = row.id || this.ids
|
||||||
|
getRecord(id).then(response => {
|
||||||
|
this.form = response.data
|
||||||
|
this.open = true
|
||||||
|
this.title = "修改团队(部门)余额变动"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/** 提交按钮 */
|
||||||
|
submitForm() {
|
||||||
|
this.$refs["form"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (this.form.id != null) {
|
||||||
|
updateRecord(this.form).then(response => {
|
||||||
|
this.$modal.msgSuccess("修改成功")
|
||||||
|
this.open = false
|
||||||
|
this.getList()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
addRecord(this.form).then(response => {
|
||||||
|
this.$modal.msgSuccess("新增成功")
|
||||||
|
this.open = false
|
||||||
|
this.getList()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
handleDelete(row) {
|
||||||
|
const ids = row.id || this.ids
|
||||||
|
this.$modal.confirm('是否确认删除团队(部门)余额变动编号为"' + ids + '"的数据项?').then(function() {
|
||||||
|
return delRecord(ids)
|
||||||
|
}).then(() => {
|
||||||
|
this.getList()
|
||||||
|
this.$modal.msgSuccess("删除成功")
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
handleExport() {
|
||||||
|
this.download('ai/record/export', {
|
||||||
|
...this.queryParams
|
||||||
|
}, `record_${new Date().getTime()}.xlsx`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -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<AiChargeRefundOrder> 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<AiChargeRefundOrder> list = aiChargeRefundOrderService.selectAiChargeRefundOrderList(aiChargeRefundOrder);
|
||||||
|
ExcelUtil<AiChargeRefundOrder> util = new ExcelUtil<AiChargeRefundOrder>(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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<AiDeptArkConfig> 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<AiDeptArkConfig> list = aiDeptArkConfigService.selectAiDeptArkConfigList(aiDeptArkConfig);
|
||||||
|
ExcelUtil<AiDeptArkConfig> util = new ExcelUtil<AiDeptArkConfig>(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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<AiGroupBalanceChangeRecord> 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<AiGroupBalanceChangeRecord> list = aiGroupBalanceChangeRecordService.selectAiGroupBalanceChangeRecordList(aiGroupBalanceChangeRecord);
|
||||||
|
ExcelUtil<AiGroupBalanceChangeRecord> util = new ExcelUtil<AiGroupBalanceChangeRecord>(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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<AiVideoReportData> 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<AiVideoReportData> list = aiVideoReportDataService.selectAiVideoReportDataList(aiVideoReportData);
|
||||||
|
ExcelUtil<AiVideoReportData> util = new ExcelUtil<AiVideoReportData>(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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -162,7 +162,7 @@ public class PortalVideoController extends BaseController {
|
||||||
List<PortalVideoProperties.ModelOption> allowed = loadModelOptionsForAiUser(uid, secondDeptId);
|
List<PortalVideoProperties.ModelOption> allowed = loadModelOptionsForAiUser(uid, secondDeptId);
|
||||||
String modelId = StringUtils.isNotEmpty(req.getModel()) ? req.getModel() : resolveDefaultModelForAiUser(uid, secondDeptId, allowed);
|
String modelId = StringUtils.isNotEmpty(req.getModel()) ? req.getModel() : resolveDefaultModelForAiUser(uid, secondDeptId, allowed);
|
||||||
if (StringUtils.isEmpty(modelId)) {
|
if (StringUtils.isEmpty(modelId)) {
|
||||||
throw new ServiceException("未配置门户视频模型:请在后台为该用户所属二级部门配置 model_parm,或在 portal.video.models 中配置全局列表");
|
throw new ServiceException("未配置门户视频模型:请在后台为该用户所属二级部门配置");
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotEmpty(req.getModel()) && !isModelInOptions(modelId, allowed)) {
|
if (StringUtils.isNotEmpty(req.getModel()) && !isModelInOptions(modelId, allowed)) {
|
||||||
throw new ServiceException("所选模型对当前部门不可用");
|
throw new ServiceException("所选模型对当前部门不可用");
|
||||||
|
|
@ -517,7 +517,7 @@ public class PortalVideoController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/options")
|
@GetMapping("/options")
|
||||||
@ApiOperation("门户视频生成可选参数(模型/比例/时长等,来自配置)")
|
@ApiOperation("门户视频生成可选参数(模型/比例/时长等,来自系统参数)")
|
||||||
public AjaxResult videoParamOptions() {
|
public AjaxResult videoParamOptions() {
|
||||||
Long uid = SecurityUtils.getAiUserId();
|
Long uid = SecurityUtils.getAiUserId();
|
||||||
Long secondDeptId = byteDeptApiKeyService.resolveSecondLevelDeptId(uid);
|
Long secondDeptId = byteDeptApiKeyService.resolveSecondLevelDeptId(uid);
|
||||||
|
|
|
||||||
|
|
@ -1,115 +1,102 @@
|
||||||
package com.ruoyi.config;
|
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 org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 门户视频生成参数(模型、比例、时长、分辨率等从配置读取,不在代码中写死业务默认值)。
|
* 门户视频生成参数(从 sys_config 读取)。
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@ConfigurationProperties(prefix = "portal.video")
|
|
||||||
public class PortalVideoProperties {
|
public class PortalVideoProperties {
|
||||||
|
|
||||||
private Defaults defaults = new Defaults();
|
private static final ObjectMapper OM = new ObjectMapper();
|
||||||
|
|
||||||
private List<ModelOption> 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";
|
||||||
|
|
||||||
/**
|
@Resource
|
||||||
* 按二级部门 {@code dept_id}(字符串,如 {@code "101"})配置专属模型列表;未命中时使用全局 {@link #models}。
|
private ISysConfigService sysConfigService;
|
||||||
*/
|
|
||||||
private Map<String, List<ModelOption>> modelsBySecondDept = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按二级部门覆盖 {@link #defaults} 中的字段;仅配置需要覆盖的项即可。
|
|
||||||
*/
|
|
||||||
private Map<String, Defaults> defaultsBySecondDept = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
private List<String> ratios = new ArrayList<>();
|
|
||||||
|
|
||||||
private List<Integer> durations = new ArrayList<>();
|
|
||||||
|
|
||||||
private List<String> resolutions = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 与 ai_manager.type 一致,用于扣费与订单;库中需存在对应记录且 status=0、del_flag=0
|
|
||||||
*/
|
|
||||||
private String functionType = "21";
|
|
||||||
|
|
||||||
public String getFunctionType() {
|
public String getFunctionType() {
|
||||||
return functionType;
|
String functionType = trimToNull(sysConfigService.selectConfigByKey(CFG_FUNCTION_TYPE));
|
||||||
}
|
return functionType != null ? functionType : DEFAULT_FUNCTION_TYPE;
|
||||||
|
|
||||||
public void setFunctionType(String functionType) {
|
|
||||||
this.functionType = functionType != null ? functionType : "21";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Defaults getDefaults() {
|
public Defaults getDefaults() {
|
||||||
return defaults;
|
Defaults defaults = parseObjectConfig(CFG_DEFAULTS, Defaults.class);
|
||||||
}
|
return defaults != null ? defaults : new Defaults();
|
||||||
|
|
||||||
public void setDefaults(Defaults defaults) {
|
|
||||||
if (defaults != null) {
|
|
||||||
this.defaults = defaults;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ModelOption> getModels() {
|
public List<ModelOption> getModels() {
|
||||||
return models;
|
List<ModelOption> models = parseListConfig(CFG_MODELS, new TypeReference<List<ModelOption>>() {
|
||||||
}
|
});
|
||||||
|
return models != null ? models : new ArrayList<>();
|
||||||
public void setModels(List<ModelOption> models) {
|
|
||||||
this.models = models != null ? models : new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, List<ModelOption>> getModelsBySecondDept() {
|
public Map<String, List<ModelOption>> getModelsBySecondDept() {
|
||||||
return modelsBySecondDept;
|
Map<String, List<ModelOption>> map = parseObjectConfig(CFG_MODELS_BY_SECOND_DEPT,
|
||||||
}
|
new TypeReference<Map<String, List<ModelOption>>>() {
|
||||||
|
});
|
||||||
public void setModelsBySecondDept(Map<String, List<ModelOption>> modelsBySecondDept) {
|
return map != null ? map : new LinkedHashMap<>();
|
||||||
this.modelsBySecondDept = modelsBySecondDept != null ? modelsBySecondDept : new LinkedHashMap<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Defaults> getDefaultsBySecondDept() {
|
public Map<String, Defaults> getDefaultsBySecondDept() {
|
||||||
return defaultsBySecondDept;
|
Map<String, Defaults> map = parseObjectConfig(CFG_DEFAULTS_BY_SECOND_DEPT,
|
||||||
}
|
new TypeReference<Map<String, Defaults>>() {
|
||||||
|
});
|
||||||
public void setDefaultsBySecondDept(Map<String, Defaults> defaultsBySecondDept) {
|
return map != null ? map : new LinkedHashMap<>();
|
||||||
this.defaultsBySecondDept = defaultsBySecondDept != null ? defaultsBySecondDept : new LinkedHashMap<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getRatios() {
|
public List<String> getRatios() {
|
||||||
return ratios;
|
List<String> ratios = parseListConfig(CFG_RATIOS, new TypeReference<List<String>>() {
|
||||||
}
|
});
|
||||||
|
return ratios != null ? ratios : Collections.emptyList();
|
||||||
public void setRatios(List<String> ratios) {
|
|
||||||
this.ratios = ratios != null ? ratios : new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Integer> getDurations() {
|
public List<Integer> getDurations() {
|
||||||
return durations;
|
List<Integer> durations = parseListConfig(CFG_DURATIONS, new TypeReference<List<Integer>>() {
|
||||||
}
|
});
|
||||||
|
return durations != null ? durations : Collections.emptyList();
|
||||||
public void setDurations(List<Integer> durations) {
|
|
||||||
this.durations = durations != null ? durations : new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getResolutions() {
|
public List<String> getResolutions() {
|
||||||
return resolutions;
|
List<String> resolutions = parseListConfig(CFG_RESOLUTIONS, new TypeReference<List<String>>() {
|
||||||
}
|
});
|
||||||
|
return resolutions != null ? resolutions : Collections.emptyList();
|
||||||
public void setResolutions(List<String> resolutions) {
|
|
||||||
this.resolutions = resolutions != null ? resolutions : new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* defaults.model 为空时,取 models 第一项的 value。
|
* defaults.model 为空时,取 models 第一项的 value。
|
||||||
*/
|
*/
|
||||||
public String resolveDefaultModelId() {
|
public String resolveDefaultModelId() {
|
||||||
|
Defaults defaults = getDefaults();
|
||||||
|
List<ModelOption> models = getModels();
|
||||||
if (defaults.getModel() != null && !defaults.getModel().isEmpty()) {
|
if (defaults.getModel() != null && !defaults.getModel().isEmpty()) {
|
||||||
return defaults.getModel();
|
return defaults.getModel();
|
||||||
}
|
}
|
||||||
|
|
@ -120,6 +107,8 @@ public class PortalVideoProperties {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ModelOption> resolveModelsForSecondDept(Long secondDeptId) {
|
public List<ModelOption> resolveModelsForSecondDept(Long secondDeptId) {
|
||||||
|
Map<String, List<ModelOption>> modelsBySecondDept = getModelsBySecondDept();
|
||||||
|
List<ModelOption> models = getModels();
|
||||||
if (secondDeptId != null) {
|
if (secondDeptId != null) {
|
||||||
List<ModelOption> byDept = modelsBySecondDept.get(String.valueOf(secondDeptId));
|
List<ModelOption> byDept = modelsBySecondDept.get(String.valueOf(secondDeptId));
|
||||||
if (byDept != null && !byDept.isEmpty()) {
|
if (byDept != null && !byDept.isEmpty()) {
|
||||||
|
|
@ -131,12 +120,13 @@ public class PortalVideoProperties {
|
||||||
|
|
||||||
public Defaults resolveEffectiveDefaults(Long secondDeptId) {
|
public Defaults resolveEffectiveDefaults(Long secondDeptId) {
|
||||||
Defaults out = new Defaults();
|
Defaults out = new Defaults();
|
||||||
Defaults g = this.defaults;
|
Defaults g = this.getDefaults();
|
||||||
out.setModel(g.getModel());
|
out.setModel(g.getModel());
|
||||||
out.setDuration(g.getDuration());
|
out.setDuration(g.getDuration());
|
||||||
out.setResolution(g.getResolution());
|
out.setResolution(g.getResolution());
|
||||||
out.setRatio(g.getRatio());
|
out.setRatio(g.getRatio());
|
||||||
if (secondDeptId != null) {
|
if (secondDeptId != null) {
|
||||||
|
Map<String, Defaults> defaultsBySecondDept = getDefaultsBySecondDept();
|
||||||
Defaults o = defaultsBySecondDept.get(String.valueOf(secondDeptId));
|
Defaults o = defaultsBySecondDept.get(String.valueOf(secondDeptId));
|
||||||
if (o != null) {
|
if (o != null) {
|
||||||
if (o.getModel() != null && !o.getModel().isEmpty()) {
|
if (o.getModel() != null && !o.getModel().isEmpty()) {
|
||||||
|
|
@ -183,6 +173,51 @@ public class PortalVideoProperties {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T> T parseObjectConfig(String key, Class<T> 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> T parseObjectConfig(String key, TypeReference<T> typeReference) {
|
||||||
|
String raw = trimToNull(sysConfigService.selectConfigByKey(key));
|
||||||
|
if (raw == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return OM.readValue(raw, typeReference);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> List<T> parseListConfig(String key, TypeReference<List<T>> typeReference) {
|
||||||
|
String raw = trimToNull(sysConfigService.selectConfigByKey(key));
|
||||||
|
if (raw == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
List<T> 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 {
|
public static class Defaults {
|
||||||
private String model;
|
private String model;
|
||||||
private Integer duration;
|
private Integer duration;
|
||||||
|
|
|
||||||
|
|
@ -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<AiUser> 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<AiOrder> 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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<AiOrder> selectVideoOrders(AiOrder query);
|
||||||
|
|
||||||
|
List<AiChargeRefundOrder> selectChargeRefundOrders(AiChargeRefundOrder query);
|
||||||
|
|
||||||
|
List<AiBalanceChangeRecord> selectUserBalanceRecords(AiBalanceChangeRecord query);
|
||||||
|
|
||||||
|
List<AiGroupBalanceChangeRecord> selectGroupBalanceRecords(AiGroupBalanceChangeRecord query);
|
||||||
|
|
||||||
|
List<AiVideoReportData> selectTeamDailyConsume(String statDate);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.ruoyi.system.service.subteam;
|
||||||
|
|
||||||
|
import com.ruoyi.system.domain.subteam.SubteamOverviewVO;
|
||||||
|
|
||||||
|
public interface ISubteamOverviewService {
|
||||||
|
|
||||||
|
SubteamOverviewVO loadOverview();
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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<AiOrder> selectVideoOrders(AiOrder query) {
|
||||||
|
Long deptId = subteamScopeService.currentTeamDeptId();
|
||||||
|
query.setDeptId(deptId);
|
||||||
|
return aiOrderMapper.selectAiOrderList(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AiChargeRefundOrder> selectChargeRefundOrders(AiChargeRefundOrder query) {
|
||||||
|
Long deptId = subteamScopeService.currentTeamDeptId();
|
||||||
|
query.setDeptId(deptId);
|
||||||
|
return aiChargeRefundOrderMapper.selectAiChargeRefundOrderList(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AiBalanceChangeRecord> selectUserBalanceRecords(AiBalanceChangeRecord query) {
|
||||||
|
Long deptId = subteamScopeService.currentTeamDeptId();
|
||||||
|
return aiBalanceChangeRecordMapper.selectAiBalanceChangeRecordListByAiUserDept(query, deptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AiGroupBalanceChangeRecord> selectGroupBalanceRecords(AiGroupBalanceChangeRecord query) {
|
||||||
|
Long deptId = subteamScopeService.currentTeamDeptId();
|
||||||
|
query.setDeptId(deptId);
|
||||||
|
return aiGroupBalanceChangeRecordMapper.selectList(
|
||||||
|
Wrappers.lambdaQuery(query).orderByDesc(AiGroupBalanceChangeRecord::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AiVideoReportData> selectTeamDailyConsume(String statDate) {
|
||||||
|
if (StringUtils.isEmpty(statDate)) {
|
||||||
|
return java.util.Collections.emptyList();
|
||||||
|
}
|
||||||
|
Long deptId = subteamScopeService.currentTeamDeptId();
|
||||||
|
return aiVideoReportDataService.selectTeamDailyConsumeByDeptId(statDate, deptId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
<?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="com.ruoyi.ai.mapper.AiChargeRefundOrderMapper">
|
||||||
|
|
||||||
|
<resultMap type="AiChargeRefundOrder" id="AiChargeRefundOrderResult">
|
||||||
|
<result property="id" column="id" />
|
||||||
|
<result property="delFlag" column="del_flag" />
|
||||||
|
<result property="createBy" column="create_by" />
|
||||||
|
<result property="createTime" column="create_time" />
|
||||||
|
<result property="updateTime" column="update_time" />
|
||||||
|
<result property="orderNum" column="order_num" />
|
||||||
|
<result property="thirdPartyOrderNum" column="third_party_order_num" />
|
||||||
|
<result property="deptId" column="dept_id" />
|
||||||
|
<result property="deptName" column="dept_name" />
|
||||||
|
<result property="orderType" column="order_type" />
|
||||||
|
<result property="money" column="money" />
|
||||||
|
<result property="amount" column="amount" />
|
||||||
|
<result property="remark" column="remark" />
|
||||||
|
<result property="status" column="status" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectAiChargeRefundOrderVo">
|
||||||
|
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'
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectAiChargeRefundOrderList" parameterType="AiChargeRefundOrder" resultMap="AiChargeRefundOrderResult">
|
||||||
|
<include refid="selectAiChargeRefundOrderVo"/>
|
||||||
|
<where>
|
||||||
|
and o.del_flag = '0'
|
||||||
|
<if test="orderNum != null and orderNum != ''"> and o.order_num = #{orderNum}</if>
|
||||||
|
<if test="thirdPartyOrderNum != null and thirdPartyOrderNum != ''"> and o.third_party_order_num = #{thirdPartyOrderNum}</if>
|
||||||
|
<if test="deptId != null "> and o.dept_id = #{deptId}</if>
|
||||||
|
<if test="deptName != null and deptName != ''"> and d.dept_name like concat('%', #{deptName}, '%')</if>
|
||||||
|
<if test="orderType != null "> and o.order_type = #{orderType}</if>
|
||||||
|
<if test="money != null "> and o.money = #{money}</if>
|
||||||
|
<if test="amount != null "> and o.amount = #{amount}</if>
|
||||||
|
<if test="status != null "> and o.status = #{status}</if>
|
||||||
|
</where>
|
||||||
|
order by o.id desc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAiChargeRefundOrderById" parameterType="Long" resultMap="AiChargeRefundOrderResult">
|
||||||
|
<include refid="selectAiChargeRefundOrderVo"/>
|
||||||
|
where o.id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insertAiChargeRefundOrder" parameterType="AiChargeRefundOrder" useGeneratedKeys="true" keyProperty="id">
|
||||||
|
insert into ai_charge_refund_order
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="delFlag != null and delFlag != ''">del_flag,</if>
|
||||||
|
<if test="createBy != null">create_by,</if>
|
||||||
|
<if test="createTime != null">create_time,</if>
|
||||||
|
<if test="updateTime != null">update_time,</if>
|
||||||
|
<if test="orderNum != null and orderNum != ''">order_num,</if>
|
||||||
|
<if test="thirdPartyOrderNum != null">third_party_order_num,</if>
|
||||||
|
<if test="deptId != null">dept_id,</if>
|
||||||
|
<if test="orderType != null">order_type,</if>
|
||||||
|
<if test="money != null">money,</if>
|
||||||
|
<if test="amount != null">amount,</if>
|
||||||
|
<if test="remark != null">remark,</if>
|
||||||
|
<if test="status != null">status,</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="delFlag != null and delFlag != ''">#{delFlag},</if>
|
||||||
|
<if test="createBy != null">#{createBy},</if>
|
||||||
|
<if test="createTime != null">#{createTime},</if>
|
||||||
|
<if test="updateTime != null">#{updateTime},</if>
|
||||||
|
<if test="orderNum != null and orderNum != ''">#{orderNum},</if>
|
||||||
|
<if test="thirdPartyOrderNum != null">#{thirdPartyOrderNum},</if>
|
||||||
|
<if test="deptId != null">#{deptId},</if>
|
||||||
|
<if test="orderType != null">#{orderType},</if>
|
||||||
|
<if test="money != null">#{money},</if>
|
||||||
|
<if test="amount != null">#{amount},</if>
|
||||||
|
<if test="remark != null">#{remark},</if>
|
||||||
|
<if test="status != null">#{status},</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateAiChargeRefundOrder" parameterType="AiChargeRefundOrder">
|
||||||
|
update ai_charge_refund_order
|
||||||
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="delFlag != null and delFlag != ''">del_flag = #{delFlag},</if>
|
||||||
|
<if test="createBy != null">create_by = #{createBy},</if>
|
||||||
|
<if test="createTime != null">create_time = #{createTime},</if>
|
||||||
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||||
|
<if test="orderNum != null and orderNum != ''">order_num = #{orderNum},</if>
|
||||||
|
<if test="thirdPartyOrderNum != null">third_party_order_num = #{thirdPartyOrderNum},</if>
|
||||||
|
<if test="deptId != null">dept_id = #{deptId},</if>
|
||||||
|
<if test="orderType != null">order_type = #{orderType},</if>
|
||||||
|
<if test="money != null">money = #{money},</if>
|
||||||
|
<if test="amount != null">amount = #{amount},</if>
|
||||||
|
<if test="remark != null">remark = #{remark},</if>
|
||||||
|
<if test="status != null">status = #{status},</if>
|
||||||
|
</trim>
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<delete id="deleteAiChargeRefundOrderById" parameterType="Long">
|
||||||
|
delete from ai_charge_refund_order where id = #{id}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<delete id="deleteAiChargeRefundOrderByIds" parameterType="String">
|
||||||
|
delete from ai_charge_refund_order where id in
|
||||||
|
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
|
</mapper>
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
<?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="com.ruoyi.ai.mapper.AiDeptArkConfigMapper">
|
||||||
|
|
||||||
|
<resultMap type="AiDeptArkConfig" id="AiDeptArkConfigResult">
|
||||||
|
<result property="id" column="id" />
|
||||||
|
<result property="deptId" column="dept_id" />
|
||||||
|
<result property="modelParm" column="model_parm" />
|
||||||
|
<result property="project" column="project" />
|
||||||
|
<result property="byteApiKey" column="byte_api_key" />
|
||||||
|
<result property="createBy" column="create_by" />
|
||||||
|
<result property="createTime" column="create_time" />
|
||||||
|
<result property="updateBy" column="update_by" />
|
||||||
|
<result property="updateTime" column="update_time" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectAiDeptArkConfigVo">
|
||||||
|
select id, dept_id, model_parm, project, byte_api_key, create_by, create_time, update_by, update_time from ai_dept_ark_config
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectAiDeptArkConfigList" parameterType="AiDeptArkConfig" resultMap="AiDeptArkConfigResult">
|
||||||
|
<include refid="selectAiDeptArkConfigVo"/>
|
||||||
|
<where>
|
||||||
|
<if test="deptId != null "> and dept_id = #{deptId}</if>
|
||||||
|
<if test="modelParm != null and modelParm != ''"> and model_parm = #{modelParm}</if>
|
||||||
|
<if test="project != null and project != ''"> and project = #{project}</if>
|
||||||
|
<if test="byteApiKey != null and byteApiKey != ''"> and byte_api_key = #{byteApiKey}</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAiDeptArkConfigById" parameterType="String" resultMap="AiDeptArkConfigResult">
|
||||||
|
<include refid="selectAiDeptArkConfigVo"/>
|
||||||
|
where id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insertAiDeptArkConfig" parameterType="AiDeptArkConfig" useGeneratedKeys="true" keyProperty="id">
|
||||||
|
insert into ai_dept_ark_config
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="deptId != null">dept_id,</if>
|
||||||
|
<if test="modelParm != null">model_parm,</if>
|
||||||
|
<if test="project != null">project,</if>
|
||||||
|
<if test="byteApiKey != null">byte_api_key,</if>
|
||||||
|
<if test="createBy != null">create_by,</if>
|
||||||
|
<if test="createTime != null">create_time,</if>
|
||||||
|
<if test="updateBy != null">update_by,</if>
|
||||||
|
<if test="updateTime != null">update_time,</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="deptId != null">#{deptId},</if>
|
||||||
|
<if test="modelParm != null">#{modelParm},</if>
|
||||||
|
<if test="project != null">#{project},</if>
|
||||||
|
<if test="byteApiKey != null">#{byteApiKey},</if>
|
||||||
|
<if test="createBy != null">#{createBy},</if>
|
||||||
|
<if test="createTime != null">#{createTime},</if>
|
||||||
|
<if test="updateBy != null">#{updateBy},</if>
|
||||||
|
<if test="updateTime != null">#{updateTime},</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateAiDeptArkConfig" parameterType="AiDeptArkConfig">
|
||||||
|
update ai_dept_ark_config
|
||||||
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="deptId != null">dept_id = #{deptId},</if>
|
||||||
|
<if test="modelParm != null">model_parm = #{modelParm},</if>
|
||||||
|
<if test="project != null">project = #{project},</if>
|
||||||
|
<if test="byteApiKey != null">byte_api_key = #{byteApiKey},</if>
|
||||||
|
<if test="createBy != null">create_by = #{createBy},</if>
|
||||||
|
<if test="createTime != null">create_time = #{createTime},</if>
|
||||||
|
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||||
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||||
|
</trim>
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<delete id="deleteAiDeptArkConfigById" parameterType="String">
|
||||||
|
delete from ai_dept_ark_config where id = #{id}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<delete id="deleteAiDeptArkConfigByIds" parameterType="String">
|
||||||
|
delete from ai_dept_ark_config where id in
|
||||||
|
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
|
</mapper>
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
<?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="com.ruoyi.ai.mapper.AiGroupBalanceChangeRecordMapper">
|
||||||
|
|
||||||
|
<resultMap type="AiGroupBalanceChangeRecord" id="AiGroupBalanceChangeRecordResult">
|
||||||
|
<result property="id" column="id" />
|
||||||
|
<result property="relationOrderNo" column="relation_order_no" />
|
||||||
|
<result property="deptId" column="dept_id" />
|
||||||
|
<result property="type" column="type" />
|
||||||
|
<result property="changeAmount" column="change_amount" />
|
||||||
|
<result property="resultAmount" column="result_amount" />
|
||||||
|
<result property="remark" column="remark" />
|
||||||
|
<result property="createTime" column="create_time" />
|
||||||
|
<result property="updateTime" column="update_time" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectAiGroupBalanceChangeRecordVo">
|
||||||
|
select id, relation_order_no, dept_id, type, change_amount, result_amount, remark, create_time, update_time from ai_group_balance_change_record
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectAiGroupBalanceChangeRecordList" parameterType="AiGroupBalanceChangeRecord" resultMap="AiGroupBalanceChangeRecordResult">
|
||||||
|
<include refid="selectAiGroupBalanceChangeRecordVo"/>
|
||||||
|
<where>
|
||||||
|
<if test="relationOrderNo != null and relationOrderNo != ''"> and relation_order_no = #{relationOrderNo}</if>
|
||||||
|
<if test="deptId != null "> and dept_id = #{deptId}</if>
|
||||||
|
<if test="type != null "> and type = #{type}</if>
|
||||||
|
<if test="changeAmount != null "> and change_amount = #{changeAmount}</if>
|
||||||
|
<if test="resultAmount != null "> and result_amount = #{resultAmount}</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAiGroupBalanceChangeRecordById" parameterType="String" resultMap="AiGroupBalanceChangeRecordResult">
|
||||||
|
<include refid="selectAiGroupBalanceChangeRecordVo"/>
|
||||||
|
where id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insertAiGroupBalanceChangeRecord" parameterType="AiGroupBalanceChangeRecord" useGeneratedKeys="true" keyProperty="id">
|
||||||
|
insert into ai_group_balance_change_record
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="relationOrderNo != null">relation_order_no,</if>
|
||||||
|
<if test="deptId != null">dept_id,</if>
|
||||||
|
<if test="type != null">type,</if>
|
||||||
|
<if test="changeAmount != null">change_amount,</if>
|
||||||
|
<if test="resultAmount != null">result_amount,</if>
|
||||||
|
<if test="remark != null">remark,</if>
|
||||||
|
<if test="createTime != null">create_time,</if>
|
||||||
|
<if test="updateTime != null">update_time,</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="relationOrderNo != null">#{relationOrderNo},</if>
|
||||||
|
<if test="deptId != null">#{deptId},</if>
|
||||||
|
<if test="type != null">#{type},</if>
|
||||||
|
<if test="changeAmount != null">#{changeAmount},</if>
|
||||||
|
<if test="resultAmount != null">#{resultAmount},</if>
|
||||||
|
<if test="remark != null">#{remark},</if>
|
||||||
|
<if test="createTime != null">#{createTime},</if>
|
||||||
|
<if test="updateTime != null">#{updateTime},</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateAiGroupBalanceChangeRecord" parameterType="AiGroupBalanceChangeRecord">
|
||||||
|
update ai_group_balance_change_record
|
||||||
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="relationOrderNo != null">relation_order_no = #{relationOrderNo},</if>
|
||||||
|
<if test="deptId != null">dept_id = #{deptId},</if>
|
||||||
|
<if test="type != null">type = #{type},</if>
|
||||||
|
<if test="changeAmount != null">change_amount = #{changeAmount},</if>
|
||||||
|
<if test="resultAmount != null">result_amount = #{resultAmount},</if>
|
||||||
|
<if test="remark != null">remark = #{remark},</if>
|
||||||
|
<if test="createTime != null">create_time = #{createTime},</if>
|
||||||
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||||
|
</trim>
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<delete id="deleteAiGroupBalanceChangeRecordById" parameterType="String">
|
||||||
|
delete from ai_group_balance_change_record where id = #{id}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<delete id="deleteAiGroupBalanceChangeRecordByIds" parameterType="String">
|
||||||
|
delete from ai_group_balance_change_record where id in
|
||||||
|
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
|
</mapper>
|
||||||
|
|
@ -0,0 +1,161 @@
|
||||||
|
<?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="com.ruoyi.ai.mapper.AiVideoReportDataMapper">
|
||||||
|
|
||||||
|
<resultMap type="AiVideoReportData" id="AiVideoReportDataResult">
|
||||||
|
<result property="id" column="id" />
|
||||||
|
<result property="dateKey" column="date_key" />
|
||||||
|
<result property="deptId" column="dept_id" />
|
||||||
|
<result property="userId" column="user_id" />
|
||||||
|
<result property="score" column="score" />
|
||||||
|
<result property="orderCount" column="order_count" />
|
||||||
|
<result property="useTokens" column="use_tokens" />
|
||||||
|
<result property="rechargeScore" column="recharge_score" />
|
||||||
|
<result property="deptName" column="dept_name" />
|
||||||
|
<result property="createTime" column="create_time" />
|
||||||
|
<result property="updateTime" column="update_time" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectAiVideoReportDataVo">
|
||||||
|
select id, date_key, dept_id, user_id, score, order_count, use_tokens, recharge_score, create_time, update_time from ai_video_report_data
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectAiVideoReportDataList" parameterType="AiVideoReportData" resultMap="AiVideoReportDataResult">
|
||||||
|
<include refid="selectAiVideoReportDataVo"/>
|
||||||
|
<where>
|
||||||
|
<if test="dateKey != null and dateKey != ''"> and date_key = #{dateKey}</if>
|
||||||
|
<if test="deptId != null "> and dept_id = #{deptId}</if>
|
||||||
|
<if test="userId != null "> and user_id = #{userId}</if>
|
||||||
|
<if test="score != null "> and score = #{score}</if>
|
||||||
|
<if test="orderCount != null "> and order_count = #{orderCount}</if>
|
||||||
|
<if test="useTokens != null "> and use_tokens = #{useTokens}</if>
|
||||||
|
<if test="rechargeScore != null "> and recharge_score = #{rechargeScore}</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAiVideoReportDataById" parameterType="String" resultMap="AiVideoReportDataResult">
|
||||||
|
<include refid="selectAiVideoReportDataVo"/>
|
||||||
|
where id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insertAiVideoReportData" parameterType="AiVideoReportData" useGeneratedKeys="true" keyProperty="id">
|
||||||
|
insert into ai_video_report_data
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="dateKey != null and dateKey != ''">date_key,</if>
|
||||||
|
<if test="deptId != null">dept_id,</if>
|
||||||
|
<if test="userId != null">user_id,</if>
|
||||||
|
<if test="score != null">score,</if>
|
||||||
|
<if test="orderCount != null">order_count,</if>
|
||||||
|
<if test="useTokens != null">use_tokens,</if>
|
||||||
|
<if test="rechargeScore != null">recharge_score,</if>
|
||||||
|
<if test="createTime != null">create_time,</if>
|
||||||
|
<if test="updateTime != null">update_time,</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="dateKey != null and dateKey != ''">#{dateKey},</if>
|
||||||
|
<if test="deptId != null">#{deptId},</if>
|
||||||
|
<if test="userId != null">#{userId},</if>
|
||||||
|
<if test="score != null">#{score},</if>
|
||||||
|
<if test="orderCount != null">#{orderCount},</if>
|
||||||
|
<if test="useTokens != null">#{useTokens},</if>
|
||||||
|
<if test="rechargeScore != null">#{rechargeScore},</if>
|
||||||
|
<if test="createTime != null">#{createTime},</if>
|
||||||
|
<if test="updateTime != null">#{updateTime},</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateAiVideoReportData" parameterType="AiVideoReportData">
|
||||||
|
update ai_video_report_data
|
||||||
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="dateKey != null and dateKey != ''">date_key = #{dateKey},</if>
|
||||||
|
<if test="deptId != null">dept_id = #{deptId},</if>
|
||||||
|
<if test="userId != null">user_id = #{userId},</if>
|
||||||
|
<if test="score != null">score = #{score},</if>
|
||||||
|
<if test="orderCount != null">order_count = #{orderCount},</if>
|
||||||
|
<if test="useTokens != null">use_tokens = #{useTokens},</if>
|
||||||
|
<if test="rechargeScore != null">recharge_score = #{rechargeScore},</if>
|
||||||
|
<if test="createTime != null">create_time = #{createTime},</if>
|
||||||
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||||
|
</trim>
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<select id="selectTeamDailyConsumeList" resultMap="AiVideoReportDataResult">
|
||||||
|
select
|
||||||
|
concat(substr(vrd.date_key, 1, 4), '-', substr(vrd.date_key, 5, 2), '-', substr(vrd.date_key, 7, 2)) as date_key,
|
||||||
|
vrd.dept_id,
|
||||||
|
d.dept_name,
|
||||||
|
sum(vrd.recharge_score) as recharge_score,
|
||||||
|
sum(vrd.score) as score,
|
||||||
|
sum(vrd.order_count) as order_count,
|
||||||
|
sum(vrd.use_tokens) as use_tokens
|
||||||
|
from ai_video_report_data vrd
|
||||||
|
left join sys_dept d on d.dept_id = vrd.dept_id
|
||||||
|
where vrd.date_key like concat(#{statDate}, '%')
|
||||||
|
and d.dept_name like concat('%', #{deptName}, '%')
|
||||||
|
group by substr(vrd.date_key, 1, 8), vrd.dept_id, d.dept_name
|
||||||
|
order by substr(vrd.date_key, 1, 8) desc, vrd.dept_id desc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectTeamDailyConsumeByDeptId" resultMap="AiVideoReportDataResult">
|
||||||
|
select
|
||||||
|
concat(substr(vrd.date_key, 1, 4), '-', substr(vrd.date_key, 5, 2), '-', substr(vrd.date_key, 7, 2)) as date_key,
|
||||||
|
vrd.dept_id,
|
||||||
|
d.dept_name,
|
||||||
|
sum(vrd.recharge_score) as recharge_score,
|
||||||
|
sum(vrd.score) as score,
|
||||||
|
sum(vrd.order_count) as order_count,
|
||||||
|
sum(vrd.use_tokens) as use_tokens
|
||||||
|
from ai_video_report_data vrd
|
||||||
|
left join sys_dept d on d.dept_id = vrd.dept_id
|
||||||
|
where vrd.date_key like concat(#{statDate}, '%')
|
||||||
|
and vrd.dept_id = #{deptId}
|
||||||
|
group by substr(vrd.date_key, 1, 8), vrd.dept_id, d.dept_name
|
||||||
|
order by substr(vrd.date_key, 1, 8) desc, vrd.dept_id desc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectDeptVideoMetricsBetween" resultType="com.ruoyi.system.domain.subteam.SubteamVideoMetrics">
|
||||||
|
select
|
||||||
|
coalesce(sum(vrd.score), 0) as consumeScore,
|
||||||
|
coalesce(sum(vrd.order_count), 0) as orderCount
|
||||||
|
from ai_video_report_data vrd
|
||||||
|
where vrd.dept_id = #{deptId}
|
||||||
|
and substr(vrd.date_key, 1, 8) >= #{startDay}
|
||||||
|
and substr(vrd.date_key, 1, 8) <= #{endDay}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="upsertVideoConsumeIncrement">
|
||||||
|
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>
|
||||||
|
|
||||||
|
<insert id="upsertRechargeScoreIncrement">
|
||||||
|
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()
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<delete id="deleteAiVideoReportDataById" parameterType="String">
|
||||||
|
delete from ai_video_report_data where id = #{id}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<delete id="deleteAiVideoReportDataByIds" parameterType="String">
|
||||||
|
delete from ai_video_report_data where id in
|
||||||
|
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
|
</mapper>
|
||||||
Loading…
Reference in New Issue