<!--
|
文件名:UserSimpleSearchInput.vue
|
作者:〈版权〉
|
描述:〈用户简易搜索input框〉
|
修改人:熊文
|
修改时间:2023/6/20 9:49
|
修改内容:〈修改内容〉
|
-->
|
|
<template>
|
<el-select
|
v-model="selectValue"
|
ref="search-select"
|
popper-class="user-simple-search-input-popper"
|
:popper-append-to-body="true"
|
:disabled="disabled"
|
:placeholder="placeholder"
|
style="width: 100%"
|
class="user-simple-search-input"
|
@visible-change="changeSelectStatus"
|
:clearable="clearable"
|
filterable
|
:size="size"
|
@clear="selectClear"
|
>
|
<el-option :label="selectLabel" :value="selectValue">
|
<div class="container" @click="endSelect" v-loading="loading">
|
<div class="search">
|
<div :class="checkedType ? 'search-left-two' : 'search-left'">
|
<el-input
|
placeholder="请输入关键词"
|
v-model.trim="keyword"
|
maxlength="20"
|
@keyup.enter.native="updateSearchList(true)"
|
>
|
<i
|
slot="suffix"
|
class="el-input__icon el-icon-search"
|
v-prevent-re-click
|
@click="updateSearchList(true)"
|
></i>
|
</el-input>
|
</div>
|
<div class="icon-box" v-if="checkedType">
|
<div
|
v-for="item in materialTypeList"
|
:key="item.name"
|
:class="item.isChecked ? 'icon-active icon-item' : 'icon-item'"
|
v-prevent-re-click
|
@click="imgClick(item)"
|
>
|
{{ item.name }}
|
</div>
|
</div>
|
</div>
|
<div v-if="checkedNum > 1">
|
<div class="selected-text">
|
已选({{ selectedUser.length }}):
|
<span
|
class="user-text"
|
v-for="(user, index) in selectedUser"
|
:key="index"
|
>
|
{{ user[obj.name] }}
|
<span
|
class="iconfont ico-delete-user"
|
@click="deleteUser(user.id)"
|
></span
|
>
|
{{ selectedUser.length > index + 1 ? "," : "" }}
|
</span>
|
</div>
|
<p class="fs12-tip" v-show="selectedUser.length == checkedNum">
|
提示:最多选择{{ checkedNum }}人!
|
</p>
|
</div>
|
<!-- <div class="bar">
|
<span class="desc">请选择产品({{ listData.length }})</span>
|
</div> -->
|
<div class="list" element-loading-text="拼命加载中">
|
<ul class="infinite-list" @scroll="loadList">
|
<div class="background_color_eee">
|
<el-row :gutter="0">
|
<el-col :span="9">
|
<div class="grid-content bg-purple">
|
<span class="name">员工编码</span>
|
</div>
|
</el-col>
|
<el-col :span="9">
|
<div class="grid-content bg-purple">员工名称</div>
|
</el-col>
|
<el-col :span="6">
|
<div class="grid-content bg-purple">手机号</div>
|
</el-col>
|
</el-row>
|
</div>
|
<li class="empty" v-if="listData.length === 0">暂无数据</li>
|
<template v-else>
|
<li
|
v-for="(user, index) in listData"
|
:key="index"
|
@click="selectUser(user)"
|
:class="selectValue == user.id ? 'highlight-color' : ''"
|
>
|
<el-row :gutter="0">
|
<el-col :span="9">
|
<div
|
class="grid-content bg-purple"
|
:title="user.id"
|
>
|
<span class="name">{{
|
user.id || "--"
|
}}</span>
|
</div>
|
</el-col>
|
<el-col :span="9">
|
<div
|
class="grid-content bg-purple"
|
:title="user[obj.name]"
|
>
|
{{
|
user[obj.name] || "--"
|
}}
|
</div>
|
</el-col>
|
<el-col :span="6">
|
<div
|
class="grid-content bg-purple"
|
:title="user.phoneNum"
|
>
|
{{ user.phoneNum || "--" }}
|
</div>
|
</el-col>
|
</el-row>
|
</li>
|
<li class="loading">{{ loading ? "加载中" : "已经到底" }}</li>
|
</template>
|
</ul>
|
</div>
|
</div>
|
</el-option>
|
</el-select>
|
</template>
|
|
<script>
|
import { getWorkerList } from "@/api/employeeManage/employeeInfo.js"
|
export default {
|
name: "UserSimpleSearchInput",
|
components: {
|
},
|
props: {
|
placeholder: {
|
type: [String],
|
default: "请选择",
|
},
|
disabled: {
|
type: [Boolean],
|
default: false,
|
},
|
// 回显值code
|
echoName: {
|
type: [String],
|
default: "",
|
},
|
// 回显名称name
|
echoValue: {
|
type: [String],
|
default: "",
|
},
|
// 可选数量
|
checkedNum: {
|
type: [String, Number],
|
default: 1,
|
},
|
//员工类别 是否在职
|
isWorking: {
|
type: [Boolean],
|
default: false,
|
},
|
//可否清空
|
clearable: {
|
type: [Boolean],
|
default: false,
|
},
|
// 请求接口的参数
|
types: {
|
type: [Array],
|
default: () => ["半成品", "成品"],
|
},
|
// 是否可选择接口参数
|
checkedType: {
|
type: [Boolean],
|
default: false,
|
},
|
// 那个页面要保存用户与产品类型关系 1=订单管理 2=计划生产 3=产品Bom
|
pageType: {
|
type: [String, Number],
|
defalut: "",
|
},
|
request: {
|
type: [String, Number],
|
defalut: "",
|
},
|
size: {
|
type: [String],
|
defalut: "medium",
|
},
|
},
|
data() {
|
return {
|
// e-select组件model绑定变量,占位使用
|
selectValue: this.echoValue
|
? this.echoValue
|
: this.echoName
|
? this.echoName
|
: "",
|
selectLabel: "",
|
// 搜索框搜索词
|
keyword: "",
|
// 查询页
|
page: 1,
|
// 每页展示数量
|
pageSize: 10,
|
// 数据总量
|
count: 0,
|
// 搜索用户结果数组
|
listData: [],
|
// 是否结束选择
|
isEndSelect: false,
|
selectedUser: [],
|
loading: true,
|
num: 0,
|
obj: {
|
name: "name",
|
id: "id",
|
},
|
materialTypeList:[],
|
arrMaterialType: [],
|
};
|
},
|
computed: {},
|
watch: {
|
echoName() {
|
this.selectValue = this.echoValue
|
? this.echoValue
|
: this.echoName
|
? this.echoName
|
: "";
|
this.checkMoreInit();
|
},
|
request(val) {
|
this.getName(val);
|
},
|
checkedType() {
|
this.getUserProductTypeData();
|
},
|
},
|
beforeMount() {
|
this.checkMoreInit();
|
this.getName(this.request);
|
this.num = 0;
|
this.getUserProductTypeData();
|
},
|
methods: {
|
async getUserProductTypeData() {
|
if (this.checkedType) {
|
// const res = await getUserProductType({ pageType: this.pageType });
|
// if (res.code == 200) {
|
// let string = res.data.typeName.split(",");
|
// for (let i in this.materialTypeList) {
|
// for (const item of string) {
|
// if (item == this.materialTypeList[i].name) {
|
// this.materialTypeList[i].isChecked = true;
|
// this.arrMaterialType.push(this.materialTypeList[i].name);
|
// break;
|
// } else {
|
// this.materialTypeList[i].isChecked = false;
|
// }
|
// }
|
// }
|
// }
|
}
|
},
|
getName(val) {
|
if (val == 1) {
|
this.obj = {
|
name: "name",
|
id: "id",
|
};
|
} else if (val == 2) {
|
this.obj = {
|
name: "moldName",
|
id: "id",
|
};
|
} else if (val == 3) {
|
this.obj = {
|
name: "frockName",
|
id: "id",
|
};
|
} else if (val == 4) {
|
this.obj = {
|
name: "referenceName",
|
id: "id",
|
};
|
}
|
},
|
imgClick(item) {
|
item.isChecked = !item.isChecked;
|
this.arrMaterialType = [];
|
for (const list of this.materialTypeList) {
|
if (list.isChecked) {
|
this.arrMaterialType.push(list.name);
|
}
|
}
|
this.getSaveUserData();
|
this.updateSearchList(true);
|
},
|
async getSaveUserData() {
|
// const res = await saveUserProductType({
|
// typeName: this.arrMaterialType.join(","),
|
// pageType: this.pageType,
|
// });
|
// if (res.code == 200) {
|
// this.$message.success("保存成功!");
|
// }
|
},
|
// 更新搜索列表
|
async updateSearchList(needInit = false, param = {}) {
|
let listParams;
|
// 初始化用户信息列表入参
|
if (needInit) {
|
this.page = 1;
|
this.count = 0;
|
this.listData = [];
|
}
|
listParams = {
|
keyword: this.keyword,
|
page: this.page,
|
pageSize: this.pageSize,
|
// types: this.types,
|
...param,
|
};
|
if (this.checkedType) {
|
listParams.types = this.arrMaterialType;
|
}
|
|
this.loading = true;
|
if (this.checkedType) {
|
if(listParams.types.length == 0 ){
|
// 3个都不选的时候数据为空,不请求接口
|
this.loading = false;
|
return true;
|
}
|
}
|
// 物料
|
const res = await getWorkerList(listParams);
|
if (res && res.code == "200" && res.data) {
|
this.loading = false;
|
this.page = res.page + 1;
|
this.count = res.total;
|
if (res.data && Array.isArray(res.data)) {
|
let arr = JSON.parse(JSON.stringify(res.data));
|
this.listData = this.listData.concat(arr);
|
}
|
this.num += 1;
|
}
|
|
setTimeout(() => {
|
this.loading = false;
|
}, 10000);
|
},
|
// 动态加载列表
|
loadList(event) {
|
const { clientHeight, scrollTop, scrollHeight } = event.currentTarget;
|
// 当滚动top距离大于一屏的距离,加载下一页数据
|
if (scrollTop > scrollHeight - clientHeight * 2) {
|
// 当loading动画未结束时、或者列表数据条数大于接口返回总条数时不再请求数据
|
if (!this.loading && this.listData.length <= this.count) {
|
this.updateSearchList();
|
}
|
}
|
},
|
// 选择用户
|
selectUser(user) {
|
if (this.checkedNum > 1) {
|
if (this.selectedUser.length < this.checkedNum) {
|
if (this.selectValue.indexOf(user.id) == -1) {
|
this.selectedUser.push(user);
|
this.selectValue = this.selectedUser
|
.map((item) => {
|
return item.id;
|
})
|
.join(",");
|
this.selectLabel = this.selectedUser
|
.map((item) => {
|
return item[this.obj.name];
|
})
|
.join(",");
|
}
|
}
|
|
this.$emit(
|
"select-user",
|
this.selectValue,
|
this.selectLabel,
|
this.selectedUser
|
);
|
} else {
|
// 变更选择开关
|
this.isEndSelect = false;
|
// 赋值el-select组件值
|
this.selectValue = user.id;
|
this.selectLabel =user[this.obj.name];
|
// 告知父组件所选用户数据
|
this.selectedUser = user;
|
this.$emit("select-user", { id: user.id, name: user[this.obj.name],...user });
|
}
|
},
|
deleteUser(id) {
|
for (let i = 0; i < this.selectedUser.length; i++) {
|
if (this.selectedUser[i].id == id) {
|
this.selectedUser.splice(i, 1);
|
}
|
}
|
this.selectValue = this.selectedUser
|
.map((item) => {
|
return item.id;
|
})
|
.join(",");
|
this.selectLabel = this.selectedUser
|
.map((item) => {
|
return item[this.obj.name];
|
})
|
.join(",");
|
this.$emit(
|
"select-user",
|
this.selectValue,
|
this.selectLabel,
|
this.selectedUser
|
);
|
},
|
// 多选时候
|
checkMoreInit() {
|
if (this.checkedNum > 1 && this.echoName) {
|
this.selectedUser = [];
|
this.selectLabel = this.echoName;
|
let arr = this.echoName.split(",");
|
let arr2 = this.echoValue.split(",");
|
for (let i = 0; i < arr.length; i++) {
|
let item = { id: arr2[i] };
|
item[this.obj.name] = arr[i];
|
this.selectedUser.push(item);
|
}
|
} else {
|
if (this.echoName) {
|
this.selectedUser = [];
|
this.selectLabel = this.echoName ? this.echoName : "";
|
let item = { id: this.echoValue };
|
item[this.obj.name] = this.echoName;
|
this.selectedUser.push(item);
|
this.selectValue = this.echoValue
|
? this.echoValue
|
: this.echoName
|
? this.echoName
|
: "";
|
} else {
|
this.selectedUser = [];
|
this.selectLabel = "";
|
this.selectValue = "";
|
}
|
}
|
},
|
// 结束选择、关闭弹窗
|
endSelect(event) {
|
this.isEndSelect && event.stopPropagation();
|
},
|
// 变更选择状态
|
changeSelectStatus(status, value) {
|
this.isEndSelect = status;
|
// 当status为true时,dialog打开,初始化page
|
if (status) {
|
this.keyword = "";
|
if (value != "clear") {
|
this.updateSearchList(true);
|
}
|
}
|
},
|
selectClear() {
|
if (this.checkedNum > 1) {
|
this.selectValue = [];
|
this.selectLabel = [];
|
this.selectedUser = [];
|
this.$emit("select-user", this.selectValue);
|
} else {
|
this.isEndSelect = true;
|
// 赋值el-select组件值
|
this.selectValue = "";
|
this.selectLabel = "";
|
// 告知父组件所选用户数据
|
this.selectedUser = "";
|
this.$emit("select-user", this.selectedUser);
|
}
|
this.changeSelectStatus(true, "clear");
|
},
|
commonSelectClear() {
|
if (this.checkedNum > 1) {
|
this.selectValue = [];
|
this.selectLabel = [];
|
this.selectedUser = [];
|
this.$emit("select-user", this.selectValue);
|
} else {
|
this.isEndSelect = true;
|
// 赋值el-select组件值
|
this.selectValue = "";
|
this.selectLabel = "";
|
// 告知父组件所选用户数据
|
this.selectedUser = "";
|
this.$emit("select-user", this.selectedUser);
|
}
|
this.changeSelectStatus(true, "clear");
|
},
|
},
|
};
|
</script>
|
|
<style lang="scss">
|
.user-simple-search-input-popper {
|
max-width: 660px;
|
.el-scrollbar__wrap {
|
overflow-y: hidden;
|
}
|
.el-select-dropdown__wrap {
|
min-width: 660px;
|
width: 100%;
|
min-height: 370px;
|
|
.el-select-dropdown__list {
|
width: 100%;
|
height: 350px;
|
padding: 0;
|
|
& > .el-select-dropdown__item {
|
width: 100%;
|
height: 350px;
|
background-color: rgba(255, 255, 255, 1);
|
padding: 0;
|
|
& > .container {
|
width: 96%;
|
height: 100%;
|
padding: 2%;
|
|
.search {
|
margin-bottom: 5px;
|
overflow: hidden;
|
.search-left-two {
|
width: calc(100% - 175px);
|
float: left;
|
}
|
.search-left {
|
width: 100%;
|
}
|
& > .el-input {
|
& > input {
|
width: 100%;
|
height: 40px;
|
background: rgba(255, 255, 255, 1);
|
border-radius: 4px;
|
font-size: 14px;
|
|
font-weight: 400;
|
color: rgba(175, 179, 190, 1);
|
}
|
|
& > .el-input__suffix {
|
& > .el-input__suffix-inner {
|
font-size: 19px;
|
}
|
|
& > .el-icon-circle-close {
|
display: none;
|
}
|
|
&
|
> i.el-input__icon.el-input__validateIcon.el-icon-circle-check {
|
display: none;
|
}
|
}
|
}
|
}
|
|
.bar {
|
width: 100%;
|
height: 40px;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
|
& > .desc {
|
font-size: 14px;
|
|
font-weight: 400;
|
color: rgba(102, 102, 102, 1);
|
}
|
}
|
|
.list {
|
width: 100%;
|
height: calc(100% - 50px);
|
background: rgba(250, 250, 252, 1);
|
border: 1px solid rgba(250, 250, 252, 1);
|
|
& > ul {
|
width: 100%;
|
overflow-y: auto;
|
overflow-x: hidden;
|
height: 100%;
|
div {
|
height: 40px;
|
font-size: 14px;
|
line-height: 40px;
|
font-weight: 600;
|
color: rgba(51, 51, 51, 1);
|
padding: 0 4px;
|
// background:#eee;
|
}
|
.highlight-color {
|
background: #eee;
|
}
|
}
|
|
& > ul > li {
|
width: 100%;
|
height: 40px;
|
font-size: 14px;
|
line-height: 40px;
|
font-weight: 400;
|
color: rgba(51, 51, 51, 1);
|
padding: 0 4px;
|
display: inline-block;
|
float: left;
|
&:hover {
|
background: rgba(255, 255, 255, 1);
|
}
|
|
&.empty {
|
width: 100%;
|
height: calc(100% - 80px);
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
|
&:hover {
|
background-color: transparent;
|
}
|
}
|
|
&.loading {
|
width: 100%;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
}
|
|
& > .el-row > .el-col {
|
& > .grid-content {
|
line-height: 48px;
|
padding: 0 7px;
|
text-overflow: ellipsis;
|
overflow: hidden;
|
white-space: nowrap;
|
}
|
|
&:nth-of-type(1) > .grid-content {
|
display: flex;
|
align-items: center;
|
justify-content: flex-start;
|
|
& > span.name {
|
width: calc(100% - 26px - 10px);
|
margin-left: 10px;
|
text-overflow: ellipsis;
|
overflow: hidden;
|
white-space: nowrap;
|
}
|
}
|
}
|
}
|
}
|
.user-text {
|
display: inline-block;
|
line-height: 24px;
|
}
|
.ico-delete-user {
|
color: #aaa;
|
font-weight: normal;
|
font-size: 16px;
|
display: none;
|
line-height: 24px;
|
padding: 0 4px 0 2px;
|
vertical-align: middle;
|
margin-top: -2px;
|
}
|
.user-text:hover .ico-delete-user {
|
display: inline-block;
|
}
|
.fs12-tip {
|
font-size: 12px;
|
font-weight: normal;
|
line-height: 16px;
|
}
|
.selected-text {
|
white-space: normal;
|
line-height: 24px;
|
}
|
}
|
}
|
}
|
}
|
}
|
.icon-box {
|
float: left;
|
width: 170px;
|
margin-left: 5px;
|
height: auto;
|
overflow: hidden;
|
box-sizing: border-box;
|
margin-top: 4px;
|
.icon-item {
|
width: auto;
|
height: 32px;
|
padding: 0 5px;
|
line-height: 35px;
|
border-radius: 6px;
|
float: left;
|
margin-right: 10px;
|
margin-bottom: 5px;
|
text-align: center;
|
box-sizing: border-box;
|
cursor: pointer;
|
color: #333;
|
|
// &:hover {
|
// background: rgba(30, 120, 235, 1);
|
// color: #fff;
|
// box-sizing: border-box;
|
// }
|
&:nth-last-child(1) {
|
margin-right: 0;
|
}
|
}
|
.icon-active {
|
background: rgba(30, 120, 235, 1);
|
color: #fff;
|
box-sizing: border-box;
|
}
|
}
|
</style>
|