feat: 管理端团队名称统一改成团队下拉框

This commit is contained in:
yys 2026-04-23 17:52:50 +08:00
parent 24f518acd1
commit 413a3b118a
9 changed files with 188 additions and 82 deletions

View File

@ -73,6 +73,9 @@ export function listSubteamUserBalance(query) {
return request({ url: '/subteam/user-balance/list', method: 'get', params: query })
}
/** 导出POST /subteam/user-balance/export与列表相同查询参数 + beginTime/endTime */
export const subteamUserBalanceExportUrl = 'subteam/user-balance/export'
export function getSubteamUserBalance(id) {
return request({ url: '/subteam/user-balance/' + id, method: 'get' })
}

View File

@ -0,0 +1,31 @@
import { listDept as listAiDept } from "@/api/ai/dept"
/**
* 统计数据ai/data一致仅启用状态 ancestors 深度为 2 的团队供筛选下拉使用
* 系统团队页system/dept请覆写 secondLevelDeptListRequest改为调用 /system/dept/list
*/
export default {
data() {
return {
secondLevelDeptOptions: []
}
},
methods: {
/** @param {object} params 如 { status: '0' } */
secondLevelDeptListRequest(params) {
return listAiDept(params)
},
loadSecondLevelDeptOptions() {
this.secondLevelDeptListRequest({ status: "0" }).then(response => {
const allDeptList = response.data || []
this.secondLevelDeptOptions = allDeptList.filter(item => this.isSecondLevelDept(item))
})
},
isSecondLevelDept(dept) {
if (!dept || !dept.ancestors) {
return false
}
return String(dept.ancestors).split(",").filter(Boolean).length === 2
}
}
}

View File

@ -17,14 +17,20 @@
/>
</el-form-item>
<el-form-item label="团队" prop="deptId">
<treeselect
<el-select
v-model="queryParams.deptId"
:options="deptOptions"
:normalizer="deptNormalizer"
placeholder="全部"
placeholder="全部团队(可选)"
clearable
filterable
style="width: 220px"
/>
>
<el-option
v-for="item in secondLevelDeptOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
/>
</el-select>
</el-form-item>
<el-form-item label="操作类型" prop="type">
<el-select
@ -151,13 +157,11 @@ import {
addRecord,
updateRecord
} from "@/api/ai/balanceChangeRecord";
import { listDept } from "@/api/ai/dept";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import secondLevelDeptFilter from "@/mixins/secondLevelDeptFilter";
export default {
name: "Record",
components: { Treeselect },
mixins: [secondLevelDeptFilter],
data() {
return {
//
@ -197,7 +201,6 @@ export default {
title: "",
//
open: false,
deptOptions: [],
//
queryParams: {
pageNum: 1,
@ -218,25 +221,10 @@ export default {
};
},
created() {
this.loadDeptTree();
this.loadSecondLevelDeptOptions();
this.getList();
},
methods: {
loadDeptTree() {
listDept().then(res => {
this.deptOptions = this.handleTree(res.data, "deptId");
});
},
deptNormalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.deptId,
label: node.deptName,
children: node.children
};
},
/** 西式千分位en-US积分为整数 */
formatPointsWestern(value) {
if (value === null || value === undefined || value === "") {

View File

@ -22,7 +22,7 @@
style="width: 220px"
>
<el-option
v-for="item in deptOptions"
v-for="item in secondLevelDeptOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
@ -114,10 +114,11 @@
<script>
import { listData } from "@/api/ai/data"
import { listDept } from "@/api/ai/dept"
import secondLevelDeptFilter from "@/mixins/secondLevelDeptFilter"
export default {
name: "TeamConsumeData",
mixins: [secondLevelDeptFilter],
data() {
return {
loading: false,
@ -125,7 +126,6 @@ export default {
total: 0,
dataList: [],
aggregate: null,
deptOptions: [],
dateRange: [],
queryParams: {
pageNum: 1,
@ -194,18 +194,6 @@ export default {
initDefaultDateRange() {
this.dateRange = this.buildLastMonthDateRange()
},
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
},
syncDateRangeToQuery() {
if (Array.isArray(this.dateRange) && this.dateRange.length === 2) {
this.queryParams.startDate = this.dateRange[0]

View File

@ -1,16 +1,24 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<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 secondLevelDeptOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
/>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="状态" clearable>
<el-select v-model="queryParams.status" placeholder="团队状态" clearable>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
@ -233,11 +241,13 @@
import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/ai/dept"
import Treeselect from "@riophae/vue-treeselect"
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
import secondLevelDeptFilter from "@/mixins/secondLevelDeptFilter"
export default {
name: "AiDept",
dicts: ['sys_normal_disable'],
components: { Treeselect },
mixins: [secondLevelDeptFilter],
data() {
return {
loading: true,
@ -249,7 +259,7 @@ export default {
isExpandAll: true,
refreshTable: true,
queryParams: {
deptName: undefined,
deptId: null,
status: undefined
},
form: {},
@ -282,6 +292,7 @@ export default {
}
},
created() {
this.loadSecondLevelDeptOptions()
this.getList()
},
computed: {
@ -299,11 +310,30 @@ export default {
methods: {
getList() {
this.loading = true
listDept(this.queryParams).then(response => {
this.deptList = this.handleTree(response.data, "deptId")
const { deptId, ...deptListQuery } = this.queryParams
listDept(deptListQuery).then(response => {
let raw = response.data || []
if (deptId != null && deptId !== "") {
const rootId = Number(deptId)
raw = raw.filter(d => this.deptRowInSubtree(d, rootId))
}
this.deptList = this.handleTree(raw, "deptId")
this.loading = false
})
},
deptRowInSubtree(d, rootId) {
if (d.deptId != null && Number(d.deptId) === rootId) {
return true
}
if (!d.ancestors) {
return false
}
return String(d.ancestors)
.split(",")
.filter(Boolean)
.map(s => Number(s))
.includes(rootId)
},
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children

View File

@ -9,13 +9,21 @@
@keyup.enter.native="handleQuery"
/>
</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 secondLevelDeptOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
/>
</el-select>
</el-form-item>
<el-form-item label="类型" prop="orderType">
<el-select v-model="queryParams.orderType" placeholder="全部" clearable style="width: 110px">
@ -138,9 +146,11 @@ import {
addGroupChargeOrder,
updateGroupChargeOrder
} from "@/api/ai/groupChargeOrder"
import secondLevelDeptFilter from "@/mixins/secondLevelDeptFilter"
export default {
name: "GroupChargeOrder",
mixins: [secondLevelDeptFilter],
data() {
return {
loading: true,
@ -154,7 +164,7 @@ export default {
pageNum: 1,
pageSize: 10,
orderNum: null,
deptName: null,
deptId: null,
orderType: null
},
form: {},
@ -181,6 +191,7 @@ export default {
}
},
created() {
this.loadSecondLevelDeptOptions()
this.getList()
},
methods: {

View File

@ -18,13 +18,21 @@
@keyup.enter.native="handleQuery"
/>
</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 secondLevelDeptOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
/>
</el-select>
</el-form-item>
<el-form-item label="用户名称" prop="userName">
<el-input
@ -135,9 +143,11 @@
<script>
import { listOrder } from "@/api/ai/order"
import secondLevelDeptFilter from "@/mixins/secondLevelDeptFilter"
export default {
name: "TeamChargeOrder",
mixins: [secondLevelDeptFilter],
data() {
return {
loading: true,
@ -162,13 +172,14 @@ export default {
orderNum: null,
thirdPartyOrderNum: null,
userName: null,
deptName: null,
deptId: null,
orderType: null,
status: null
}
}
},
created() {
this.loadSecondLevelDeptOptions()
this.initDefaultDateRange()
this.getList()
},

View File

@ -10,14 +10,21 @@
@keyup.enter.native="handleQuery"
/>
</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
style="width: 140px"
@keyup.enter.native="handleQuery"
/>
filterable
style="width: 220px"
>
<el-option
v-for="item in secondLevelDeptOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
/>
</el-select>
</el-form-item>
<el-form-item label="类型" prop="type">
<el-select v-model="queryParams.type" clearable placeholder="全部类型" style="width: 112px">
@ -93,9 +100,11 @@
<script>
import { listRecord } from "@/api/ai/record"
import secondLevelDeptFilter from "@/mixins/secondLevelDeptFilter"
export default {
name: "Record",
mixins: [secondLevelDeptFilter],
data() {
return {
loading: true,
@ -114,12 +123,13 @@ export default {
pageNum: 1,
pageSize: 10,
relationOrderNo: null,
deptName: null,
deptId: null,
type: null
}
}
},
created() {
this.loadSecondLevelDeptOptions()
this.getList()
},
methods: {

View File

@ -1,13 +1,21 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<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 secondLevelDeptOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
/>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="团队状态" clearable>
@ -399,11 +407,13 @@ import {
} from "@/utils/westernNumberFormat"
import Treeselect from "@riophae/vue-treeselect"
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
import secondLevelDeptFilter from "@/mixins/secondLevelDeptFilter"
export default {
name: "Dept",
dicts: ['sys_normal_disable'],
components: { Treeselect },
mixins: [secondLevelDeptFilter],
data() {
return {
//
@ -502,7 +512,7 @@ export default {
refreshTable: true,
//
queryParams: {
deptName: undefined,
deptId: null,
status: undefined
},
//
@ -547,6 +557,7 @@ export default {
}
},
created() {
this.loadSecondLevelDeptOptions()
this.getList()
},
computed: {
@ -801,11 +812,34 @@ export default {
this.resetArkForm()
})
},
/** 二级团队下拉:走系统部门接口(与页面列表权限一致) */
secondLevelDeptListRequest(params) {
return listDept(params)
},
deptRowInSubtree(d, rootId) {
if (d.deptId != null && Number(d.deptId) === rootId) {
return true
}
if (!d.ancestors) {
return false
}
return String(d.ancestors)
.split(",")
.filter(Boolean)
.map(s => Number(s))
.includes(rootId)
},
/** 查询部门列表 */
getList() {
this.loading = true
listDept(this.queryParams).then(response => {
this.deptList = this.handleTree(response.data, "deptId")
const { deptId, ...deptListQuery } = this.queryParams
listDept(deptListQuery).then(response => {
let raw = response.data || []
if (deptId != null && deptId !== "") {
const rootId = Number(deptId)
raw = raw.filter(d => this.deptRowInSubtree(d, rootId))
}
this.deptList = this.handleTree(raw, "deptId")
this.loading = false
})
},