<template>
|
<el-dialog @open="openDialog" class="select-member" :visible.sync="visible" width="53.33%"
|
:close-on-click-modal="false" :show-close="false">
|
<template #title>
|
<div>选择参与人员</div>
|
</template>
|
<div class="select-member-content">
|
<el-row :gutter="16">
|
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
|
<div class="select-member-content-left">
|
<div class="select-member-content-left-search">
|
<div class="select-member-content-left-search-input">
|
<img src="@/assets/public/search-outline@2x.png" />
|
<el-input v-model="search" placeholder="请输入" />
|
<div class="select-member-content-left-search-input-close">
|
<img @click.stop="searchRoleRest" v-if="search"
|
src="@/assets/public/close-circle-fill@2x.png" />
|
</div>
|
</div>
|
<el-button type="primary" @click="searchRole()">搜索</el-button>
|
</div>
|
<div class="select-member-content-left-list">
|
<div class="select-member-content-left-list-title">角色列表</div>
|
<div class="select-member-content-left-list-itemBox">
|
<div @click="handleRoleClick(item.roleId)" v-for="item in roleList" :key="item.roleId"
|
class="select-member-content-left-list-itemBox-item"
|
:class="roleId == item.roleId && 'active'">
|
{{ item.roleName }}
|
</div>
|
</div>
|
</div>
|
</div>
|
</el-col>
|
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16">
|
<div class="select-member-content-right">
|
<div class="select-member-content-right-header">
|
<div class="select-member-content-right-header-text">人员列表</div>
|
<div class="select-member-content-right-header-search">
|
<el-input clearable v-model="nickNameOrPhone" placeholder="请输入姓名" />
|
<el-button type="primary" @click="searchUserList(null)">搜索</el-button>
|
</div>
|
</div>
|
<Table ref="memberTable" :height="500" :row-key="row => row.userId" :data="tableData" :total="0"
|
@selection-change="handleSelectionChange" :row-class-name="tableRowClassName">
|
<el-table-column type="selection" width="55" />
|
<el-table-column label="角色" prop="roleId">
|
<template #default="scope">
|
<span v-if="scope.row.roleId == 1">超级管理员</span>
|
<span v-if="scope.row.roleId == 2">审批人</span>
|
<span v-if="scope.row.roleId == 3">工艺工程师</span>
|
<span v-if="scope.row.roleId == 4">化验师</span>
|
<span v-if="scope.row.roleId == 5">实验员</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="姓名" prop="nickName" />
|
<el-table-column label="头像" prop="avatar">
|
<template #default="scope">
|
<img :src="scope.row.avatar || require('../../assets/login/img1111.png')"
|
style="width: 50px;height: 50px;border-radius: 50%;" />
|
</template>
|
</el-table-column>
|
<el-table-column label="创建时间" prop="createTime" />
|
</Table>
|
</div>
|
</el-col>
|
</el-row>
|
</div>
|
<div class="select-member-footer">
|
<el-button @click="close" type="default">关闭</el-button>
|
<el-button type="primary" @click="submit">确认选择</el-button>
|
</div>
|
</el-dialog>
|
</template>
|
|
<script>
|
import { getRoleList, getUserList, listByRole } from './service'
|
export default {
|
props: {
|
projectId: {
|
type: [String, Number],
|
default: null
|
},
|
roleType: {
|
type: [String, Number],
|
default: null
|
},
|
},
|
data() {
|
return {
|
visible: false,
|
search: '',
|
nickNameOrPhone: '',
|
tableData: [],
|
selectData: [],
|
roleList: [],
|
roleId: null,
|
}
|
},
|
methods: {
|
searchRole() {
|
if (this.search) {
|
this.roleList = this.roleList.filter(item => item.roleName.includes(this.search))
|
} else {
|
getRoleList().then(res => {
|
if (this.projectId) {
|
// 过滤出实验员和化验师角色
|
this.roleList = res.filter(item => item.roleId == 4 || item.roleId == 5);
|
} else {
|
this.roleList = res;
|
}
|
});
|
}
|
|
},
|
setSelection(selected) {
|
this.selectData = selected;
|
// 确保 tableData 和 memberTable 都存在
|
if (this.tableData && this.$refs.memberTable) {
|
this.$nextTick(() => {
|
// 设置新的选中状态
|
this.tableData.forEach(row => {
|
const isSelected = selected.some(i => i.userId === row.userId);
|
this.$refs.memberTable.toggleRowSelection(row, isSelected);
|
});
|
});
|
}
|
},
|
openDialog() {
|
// 获取角色列表并根据项目组ID进行过滤
|
getRoleList().then(res => {
|
if (this.projectId) {
|
// 过滤出实验员和化验师角色
|
this.roleList = res.filter(item => item.roleId == 4 || item.roleId == 5);
|
} else if (this.roleType) {
|
this.roleList = res.filter(item => item.roleId == this.roleType);
|
} else {
|
this.roleList = res;
|
}
|
});
|
this.searchUserList(null);
|
},
|
handleSelectionChange(val) {
|
// 获取当前表格所有 userId
|
const currentIds = this.tableData.map(i => i.userId);
|
// 1. 保留不在当前表格的已选
|
const remain = this.selectData.filter(i => !currentIds.includes(i.userId));
|
// 2. 合并当前表格新选中的
|
const merged = [...remain, ...val];
|
// 3. 去重(以 userId 为唯一标识)
|
const unique = [];
|
const map = {};
|
for (const item of merged) {
|
if (!map[item.userId]) {
|
unique.push(item);
|
map[item.userId] = true;
|
}
|
}
|
this.selectData = unique;
|
},
|
handleRoleClick(clickedRoleId) {
|
if (this.roleId === clickedRoleId) {
|
// 再次点击,取消筛选
|
this.roleId = null;
|
this.searchUserList(null);
|
} else {
|
// 切换到新角色
|
this.roleId = clickedRoleId;
|
this.searchUserList(clickedRoleId);
|
}
|
},
|
async searchUserList(roleId) {
|
// this.roleId = roleId // 不再赋值 roleId,由 handleRoleClick 控制
|
// 根据是否有项目组ID来决定调用不同的接口
|
let params = {
|
roleIds: roleId ? [roleId] : [],
|
nickNameOrPhone: this.nickNameOrPhone,
|
pageSize: 9999,
|
pageNum: 1
|
};
|
if (this.projectId) {
|
params = {
|
...params,
|
roleId: roleId ? roleId : '',
|
projectId: this.projectId,
|
nickName: this.nickNameOrPhone,
|
}
|
delete params.roleIds;
|
// TODO: 这里需要替换为新的接口调用
|
const res = await listByRole(params);
|
this.tableData = res.filter(item => item.status == 0 && (item.roleId == 4 || item.roleId == 5));
|
} else if (this.roleType) {
|
params = {
|
...params,
|
roleIds: [this.roleType],
|
}
|
const res = await getUserList(params);
|
this.tableData = res.records;
|
} else {
|
const res = await getUserList(params);
|
this.tableData = res.records.filter(item => item.status == 0);
|
}
|
// 数据加载完成后重新应用选中状态
|
this.setSelection(this.selectData)
|
},
|
searchRoleRest() {
|
this.search = ''
|
},
|
open() {
|
this.visible = true
|
},
|
close() {
|
this.visible = false;
|
this.selectData = [];
|
this.roleId = null;
|
this.search = '';
|
this.nickNameOrPhone = '';
|
this.tableData = [];
|
},
|
submit() {
|
this.$emit('submit', this.selectData)
|
},
|
tableRowClassName({ row, rowIndex }) {
|
if (this.selectData.findIndex(item => item.userId === row.userId) != -1) {
|
return 'select-row';
|
}
|
return '';
|
}
|
}
|
}
|
</script>
|
|
<style scoped lang="less">
|
.select-member-content {
|
.select-member-content-left {
|
box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08);
|
border-radius: 10px;
|
margin-bottom: 31px;
|
|
&-search {
|
padding: 6px 7px 6px 10px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
border-bottom: 1px solid rgba(238, 238, 238, 1);
|
|
&-input {
|
display: flex;
|
align-items: center;
|
background: rgba(0, 0, 0, 0.04);
|
border-radius: 4px;
|
margin-right: 10px;
|
flex: 1;
|
|
::v-deep .el-input__inner {
|
background-color: transparent;
|
border: none;
|
height: 36px;
|
line-height: 36px;
|
padding: 0;
|
width: 100%;
|
}
|
|
img {
|
flex-shrink: 0;
|
width: 19px;
|
height: 20px;
|
margin: 0 5px;
|
}
|
|
&-close {
|
width: 19px;
|
height: 20px;
|
margin: 0 9px;
|
flex-shrink: 0;
|
|
img {
|
cursor: pointer;
|
}
|
}
|
}
|
}
|
|
&-list {
|
padding: 15px 13px;
|
|
&-title {
|
font-weight: 500;
|
font-size: 16px;
|
line-height: 16px;
|
color: #222222;
|
font-family: 'SourceHanSansCN-Medium';
|
margin-bottom: 8px;
|
}
|
|
&-itemBox {
|
height: 451px;
|
background: #F4F6F8;
|
border-radius: 10px;
|
padding: 12px 10px;
|
overflow-y: auto;
|
|
&-item {
|
cursor: pointer;
|
font-weight: 400;
|
font-size: 14px;
|
line-height: 22px;
|
color: rgba(0, 0, 0, 0.88);
|
font-family: 'PingFangSCRegular';
|
background: #FFFFFF;
|
border-radius: 4px;
|
padding: 9px 15px;
|
margin-bottom: 10px;
|
|
&:last-child {
|
margin-bottom: 0;
|
}
|
|
&:hover,
|
&.active {
|
background: rgba(4, 156, 154, 0.1);
|
color: #049C9A;
|
}
|
}
|
}
|
}
|
}
|
|
.select-member-content-right {
|
margin-bottom: 31px;
|
|
&-header {
|
display: flex;
|
align-items: center;
|
margin-top: 5px;
|
justify-content: space-between;
|
margin-bottom: 21px;
|
|
&-text {
|
flex-shrink: 0;
|
font-weight: 500;
|
font-size: 16px;
|
line-height: 16px;
|
color: #222222;
|
font-family: 'SourceHanSansCN-Medium';
|
margin-right: 20px;
|
}
|
|
&-search {
|
display: flex;
|
align-items: center;
|
|
::v-deep .el-input {
|
margin-right: 12px;
|
}
|
}
|
}
|
}
|
}
|
</style>
|