改组织架构不合理地方

This commit is contained in:
2026-02-26 20:56:55 +08:00
parent ef5eb809bc
commit f8437d15b4
6 changed files with 446 additions and 231 deletions
+64
View File
@@ -63,3 +63,67 @@ export function deleteOrganization(id) {
method: "delete",
});
}
/*************************************************
****************** 员工相关接口 ******************
*************************************************/
/**
* 获取员工列表
* @returns {Promise}
*/
export function getEmployeeList() {
return request({
url: '/admin/erp/getEmployee',
method: 'get'
});
}
/**
* 获取员工详情
* @param {number} id 员工ID
* @returns {Promise}
*/
export function getEmployeeDetail(id) {
return request({
url: `/admin/erp/getEmployeeDetail/${id}`,
method: "get",
});
}
/**
* 创建员工数据
* @param {Object} data 员工数据
* @returns {Promise}
*/
export function createEmployee(data) {
return request({
url: "/admin/erp/createEmployee",
method: "post",
data: data,
headers: {
"Content-Type": "multipart/form-data"
}
});
}
// 更新员工信息
export function editEmployee(id, data) {
return request({
url: `/admin/erp/editEmployee/${id}`,
method: 'post',
data: data
});
}
/**
* 删除员工数据
* @param {number} id 员工ID
* @returns {Promise}
*/
export function deleteEmployee(id) {
return request({
url: `/admin/erp/deleteEmployee/${id}`,
method: "delete",
});
}
+61 -20
View File
@@ -30,27 +30,13 @@
</el-form-item>
<el-divider></el-divider>
<div class="form-title">个人信息</div>
<!-- 姓名 -->
<el-form-item label="姓名">
<el-input v-model="form.name" placeholder="请输入姓名" />
</el-form-item>
<!-- 电话 -->
<el-form-item label="电话">
<el-input v-model="form.phone" placeholder="请输入电话" />
</el-form-item>
<!-- 邮箱 -->
<el-form-item label="邮箱">
<el-input v-model="form.email" placeholder="请输入邮箱" />
</el-form-item>
<!-- QQ -->
<el-form-item label="QQ">
<el-input v-model="form.qq" placeholder="请输入QQ" />
</el-form-item>
<!-- 性别 -->
<el-form-item label="性别">
<el-radio-group v-model="form.sex" placeholder="请选择性别">
@@ -59,13 +45,68 @@
</el-radio-group>
</el-form-item>
<!-- 生日 -->
<el-form-item label="生日">
<el-date-picker
v-model="form.birthday"
type="date"
placeholder="请选择生日"
/>
</el-form-item>
<!-- 隶属单位 -->
<el-form-item label="隶属单位">
<el-input v-model="form.affiliate_unit" placeholder="请输入隶属单位" />
</el-form-item>
<!-- 部门 -->
<el-form-item label="部门">
<el-input v-model="form.department" placeholder="请输入部门" />
</el-form-item>
<!-- 职位 -->
<el-form-item label="职位">
<el-input v-model="form.position" placeholder="请输入职位" />
</el-form-item>
<!-- 学历 -->
<el-form-item label="学历">
<el-input v-model="form.education" placeholder="请输入学历" />
</el-form-item>
<!-- 民族 -->
<el-form-item label="民族">
<el-input v-model="form.nationality" placeholder="请输入民族" />
</el-form-item>
<!-- 手机 -->
<el-form-item label="手机">
<el-input v-model="form.phone" placeholder="请输入手机号" />
</el-form-item>
<!-- 微信 -->
<el-form-item label="微信">
<el-input v-model="form.wechat" placeholder="请输入微信" />
</el-form-item>
<!-- 邮箱 -->
<el-form-item label="邮箱">
<el-input v-model="form.email" placeholder="请输入邮箱" />
</el-form-item>
<!-- 家庭住址 -->
<el-form-item label="家庭住址">
<el-input v-model="form.home_address" placeholder="请输入家庭住址" />
</el-form-item>
<!-- 状态 -->
<el-form-item label="状态">
<el-select
v-model="form.status"
v-model="form.account_status"
placeholder="请选择状态"
style="width: 100%"
>
<el-option label="离职" :value="2" v-if="!isAdd" />
<el-option label="启用" :value="1" />
<el-option label="禁用" :value="0" />
</el-select>
@@ -83,7 +124,7 @@
<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { ElMessage } from "element-plus";
import { addUser, editUser, getUserInfo } from "@/api/user";
import { createEmployee, editEmployee, getEmployeeDetail } from "@/api/erp";
const props = defineProps({
modelValue: {
@@ -214,7 +255,7 @@
throw new Error("未提供有效的用户 ID");
}
const res = await getUserInfo(userId);
const res = await getEmployeeDetail(userId);
const data = res.data || res;
@@ -301,7 +342,7 @@
password: form.value.password,
};
await addUser(submitData);
await createEmployee(submitData);
ElMessage.success("添加成功");
} else {
// 编辑用户
@@ -326,7 +367,7 @@
submitData.password = form.value.password;
}
await editUser(form.value.id, submitData);
await editEmployee(form.value.id, submitData);
ElMessage.success("更新成功");
}
+74
View File
@@ -57,11 +57,85 @@
<el-pagination :current-page="page" :page-size="pageSize" :total="total" @current-change="handlePageChange"
layout="total, prev, pager, next" />
</div>
<!-- 编辑弹窗 -->
<Edit ref="editRef" @submit="fetchData" />
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Plus, Refresh } from "@element-plus/icons-vue";
import { getEmployeeList, deleteEmployee } from "@/api/erp";
import Edit from "./components/edit.vue";
const users = ref<any[]>([]);
const loading = ref(false);
const page = ref(1);
const pageSize = ref(10);
const total = ref(0);
const editRef = ref<any>(null);
// 获取列表数据
const fetchData = async () => {
loading.value = true;
try {
const res = await getEmployeeList();
users.value = res.data || res || [];
total.value = users.value.length;
} catch (e: any) {
ElMessage.error(e?.message || "获取列表失败");
} finally {
loading.value = false;
}
};
// 刷新
const refresh = () => {
fetchData();
};
// 添加用户
const handleAddUser = () => {
editRef.value?.openAdd();
};
// 编辑用户
const handleEdit = (row: any) => {
editRef.value?.openEdit(row);
};
// 查看
const handlePreview = (row: any) => {
editRef.value?.openEdit(row);
};
// 删除用户
const handleDelete = async (row: any) => {
try {
await ElMessageBox.confirm(`确定删除用户 "${row.name}" 吗?`, "提示", {
type: "warning",
});
await deleteEmployee(row.id);
ElMessage.success("删除成功");
fetchData();
} catch (e: any) {
if (e !== "cancel") {
ElMessage.error(e?.message || "删除失败");
}
}
};
// 分页变化
const handlePageChange = (val: number) => {
page.value = val;
fetchData();
};
onMounted(() => {
fetchData();
});
</script>
<style lang="less" scoped>
@@ -1,27 +1,18 @@
<template>
<el-dialog
v-model="visible"
:title="isEdit ? '编辑部门' : '添加部门'"
width="500px"
:close-on-click-modal="false"
>
<el-dialog v-model="visible" :title="isEdit ? '编辑组织' : '添加组织'" width="500px" :close-on-click-modal="false">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
<el-form-item label="上级部门" prop="parent_id">
<el-tree-select
v-model="formData.parent_id"
:data="treeData"
:props="treeProps"
check-strictly
placeholder="请选择上级部门"
clearable
style="width: 100%"
/>
<el-form-item label="上级组织" prop="parent_id">
<el-tree-select v-model="formData.parent_id" :data="extendedTreeData"
:props="props.treeProps || defaultTreeProps" check-strictly placeholder="请选择上级组织" clearable
style="width: 100%" />
</el-form-item>
<el-form-item label="部门名称" prop="org_name">
<el-input v-model="formData.org_name" placeholder="请输入部门名称,例如:连云港云泽集团" />
<el-form-item label="组织名称" prop="org_name">
<el-input v-model="formData.org_name" placeholder="请输入组织名称,例如:连云港云泽集团" />
</el-form-item>
<el-form-item label="部门编码" prop="org_code">
<el-input v-model="formData.org_code" placeholder="请输入部门编码,例如:LYG-YZ-GROUP" />
<el-form-item label="组织编码" prop="org_code">
<el-input v-model="formData.org_code" placeholder="请输入组织编码,例如:LYG-YZ-GROUP" />
</el-form-item>
<el-form-item label="负责人" prop="leader_id">
<el-select v-model="formData.leader_id" placeholder="请选择负责人">
@@ -31,6 +22,12 @@
<el-form-item label="排序" prop="sort">
<el-input-number v-model="formData.sort" :min="0" :max="999" controls-position="right" style="width: 100%" />
</el-form-item>
<el-form-item label="是否是公司" prop="is_company">
<el-radio-group v-model="formData.is_company">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio :label="1">启用</el-radio>
@@ -47,9 +44,9 @@
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
import { createOrganization, editOrganization } from '@/api/erp'
import { useAuthStore } from '@/stores/auth'
@@ -64,13 +61,26 @@ interface TreeNode {
leader_id?: number
sort?: number
status?: number
is_company?: number
remark?: string
}
const props = defineProps<{
treeData: TreeNode[]
treeProps?: {
label: string
children: string
value: string
}
}>()
// 默认 treeProps
const defaultTreeProps = {
label: 'org_name',
children: 'children',
value: 'id'
}
const emit = defineEmits<{
success: []
}>()
@@ -89,23 +99,36 @@ const formData = reactive({
org_code: '',
leader_id: undefined as number | undefined,
sort: 0,
is_company: 0,
status: 1,
remark: ''
})
const formRules: FormRules = {
org_name: [{ required: true, message: '请输入部门名称', trigger: 'blur' }],
org_code: [{ required: true, message: '请输入部门编码', trigger: 'blur' }]
org_name: [{ required: true, message: '请输入组织名称', trigger: 'blur' }],
org_code: [{ required: true, message: '请输入组织编码', trigger: 'blur' }]
}
onMounted(() => {
getLeaderList()
const treeOptions = computed(() => {
return [
{
id: 0,
org_name: '顶级组织', // 显示名称
children: props.treeData // 将原有的树结构作为其子节点(或者并列,取决于你的业务)
}
]
})
// 如果你希望“顶级组织”是作为一个独立的根选项,而不是所有节点的父级:
const extendedTreeData = computed(() => {
const rootNode = { id: 0, org_name: '顶级组织' }
return [rootNode, ...props.treeData]
})
const getLeaderList = async () => {
const res = await getTenantUsers(tenantId)
if (res.code === 200) {
leaderList.value = res.data.list
leaderList.value = res.data.list
}
}
@@ -115,10 +138,11 @@ const open = (data?: TreeNode, parentId?: number) => {
// 编辑:只拷贝需要的字段,避免把 children 等多余字段带到表单
isEdit.value = true
formData.id = data.id
formData.parent_id = data.parent_id
formData.parent_id = data.parent_id ?? 0
formData.org_name = data.org_name
formData.org_code = data.org_code || ''
formData.leader_id = data.leader_id
formData.is_company = data.is_company ?? 0
formData.sort = data.sort ?? 0
formData.status = data.status ?? 1
formData.remark = data.remark || ''
@@ -126,10 +150,11 @@ const open = (data?: TreeNode, parentId?: number) => {
// 新增
isEdit.value = false
formData.id = 0
formData.parent_id = parentId
formData.parent_id = parentId ?? 0
formData.org_name = ''
formData.org_code = ''
formData.leader_id = undefined
formData.is_company = 0
formData.sort = 0
formData.status = 1
formData.remark = ''
@@ -153,8 +178,9 @@ const handleSubmit = async () => {
try {
let res
// 只允许提交到后台的字段白名单
const allowedKeys = ['parent_id', 'org_name', 'org_code', 'leader_id', 'sort', 'status', 'remark']
const allowedKeys = ['parent_id', 'org_name', 'org_code', 'leader_id', 'sort', 'is_company', 'status', 'remark']
if (isEdit.value && formData.id) {
// 编辑:使用普通对象提交
@@ -199,9 +225,11 @@ const handleSubmit = async () => {
}
}
onMounted(() => {
getLeaderList()
})
defineExpose({ open })
</script>
+13 -5
View File
@@ -53,19 +53,24 @@
<div v-if="selectedNode" class="detail-content">
<el-descriptions :column="2" border>
<el-descriptions-item label="部门名称">
<el-descriptions-item label="组织名称">
{{ selectedNode.org_name }}
</el-descriptions-item>
<el-descriptions-item label="部门编码">
<el-descriptions-item label="组织编码">
{{ selectedNode.org_code || '-' }}
</el-descriptions-item>
<el-descriptions-item label="上级部门">
{{ selectedNode.parent_name || '顶级部门' }}
<el-descriptions-item label="上级组织">
{{ selectedNode.parent_name || '顶级组织' }}
</el-descriptions-item>
<el-descriptions-item label="负责人">
{{ selectedNode.leader_name || '-' }}
</el-descriptions-item>
<el-descriptions-item label="状态" :span="2">
<el-descriptions-item label="是否是公司">
<el-tag :type="selectedNode.is_company === 1 ? 'primary' : 'info'">
{{ selectedNode.is_company === 1 ? '是' : '否' }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="状态">
<el-tag :type="selectedNode.status === 1 ? 'success' : 'danger'">
{{ selectedNode.status === 1 ? '启用' : '禁用' }}
</el-tag>
@@ -119,6 +124,7 @@ interface TreeNode {
parent_name?: string
leader_id?: number
leader_name?: string
is_company?: number
sort?: number
status?: number
remark?: string
@@ -154,6 +160,7 @@ const buildTree = (list: any[]): TreeNode[] => {
parent_name: item.parent_name,
leader_id: item.leader_id,
leader_name: item.leader_name,
is_company: item.is_company,
sort: item.sort,
status: item.status,
remark: item.remark,
@@ -193,6 +200,7 @@ const loadOrganizationDetail = async (id: number) => {
parent_name: data.parent_name,
leader_id: data.leader_id,
leader_name: data.leader_name,
is_company: data.is_company,
sort: data.sort,
status: data.status,
remark: data.remark,