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 clearable
/> />
</el-form-item> </el-form-item>
<el-form-item label="团队名称" prop="deptName"> <el-form-item label="团队名称" prop="deptId">
<el-input <el-select
v-model="queryParams.deptName" v-model="queryParams.deptId"
placeholder="请输入团队名称" placeholder="请选择团队"
clearable 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-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>
@ -50,19 +58,22 @@
<script> <script>
import { listData } from "@/api/ai/data" import { listData } from "@/api/ai/data"
import { listDept } from "@/api/ai/dept"
export default { export default {
name: "TeamConsumeData", name: "TeamConsumeData",
data() { data() {
return { return {
// //
loading: true, loading: false,
// //
showSearch: true, showSearch: true,
// //
total: 0, total: 0,
// //
dataList: [], dataList: [],
//
deptOptions: [],
// //
searched: false, searched: false,
// //
@ -70,11 +81,28 @@ export default {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
statDate: null, statDate: null,
deptName: null deptId: null
}, },
} }
}, },
created() {
this.loadSecondLevelDeptOptions()
},
methods: { 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() { getList() {
if (!this.searched) { if (!this.searched) {
@ -92,7 +120,7 @@ export default {
}, },
/** 搜索按钮操作 */ /** 搜索按钮操作 */
handleQuery() { handleQuery() {
if (!this.queryParams.statDate || !this.queryParams.deptName) { if (!this.queryParams.statDate || !this.queryParams.deptId) {
this.$modal.msgWarning("请先填写日期和团队名称后再搜索") this.$modal.msgWarning("请先填写日期和团队名称后再搜索")
return return
} }
@ -104,6 +132,7 @@ export default {
resetQuery() { resetQuery() {
this.resetForm("queryForm") this.resetForm("queryForm")
this.searched = false this.searched = false
this.loading = false
this.dataList = [] this.dataList = []
this.total = 0 this.total = 0
} }

View File

@ -46,6 +46,20 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" width="200"> <el-table-column label="操作" width="200">
<template slot-scope="scope"> <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: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: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> <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> <el-button @click="cancel"> </el-button>
</div> </div>
</el-dialog> </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> </div>
</template> </template>
@ -84,6 +136,7 @@ import {
listSubteamUser, getSubteamUser, addSubteamUser, updateSubteamUser, delSubteamUser, listSubteamUser, getSubteamUser, addSubteamUser, updateSubteamUser, delSubteamUser,
resetSubteamUserPwd resetSubteamUserPwd
} from '@/api/subteam' } from '@/api/subteam'
import { issueDeptScore, reclaimDeptScore } from '@/api/ai/user'
export default { export default {
name: 'SubteamUser', name: 'SubteamUser',
@ -99,6 +152,27 @@ export default {
multiple: true, multiple: true,
title: '', title: '',
open: false, 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 }, queryParams: { pageNum: 1, pageSize: 10, username: undefined, phone: undefined, status: undefined },
form: {}, form: {},
rules: { rules: {
@ -173,6 +247,53 @@ export default {
this.$prompt('新密码', '重置', { inputType: 'password' }).then(({ value }) => { this.$prompt('新密码', '重置', { inputType: 'password' }).then(({ value }) => {
resetSubteamUserPwd({ id: row.id, password: value }).then(() => this.$modal.msgSuccess('已重置')) resetSubteamUserPwd({ id: row.id, password: value }).then(() => this.$modal.msgSuccess('已重置'))
}).catch(() => {}) }).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-form>
<el-row :gutter="10" class="mb8"> <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-col :span="1.5">
<el-button <el-button
type="info" type="info"

View File

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

View File

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

View File

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

View File

@ -94,7 +94,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
from ai_video_report_data vrd from ai_video_report_data vrd
left join sys_dept d on d.dept_id = vrd.dept_id left join sys_dept d on d.dept_id = vrd.dept_id
where vrd.date_key like concat(#{statDate}, '%') 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 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 order by substr(vrd.date_key, 1, 8) desc, vrd.dept_id desc
</select> </select>