236 lines
6.9 KiB
Vue
236 lines
6.9 KiB
Vue
<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)?.tid
|
||
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.tid = 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('tid', 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>
|