|
@@ -1,106 +1,115 @@
|
|
|
<template>
|
|
|
<div class="w-full h-full flex flex-col">
|
|
|
<div class="w-full pt-2">
|
|
|
- <van-search
|
|
|
- v-model.trim="searchForValue"
|
|
|
- shape="round"
|
|
|
- placeholder="请输入搜索关键词"
|
|
|
- @update:model-value="debouncedSearchOptions"
|
|
|
- />
|
|
|
+ <van-search v-model.trim="searchForValue" shape="round" placeholder="请输入搜索关键词"
|
|
|
+ @update:model-value="debouncedSearchOptions" />
|
|
|
</div>
|
|
|
<div class="flex-1 my-2 overflow-y-auto">
|
|
|
- <template v-if="!multipleChoice">
|
|
|
- <!-- 单选 -->
|
|
|
- <van-radio-group v-model="selectChecked">
|
|
|
- <template v-for="item in renderingOptions">
|
|
|
+ <!-- 加载 -->
|
|
|
+ <template v-if="listLoading">
|
|
|
+ <van-skeleton :row="10" />
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <template v-if="!multipleChoice">
|
|
|
+ <!-- 单选 -->
|
|
|
+ <van-radio-group v-model="selectChecked">
|
|
|
+ <template v-for="item in renderingOptions">
|
|
|
+ <van-cell-group inset>
|
|
|
+ <van-cell clickable @click="selectChecked = item.value">
|
|
|
+ <template #right-icon>
|
|
|
+ <van-radio :name="item.value" />
|
|
|
+ </template>
|
|
|
+ <template #title>
|
|
|
+ {{ item.label }}
|
|
|
+ </template>
|
|
|
+ </van-cell>
|
|
|
+ </van-cell-group>
|
|
|
+ </template>
|
|
|
+ </van-radio-group>
|
|
|
+ </template>
|
|
|
+ <!-- 多选 -->
|
|
|
+ <template v-if="multipleChoice">
|
|
|
+ <van-checkbox-group v-model="selectChecked">
|
|
|
<van-cell-group inset>
|
|
|
- <van-cell clickable @click="selectChecked = item.value">
|
|
|
+ <van-cell v-for="(item, index) in renderingOptions" clickable :key="index" @click="toggle(index)">
|
|
|
<template #right-icon>
|
|
|
- <van-radio :name="item.value" />
|
|
|
+ <van-checkbox :name="item.value" :ref="(el) => (checkboxRefs[index] = el)" @click.stop />
|
|
|
</template>
|
|
|
<template #title>
|
|
|
{{ item.label }}
|
|
|
</template>
|
|
|
</van-cell>
|
|
|
</van-cell-group>
|
|
|
- </template>
|
|
|
- </van-radio-group>
|
|
|
- </template>
|
|
|
- <!-- 多选 -->
|
|
|
- <template v-if="multipleChoice">
|
|
|
- <van-checkbox-group v-model="selectChecked">
|
|
|
- <van-cell-group inset>
|
|
|
- <van-cell
|
|
|
- v-for="(item, index) in renderingOptions"
|
|
|
- clickable
|
|
|
- :key="index"
|
|
|
- @click="toggle(index)"
|
|
|
- >
|
|
|
- <template #right-icon>
|
|
|
- <van-checkbox
|
|
|
- :name="item.value"
|
|
|
- :ref="(el) => (checkboxRefs[index] = el)"
|
|
|
- @click.stop
|
|
|
- />
|
|
|
- </template>
|
|
|
- <template #title>
|
|
|
- {{ item.label }}
|
|
|
- </template>
|
|
|
- </van-cell>
|
|
|
- </van-cell-group>
|
|
|
- </van-checkbox-group>
|
|
|
+ </van-checkbox-group>
|
|
|
+ </template>
|
|
|
</template>
|
|
|
</div>
|
|
|
<div class="w-full pb-2 px-4">
|
|
|
- <van-button
|
|
|
- type="primary"
|
|
|
- round
|
|
|
- class="w-full"
|
|
|
- :disabled="!selectChecked"
|
|
|
- @click="confirmClick"
|
|
|
- >确定</van-button
|
|
|
- >
|
|
|
+ <van-button type="primary" round class="w-full" :disabled="!selectChecked || !selectChecked.length" @click="confirmClick">确定</van-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
import { ref, onBeforeUpdate, reactive, watch, onMounted } from "vue";
|
|
|
-import { manualCopying, useDebounce } from "@hooks/useCommon"
|
|
|
+import { manualCopying, useDebounce } from "@hooks/useCommon";
|
|
|
+import requests from "@common/requests";
|
|
|
+import { GET_ALL_PERSONNEL } from "@hooks/useApi";
|
|
|
+import useFixedData from "@store/useFixedData";
|
|
|
|
|
|
const props = defineProps({
|
|
|
options: {
|
|
|
type: Array,
|
|
|
- required: true,
|
|
|
default: () => [],
|
|
|
},
|
|
|
value: {
|
|
|
type: [String, Array],
|
|
|
- default: () => null
|
|
|
+ default: () => null,
|
|
|
},
|
|
|
- multipleChoice: {
|
|
|
+ doYouNeedTranslation: {
|
|
|
type: Boolean,
|
|
|
default: () => true,
|
|
|
},
|
|
|
+ multipleChoice: {
|
|
|
+ type: Boolean,
|
|
|
+ default: () => false,
|
|
|
+ },
|
|
|
});
|
|
|
|
|
|
-const emit = defineEmits(['change'])
|
|
|
+const emit = defineEmits(["change"]);
|
|
|
+const fixedData = useFixedData();
|
|
|
|
|
|
+const listLoading = ref(false);
|
|
|
const selectChecked = ref();
|
|
|
const checkboxRefs = ref([]);
|
|
|
const searchForValue = ref("");
|
|
|
-const allOptions = ref([])
|
|
|
-const renderingOptions = ref([])
|
|
|
+const allOptions = ref([]);
|
|
|
+const renderingOptions = ref([]);
|
|
|
|
|
|
const debouncedSearchOptions = useDebounce(searchOptions, 500);
|
|
|
|
|
|
function searchOptions(val) {
|
|
|
- if(!val) {
|
|
|
- renderingOptions.value = manualCopying(allOptions.value)
|
|
|
+ listLoading.value = true
|
|
|
+ if (!props.doYouNeedTranslation) {
|
|
|
+ setTimeout(() => {
|
|
|
+ listLoading.value = false
|
|
|
+ }, 200)
|
|
|
+ if (!val) {
|
|
|
+ renderingOptions.value = manualCopying(allOptions.value);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const list = manualCopying(allOptions.value);
|
|
|
+ renderingOptions.value = list.filter((item) => item.label.indexOf(val) > -1);
|
|
|
return
|
|
|
}
|
|
|
- const list = manualCopying(allOptions.value)
|
|
|
- renderingOptions.value = list.filter(item => item.label.indexOf(val) > -1)
|
|
|
+
|
|
|
+ // 转译人员搜索
|
|
|
+ requests.post(GET_ALL_PERSONNEL, { keyword: val }).then((res) => {
|
|
|
+ const { data } = res
|
|
|
+ renderingOptions.value = [ ...data ]
|
|
|
+ }).finally(() => {
|
|
|
+ listLoading.value = false
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
function toggle(index) {
|
|
@@ -108,15 +117,35 @@ function toggle(index) {
|
|
|
}
|
|
|
|
|
|
function valueTaking(val) {
|
|
|
- if(Array.isArray(val)) {
|
|
|
- return allOptions.value.filter(item => val.includes(item.value)).map(item => item.label)
|
|
|
+ if (Array.isArray(val)) {
|
|
|
+ return allOptions.value
|
|
|
+ .filter((item) => val.includes(item.value))
|
|
|
+ .map((item) => item.label);
|
|
|
} else {
|
|
|
- return allOptions.value.find(item => item.value === val)?.label
|
|
|
+ return allOptions.value.find((item) => item.value === val)?.label;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function obtainPersonnelData() {
|
|
|
+ if (fixedData.allUserData && fixedData.allUserData.length) {
|
|
|
+ renderingOptions.value = [...fixedData.allUserData];
|
|
|
+ allOptions.value = [...fixedData.allUserData];
|
|
|
+ return;
|
|
|
}
|
|
|
+ listLoading.value = true;
|
|
|
+ requests.post(GET_ALL_PERSONNEL, {}).then(({ data = [] }) => {
|
|
|
+ renderingOptions.value = [...data];
|
|
|
+ allOptions.value = [...data];
|
|
|
+ fixedData.updateState({
|
|
|
+ allUserData: [...data]
|
|
|
+ })
|
|
|
+ }).finally(() => {
|
|
|
+ listLoading.value = false;
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
function confirmClick() {
|
|
|
- emit('change', selectChecked.value, valueTaking(selectChecked.value))
|
|
|
+ emit("change", selectChecked.value, valueTaking(selectChecked.value));
|
|
|
}
|
|
|
|
|
|
onBeforeUpdate(() => {
|
|
@@ -124,8 +153,13 @@ onBeforeUpdate(() => {
|
|
|
});
|
|
|
|
|
|
onMounted(() => {
|
|
|
- selectChecked.value = props.multipleChoice ? [] : "";
|
|
|
- renderingOptions.value = manualCopying(props.options)
|
|
|
- allOptions.value = manualCopying(props.options)
|
|
|
+ selectChecked.value = props.multipleChoice ? [] : null;
|
|
|
+ const isItAnArray = Array.isArray(props.options);
|
|
|
+ if (isItAnArray && props.options.length > 0) {
|
|
|
+ renderingOptions.value = manualCopying(props.options);
|
|
|
+ allOptions.value = manualCopying(props.options);
|
|
|
+ } else {
|
|
|
+ obtainPersonnelData();
|
|
|
+ }
|
|
|
});
|
|
|
</script>
|