558 lines
21 KiB
Vue
558 lines
21 KiB
Vue
<template>
|
||
<div class="edit-popup">
|
||
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit" @close="handleClose">
|
||
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
|
||
<el-form-item label="项目名称" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
|
||
<el-input v-model="project_name" @click="showDialog = true" clearable placeholder="点击选择项目" />
|
||
</el-form-item>
|
||
<el-form-item label="项目编码" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
|
||
<el-input v-model="project_code" disabled clearable placeholder="系统自动填写" />
|
||
</el-form-item>
|
||
<el-form-item label="客户名称" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
|
||
<el-input v-model="custom_name" disabled @click="showDialog = true" clearable placeholder="系统自动填写" />
|
||
</el-form-item>
|
||
<el-form-item label="技术人员" prop="technician_ids">
|
||
<!-- <el-input v-model="technician" clearable placeholder="请输入技术人员" @click="userone('1')" /> -->
|
||
<!-- <el-input placeholder="请输入技术人员" v-model="technician" @click="userone('1')">
|
||
</el-input> -->
|
||
<el-button @click="userone('1')">添加</el-button>
|
||
|
||
<div style=" display: block;width: 100%;margin-top: 10px;">
|
||
<el-tag v-for="(tag, index) in technician" :key="index" closable @close="removeTag1(index)" style="margin-right: 10px;">
|
||
{{ tag.name }}
|
||
</el-tag>
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item label="商务人员" prop="business_people_ids">
|
||
<!-- <el-input v-model="business_people" clearable placeholder="请输入商务人员" @click="userone('2')" /> -->
|
||
<el-button @click="userone('2')">添加</el-button>
|
||
|
||
<div style=" display: block;width: 100%;margin-top: 10px;">
|
||
|
||
<el-tag v-for="(tag, index) in business_people" :key="index" closable @close="removeTag2(index)" style="margin-right: 10px;">
|
||
{{ tag.name }}
|
||
</el-tag>
|
||
</div>
|
||
|
||
</el-form-item>
|
||
<el-form-item label="跨部门人员" prop="cross_departmental_personnel_ids">
|
||
<!-- <el-input v-model="cross_departmental_personnel" clearable placeholder="请输入跨部门人员" @click="userone('3')" /> -->
|
||
<el-button @click="userone('3')">添加</el-button>
|
||
|
||
<div style=" display: block;width: 100%;margin-top: 10px;">
|
||
|
||
<el-tag v-for="(tag, index) in cross_departmental_personnel" :key="index" closable @close="removeTag3(index)" style="margin-right: 10px;">
|
||
{{ tag.name }}
|
||
</el-tag>
|
||
</div>
|
||
|
||
</el-form-item>
|
||
<el-dialog v-model="showDialog" title="选择项目" width="70%">
|
||
<projectTable @customEvent="customEvent"></projectTable>
|
||
|
||
</el-dialog>
|
||
</el-form>
|
||
</popup>
|
||
<el-dialog v-model="dialogVisible" title="人员选择器" width="600px" :before-close="handleClose">
|
||
<div>
|
||
<el-radio-group v-model="isCollapse" style="margin-bottom: 20px">
|
||
<el-radio-button :label="1">全部人员</el-radio-button>
|
||
<el-radio-button :label="2">按部门筛选</el-radio-button>
|
||
<el-radio-button :label="3">按岗位筛选</el-radio-button>
|
||
</el-radio-group>
|
||
|
||
<div v-if="isCollapse == 1" style="margin-bottom: 20px">
|
||
<!-- <el-input v-model="content" clearable placeholder="搜索人员" /> -->
|
||
<div style="margin-top: 20px">
|
||
<el-checkbox-group v-model="radiolist">
|
||
<el-checkbox :label="item" v-for="(item, i) in uesrlist" :key="i" style="margin-bottom: 20px;">
|
||
<div class="radio-con">
|
||
<div class="radioa">
|
||
<img :src="item.avatar" alt="" />
|
||
</div>
|
||
<div class="radiob">
|
||
<div class="radiob_a">{{ item.name }}</div>
|
||
<div class="radiob_b">
|
||
<!-- {{ item.org_name }}/{{ item.dept_name }}/{{ item.job_name }} -->
|
||
<text v-if="item.org_name.length > 0">{{ item.org_name }}</text>
|
||
<text v-if="item.dept_name.length > 0">/{{ item.dept_name }}</text>
|
||
<text v-if="item.job_name.length > 0">/{{ item.job_name }}</text>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-checkbox><br />
|
||
</el-checkbox-group>
|
||
</div>
|
||
</div>
|
||
<div v-if="isCollapse == 2">
|
||
<div v-if="isshow">
|
||
<div class="lad" v-for="(item, i) in deparmetlist" :key="i">
|
||
<div class="lad">{{ i }}</div>
|
||
<div class="flex " v-for="(items, k) in item" style="justify-content: space-between;" @click="deparmetclck(items)">
|
||
<div>{{ items.name }}</div>
|
||
<div class="Collapsebj">{{ items.admin_num }}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div v-else>
|
||
|
||
|
||
<!-- <el-input v-model="content" clearable placeholder="搜索人员" style="margin-bottom: 20px;" /> -->
|
||
|
||
<el-checkbox-group v-model="radiolist">
|
||
<el-checkbox :label="item" v-for="(item, i) in deparmetlist1" :key="i" style="margin-bottom: 20px;">
|
||
<div class="radio-con">
|
||
<div class="radioa">
|
||
<img :src="item.avatar" alt="" />
|
||
</div>
|
||
<div class="radiob">
|
||
<div class="radiob_a">{{ item.name }}</div>
|
||
<div class="radiob_b">
|
||
|
||
<text v-if="item.org_name.length > 0">{{ item.org_name }}</text>
|
||
<text v-if="item.dept_name.length > 0">/{{ item.dept_name }}</text>
|
||
<text v-if="item.job_name.length > 0">/{{ item.job_name }}</text>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-checkbox><br />
|
||
</el-checkbox-group>
|
||
</div>
|
||
</div>
|
||
<div v-if="isCollapse == 3">
|
||
<div class="lad " v-if="isshow1">
|
||
<div class="flex " v-for="(item, j) in jobslist" :key="j" style="justify-content: space-between;" @click="gwclck(item)">
|
||
<div>{{ item.name }}</div>
|
||
<div class="Collapsebj">{{ item.admin_num }}</div>
|
||
</div>
|
||
</div>
|
||
<div v-else>
|
||
<!-- <el-input v-model="content" clearable placeholder="搜索人员" style="margin-bottom: 20px;" /> -->
|
||
<el-checkbox-group v-model="radiolist">
|
||
<el-checkbox :label="item" v-for="(item, i) in jobslist1" :key="i" style="margin-bottom: 20px;">
|
||
<div class="radio-con">
|
||
<div class="radioa">
|
||
<img :src="item.avatar" alt="" />
|
||
</div>
|
||
<div class="radiob">
|
||
<div class="radiob_a">{{ item.name }}</div>
|
||
<div class="radiob_b">
|
||
<!-- {{ item.org_name }}/{{ item.dept_name }}/{{ item.job_name }} -->
|
||
<text v-if="item.org_name.length > 0">{{ item.org_name }}</text>
|
||
<text v-if="item.dept_name.length > 0">/{{ item.dept_name }}</text>
|
||
<text v-if="item.job_name.length > 0">/{{ item.job_name }}</text>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-checkbox><br />
|
||
</el-checkbox-group>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<template #footer>
|
||
<span class="dialog-footer">
|
||
<el-button @click="dialogVisible = false">取消</el-button>
|
||
<el-button type="primary" @click="userclick"> {{ radiolist.length > 0 ? '已选' : '未选' }}
|
||
<text v-if="radiolist.length > 0">{{ radiolist.length }}</text></el-button>
|
||
</span>
|
||
</template>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts" setup name="projectPreSalesMembersEdit">
|
||
import type { FormInstance } from 'element-plus'
|
||
import Popup from '@/components/popup/index.vue'
|
||
import projectTable from "@/components/project/index.vue"
|
||
import { computed, nextTick, onMounted, reactive, shallowRef, watch } from 'vue'
|
||
import { apiProjectPreSalesMembersAdd, apiProjectPreSalesMembersEdit, apiProjectPreSalesMembersDetail } from '@/api/project_pre_sales_members'
|
||
import { getAdminsByAll, getAllDept, getAllJobs, getAdminsByDept, getAdminsByJob } from '@/api/common'
|
||
import { timeFormat } from '@/utils/util'
|
||
import feedback from '@/utils/feedback'
|
||
import type { PropType } from 'vue'
|
||
const leixin = ref('0')
|
||
defineProps({
|
||
dictData: {
|
||
type: Object as PropType<Record<string, any[]>>,
|
||
default: () => ({})
|
||
}
|
||
})
|
||
|
||
const dialogVisible = ref(false)
|
||
const active = ref(0);
|
||
|
||
const isCollapse = ref(1);
|
||
const emit = defineEmits(['success', 'close'])
|
||
const formRef = shallowRef<FormInstance>()
|
||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||
const mode = ref('add')
|
||
const uesrlist = reactive([])
|
||
const deparmetlist = reactive({})
|
||
const deparmetlist1 = reactive([])
|
||
const jobslist = reactive({})
|
||
const jobslist1 = reactive([])
|
||
const isshow = ref(true);
|
||
const isshow1 = ref(true);
|
||
const radiolist = ref([])
|
||
const cross_departmental_personnel = ref([])
|
||
const technician
|
||
= ref([])
|
||
const business_people
|
||
= ref([])
|
||
|
||
const custom_name = ref('')
|
||
const project_name = ref('')
|
||
const project_code = ref('')
|
||
|
||
const showDialog = ref(false)
|
||
const customEvent = (e: any) => {
|
||
formData.project_id = e.id;
|
||
project_name.value = e.name;
|
||
project_code.value = e.project_code;
|
||
custom_name.value = e.custom_name;
|
||
showDialog.value = false;
|
||
};
|
||
// 获取全部人员
|
||
const getlist = () => {
|
||
getAdminsByAll().then((res) => {
|
||
// console.log(res)
|
||
Object.assign(uesrlist, res)
|
||
})
|
||
}
|
||
|
||
//获取所有部门
|
||
const deparmet = () => {
|
||
getAllDept().then((res) => {
|
||
console.log(res)
|
||
Object.assign(deparmetlist, res)
|
||
})
|
||
}
|
||
//获取部门下的人员
|
||
const deparmetclck = (item: { id: any }) => {
|
||
console.log(item)
|
||
getAdminsByDept({ 'dept_id': item.id }).then((res) => {
|
||
if (res.length > 0) {
|
||
Object.assign(deparmetlist1, res)
|
||
isshow.value = false
|
||
}
|
||
|
||
})
|
||
}
|
||
|
||
//获取岗位
|
||
|
||
const Jobs = () => {
|
||
getAllJobs().then((res) => {
|
||
console.log(res)
|
||
Object.assign(jobslist, res)
|
||
})
|
||
}
|
||
|
||
//获取岗位下的人员
|
||
const gwclck = (item: { id: any }) => {
|
||
|
||
getAdminsByJob({ 'job_id': item.id }).then((res) => {
|
||
if (res.length > 0) {
|
||
Object.assign(jobslist1, res)
|
||
isshow1.value = false
|
||
}
|
||
|
||
})
|
||
}
|
||
|
||
|
||
//打开弹窗
|
||
const userone = (e: any) => {
|
||
leixin.value = e
|
||
if (mode.value != 'add') {
|
||
if (e == 1) {
|
||
const arry4 = [...technician.value]
|
||
radiolist.value = arry4
|
||
} else if (e == 2) {
|
||
const arry4 = [...business_people.value]
|
||
radiolist.value = arry4
|
||
} else {
|
||
const arry4 = [...cross_departmental_personnel.value]
|
||
radiolist.value = arry4
|
||
}
|
||
}
|
||
dialogVisible.value = true
|
||
}
|
||
|
||
//获取选择的数据
|
||
const userclick = () => {
|
||
if (radiolist.value.length > 0) {
|
||
if (leixin.value === '1') {
|
||
// 如果 leixin 的值为 1,则执行这里的代码块
|
||
formData.technician_ids = radiolist.value.map((item) => item.id).toString()
|
||
const newArray = radiolist.value.map((item) => item)
|
||
|
||
// if (!technician.value.some(elem => newArray.some(newElem => elem === newElem.id))) {
|
||
// // 如果不存在,则将 newElem 添加到 cont 数组中
|
||
// technician.value.push(...newArray);
|
||
// }
|
||
newArray.forEach(newElem => {
|
||
if (!technician.value.some(elem => elem.id === newElem.id)) {
|
||
// 如果不存在,则将 newElem 添加到 newArray1 数组中
|
||
technician.value.push(newElem);
|
||
}
|
||
});
|
||
} else if (leixin.value === '2') {
|
||
// 如果 leixin 的值为 2,则执行这里的代码块
|
||
formData.business_people_ids = radiolist.value.map((item) => item.id).toString()
|
||
const newArray = radiolist.value.map((item) => item)
|
||
newArray.forEach(newElem => {
|
||
if (!business_people.value.some(elem => elem.id === newElem.id)) {
|
||
// 如果不存在,则将 newElem 添加到 newArray1 数组中
|
||
business_people.value.push(newElem);
|
||
}
|
||
});
|
||
// if (!business_people.value.some(elem => newArray.some(newElem => JSON.stringify(elem.id) === JSON.stringify(newElem.id)))) {
|
||
// // 如果不存在,则将 newElem 添加到 cont 数组中
|
||
// business_people.value.push(...newArray);
|
||
// }
|
||
} else {
|
||
// 如果 leixin 的值不是 1 或 2,则执行这里的代码块
|
||
formData.cross_departmental_personnel_ids = radiolist.value.map((item) => item.id).toString()
|
||
const newArray = radiolist.value.map((item) => item)
|
||
newArray.forEach(newElem => {
|
||
if (!cross_departmental_personnel.value.some(elem => elem.id === newElem.id)) {
|
||
// 如果不存在,则将 newElem 添加到 newArray1 数组中
|
||
cross_departmental_personnel.value.push(newElem);
|
||
}
|
||
});
|
||
// if (!cross_departmental_personnel.value.some(elem => newArray.some(newElem => JSON.stringify(elem.id) === JSON.stringify(newElem.id)))) {
|
||
// // 如果不存在,则将 newElem 添加到 cont 数组中
|
||
// cross_departmental_personnel.value.push(...newArray);
|
||
// }
|
||
}
|
||
|
||
dialogVisible.value = false
|
||
radiolist.value = []
|
||
} else {
|
||
feedback.msgError('请重新选择')
|
||
}
|
||
}
|
||
//删除选择数据
|
||
|
||
const removeTag1 = (tag) => {
|
||
technician.value.splice(tag, 1)
|
||
if (technician.value.length > 0) {
|
||
formData.technician_ids = technician.value.map((item) => item.id).toString()
|
||
}
|
||
}
|
||
|
||
const removeTag2 = (tag) => {
|
||
business_people.value.splice(tag, 1)
|
||
if (business_people.value.length > 0) {
|
||
formData.business_people_ids = business_people.value.map((item) => item.id).toString()
|
||
}
|
||
}
|
||
|
||
const removeTag3 = (tag) => {
|
||
cross_departmental_personnel.value.splice(tag, 1)
|
||
if (cross_departmental_personnel.value.length > 0) {
|
||
formData.cross_departmental_personnel_ids = cross_departmental_personnel.value.map((item) => item.id).toString()
|
||
}
|
||
}
|
||
|
||
// 弹窗标题
|
||
const popupTitle = computed(() => {
|
||
return mode.value == 'edit' ? '编辑售前项目成员' : '新增售前项目成员'
|
||
})
|
||
|
||
// 表单数据
|
||
const formData = reactive({
|
||
id: '',
|
||
project_id: '',
|
||
technician_ids: '',
|
||
business_people_ids: '',
|
||
cross_departmental_personnel_ids: '',
|
||
})
|
||
|
||
|
||
// 表单验证
|
||
const formRules = reactive<any>({
|
||
|
||
})
|
||
|
||
|
||
// 获取详情
|
||
const setFormData = async (data: Record<any, any>) => {
|
||
|
||
setTimeout(() => {
|
||
if (data.technician_ids && data.technician_ids.length > 0) {
|
||
if (data.technician_ids.includes(",")) {
|
||
const arry1 = data.technician_ids.split(',')
|
||
const arry2 = uesrlist
|
||
const arry3 = arry2.filter(obj => arry1.includes(obj.id.toString()))
|
||
technician.value = arry3
|
||
} else {
|
||
const arry1 = [data.technician_ids]
|
||
const arry2 = uesrlist
|
||
const arry3 = arry2.filter(obj => arry1.includes(obj.id.toString()))
|
||
technician.value = arry3
|
||
}
|
||
}
|
||
if (data.business_people_ids && data.business_people_ids.length > 0) {
|
||
if (data.business_people_ids.includes(",")) {
|
||
const arry1 = data.business_people_ids.split(',')
|
||
const arry2 = uesrlist
|
||
const arry3 = arry2.filter(obj => arry1.includes(obj.id.toString()))
|
||
business_people.value = arry3
|
||
} else {
|
||
const arry1 = [data.business_people_ids]
|
||
const arry2 = uesrlist
|
||
const arry3 = arry2.filter(obj => arry1.includes(obj.id.toString()))
|
||
business_people.value = arry3
|
||
}
|
||
}
|
||
if (data.cross_departmental_personnel_ids && data.cross_departmental_personnel_ids.length > 0) {
|
||
if (data.cross_departmental_personnel_ids.includes(",")) {
|
||
const arry1 = data.cross_departmental_personnel_ids.split(',')
|
||
const arry2 = uesrlist
|
||
const arry3 = arry2.filter(obj => arry1.includes(obj.id.toString()))
|
||
cross_departmental_personnel.value = arry3
|
||
} else {
|
||
const arry1 = [data.cross_departmental_personnel_ids]
|
||
const arry2 = uesrlist
|
||
const arry3 = arry2.filter(obj => arry1.includes(obj.id.toString()))
|
||
cross_departmental_personnel.value = arry3
|
||
}
|
||
}
|
||
// const arry4 = [...cross_departmental_personnel.value, ...business_people.value, ...technician.value]
|
||
// radiolist.value = arry4
|
||
},
|
||
1000)
|
||
|
||
|
||
// technician.value = data.technician
|
||
// business_people.value = data.business_people
|
||
// cross_departmental_personnel.value = data.cross_departmental_personnel
|
||
|
||
for (const key in formData) {
|
||
if (data[key] != null && data[key] != undefined) {
|
||
//@ts-ignore
|
||
formData[key] = data[key]
|
||
}
|
||
}
|
||
|
||
project_name.value = data.project_name;
|
||
project_code.value = data.project_code;
|
||
custom_name.value = data.custom_name;
|
||
}
|
||
|
||
const getDetail = async (row: Record<string, any>) => {
|
||
const data = await apiProjectPreSalesMembersDetail({
|
||
id: row.id
|
||
})
|
||
setFormData(data)
|
||
}
|
||
|
||
|
||
// 提交按钮
|
||
const handleSubmit = async () => {
|
||
await formRef.value?.validate()
|
||
const data = { ...formData, }
|
||
mode.value == 'edit'
|
||
? await apiProjectPreSalesMembersEdit(data)
|
||
: await apiProjectPreSalesMembersAdd(data)
|
||
popupRef.value?.close()
|
||
emit('success')
|
||
}
|
||
|
||
//打开弹窗
|
||
const open = (type = 'add') => {
|
||
getlist()
|
||
deparmet()
|
||
Jobs()
|
||
mode.value = type
|
||
popupRef.value?.open()
|
||
}
|
||
|
||
// 关闭回调
|
||
const handleClose = () => {
|
||
emit('close')
|
||
}
|
||
|
||
|
||
|
||
defineExpose({
|
||
open,
|
||
setFormData,
|
||
getDetail
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.userlist {
|
||
display: flex;
|
||
|
||
img {
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: 50%;
|
||
}
|
||
|
||
text-align: center;
|
||
|
||
.userlist-con {
|
||
margin-right: 10px;
|
||
}
|
||
}
|
||
|
||
.user {
|
||
img {
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: 50%;
|
||
}
|
||
}
|
||
|
||
.radio-con {
|
||
display: flex;
|
||
width: 500px;
|
||
|
||
.radioa {
|
||
img {
|
||
margin-right: 20px;
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: 50%;
|
||
}
|
||
}
|
||
|
||
.radiob {
|
||
.radiob_a {
|
||
margin-bottom: 10px;
|
||
margin-top: 3px;
|
||
|
||
}
|
||
|
||
.radiob_b {}
|
||
|
||
}
|
||
}
|
||
|
||
.lad {
|
||
padding: 10px 0;
|
||
border-bottom: 1px solid #f7f7f7;
|
||
|
||
div {
|
||
margin: 10px 0;
|
||
}
|
||
|
||
.Collapsebj {
|
||
background-color: #3e8ef7;
|
||
height: 20px;
|
||
width: 20px;
|
||
line-height: 20px;
|
||
text-align: center;
|
||
border-radius: 6px;
|
||
color: #f7f7f7;
|
||
|
||
}
|
||
}
|
||
</style> |