fix:新功能提交 子后台新增下放积分

This commit is contained in:
old burden 2026-04-20 17:40:14 +08:00
parent b3b54f14bc
commit a3bc2e24da
8 changed files with 169 additions and 29 deletions

View File

@ -10,13 +10,21 @@
clearable
/>
</el-form-item>
<el-form-item label="团队名称" prop="deptName">
<el-input
v-model="queryParams.deptName"
placeholder="请输入团队名称"
<el-form-item label="团队名称" prop="deptId">
<el-select
v-model="queryParams.deptId"
placeholder="请选择团队"
clearable
@keyup.enter.native="handleQuery"
filterable
style="width: 220px"
>
<el-option
v-for="item in deptOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
@ -50,19 +58,22 @@
<script>
import { listData } from "@/api/ai/data"
import { listDept } from "@/api/ai/dept"
export default {
name: "TeamConsumeData",
data() {
return {
//
loading: true,
//
loading: false,
//
showSearch: true,
//
total: 0,
//
dataList: [],
//
deptOptions: [],
//
searched: false,
//
@ -70,11 +81,28 @@ export default {
pageNum: 1,
pageSize: 10,
statDate: null,
deptName: null
deptId: null
},
}
},
created() {
this.loadSecondLevelDeptOptions()
},
methods: {
/** 加载二级部门选项 */
loadSecondLevelDeptOptions() {
listDept({ status: "0" }).then(response => {
const allDeptList = response.data || []
this.deptOptions = allDeptList.filter(item => this.isSecondLevelDept(item))
})
},
/** 判断是否为二级部门(一级部门的直属子部门) */
isSecondLevelDept(dept) {
if (!dept || !dept.ancestors) {
return false
}
return String(dept.ancestors).split(",").filter(Boolean).length === 2
},
/** 查询团队每日消耗统计列表 */
getList() {
if (!this.searched) {
@ -92,7 +120,7 @@ export default {
},
/** 搜索按钮操作 */
handleQuery() {
if (!this.queryParams.statDate || !this.queryParams.deptName) {
if (!this.queryParams.statDate || !this.queryParams.deptId) {
this.$modal.msgWarning("请先填写日期和团队名称后再搜索")
return
}
@ -104,6 +132,7 @@ export default {
resetQuery() {
this.resetForm("queryForm")
this.searched = false
this.loading = false
this.dataList = []
this.total = 0
}

View File

@ -46,6 +46,20 @@
</el-table-column>
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-download"
@click="openDeptScoreDialog(scope.row, 'issue')"
v-hasPermi="['ai:user:deptScoreIssue']"
>下放积分</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-upload2"
@click="openDeptScoreDialog(scope.row, 'reclaim')"
v-hasPermi="['ai:user:deptScoreReclaim']"
>回收积分</el-button>
<el-button v-hasPermi="['subteam:user:edit']" size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
<el-button v-hasPermi="['subteam:user:resetPwd']" size="mini" type="text" icon="el-icon-key" @click="handleResetPwd(scope.row)">密码</el-button>
<el-button v-hasPermi="['subteam:user:remove']" size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
@ -76,6 +90,44 @@
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<el-dialog
:title="deptScoreMode === 'issue' ? '下放积分' : '回收积分'"
:visible.sync="deptScoreOpen"
width="480px"
append-to-body
@close="cancelDeptScore"
>
<el-form ref="deptScoreFormRef" :model="deptScoreForm" :rules="deptScoreRules" label-width="88px">
<el-form-item label="用户账号">
<span>{{ deptScoreForm.username }}</span>
</el-form-item>
<el-form-item label="积分数量" prop="amount">
<el-input-number
v-model="deptScoreForm.amount"
:min="1"
:max="100000000"
:precision="0"
:step="1"
controls-position="right"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
v-model="deptScoreForm.remark"
type="textarea"
:rows="2"
maxlength="50"
show-word-limit
placeholder="选填最多50字"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitDeptScore"> </el-button>
<el-button @click="cancelDeptScore"> </el-button>
</div>
</el-dialog>
</div>
</template>
@ -84,6 +136,7 @@ import {
listSubteamUser, getSubteamUser, addSubteamUser, updateSubteamUser, delSubteamUser,
resetSubteamUserPwd
} from '@/api/subteam'
import { issueDeptScore, reclaimDeptScore } from '@/api/ai/user'
export default {
name: 'SubteamUser',
@ -99,6 +152,27 @@ export default {
multiple: true,
title: '',
open: false,
deptScoreOpen: false,
deptScoreMode: 'issue',
deptScoreForm: {
userId: null,
username: '',
amount: undefined,
remark: ''
},
deptScoreRules: {
amount: [
{ required: true, message: '请输入积分数量', trigger: 'blur' },
{
type: 'number',
min: 1,
max: 100000000,
message: '请输入 1100000000 的整数',
trigger: 'blur'
}
],
remark: [{ max: 50, message: '备注最多50个字', trigger: 'blur' }]
},
queryParams: { pageNum: 1, pageSize: 10, username: undefined, phone: undefined, status: undefined },
form: {},
rules: {
@ -173,6 +247,53 @@ export default {
this.$prompt('新密码', '重置', { inputType: 'password' }).then(({ value }) => {
resetSubteamUserPwd({ id: row.id, password: value }).then(() => this.$modal.msgSuccess('已重置'))
}).catch(() => {})
},
openDeptScoreDialog(row, mode) {
if (!row.deptId) {
this.$modal.msgWarning('请先分配归属部门后再操作积分')
return
}
this.deptScoreMode = mode
this.deptScoreForm = {
userId: row.id,
username: row.username || row.userId || '',
amount: undefined,
remark: ''
}
this.deptScoreOpen = true
this.$nextTick(() => {
if (this.$refs.deptScoreFormRef) {
this.$refs.deptScoreFormRef.clearValidate()
}
})
},
submitDeptScore() {
this.$refs.deptScoreFormRef.validate(valid => {
if (!valid) {
return
}
const raw = this.deptScoreForm.amount
const amount = typeof raw === 'number' ? Math.trunc(raw) : parseInt(String(raw), 10)
if (!Number.isFinite(amount) || amount < 1 || amount > 100000000) {
this.$modal.msgWarning('请输入 1100000000 的整数积分')
return
}
const payload = {
userId: this.deptScoreForm.userId,
amount,
remark: this.deptScoreForm.remark || undefined
}
const req = this.deptScoreMode === 'issue' ? issueDeptScore : reclaimDeptScore
req(payload).then(() => {
this.$modal.msgSuccess('操作成功')
this.deptScoreOpen = false
this.getList()
})
})
},
cancelDeptScore() {
this.deptScoreOpen = false
this.deptScoreForm = { userId: null, username: '', amount: undefined, remark: '' }
}
}
}

View File

@ -26,16 +26,6 @@
</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="['system:dept:add']"
>新增二级部门</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"

View File

@ -42,13 +42,13 @@ public class AiVideoReportDataController extends BaseController
@GetMapping("/list")
public TableDataInfo list(AiVideoReportData aiVideoReportData)
{
if (StringUtils.isEmpty(aiVideoReportData.getStatDate()) || StringUtils.isEmpty(aiVideoReportData.getDeptName()))
if (StringUtils.isEmpty(aiVideoReportData.getStatDate()) || aiVideoReportData.getDeptId() == null)
{
return getDataTable(java.util.Collections.emptyList());
}
startPage();
List<AiVideoReportData> list = aiVideoReportDataService.selectTeamDailyConsumeList(
aiVideoReportData.getStatDate(), aiVideoReportData.getDeptName());
aiVideoReportData.getStatDate(), aiVideoReportData.getDeptId());
return getDataTable(list);
}

View File

@ -19,11 +19,11 @@ public interface AiVideoReportDataMapper extends BaseMapper<AiVideoReportData> {
* 团队每日消耗统计查询按天团队聚合
*
* @param statDate 统计日期yyyyMMdd
* @param deptName 团队名称
* @param deptId 团队部门ID精确匹配
* @return 聚合结果
*/
List<AiVideoReportData> selectTeamDailyConsumeList(@Param("statDate") String statDate,
@Param("deptName") String deptName);
@Param("deptId") Long deptId);
/**
* 按团队部门日期聚合团队后台消耗统计

View File

@ -75,10 +75,10 @@ public interface IAiVideoReportDataService {
* 团队每日消耗统计查询按天团队聚合
*
* @param statDate 统计日期yyyyMMdd必填
* @param deptName 团队名称必填模糊匹配
* @param deptId 团队部门ID必填精确匹配
* @return 聚合后的统计数据
*/
List<AiVideoReportData> selectTeamDailyConsumeList(String statDate, String deptName);
List<AiVideoReportData> selectTeamDailyConsumeList(String statDate, Long deptId);
/**
* 团队每日消耗按部门 ID团队后台

View File

@ -112,8 +112,8 @@ public class AiVideoReportDataServiceImpl implements IAiVideoReportDataService {
}
@Override
public List<AiVideoReportData> selectTeamDailyConsumeList(String statDate, String deptName) {
return aiVideoReportDataMapper.selectTeamDailyConsumeList(statDate, deptName);
public List<AiVideoReportData> selectTeamDailyConsumeList(String statDate, Long deptId) {
return aiVideoReportDataMapper.selectTeamDailyConsumeList(statDate, deptId);
}
@Override

View File

@ -94,7 +94,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
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}, '%')
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>