123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- <template>
- <div class="select-table">
- <cip-search-form v-if="searchFieldList.length > 0"
- style="margin-bottom: 10px;"
- :grid="3"
- v-model:model="searchFilter"
- :field-list="searchFieldList"
- :default-model="config?.defaultSearchFilter"
- @search="handleSearch" />
- <div class="select-table-box">
- <page-layout-list class="dialog-table">
- <cip-table
- v-if="checkType === 'radio'"
- ref="tableRef"
- v-loading="listLoading"
- :data="itemList"
- :columns="tableColumns"
- :offset="offset"
- size="small"
- :select-type="checkType"
- :select-radio="selectRadio"
- :select-label="optionProps.value"
- @current-change="currentChange"></cip-table>
- <cip-table
- v-if="checkType === 'checkbox'"
- ref="tableRef"
- v-loading="listLoading"
- :data="itemList"
- :columns="tableColumns"
- :offset="offset"
- size="small"
- :select-type="checkType"
- :selectable="selectable"
- @select="onSelect"
- @select-all="onSelectAll"></cip-table>
- <template v-if="withPagination" #pagination>
- <cip-pagination
- v-model:offset="offset"
- v-model:limit="limit"
- :total="total"
- :current-page="currentPage"
- @refresh="getItemList"></cip-pagination>
- </template>
- </page-layout-list>
- <slot name="group"></slot>
- <tags
- v-if="!$slots.group && withTags"
- class="dialog-tags"
- :options="checkOptions"
- :key-prop="optionProps"
- @update:options="updateOptions"></tags>
- </div>
- </div>
- </template>
- <script>
- import { useCurd } from '@cip/hooks/use-curd'
- import { useTableCacheSelect } from '@cip/components/hooks/table-cache-select'
- import { ref, computed, nextTick, watch, watchEffect } from 'vue'
- import { ElLoading } from 'element-plus'
- import PageLayoutList from '@cip/components/page-layout/list'
- import CipSearchForm from '@cip/components/cip-search-form'
- import CipTable from '@cip/components/cip-table'
- import CipPagination from '@cip/components/cip-pagination'
- import { useFormInput, useOptions } from '@cip/components/hooks/form-input'
- import { formInputProps, fromInputEmits } from '../../form-input-props'
- import Tags from './tags.vue'
- export default {
- components: { Tags, PageLayoutList, CipSearchForm, CipTable, CipPagination },
- directives: {
- loading: ElLoading.directive
- },
- props: formInputProps,
- emits: [...fromInputEmits],
- setup (props, context) {
- const { proxyValue, updateStream, securityConfig } = useFormInput(
- props,
- context
- )
- const { optionProps } = useOptions(props, false, updateStream)
- const valueKey = computed(() => optionProps.value.value)
- const labelKey = computed(() => optionProps.value.label)
- const checkType = computed(() => securityConfig.value.checkType ?? 'radio')
- const tableColumns = computed(() => securityConfig.value.tableColumns ?? [])
- const searchFieldList = computed(
- () => securityConfig.value.searchFieldList ?? []
- )
- const withPagination = computed(
- () => securityConfig.value.withPagination ?? true
- )
- const withTags = computed(() => securityConfig.value.withTags ?? true)
- const selectable = computed(
- () => securityConfig.value.selectable ?? (() => true)
- )
- const multiple = computed(() => checkType.value === 'checkbox')
- const tableRef = ref()
- const CURD = useCurd(props.config.entity, {
- ...props.config.curdFn,
- itemType: props.config.itemType
- })
- const { itemList, getItemList, searchFilter, search } = CURD
- // 外层触发请求
- const getTableList = (item = {}) => {
- searchFilter.value = {
- ...props.config.defaultSearchFilter,
- ...searchFilter.value,
- ...item
- }
- getItemList()
- }
- // 外层获取search搜索条件值
- const getSearchFilter = () => {
- return { ...props.config.defaultSearchFilter, ...searchFilter.value }
- }
- const { cacheSelectedList, onSelect, onSelectAll } = useTableCacheSelect(
- itemList,
- valueKey.value,
- (val) => {
- proxyValue.value = val
- }
- )
- const checkOptions = computed(() => {
- if (cacheSelectedList.value.length === 0) {
- if (props.modelValue) {
- return multiple.value
- ? props.modelValue
- : {
- [valueKey.value]: props.modelValue[valueKey.value] ?? '',
- [labelKey.value]: props.modelValue[labelKey.value] ?? ''
- }
- }
- return multiple.value ? [] : {}
- } else {
- return cacheSelectedList.value
- }
- })
- // 右侧数据改变
- const updateOptions = (newSelectedValue) => {
- cacheSelectedList.value = newSelectedValue
- proxyValue.value = newSelectedValue
- handleSelectShow()
- }
- watch(
- () => props.config?.defaultSearchFilter,
- (val = {}) => {
- getTableList(val)
- },
- { immediate: true }
- )
- // 已选择的radio
- const selectRadio = computed(() => {
- if (props.modelValue && props.modelValue[valueKey.value]) {
- return props.modelValue[valueKey.value]
- }
- return radioCache.value
- })
- // radio类型时的缓存
- const radioCache = computed(() => {
- const cache = itemList.value?.find(
- (v) => v[valueKey.value] === props.modelValue
- )
- return cache ? cache[valueKey.value] : undefined
- })
- const currentChange = (currentRow) => {
- // 单选不能取消,只能有值时才填入
- if (currentRow) {
- proxyValue.value = currentRow
- }
- }
- // checkbox类型更新选中视图
- const showSelectedView = (rows, select) => {
- nextTick(() => {
- rows.forEach((row) => {
- tableRef.value.cipTableRef.toggleRowSelection(row, select)
- })
- })
- }
- // tag组件传入值需要更新table选中视图
- const handleSelectShow = () => {
- const selectedPropsCode = cacheSelectedList.value.map(
- (button) => button[valueKey.value]
- )
- const rows = itemList.value.filter((item) => {
- return !selectedPropsCode.includes(item[valueKey.value])
- })
- showSelectedView(rows, false)
- }
- if (checkType.value === 'checkbox') {
- // 分页切换时缓存数据处理
- watch(
- () => [itemList.value, props.modelValue],
- () => {
- cacheHandle()
- }
- )
- } else {
- const unWatch = watchEffect(() => {
- if (props.modelValue && props.modelValue[valueKey.value]) {
- const checkItem = itemList.value.filter(
- (item) => item[valueKey.value] === props.modelValue[valueKey.value]
- )[0]
- if (checkItem) {
- proxyValue.value = checkItem
- unWatch()
- }
- }
- })
- }
- // 缓存数据处理
- const cacheHandle = () => {
- if (cacheSelectedList.value.length === 0) {
- cacheSelectedList.value = props.modelValue ?? []
- }
- const cacheSelectButtonCode = cacheSelectedList.value.map(
- (button) => button[valueKey.value]
- )
- const rows = itemList.value.filter((item) => {
- const selectList =
- props.modelValue ||
- (cacheSelectButtonCode.includes(item[valueKey.value])
- ? cacheSelectButtonCode
- : [])
- return (
- selectList.findIndex(
- (v) => v[valueKey.value] === item[valueKey.value]
- ) !== -1
- )
- })
- showSelectedView(rows, true)
- }
- // 搜索
- const handleSearch = (type) => {
- search()
- }
- return {
- updateOptions,
- checkOptions,
- getTableList,
- getSearchFilter,
- handleSearch,
- optionProps,
- checkType,
- tableColumns,
- searchFieldList,
- withPagination,
- withTags,
- ...CURD,
- tableRef,
- selectable,
- selectRadio,
- currentChange,
- onSelect,
- onSelectAll,
- cacheSelectedList
- }
- }
- }
- </script>
- <style lang="less" scoped>
- .select-table {
- flex: 1;
- .select-table-box {
- display: flex;
- }
- .dialog-table {
- flex: 1;
- margin: 0 15px 15px 0;
- padding: 0;
- }
- .dialog-tags {
- padding: 8px 0;
- flex-basis: 220px;
- }
- }
- </style>
|