优化:添加编辑部门允许负责人为空

This commit is contained in:
SillyBoy 2025-03-01 19:38:33 +08:00
parent 34fdf59432
commit 2dd72e404a
4 changed files with 206 additions and 198 deletions

View File

@ -3,6 +3,8 @@ package net.lab1024.sa.admin.module.system.department.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -34,6 +36,7 @@ public class DepartmentEntity {
/** /**
* 负责人员工 id * 负责人员工 id
*/ */
@TableField(updateStrategy = FieldStrategy.ALWAYS)
private Long managerId; private Long managerId;
/** /**

View File

@ -3,6 +3,8 @@ package net.lab1024.sa.admin.module.system.department.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -34,6 +36,7 @@ public class DepartmentEntity {
/** /**
* 负责人员工 id * 负责人员工 id
*/ */
@TableField(updateStrategy = FieldStrategy.IGNORED)
private Long managerId; private Long managerId;
/** /**

View File

@ -11,86 +11,87 @@
<a-modal v-model:open="visible" :title="formState.departmentId ? '编辑部门' : '添加部门'" @ok="handleOk" destroyOnClose> <a-modal v-model:open="visible" :title="formState.departmentId ? '编辑部门' : '添加部门'" @ok="handleOk" destroyOnClose>
<a-form ref="formRef" :model="formState" :rules="rules" layout="vertical"> <a-form ref="formRef" :model="formState" :rules="rules" layout="vertical">
<a-form-item label="上级部门" name="parentId" v-if="formState.parentId != 0"> <a-form-item label="上级部门" name="parentId" v-if="formState.parentId != 0">
<DepartmentTreeSelect ref="departmentTreeSelect" v-model:value="formState.parentId" :defaultValueFlag="false" width="100%" /> <DepartmentTreeSelect ref="departmentTreeSelect" v-model:value="formState.parentId" :defaultValueFlag="false"
width="100%" />
</a-form-item> </a-form-item>
<a-form-item label="部门名称" name="name"> <a-form-item label="部门名称" name="name">
<a-input v-model:value.trim="formState.name" placeholder="请输入部门名称" /> <a-input v-model:value.trim="formState.name" placeholder="请输入部门名称" />
</a-form-item> </a-form-item>
<a-form-item label="部门负责人" name="managerId"> <a-form-item label="部门负责人" name="managerId">
<EmployeeSelect ref="employeeSelect" placeholder="请选择部门负责人" width="100%" v-model:value="formState.managerId" :leaveFlag="false" /> <EmployeeSelect ref="employeeSelect" placeholder="请选择部门负责人" width="100%" v-model:value="formState.managerId"
:leaveFlag="false" />
</a-form-item> </a-form-item>
<a-form-item label="部门排序 (值越大越靠前!)" name="sort"> <a-form-item label="部门排序 (值越大越靠前!)" name="sort">
<a-input-number style="width: 100%" v-model:value="formState.sort" :min="0" placeholder="请输入部门名称" /> <a-input-number style="width: 100%" v-model:value="formState.sort" :min="0" placeholder="请输入部门排序" />
</a-form-item> </a-form-item>
</a-form> </a-form>
</a-modal> </a-modal>
</template> </template>
<script setup> <script setup>
import message from 'ant-design-vue/lib/message'; import message from 'ant-design-vue/lib/message';
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import { departmentApi } from '/@/api/system/department-api'; import { departmentApi } from '/@/api/system/department-api';
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue'; import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
import EmployeeSelect from '/@/components/system/employee-select/index.vue'; import EmployeeSelect from '/@/components/system/employee-select/index.vue';
import { smartSentry } from '/@/lib/smart-sentry'; import { smartSentry } from '/@/lib/smart-sentry';
import { SmartLoading } from '/@/components/framework/smart-loading'; import { SmartLoading } from '/@/components/framework/smart-loading';
// ----------------------- --------------------- // ----------------------- ---------------------
defineExpose({ defineExpose({
showModal, showModal,
}); });
// ----------------------- modal --------------------- // ----------------------- modal ---------------------
const emits = defineEmits(['refresh']); const emits = defineEmits(['refresh']);
const visible = ref(false); const visible = ref(false);
function showModal(data) { function showModal(data) {
visible.value = true; visible.value = true;
updateFormData(data); updateFormData(data);
} }
function closeModal() { function closeModal() {
visible.value = false; visible.value = false;
resetFormData(); resetFormData();
} }
// ----------------------- form --------------------- // ----------------------- form ---------------------
const formRef = ref(); const formRef = ref();
const departmentTreeSelect = ref(); const departmentTreeSelect = ref();
const defaultDepartmentForm = { const defaultDepartmentForm = {
id: undefined, id: undefined,
managerId: undefined, // managerId: undefined, //
name: undefined, name: undefined,
parentId: undefined, parentId: undefined,
sort: 0, sort: 0,
}; };
const employeeSelect = ref(); const employeeSelect = ref();
let formState = reactive({ let formState = reactive({
...defaultDepartmentForm, ...defaultDepartmentForm,
}); });
// //
const rules = { const rules = {
parentId: [{ required: true, message: '上级部门不能为空' }], parentId: [{ required: true, message: '上级部门不能为空' }],
name: [ name: [
{ required: true, message: '部门名称不能为空' }, { required: true, message: '部门名称不能为空' },
{ max: 50, message: '部门名称不能大于20个字符', trigger: 'blur' }, { max: 50, message: '部门名称不能大于20个字符', trigger: 'blur' },
], ],
managerId: [{ required: true, message: '部门负责人不能为空' }], };
}; //
// function updateFormData(data) {
function updateFormData(data) {
Object.assign(formState, defaultDepartmentForm); Object.assign(formState, defaultDepartmentForm);
if (data) { if (data) {
Object.assign(formState, data); Object.assign(formState, data);
} }
visible.value = true; visible.value = true;
} }
// //
function resetFormData() { function resetFormData() {
Object.assign(formState, defaultDepartmentForm); Object.assign(formState, defaultDepartmentForm);
} }
async function handleOk() { async function handleOk() {
try { try {
await formRef.value.validate(); await formRef.value.validate();
if (formState.departmentId) { if (formState.departmentId) {
@ -101,11 +102,11 @@
} catch (error) { } catch (error) {
message.error('参数验证错误,请仔细填写表单数据!'); message.error('参数验证错误,请仔细填写表单数据!');
} }
} }
// ----------------------- form ajax --------------------- // ----------------------- form ajax ---------------------
//ajax //ajax
async function addDepartment() { async function addDepartment() {
SmartLoading.show(); SmartLoading.show();
try { try {
await departmentApi.addDepartment(formState); await departmentApi.addDepartment(formState);
@ -116,14 +117,14 @@
} finally { } finally {
SmartLoading.hide(); SmartLoading.hide();
} }
} }
//ajax //ajax
async function updateDepartment() { async function updateDepartment() {
SmartLoading.show(); SmartLoading.show();
try { try {
if (formState.parentId == formState.departmentId) { if (formState.parentId == formState.departmentId) {
message.warning('上级菜单不能为自己'); message.warning('上级部门不能为自己');
return; return;
} }
await departmentApi.updateDepartment(formState); await departmentApi.updateDepartment(formState);
@ -134,5 +135,5 @@
} finally { } finally {
SmartLoading.hide(); SmartLoading.hide();
} }
} }
</script> </script>

View File

@ -11,86 +11,87 @@
<a-modal v-model:open="visible" :title="formState.departmentId ? '编辑部门' : '添加部门'" @ok="handleOk" destroyOnClose> <a-modal v-model:open="visible" :title="formState.departmentId ? '编辑部门' : '添加部门'" @ok="handleOk" destroyOnClose>
<a-form ref="formRef" :model="formState" :rules="rules" layout="vertical"> <a-form ref="formRef" :model="formState" :rules="rules" layout="vertical">
<a-form-item label="上级部门" name="parentId" v-if="formState.parentId != 0"> <a-form-item label="上级部门" name="parentId" v-if="formState.parentId != 0">
<DepartmentTreeSelect ref="departmentTreeSelect" v-model:value="formState.parentId" :defaultValueFlag="false" width="100%" /> <DepartmentTreeSelect ref="departmentTreeSelect" v-model:value="formState.parentId" :defaultValueFlag="false"
width="100%" />
</a-form-item> </a-form-item>
<a-form-item label="部门名称" name="name"> <a-form-item label="部门名称" name="name">
<a-input v-model:value.trim="formState.name" placeholder="请输入部门名称" /> <a-input v-model:value.trim="formState.name" placeholder="请输入部门名称" />
</a-form-item> </a-form-item>
<a-form-item label="部门负责人" name="managerId"> <a-form-item label="部门负责人" name="managerId">
<EmployeeSelect ref="employeeSelect" placeholder="请选择部门负责人" width="100%" v-model:value="formState.managerId" :leaveFlag="false" /> <EmployeeSelect ref="employeeSelect" placeholder="请选择部门负责人" width="100%" v-model:value="formState.managerId"
:leaveFlag="false" />
</a-form-item> </a-form-item>
<a-form-item label="部门排序 (值越大越靠前!)" name="sort"> <a-form-item label="部门排序 (值越大越靠前!)" name="sort">
<a-input-number style="width: 100%" v-model:value="formState.sort" :min="0" placeholder="请输入部门名称" /> <a-input-number style="width: 100%" v-model:value="formState.sort" :min="0" placeholder="请输入部门排序" />
</a-form-item> </a-form-item>
</a-form> </a-form>
</a-modal> </a-modal>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import message from 'ant-design-vue/lib/message'; import message from 'ant-design-vue/lib/message';
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import { departmentApi } from '/@/api/system/department-api'; import { departmentApi } from '/@/api/system/department-api';
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue'; import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
import EmployeeSelect from '/@/components/system/employee-select/index.vue'; import EmployeeSelect from '/@/components/system/employee-select/index.vue';
import { smartSentry } from '/@/lib/smart-sentry'; import { smartSentry } from '/@/lib/smart-sentry';
import { SmartLoading } from '/@/components/framework/smart-loading'; import { SmartLoading } from '/@/components/framework/smart-loading';
// ----------------------- --------------------- // ----------------------- ---------------------
defineExpose({ defineExpose({
showModal, showModal,
}); });
// ----------------------- modal --------------------- // ----------------------- modal ---------------------
const emits = defineEmits(['refresh']); const emits = defineEmits(['refresh']);
const visible = ref(false); const visible = ref(false);
function showModal(data) { function showModal(data) {
visible.value = true; visible.value = true;
updateFormData(data); updateFormData(data);
} }
function closeModal() { function closeModal() {
visible.value = false; visible.value = false;
resetFormData(); resetFormData();
} }
// ----------------------- form --------------------- // ----------------------- form ---------------------
const formRef = ref(); const formRef = ref();
const departmentTreeSelect = ref(); const departmentTreeSelect = ref();
const defaultDepartmentForm = { const defaultDepartmentForm = {
id: undefined, id: undefined,
managerId: undefined, // managerId: undefined, //
name: undefined, name: undefined,
parentId: undefined, parentId: undefined,
sort: 0, sort: 0,
}; };
const employeeSelect = ref(); const employeeSelect = ref();
let formState = reactive({ let formState = reactive({
...defaultDepartmentForm, ...defaultDepartmentForm,
}); });
// //
const rules = { const rules = {
parentId: [{ required: true, message: '上级部门不能为空' }], parentId: [{ required: true, message: '上级部门不能为空' }],
name: [ name: [
{ required: true, message: '部门名称不能为空' }, { required: true, message: '部门名称不能为空' },
{ max: 50, message: '部门名称不能大于20个字符', trigger: 'blur' }, { max: 50, message: '部门名称不能大于20个字符', trigger: 'blur' },
], ],
managerId: [{ required: true, message: '部门负责人不能为空' }], };
}; //
// function updateFormData(data) {
function updateFormData(data) {
Object.assign(formState, defaultDepartmentForm); Object.assign(formState, defaultDepartmentForm);
if (data) { if (data) {
Object.assign(formState, data); Object.assign(formState, data);
} }
visible.value = true; visible.value = true;
} }
// //
function resetFormData() { function resetFormData() {
Object.assign(formState, defaultDepartmentForm); Object.assign(formState, defaultDepartmentForm);
} }
async function handleOk() { async function handleOk() {
try { try {
await formRef.value.validate(); await formRef.value.validate();
if (formState.departmentId) { if (formState.departmentId) {
@ -101,11 +102,11 @@
} catch (error) { } catch (error) {
message.error('参数验证错误,请仔细填写表单数据!'); message.error('参数验证错误,请仔细填写表单数据!');
} }
} }
// ----------------------- form ajax --------------------- // ----------------------- form ajax ---------------------
//ajax //ajax
async function addDepartment() { async function addDepartment() {
SmartLoading.show(); SmartLoading.show();
try { try {
await departmentApi.addDepartment(formState); await departmentApi.addDepartment(formState);
@ -116,14 +117,14 @@
} finally { } finally {
SmartLoading.hide(); SmartLoading.hide();
} }
} }
//ajax //ajax
async function updateDepartment() { async function updateDepartment() {
SmartLoading.show(); SmartLoading.show();
try { try {
if (formState.parentId == formState.departmentId) { if (formState.parentId == formState.departmentId) {
message.warning('上级菜单不能为自己'); message.warning('上级部门不能为自己');
return; return;
} }
await departmentApi.updateDepartment(formState); await departmentApi.updateDepartment(formState);
@ -134,5 +135,5 @@
} finally { } finally {
SmartLoading.hide(); SmartLoading.hide();
} }
} }
</script> </script>