<script setup>
|
import { ref, reactive, computed, onMounted } from "vue";
|
import { addUser, updateUser } from "@/api/user";
|
import useElement from "@/hooks/useElement.js";
|
import { getAreaTreeApi } from "@/api/area";
|
import { formatAreaTree } from "@/utils/tree";
|
const { $loading, $message, $confirm } = useElement();
|
const props = defineProps({
|
info: {
|
type: Object,
|
},
|
});
|
const props1 = { value: 'id', checkStrictly: true, multiple: true };
|
const formRef = ref();
|
const areaList = ref([]);
|
const form1 = reactive({
|
uname: "",
|
uid: "",
|
urole: "",
|
realName: "",
|
phoneNumber: "",
|
address: "",
|
areaId: 0,
|
permission: false,
|
});
|
|
const otherIdList = ref([]);
|
|
const rules = {
|
uname: [
|
{
|
required: true,
|
message: "不能为空",
|
trigger: ["blur", "change"],
|
},
|
],
|
realName: [
|
{
|
required: true,
|
message: "不能为空",
|
trigger: ["blur", "change"],
|
},
|
],
|
urole: [
|
{
|
required: true,
|
message: "不能为空",
|
trigger: ["blur", "change"],
|
},
|
],
|
areaId: [
|
{
|
required: true,
|
message: "不能为空",
|
trigger: ["change", "blur"],
|
},
|
{
|
validator: (rule, value, callback) => {
|
if (!value.length) {
|
callback(new Error("请选择区域"));
|
} else {
|
callback();
|
}
|
},
|
trigger: ["change", "blur"],
|
},
|
],
|
};
|
|
const isEdit = computed(() => !!props.info?.uid);
|
const $emit = defineEmits(["cancel", "success"]);
|
function close() {
|
$emit("cancel");
|
}
|
async function update() {
|
let valid = await formRef.value.validate(() => { });
|
// console.log('valid', valid, '=============');
|
|
if (!valid) {
|
$message.error("表单验证失败");
|
return false;
|
}
|
let params = {
|
uname: form1.uname.trim(),
|
uid: form1.uid || undefined,
|
realName: form1.realName.trim(),
|
phoneNumber: form1.phoneNumber?.trim(),
|
address: form1.address?.trim(),
|
idList: form1.areaId.map(v => v[v.length - 1]).concat(otherIdList.value),
|
urole: form1.urole,
|
};
|
|
// 编辑用户时, 区域中不在管理员管理内的区域要挑出来 最后更新时再追加进去
|
console.log("params update", params, "=============");
|
|
let loading = $loading();
|
updateUser(params)
|
.then((res) => {
|
let { code, data } = res;
|
if (code && data) {
|
$emit("success");
|
$message.success("操作成功");
|
} else {
|
$message.error("操作失败");
|
}
|
loading.close();
|
})
|
.catch((err) => {
|
console.log(err);
|
loading.close();
|
});
|
}
|
async function onSubmit() {
|
let valid = await formRef.value.validate(() => { });
|
// console.log('valid', valid, '=============');
|
|
if (!valid) {
|
$message.error("表单验证失败");
|
return false;
|
}
|
|
let params = {
|
uname: form1.uname.trim(),
|
uid: form1.uid || undefined,
|
realName: form1.realName.trim(),
|
phoneNumber: form1.phoneNumber?.trim(),
|
address: form1.address?.trim(),
|
idList: form1.areaId.map(v => v[v.length - 1]),
|
urole: form1.urole,
|
};
|
console.log("params", params, "=============");
|
|
let loading = $loading();
|
addUser(params)
|
.then((res) => {
|
let { code, data } = res;
|
if (code && data) {
|
$emit("success");
|
$message.success("操作成功");
|
} else {
|
$message.error("操作失败");
|
}
|
loading.close();
|
})
|
.catch((err) => {
|
console.log(err);
|
loading.close();
|
});
|
}
|
|
async function getAreaTree() {
|
try {
|
const res = await getAreaTreeApi();
|
let _data = [];
|
if (res.code === 1 && res.data) {
|
_data = res.data2;
|
}
|
const treeList = [];
|
let ids = _data.map((v) => v.id);
|
for (let i = 0; i < _data.length; i++) {
|
formatAreaTree(_data[i], ids, treeList);
|
}
|
// console.log(_data, 'data');
|
console.log(treeList, 'treeList');
|
areaList.value = treeList;
|
formatAreaSelected(treeList);
|
} catch (e) {
|
console.log(e);
|
}
|
}
|
|
// 区域树 根节点
|
// const areaRoots = computed(() => {
|
// if (!areaList.value) {
|
// return [];
|
// } else {
|
// return areaList.value.map(v => v.id);
|
// }
|
// });
|
|
function formatAreaSelected(treeList) {
|
let roots = treeList.map(v => v.id);
|
let otherAreas = form1.areaId.filter(v => !v.some((vv) => roots.includes(vv)));
|
let otherIds = otherAreas.map(v => v[v.length - 1]);
|
|
otherIdList.value = otherIds;
|
|
form1.areaId = form1.areaId.filter(v => v.some((vv) => roots.includes(vv))).map(v => {
|
let idx = 0;
|
for (let i = 0; i < roots.length; i++) {
|
if (v.includes(roots[i])) {
|
idx = v.indexOf(roots[i]);
|
break;
|
}
|
}
|
|
return v.slice(idx);
|
});
|
console.log('form1.areaId', form1.areaId, '=============');
|
|
}
|
|
function handleChange(value) {
|
let oldV = value.slice(0, value.length - 1);
|
let newV = value[value.length - 1];
|
console.log('value', value, '=============', oldV, newV);
|
|
// 检查新选中的项是否与已选中的项有包含关系
|
const hasInclusion = checkInclusion(newV, oldV);
|
if (hasInclusion) {
|
// 弹出对话框询问用户是否取消之前的项
|
$message.error('取消之前的项(新选中的项与已选中的项存在包含关系)');
|
form1.areaId = value.slice(0, value.length - 1);
|
// $confirm('取消之前的项(新选中的项与已选中的项存在包含关系)', () => {
|
// form1.areaId = value;
|
// });
|
}
|
};
|
|
function checkInclusion(newValue, oldValue) {
|
// 遍历新选中的项
|
for (let j = 0; j < oldValue.length; j++) {
|
const oldItem = oldValue[j];
|
if (isIncluded(newValue, oldItem) || isIncluded(oldItem, newValue)) {
|
return true;
|
}
|
}
|
return false;
|
};
|
|
function isIncluded(item1, item2) {
|
// 新元素是一个选项 取数组的最后一个元素
|
const id = item1[item1.length - 1];
|
return item2.includes(id);
|
};
|
|
onMounted(() => {
|
let info = props.info;
|
if (info) {
|
form1.uname = info.uname;
|
form1.uid = info.uid;
|
form1.realName = info.realName;
|
form1.phoneNumber = info.phoneNumber;
|
form1.address = info.address;
|
form1.areaId = info.areaId;
|
form1.urole = info.urole;
|
}
|
getAreaTree();
|
});
|
</script>
|
|
<template>
|
<div class="">
|
<el-form ref="formRef" :model="form1" label-width="80px" :rules="rules">
|
<el-form-item label="用户名" prop="uname">
|
<el-input v-model="form1.uname" :disabled="isEdit"></el-input>
|
</el-form-item>
|
<el-form-item label="真实姓名" prop="realName">
|
<el-input v-model="form1.realName"></el-input>
|
</el-form-item>
|
<el-form-item label="手机号" prop="phoneNumber">
|
<el-input v-model="form1.phoneNumber"></el-input>
|
</el-form-item>
|
<el-form-item label="所属区域" prop="areaId">
|
<el-cascader class="select" filterable clearable v-model="form1.areaId" :props="props1" @change="handleChange"
|
:options="areaList"><template #default="{ node, data }">
|
<span>{{ data.label }}</span>
|
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
|
</template></el-cascader>
|
</el-form-item>
|
<el-form-item label="所属角色" prop="urole">
|
<el-select v-model="form1.urole">
|
<el-option label="普通用户" :value="0" />
|
<el-option label="区域管理员" :value="1" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="通讯地址" prop="address">
|
<el-input v-model="form1.address"></el-input>
|
</el-form-item>
|
<el-form-item>
|
<el-button v-if="isEdit" type="primary" @click="update">修改</el-button>
|
<el-button v-else type="primary" @click="onSubmit">新增</el-button>
|
<el-button @click="close">取消</el-button>
|
</el-form-item>
|
</el-form>
|
</div>
|
</template>
|
|
<style scoped lang="scss">
|
:deep(.select) {
|
width: 100%;
|
}
|
</style>
|