backend/src/views/apps/erp/organization/components/edit.vue

236 lines
6.9 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>
<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="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>
<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="请选择负责人">
<el-option v-for="item in leaderList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<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>
<el-radio :label="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" :loading="loading" @click="handleSubmit">确定</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
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'
import { getTenantUsers } from '@/api/user'
interface TreeNode {
id: number
org_name: string
org_code?: string
parent_id?: number
parent_name?: string
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: []
}>()
const visible = ref(false)
const loading = ref(false)
const formRef = ref<FormInstance>()
const isEdit = ref(false)
const authStore = useAuthStore()
const tenantId = (authStore.user as any)?.tenant_id
const leaderList = ref([])
const formData = reactive({
id: 0,
parent_id: undefined as number | undefined,
org_name: '',
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' }]
}
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
}
}
// 打开弹窗
const open = (data?: TreeNode, parentId?: number) => {
if (data) {
// 编辑:只拷贝需要的字段,避免把 children 等多余字段带到表单
isEdit.value = true
formData.id = data.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 || ''
} else {
// 新增
isEdit.value = false
formData.id = 0
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 = ''
}
visible.value = true
}
// 关闭弹窗
const handleClose = () => {
visible.value = false
formRef.value?.resetFields()
}
// 提交
const handleSubmit = async () => {
if (!formRef.value) return
await formRef.value.validate()
loading.value = true
try {
let res
// 只允许提交到后台的字段白名单
const allowedKeys = ['parent_id', 'org_name', 'org_code', 'leader_id', 'sort', 'is_company', 'status', 'remark']
if (isEdit.value && formData.id) {
// 编辑:使用普通对象提交
const submitData: Record<string, any> = {}
allowedKeys.forEach(key => {
const value = (formData as any)[key]
if (value !== undefined && value !== null) {
submitData[key] = value
}
})
if (tenantId) {
submitData.tenant_id = tenantId
}
res = await editOrganization(formData.id, submitData)
} else {
// 新增:使用 FormData 以兼容后端 multipart/form-data
const submitData = new FormData()
allowedKeys.forEach(key => {
const value = (formData as any)[key]
if (value !== undefined && value !== null) {
submitData.append(key, String(value))
}
})
if (tenantId) {
submitData.append('tenant_id', String(tenantId))
}
res = await createOrganization(submitData)
}
if (res.code === 200) {
ElMessage.success(isEdit.value ? '编辑成功' : '添加成功')
emit('success')
handleClose()
} else {
ElMessage.error(res.msg || (isEdit.value ? '编辑失败' : '添加失败'))
}
} catch (error) {
console.error('提交失败:', error)
ElMessage.error('提交失败')
} finally {
loading.value = false
}
}
onMounted(() => {
getLeaderList()
})
defineExpose({ open })
</script>