123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- <template>
- <div class="w-full h-full flex flex-col">
- <div class="w-full pt-2 searchKeywords">
- <van-search v-model.trim="searchForValue" shape="round" placeholder="请输入搜索关键词"
- @update:model-value="debouncedSearchOptions" input-align="left" />
- </div>
- <div class="flex-1 my-2 overflow-y-auto">
- <template v-if="renderingOptions.length == 1 && renderingOptions[0] && !renderingOptions[0].label">
- <van-empty />
- </template>
- <template v-else>
- <!-- 加载 -->
- <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>
- <TranslationComponent :openId="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>
- <TranslationComponent :openId="item.label" />
- </template>
- </van-cell>
- </van-cell-group>
- </van-checkbox-group>
- </template>
- </template>
- </template>
- </div>
- <div class="w-full pb-2 px-4">
- <van-button type="primary" round class="w-full" :disabled="multipleChoice ? !selectChecked.length : (!selectChecked && selectChecked != 0)" @click="confirmClick">确定</van-button>
- </div>
- </div>
- </template>
- <script setup>
- import { ref, onBeforeUpdate, reactive, watch, onMounted, onActivated } from "vue";
- 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,
- default: () => [],
- },
- showElement: {
- type: Boolean,
- default: () => false,
- },
- value: {
- type: [String, Array],
- default: () => [],
- },
- doYouNeedTranslation: {
- type: Boolean,
- default: () => true,
- },
- multipleChoice: {
- type: Boolean,
- default: () => false,
- },
- });
- 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 debouncedSearchOptions = useDebounce(searchOptions, 500);
- watch(() => props.options, (newValue) => {
- selectChecked.value = props.multipleChoice ? [] : null;
- const isItAnArray = Array.isArray(newValue);
- if (isItAnArray && newValue.length > 0) {
- renderingOptions.value = manualCopying(newValue);
- allOptions.value = manualCopying(newValue);
- } else {
- obtainPersonnelData();
- }
- })
- watch(() => props.value, (newValue) => {
- if(!newValue) {
- selectChecked.value = []
- }
- selectChecked.value = Array.isArray(newValue) ? newValue : [newValue]
- })
- watch(() => props.showElement, (newValue) => {
- if(!newValue) {
- setTimeout(() => {
- searchForValue.value = ''
- searchOptions('')
- const val = (props.value && Array.isArray(props.value) && props.value.length > 0)
- selectChecked.value = val ? selectChecked.value : []
- }, 500)
- }
- })
- function searchOptions(val) {
- 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
- }
- // 转译人员搜索
- requests.post(GET_ALL_PERSONNEL, { keyword: val }).then((res) => {
- const { data } = res
- renderingOptions.value = [ ...data ]
- }).finally(() => {
- listLoading.value = false
- })
- }
- function toggle(index) {
- checkboxRefs.value[index].toggle();
- }
- function valueTaking(val) {
- 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;
- }
- }
- 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));
- }
- onBeforeUpdate(() => {
- checkboxRefs.value = [];
- });
- onMounted(() => {
- 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();
- }
- if(props.value) {
- selectChecked.value = props.multipleChoice ? Array.isArray(props.value) ? props.value : props.value.split(',') : props.value
- }
- });
- </script>
- <style lang="scss" scoped>
- </style>
|