personnelSearch.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <script lang="ts" setup>
  2. import { ref, reactive, onMounted, inject, watchEffect, computed } from 'vue';
  3. import { debounce } from 'lodash';
  4. import { storeToRefs } from 'pinia';
  5. import { Emits, optionsType } from './type';
  6. import { useStore } from '@/store/index'
  7. import { generateUniqueId } from '@/utils/tools'
  8. import { post, get, uploadFile } from "@/utils/request";
  9. const props = defineProps({
  10. modelValue: { type: [String, Number, Array, Object, Boolean], required: true },
  11. multiple: { type: Boolean, required: false, default: false },
  12. size: { type: String as () => assemblySize, required: true, default: () => 'small' },
  13. placeholder: { type: String, required: false, default: () => '请选择' },
  14. disabled: { type: Boolean, required: false, default: false },
  15. options: { type: Array as () => optionsType, required: false, default: () => [] },
  16. width: { type: String, required: false, default: () => '100%' },
  17. });
  18. const emit = defineEmits<Emits>();
  19. const personnelArray = ref<optionsType>([]);
  20. const { userInfo, personnelList } = storeToRefs(useStore());
  21. const { setValue } = useStore()
  22. const timeRef = generateUniqueId()
  23. const selectLoading = ref(false);
  24. const controlTranslation = reactive({
  25. visibleFlag: false // 下拉框出现隐藏
  26. })
  27. const selectedValue = ref(props.modelValue); // 响应式绑定 v-model 的值
  28. const getSelectedLabel = computed(() => {
  29. if (!props.multiple) {
  30. const item = getPersonnelListItems(selectedValue.value);
  31. return item ? item.label : props.placeholder
  32. }
  33. if (props.multiple) {
  34. if (Array.isArray(selectedValue.value)) {
  35. if (selectedValue.value.length <= 0) {
  36. return props.placeholder
  37. }
  38. const item = getPersonnelListItems(selectedValue.value);
  39. return item ? item.label : props.placeholder
  40. } else {
  41. return props.placeholder
  42. }
  43. }
  44. return props.placeholder
  45. })
  46. function tagClose(_evt: MouseEvent) {
  47. if (Array.isArray(selectedValue.value)) {
  48. selectedValue.value.shift()
  49. updateValue(selectedValue.value)
  50. }
  51. }
  52. function getPersonnelListItems(val: any) {
  53. let value = val;
  54. if (Array.isArray(val) && val.length > 0) {
  55. value = val[0]
  56. }
  57. return personnelList.value.find((item: any) => item.value == value)
  58. }
  59. function getUserList(keyword: string = '') {
  60. post(`/user/getSimpleActiveUserListNew`, { keyword }).then(res => {
  61. personnelArray.value = res.data
  62. if (!keyword) {
  63. setValue((res.data || []), 'personnelList')
  64. }
  65. }).finally(() => {
  66. selectLoading.value = false
  67. })
  68. }
  69. function visibleChange(visible: boolean) { // 下拉框出现/隐藏时触发
  70. controlTranslation.visibleFlag = visible
  71. }
  72. const filterMethod = debounce(filterMethods, 500)
  73. function filterMethods(val: string) {
  74. if (val == '') {
  75. personnelArray.value = personnelList.value
  76. selectLoading.value = false
  77. return personnelArray.value
  78. }
  79. getUserList(val)
  80. }
  81. function updateValue(val: any) { // 值改变的时候触发
  82. emit('update:modelValue', selectedValue.value)
  83. emit('change', val)
  84. }
  85. onMounted(() => {
  86. if (personnelList.value.length == 0) {
  87. getUserList()
  88. } else {
  89. personnelArray.value = personnelList.value
  90. }
  91. })
  92. </script>
  93. <template>
  94. <!-- <el-select v-model="selectedValue" :ref="`selectRef${timeRef}`" :multiple="multiple" :size="size"
  95. :loading="selectLoading" :placeholder="placeholder" :disabled="disabled" clearable filterable collapse-tags
  96. :style="`width: ${width}`"
  97. :class="`custom-select ${userInfo.userNameNeedTranslate != 1 && !controlTranslation.visibleFlag ? 'setUpInput' : ''}`"
  98. @change="updateValue" @visible-change="visibleChange"
  99. :filter-method="(val: string) => { selectLoading = true, filterMethod(val) }">
  100. 搜索内容显示
  101. <template #prefix v-if="!multiple">
  102. <div style="height: 100%;display: flex;align-items: center;">
  103. 单选
  104. <div v-if="!controlTranslation.visibleFlag" class="selectSingleChoice">
  105. <template v-if="getSelectedLabel == placeholder">
  106. {{ placeholder }}
  107. </template>
  108. <template v-else>
  109. <span style="color: #303133;">
  110. <TextTranslation translationTypes="userName" :translationValue="getSelectedLabel"></TextTranslation>
  111. </span>
  112. </template>
  113. </div>
  114. </div>
  115. </template>
  116. <template #tag v-if="multiple">
  117. 多选
  118. <template v-if="Array.isArray(selectedValue) && selectedValue.length > 0">
  119. <el-tag type="info" :size="size" closable @close="tagClose">
  120. <TextTranslation translationTypes="userName" :translationValue="getSelectedLabel"></TextTranslation>
  121. </el-tag>
  122. <el-tag type="info" :size="size" v-if="selectedValue.length > 1">+{{ selectedValue.length }}</el-tag>
  123. </template>
  124. <template v-else>
  125. <span style="color: #A8ABB2">{{ placeholder }}</span>
  126. </template>
  127. </template>
  128. 主题内容显示
  129. <el-option v-for="item in personnelArray" :key="item.value" :label="item.label" :value="item.value"></el-option>
  130. </el-select> -->
  131. <el-select-v2 v-model="selectedValue" :ref="`selectRef${timeRef}`" :multiple="multiple" :size="size"
  132. :loading="selectLoading" :placeholder="placeholder" :disabled="disabled" clearable filterable collapse-tags
  133. :style="`width: ${width}`" :options="personnelArray"
  134. :class="`custom-select ${!controlTranslation.visibleFlag ? 'setUpInput' : ''}`" @change="updateValue"
  135. @visible-change="visibleChange" :filter-method="filterMethod">
  136. <!-- 搜索内容显示 -->
  137. <template #prefix v-if="!multiple">
  138. <div style="height: 100%;display: flex;align-items: center;">
  139. <!-- 单选 -->
  140. <div v-if="!controlTranslation.visibleFlag" class="selectSingleChoice">
  141. <template v-if="getSelectedLabel == placeholder">
  142. {{ placeholder }}
  143. </template>
  144. <template v-else>
  145. <span style="color: #303133;">
  146. <TextTranslation translationTypes="userName" :translationValue="getSelectedLabel"></TextTranslation>
  147. </span>
  148. </template>
  149. </div>
  150. </div>
  151. </template>
  152. <template #tag v-if="multiple">
  153. <!-- 多选 -->
  154. <template v-if="Array.isArray(selectedValue) && selectedValue.length > 0">
  155. <el-tag type="info" :size="size" closable @close="tagClose">
  156. <TextTranslation translationTypes="userName" :translationValue="getSelectedLabel"></TextTranslation>
  157. </el-tag>
  158. <el-tag type="info" :size="size" v-if="selectedValue.length > 1">+{{ selectedValue.length }}</el-tag>
  159. </template>
  160. <template v-else>
  161. <span style="color: #A8ABB2">{{ placeholder }}</span>
  162. </template>
  163. </template>
  164. <!-- 基础 -->
  165. <template #default="{ item }">
  166. <div class="flex items-center">
  167. <TextTranslation translationTypes="userName" :translationValue="item.label"></TextTranslation>
  168. </div>
  169. </template>
  170. </el-select-v2>
  171. <span class="aabbcc">aabbcc</span>
  172. </template>
  173. <style lang="scss" scoped>
  174. .custom-select {
  175. :deep(.el-select__placeholder.is-transparent) {
  176. color: transparent !important;
  177. }
  178. :deep(.el-select__placeholder) {
  179. span {
  180. display: none;
  181. }
  182. }
  183. :deep(.el-select__input) {
  184. margin-left: 0;
  185. }
  186. }
  187. .setUpInput :deep(.el-input__inner) {
  188. color: #fff !important;
  189. }
  190. .aabbcc {
  191. color: $modena;
  192. }
  193. </style>