| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- import type VbModalVue from '@@@/modal/VbModal.vue';
- <script setup lang="ts">
- const props = withDefaults(
- defineProps<{
- modelValue?: any[] | any
- selectList?: any[] | any
- tableOpts: {
- columns: any[]
- queryParams: any
- tableListFun: any
- searchFormItems?: any[]
- customBtns?: any[]
- }
- modalTitle: string
- showTag?: boolean
- tagId?: string
- tagName?: string
- optionSelectFun?: (v: any) => any // 自定义选项数据转换,如果需要回显则需要配置,一般不需要
- convertDataFun: (v: any) => any
- modalConfig?: any
- multiple?: boolean
- saveAutoClose?: boolean
- queryCustomFun?: (v: any) => any
- }>(),
- {
- showTag: false,
- tagId: "id",
- tagName: "name",
- multiple: true,
- saveAutoClose: true
- }
- )
- const emits = defineEmits<{
- (e: "update:modelValue", v: any[]): void
- (e: "update:selectList", v: any[]): void
- (e: "confirm", v: any[]): void
- }>()
- const selectIds = ref<string[]>([])
- const selectList = ref<any[]>([])
- const tableRef = ref()
- const modalRef = ref()
- const tableOpts = reactive(props.tableOpts)
- const modalOpts = computed(() => {
- return Object.assign(
- {
- title: props.modalTitle,
- modalDialogStyle: "width:1200px;max-width:1200px;",
- modalBodyClass: "pt-0",
- saveAutoClose: false
- },
- props.modalConfig || {}
- )
- })
- const { queryParams } = toRefs(tableOpts)
- /** 搜索按钮操作 */
- function handleQuery(query?: any) {
- query = query || tableRef.value?.getQueryParams() || queryParams.value
- if (props.queryCustomFun) {
- query = props.queryCustomFun(query)
- }
- tableRef.value?.query(query)
- //addDateRange(query, query.dateRange)
- initSelectData()
- }
- /** 重置按钮操作 */
- function resetQuery(query?: any) {
- query = query || tableRef.value?.getQueryParams() || queryParams.value
- query.dateRange = []
- addDateRange(query, query.dateRange)
- }
- function onCheckboxChange(isChecked: boolean, row: any) {
- if (!props.multiple && isChecked) {
- selectList.value = []
- }
- if (isChecked) {
- selectList.value.push(convertData(row))
- } else {
- selectList.value = selectList.value.filter((item: any) => item[props.tagId] != row[props.tagId])
- }
- selectIds.value = selectList.value.map((v: any) => String(v[props.tagId]))
- emits("update:selectList", selectList.value)
- }
- function onCheckboxAll(isChecked: boolean, rows: any[]) {
- if (isChecked) {
- rows.forEach((row) => {
- if (!selectList.value.some((item: any) => item[props.tagId] === row[props.tagId])) {
- selectList.value.push(convertData(row))
- }
- })
- } else {
- selectList.value = selectList.value.filter((item: any) => {
- return !rows.some((row) => row[props.tagId] == item[props.tagId])
- })
- }
- selectIds.value = selectList.value.map((v: any) => String(v[props.tagId]))
- emits("update:selectList", selectList.value)
- }
- function handleCloseTag(item: any) {
- const index = selectList.value.findIndex((v: any) => v[props.tagId] == item[props.tagId])
- if (index > -1) {
- const row = tableRef.value.getData().find((v: any) => v[props.tagId] == item[props.tagId])
- tableRef.value?.setSelecteds([row], false)
- selectList.value.splice(index, 1)
- }
- }
- /**
- * 初始化选中数据
- */
- function initSelectData() {
- const ids = selectIds.value
- if (ids.length > 0) {
- if (props.optionSelectFun) {
- props.optionSelectFun(ids).then((res: any) => {
- selectList.value = res.data ? res.data.map((v: any) => convertData(v)) : []
- emits("update:selectList", selectList.value)
- })
- }
- let i = 0,
- data = []
- init()
- function init() {
- data = toValue(tableRef.value.getData())
- if (i <= 100 && data.length <= 0) {
- i++
- setTimeout(init, 100)
- }
- if (data.length > 0) {
- const rows = data.filter((item: any) => {
- return ids.includes(String(item[props.tagId]))
- })
- nextTick(() => {
- tableRef.value.setSelecteds(rows, true)
- })
- }
- }
- }
- }
- function convertData(row: any) {
- return props.convertDataFun(row)
- }
- function confirm() {
- emits("update:modelValue", selectIds.value)
- emits("confirm", selectList.value)
- if (props.saveAutoClose) {
- close()
- }
- }
- function initSelectIds() {
- selectIds.value = []
- const data = props.modelValue
- if (!data) {
- return
- }
- if (data instanceof Array) {
- selectIds.value = data.map((v) => String(v))
- } else if (typeof data === "string") {
- selectIds.value = data.split(",").map((v) => String(v))
- } else if (typeof data === "number") {
- selectIds.value = [String(data)]
- } else {
- console.warn("<ModalSelect> 数据的数据类型应该是数组、字符串或数字")
- }
- }
- function init() {
- //initSelectIds()
- }
- function open() {
- initSelectIds()
- handleQuery()
- modalRef.value.show()
- }
- function close() {
- tableRef.value.clearSelecteds()
- selectList.value = []
- modalRef.value.hide()
- }
- onMounted(init)
- defineExpose({
- open,
- close,
- handleQuery
- })
- </script>
- <template>
- <div>
- <VbModal
- v-model:modal="modalRef"
- :title="modalOpts.title"
- v-bind="modalOpts"
- :save-auto-close="false"
- @confirm="confirm"
- append-to-body>
- <template #body>
- <transition-group name="vb-fade">
- <el-card shadow="hover" class="mt-5 mb-2">
- <el-tag
- v-for="(data, key) in selectList"
- :key="key"
- closable
- style="margin: 2px"
- @close="handleCloseTag(data)">
- {{ data[props.tagName] }}
- </el-tag>
- </el-card>
- </transition-group>
- <VbDataTable
- ref="tableRef"
- v-model:query-params="queryParams"
- :search-form-items="tableOpts.searchFormItems"
- :columns="tableOpts.columns"
- :remote-fun="tableOpts.tableListFun"
- :check-multiple="multiple"
- :has-checkbox="true"
- :show-right-toolbar="false"
- :reset-search-form-fun="resetQuery"
- :custom-search-fun="handleQuery"
- :page-size="10"
- :init-search="false"
- :page-size-array="[10, 20, 50, 100]"
- @checkbox-change="onCheckboxChange"
- @checkbox-all="onCheckboxAll"
- table-box-height="70vh">
- <template v-for="(_, name) in $slots" #[name]="{ row }">
- <slot :name="name" :row="row" />
- </template>
- </VbDataTable>
- </template>
- </VbModal>
- </div>
- </template>
|