ai_images/admin-ui/src/views/system/dept/index.vue

980 lines
32 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<el-form-item label="团队" prop="deptId">
<el-select
v-model="queryParams.deptId"
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="status">
<el-select v-model="queryParams.status" placeholder="团队状态" clearable>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</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-button
type="info"
plain
icon="el-icon-sort"
size="mini"
@click="toggleExpandAll"
>展开/折叠</el-button>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-form-item>
</el-form>
<el-table
v-if="refreshTable"
v-loading="loading"
:data="deptList"
row-key="deptId"
:default-expand-all="isExpandAll"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
>
<el-table-column prop="deptName" label="团队名称" width="260"></el-table-column>
<el-table-column prop="orderNum" label="排序" width="200"></el-table-column>
<el-table-column prop="maxUserCount" label="账号上限" width="100" align="center">
<template slot-scope="scope">
<span>{{ scope.row.maxUserCount != null && scope.row.maxUserCount > 0 ? scope.row.maxUserCount : '不限制' }}</span>
</template>
</el-table-column>
<el-table-column prop="balance" label="剩余积分" width="120" align="right">
<template slot-scope="scope">
<span>{{ formatDeptBalance(scope.row.balance) }}</span>
</template>
</el-table-column>
<el-table-column prop="status" label="状态" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="200">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="480" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
v-if="isFirstLevelRow(scope.row) || isSecondLevelRow(scope.row)"
size="mini"
type="text"
icon="el-icon-setting"
@click="handleArkConfig(scope.row)"
v-hasPermi="['system:dept:query', 'system:dept:edit']"
>火山引擎</el-button>
<el-button
v-if="isFirstLevelRow(scope.row) || isSecondLevelRow(scope.row)"
size="mini"
type="text"
icon="el-icon-wallet"
@click="handleChargeRefund(scope.row)"
v-hasPermi="['system:dept:chargeRefund']"
>充值/退款</el-button>
<el-button
v-if="isFirstLevelRow(scope.row) || isSecondLevelRow(scope.row)"
size="mini"
type="text"
icon="el-icon-s-operation"
@click="handleEditScore(scope.row)"
v-hasPermi="['system:dept:editScore']"
>积分更正</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:dept:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-plus"
@click="handleAdd(scope.row)"
v-if="isFirstLevelRow(scope.row)"
v-hasPermi="['system:dept:add']"
>新增</el-button>
<el-button
v-if="scope.row.parentId != 0"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:dept:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加或修改团队对话框 -->
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row>
<el-col :span="24" v-if="form.parentId !== 0">
<el-form-item label="上级团队" prop="parentId">
<treeselect v-model="form.parentId" :options="deptOptions" :normalizer="normalizer" placeholder="选择上级团队" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="团队名称" prop="deptName">
<el-input v-model="form.deptName" placeholder="请输入团队名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="显示排序" prop="orderNum">
<el-input-number v-model="form.orderNum" controls-position="right" :min="0" :disabled="isFirstLevelEditForm" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="负责人" prop="leader">
<el-input v-model="form.leader" placeholder="请输入负责人" maxlength="20" :disabled="isFirstLevelEditForm" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系电话" prop="phone">
<el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" :disabled="isFirstLevelEditForm" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" :disabled="isFirstLevelEditForm" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="团队状态">
<el-radio-group v-model="form.status" :disabled="isFirstLevelEditForm">
<el-radio
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="账号上限" prop="maxUserCount">
<el-input-number
v-model="form.maxUserCount"
:min="0"
:max="999999"
:precision="0"
controls-position="right"
placeholder="0 表示不限制"
style="width: 100%"
:disabled="isFirstLevelEditForm"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<p class="model-parm-hint" style="margin: 0; padding-top: 8px">&nbsp;&nbsp;限制本团队下「启用」状态账号数量0 表示不限制。</p>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<span v-if="isFirstLevelEditForm" class="form-tip">一级团队仅允许修改名称</span>
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
<el-dialog title="火山引擎" :visible.sync="arkOpen" width="800px" append-to-body @close="resetArkForm">
<el-form ref="arkFormRef" :model="arkForm" label-width="120px">
<el-row>
<el-col :span="24">
<el-form-item label="ApiKey">
<el-input
v-model="arkForm.byteApiKey"
type="password"
show-password
placeholder="选填"
maxlength="255"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="火山项目">
<el-input
v-model="arkForm.project"
type="password"
show-password
placeholder="选填"
maxlength="255"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="视频模型">
<div class="model-parm-block">
<div
v-for="(row, idx) in arkModelParamRows"
:key="'ark-mp-' + idx"
class="model-parm-row"
>
<el-input
v-model="row.label"
placeholder="显示名称(如 Seedance 2.0"
class="model-parm-input-label"
/>
<el-input
v-model="row.value"
placeholder="Endpoint / 模型 IDep-…)"
class="model-parm-input-value"
/>
<el-button
type="text"
icon="el-icon-delete"
:disabled="arkModelParamRows.length <= 1"
@click="removeArkModelParamRow(idx)"
/>
</div>
<el-button type="text" icon="el-icon-plus" @click="addArkModelParamRow">添加模型</el-button>
<p class="model-parm-hint">
保存为 JSON 写入 ai_dept_ark_config.model_parm门户「视频生成」按 ai_user.dept_id 与本团队配置读取。
留空则使用 portal.video.models。
</p>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitArkForm" v-hasPermi="['system:dept:edit']">确 定</el-button>
<el-button @click="arkOpen = false">取 消</el-button>
</div>
</el-dialog>
<el-dialog
:title="'充值/退款 — ' + (chargeRefundForm.deptName || '')"
:visible.sync="chargeRefundOpen"
width="520px"
append-to-body
@close="resetChargeRefund"
>
<el-form ref="chargeRefundFormRef" :model="chargeRefundForm" :rules="chargeRefundRules" label-width="88px">
<el-form-item label="类型" prop="orderType">
<el-radio-group v-model="chargeRefundForm.orderType">
<el-radio :label="0">充值</el-radio>
<el-radio :label="1">退款</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="金额" prop="money">
<el-input
:value="chargeRefundMoneyDisplay"
placeholder="财务记录(元),如 9,999,999.00"
clearable
@input="onChargeRefundMoneyInput"
@blur="onChargeRefundMoneyBlur"
/>
</el-form-item>
<el-form-item label="积分" prop="amount">
<el-input
:value="chargeRefundAmountDisplay"
placeholder="变动积分,如 99,999,999"
clearable
@input="onChargeRefundAmountInput"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
v-model="chargeRefundForm.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="submitChargeRefund">确 定</el-button>
<el-button @click="chargeRefundOpen = false">取 消</el-button>
</div>
</el-dialog>
<el-dialog
:title="'积分更正 — ' + (editScoreForm.deptName || '')"
:visible.sync="editScoreOpen"
width="520px"
append-to-body
@close="resetEditScore"
>
<el-form ref="editScoreFormRef" :model="editScoreForm" :rules="editScoreRules" label-width="88px">
<el-form-item label="积分" prop="score">
<el-input
:value="editScoreScoreDisplay"
class="edit-score-input"
clearable
placeholder="正数增加负数扣减不能为0如 9,999,999 或 -1,000,000"
@input="onEditScoreInput"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
v-model="editScoreForm.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="submitEditScore">确 定</el-button>
<el-button @click="editScoreOpen = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<style scoped>
.model-parm-block {
width: 100%;
}
.model-parm-row {
display: flex;
align-items: center;
margin-bottom: 8px;
}
.model-parm-input-label {
width: 38%;
margin-right: 8px;
}
.model-parm-input-value {
flex: 1;
margin-right: 8px;
}
.model-parm-hint {
margin: 8px 0 0;
font-size: 12px;
color: #909399;
line-height: 1.5;
}
.form-tip {
margin-right: 16px;
color: #e6a23c;
font-size: 12px;
}
.edit-score-input {
width: 100%;
}
</style>
<script>
import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild, getDeptArk, updateDeptArk, chargeRefundDept, editScore } from "@/api/system/dept"
import {
WESTERN_MONEY_MAX,
sanitizeMoneyDigits,
formatMoneyWesternDisplay,
moneyStringToNumber,
formatMoneyWesternFinal,
sanitizeIntDigits,
formatIntWesternDisplay,
intStringToNumber,
sanitizeSignedIntDigits,
formatSignedIntDisplay,
signedIntStringToNumber
} 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 {
// 遮罩层
loading: true,
// 显示搜索条件
showSearch: true,
// 表格树数据
deptList: [],
// 部门树选项
deptOptions: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
arkOpen: false,
arkDeptId: null,
arkForm: {
byteApiKey: undefined,
project: undefined,
modelParm: undefined
},
arkModelParamRows: [{ label: '', value: '' }],
chargeRefundOpen: false,
chargeRefundMoneyDisplay: "",
chargeRefundAmountDisplay: "",
chargeRefundForm: {
deptId: undefined,
deptName: "",
orderType: 0,
money: undefined,
amount: undefined,
remark: ""
},
chargeRefundRules: {
orderType: [
{ required: true, message: "类型不能为空", trigger: "change" }
],
money: [
{ required: true, message: "金额不能为空", trigger: "blur" },
{ type: "number", min: 0, max: 10000000, message: "金额须在 010000000 之间", trigger: "blur" }
],
amount: [
{ required: true, message: "积分不能为空", trigger: "blur" },
{ type: "number", min: 1, max: 100000000, message: "积分须在 1100000000 之间", trigger: "blur" }
],
remark: [
{ max: 50, message: "备注不能超过50个字符", trigger: "blur" }
]
},
editScoreOpen: false,
editScoreScoreDisplay: "",
editScoreForm: {
deptId: undefined,
deptName: "",
score: undefined,
remark: ""
},
editScoreRules: {
score: [
{ required: true, message: "积分不能为空", trigger: "blur" },
{
validator(rule, value, callback) {
if (value === undefined || value === null || value === "") {
callback(new Error("积分不能为空"))
} else if (!Number.isInteger(Number(value))) {
callback(new Error("积分须为整数"))
} else if (Number(value) === 0) {
callback(new Error("积分不能为0"))
} else if (Number(value) < -100000000 || Number(value) > 100000000) {
callback(new Error("积分须在 -100000000100000000 之间不含0"))
} else {
callback()
}
},
trigger: "blur"
}
],
remark: [
{ required: true, message: "备注不能为空", trigger: "blur" },
{
validator(rule, value, callback) {
if (!value || String(value).trim() === "") {
callback(new Error("备注不能为空"))
} else {
callback()
}
},
trigger: "blur"
},
{ max: 50, message: "备注不能超过50个字符", trigger: "blur" }
]
},
// 是否展开,默认全部展开
isExpandAll: true,
// 重新渲染表格状态
refreshTable: true,
// 查询参数
queryParams: {
deptId: null,
status: undefined
},
// 表单参数
form: {},
originalForm: {},
// 表单校验
rules: {
parentId: [
{ required: true, message: "上级团队不能为空", trigger: "blur" }
],
deptName: [
{ required: true, message: "团队名称不能为空", trigger: "blur" }
],
orderNum: [
{ required: true, message: "显示排序不能为空", trigger: "blur" }
],
email: [
{
type: "email",
message: "请输入正确的邮箱地址",
trigger: ["blur", "change"]
}
],
phone: [
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: "请输入正确的手机号码",
trigger: "blur"
}
],
maxUserCount: [
{ required: true, message: "账号上限不能为空", trigger: "change" },
{
type: "number",
min: 0,
max: 999999,
message: "账号上限须为 0999999 的整数0 表示不限制",
trigger: "change"
}
]
}
}
},
created() {
this.loadSecondLevelDeptOptions()
this.getList()
},
computed: {
isFirstLevelEditForm() {
return this.form.deptId !== undefined && this.isFirstLevelRow(this.form)
}
},
methods: {
/** 列表「剩余积分」:西式千分位,与业务积分展示一致;空为 — */
formatDeptBalance(value) {
if (value == null || value === "") {
return "—"
}
const n = Number(value)
if (Number.isNaN(n)) {
return "—"
}
return n.toLocaleString("en-US", { maximumFractionDigits: 2, minimumFractionDigits: 0 })
},
onEditScoreInput(val) {
const s = sanitizeSignedIntDigits(val)
this.editScoreScoreDisplay = s === "" ? "" : s === "-" ? "-" : formatSignedIntDisplay(s)
this.editScoreForm.score = signedIntStringToNumber(s)
},
isFirstLevelRow(row) {
if (!row) {
return false
}
return Number(row.parentId) === 0 && String(row.ancestors || "") === "0"
},
isSecondLevelRow(row) {
if (!row) {
return false
}
const ancestors = String(row.ancestors || "").split(",").filter(Boolean)
return ancestors.length === 2
},
getFirstLevelDeptOptions(nodes) {
if (!Array.isArray(nodes)) {
return []
}
return nodes.filter(item => this.isFirstLevelRow(item)).map(item => {
const current = { ...item }
delete current.children
return current
})
},
syncArkModelRowsFromForm() {
this.arkModelParamRows = [{ label: '', value: '' }]
const raw = this.arkForm.modelParm
if (!raw || String(raw).trim() === '') {
return
}
try {
const arr = JSON.parse(raw)
if (Array.isArray(arr) && arr.length) {
this.arkModelParamRows = arr.map(x => ({
label: (x && x.label) ? String(x.label) : '',
value: (x && x.value) ? String(x.value) : ''
}))
}
} catch (e) {
this.arkModelParamRows = [{ label: '', value: '' }]
}
},
buildArkModelParmPayload() {
const rows = (this.arkModelParamRows || []).filter(r => r.label && r.value)
this.arkForm.modelParm = rows.length ? JSON.stringify(rows) : ''
},
addArkModelParamRow() {
this.arkModelParamRows.push({ label: '', value: '' })
},
removeArkModelParamRow(idx) {
if (this.arkModelParamRows.length <= 1) {
return
}
this.arkModelParamRows.splice(idx, 1)
},
resetArkForm() {
this.arkDeptId = null
this.arkForm = {
byteApiKey: undefined,
project: undefined,
modelParm: undefined
}
this.arkModelParamRows = [{ label: '', value: '' }]
if (this.$refs.arkFormRef) {
this.$refs.arkFormRef.resetFields()
}
},
handleArkConfig(row) {
if (!this.isFirstLevelRow(row) && !this.isSecondLevelRow(row)) {
return
}
this.arkDeptId = row.deptId
getDeptArk(row.deptId).then(response => {
const d = response.data || {}
this.arkForm = {
byteApiKey: d.byteApiKey,
project: d.project,
modelParm: d.modelParm
}
this.syncArkModelRowsFromForm()
this.arkOpen = true
})
},
resetChargeRefund() {
this.chargeRefundMoneyDisplay = ""
this.chargeRefundAmountDisplay = ""
this.chargeRefundForm = {
deptId: undefined,
deptName: "",
orderType: 0,
money: undefined,
amount: undefined,
remark: ""
}
this.$nextTick(() => {
if (this.$refs.chargeRefundFormRef) {
this.$refs.chargeRefundFormRef.clearValidate()
}
})
},
handleChargeRefund(row) {
if (!this.isFirstLevelRow(row) && !this.isSecondLevelRow(row)) {
return
}
this.chargeRefundMoneyDisplay = ""
this.chargeRefundAmountDisplay = ""
this.chargeRefundForm = {
deptId: row.deptId,
deptName: row.deptName,
orderType: 0,
money: undefined,
amount: undefined,
remark: ""
}
this.chargeRefundOpen = true
this.$nextTick(() => {
if (this.$refs.chargeRefundFormRef) {
this.$refs.chargeRefundFormRef.clearValidate()
}
})
},
onChargeRefundMoneyInput(val) {
const sanitized = sanitizeMoneyDigits(val)
if (!sanitized) {
this.chargeRefundMoneyDisplay = ""
this.chargeRefundForm.money = undefined
return
}
const raw = parseFloat(sanitized)
if (!isNaN(raw) && raw > WESTERN_MONEY_MAX) {
this.chargeRefundForm.money = WESTERN_MONEY_MAX
this.chargeRefundMoneyDisplay = formatMoneyWesternFinal(WESTERN_MONEY_MAX)
return
}
this.chargeRefundMoneyDisplay = formatMoneyWesternDisplay(sanitized)
this.chargeRefundForm.money = moneyStringToNumber(sanitized)
},
onChargeRefundMoneyBlur() {
if (this.chargeRefundForm.money !== undefined && this.chargeRefundForm.money !== null) {
this.chargeRefundMoneyDisplay = formatMoneyWesternFinal(this.chargeRefundForm.money)
}
},
onChargeRefundAmountInput(val) {
const digits = sanitizeIntDigits(val)
this.chargeRefundAmountDisplay = digits === "" ? "" : formatIntWesternDisplay(digits)
this.chargeRefundForm.amount = intStringToNumber(digits)
},
submitChargeRefund() {
this.onChargeRefundMoneyBlur()
this.$refs["chargeRefundFormRef"].validate(valid => {
if (!valid) {
return
}
const data = {
deptId: this.chargeRefundForm.deptId,
orderType: this.chargeRefundForm.orderType,
money: this.chargeRefundForm.money,
amount: this.chargeRefundForm.amount,
remark: this.chargeRefundForm.remark ? this.chargeRefundForm.remark.trim() : undefined
}
chargeRefundDept(data).then(() => {
this.$modal.msgSuccess("操作成功")
this.chargeRefundOpen = false
this.getList()
})
})
},
resetEditScore() {
this.editScoreScoreDisplay = ""
this.editScoreForm = {
deptId: undefined,
deptName: "",
score: undefined,
remark: ""
}
this.$nextTick(() => {
if (this.$refs.editScoreFormRef) {
this.$refs.editScoreFormRef.clearValidate()
}
})
},
handleEditScore(row) {
if (!this.isFirstLevelRow(row) && !this.isSecondLevelRow(row)) {
return
}
this.editScoreScoreDisplay = ""
this.editScoreForm = {
deptId: row.deptId,
deptName: row.deptName,
score: undefined,
remark: ""
}
this.editScoreOpen = true
this.$nextTick(() => {
if (this.$refs.editScoreFormRef) {
this.$refs.editScoreFormRef.clearValidate()
}
})
},
submitEditScore() {
this.$refs["editScoreFormRef"].validate(valid => {
if (!valid) {
return
}
const remark = (this.editScoreForm.remark || "").trim()
const data = {
deptId: this.editScoreForm.deptId,
score: this.editScoreForm.score,
remark: remark
}
editScore(data).then(() => {
this.$modal.msgSuccess("操作成功")
this.editScoreOpen = false
this.getList()
})
})
},
submitArkForm() {
this.buildArkModelParmPayload()
const payload = {
deptId: this.arkDeptId,
byteApiKey: this.arkForm.byteApiKey !== undefined && this.arkForm.byteApiKey !== null ? this.arkForm.byteApiKey : '',
project: this.arkForm.project !== undefined && this.arkForm.project !== null ? this.arkForm.project : '',
modelParm: this.arkForm.modelParm !== undefined && this.arkForm.modelParm !== null ? this.arkForm.modelParm : ''
}
updateDeptArk(payload).then(() => {
this.$modal.msgSuccess('保存成功')
this.arkOpen = false
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
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
})
},
/** 转换部门数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children
}
return {
id: node.deptId,
label: node.deptName,
children: node.children
}
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
deptId: undefined,
parentId: undefined,
ancestors: undefined,
deptName: undefined,
orderNum: undefined,
leader: undefined,
phone: undefined,
email: undefined,
maxUserCount: 0,
status: "0"
}
this.originalForm = {}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd(row) {
this.reset()
if (row !== undefined) {
if (!this.isFirstLevelRow(row)) {
this.$modal.msgError("仅允许在一级团队下新增二级团队")
return
}
this.form.parentId = row.deptId
}
this.form.maxUserCount = 0
this.open = true
this.title = "添加二级团队"
listDept().then(response => {
this.deptOptions = this.getFirstLevelDeptOptions(this.handleTree(response.data, "deptId"))
})
},
/** 展开/折叠操作 */
toggleExpandAll() {
this.refreshTable = false
this.isExpandAll = !this.isExpandAll
this.$nextTick(() => {
this.refreshTable = true
})
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
getDept(row.deptId).then(response => {
this.form = { ...response.data }
this.originalForm = { ...response.data }
if (this.form.maxUserCount == null) {
this.form.maxUserCount = 0
}
this.open = true
this.title = "修改团队"
listDeptExcludeChild(row.deptId).then(response => {
const allOptions = this.handleTree(response.data, "deptId")
this.deptOptions = this.getFirstLevelDeptOptions(allOptions)
if (this.deptOptions.length == 0) {
const noResultsOptions = { deptId: this.form.parentId, deptName: this.form.parentName, children: [] }
this.deptOptions.push(noResultsOptions)
}
})
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.deptId == undefined && !this.deptOptions.some(item => Number(item.deptId) === Number(this.form.parentId))) {
this.$modal.msgError("仅允许在一级团队下创建二级团队")
return
}
if (this.form.deptId != undefined) {
if (this.isFirstLevelEditForm) {
const oldDept = this.originalForm || {}
this.form.parentId = oldDept.parentId
this.form.orderNum = oldDept.orderNum
this.form.leader = oldDept.leader
this.form.phone = oldDept.phone
this.form.email = oldDept.email
this.form.status = oldDept.status
this.form.maxUserCount = oldDept.maxUserCount
}
updateDept(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addDept(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
this.$modal.confirm('是否确认删除名称为"' + row.deptName + '"的数据项?').then(function() {
return delDept(row.deptId)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
}
}
}
</script>