123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442 |
- <template>
- <VxeGrid v-bind="getProps" ref="xGrid" :class="`${prefixCls}`" class="xtable-scrollbar">
- <template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
- <slot :name="item" v-bind="data || {}"></slot>
- </template>
- </VxeGrid>
- </template>
- <script setup lang="ts" name="XTable">
- import { PropType } from 'vue'
- import { SizeType, VxeGridInstance } from 'vxe-table'
- import { useAppStore } from '@/store/modules/app'
- import { useDesign } from '@/hooks/web/useDesign'
- import { XTableProps } from './type'
- import { isBoolean, isFunction } from '@/utils/is'
- import styleCss from './style/dark.scss?inline'
- import download from '@/utils/download'
- const { t } = useI18n()
- const message = useMessage() // 消息弹窗
- const appStore = useAppStore()
- const { getPrefixCls } = useDesign()
- const prefixCls = getPrefixCls('x-vxe-table')
- const attrs = useAttrs()
- const emit = defineEmits(['register'])
- const removeStyles = () => {
- const filename = 'cssTheme'
- //移除引入的文件名
- const targetelement = 'style'
- const targetattr = 'id'
- let allsuspects = document.getElementsByTagName(targetelement)
- for (let i = allsuspects.length; i >= 0; i--) {
- if (
- allsuspects[i] &&
- allsuspects[i].getAttribute(targetattr) != null &&
- allsuspects[i].getAttribute(targetattr)?.indexOf(filename) != -1
- ) {
- console.log(allsuspects[i], 'node')
- allsuspects[i].parentNode?.removeChild(allsuspects[i])
- }
- }
- }
- const reImport = () => {
- let head = document.getElementsByTagName('head')[0]
- let style = document.createElement('style')
- style.innerText = styleCss
- style.id = 'cssTheme'
- head.appendChild(style)
- }
- watch(
- () => appStore.getIsDark,
- () => {
- if (appStore.getIsDark == true) {
- reImport()
- }
- if (appStore.getIsDark == false) {
- removeStyles()
- }
- },
- { immediate: true }
- )
- const currentSize = computed(() => {
- let resSize: SizeType = 'small'
- const appsize = appStore.getCurrentSize
- switch (appsize) {
- case 'large':
- resSize = 'medium'
- break
- case 'default':
- resSize = 'small'
- break
- case 'small':
- resSize = 'mini'
- break
- }
- return resSize
- })
- const props = defineProps({
- options: {
- type: Object as PropType<XTableProps>,
- default: () => {}
- }
- })
- const innerProps = ref<Partial<XTableProps>>()
- const getProps = computed(() => {
- const options = innerProps.value || props.options
- options.size = currentSize as any
- options.height = 700
- getOptionInitConfig(options)
- getColumnsConfig(options)
- getProxyConfig(options)
- getPageConfig(options)
- getToolBarConfig(options)
- // console.log(options);
- return {
- ...options,
- ...attrs
- }
- })
- const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
- let proxyForm = false
- const getOptionInitConfig = (options: XTableProps) => {
- options.size = currentSize as any
- options.rowConfig = {
- isCurrent: true, // 当鼠标点击行时,是否要高亮当前行
- isHover: true // 当鼠标移到行时,是否要高亮当前行
- }
- }
- // columns
- const getColumnsConfig = (options: XTableProps) => {
- const { allSchemas } = options
- if (!allSchemas) return
- if (allSchemas.printSchema) {
- options.printConfig = {
- columns: allSchemas.printSchema
- }
- }
- if (allSchemas.formSchema) {
- proxyForm = true
- options.formConfig = {
- enabled: true,
- titleWidth: 100,
- titleAlign: 'right',
- items: allSchemas.searchSchema
- }
- }
- if (allSchemas.tableSchema) {
- options.columns = allSchemas.tableSchema
- }
- }
- // 动态请求
- const getProxyConfig = (options: XTableProps) => {
- const { getListApi, proxyConfig, data, isList } = options
- if (proxyConfig || data) return
- if (getListApi && isFunction(getListApi)) {
- if (!isList) {
- options.proxyConfig = {
- seq: true, // 启用动态序号代理(分页之后索引自动计算为当前页的起始序号)
- form: proxyForm, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为
- props: { result: 'list', total: 'total' },
- ajax: {
- query: async ({ page, form }) => {
- let queryParams: any = Object.assign({}, JSON.parse(JSON.stringify(form)))
- if (options.params) {
- queryParams = Object.assign(queryParams, options.params)
- }
- if (!options?.treeConfig) {
- queryParams.pageSize = page.pageSize
- queryParams.pageNo = page.currentPage
- }
- return new Promise(async (resolve) => {
- resolve(await getListApi(queryParams))
- })
- },
- delete: ({ body }) => {
- return new Promise(async (resolve) => {
- if (options.deleteApi) {
- resolve(await options.deleteApi(JSON.stringify(body)))
- } else {
- Promise.reject('未设置deleteApi')
- }
- })
- },
- queryAll: ({ form }) => {
- const queryParams = Object.assign({}, JSON.parse(JSON.stringify(form)))
- return new Promise(async (resolve) => {
- if (options.getAllListApi) {
- resolve(await options.getAllListApi(queryParams))
- } else {
- resolve(await getListApi(queryParams))
- }
- })
- }
- }
- }
- } else {
- options.proxyConfig = {
- seq: true, // 启用动态序号代理(分页之后索引自动计算为当前页的起始序号)
- form: true, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为
- props: { result: 'data' },
- ajax: {
- query: ({ form }) => {
- let queryParams: any = Object.assign({}, JSON.parse(JSON.stringify(form)))
- if (options?.params) {
- queryParams = Object.assign(queryParams, options.params)
- }
- return new Promise(async (resolve) => {
- resolve(await getListApi(queryParams))
- })
- }
- }
- }
- }
- }
- if (options.exportListApi) {
- options.exportConfig = {
- filename: options?.exportName,
- // 默认选中类型
- type: 'csv',
- // 自定义数据量列表
- modes: options?.getAllListApi ? ['current', 'all'] : ['current'],
- columns: options?.allSchemas?.printSchema
- }
- }
- }
- // 分页
- const getPageConfig = (options: XTableProps) => {
- const { pagination, pagerConfig, treeConfig, isList } = options
- if (isList) return
- if (treeConfig) {
- options.treeConfig = options.treeConfig
- return
- }
- if (pagerConfig) return
- if (pagination) {
- if (isBoolean(pagination)) {
- options.pagerConfig = {
- border: false, // 带边框
- background: false, // 带背景颜色
- perfect: false, // 配套的样式
- pageSize: 10, // 每页大小
- pagerCount: 7, // 显示页码按钮的数量
- autoHidden: false, // 当只有一页时自动隐藏
- pageSizes: [5, 10, 20, 30, 50, 100], // 每页大小选项列表
- layouts: [
- 'PrevJump',
- 'PrevPage',
- 'JumpNumber',
- 'NextPage',
- 'NextJump',
- 'Sizes',
- 'FullJump',
- 'Total'
- ]
- }
- return
- }
- options.pagerConfig = pagination
- } else {
- if (pagination != false) {
- options.pagerConfig = {
- border: false, // 带边框
- background: false, // 带背景颜色
- perfect: false, // 配套的样式
- pageSize: 10, // 每页大小
- pagerCount: 7, // 显示页码按钮的数量
- autoHidden: false, // 当只有一页时自动隐藏
- pageSizes: [5, 10, 20, 30, 50, 100], // 每页大小选项列表
- layouts: [
- 'Sizes',
- 'PrevJump',
- 'PrevPage',
- 'Number',
- 'NextPage',
- 'NextJump',
- 'FullJump',
- 'Total'
- ]
- }
- }
- }
- }
- // tool bar
- const getToolBarConfig = (options: XTableProps) => {
- const { toolBar, toolbarConfig, topActionSlots } = options
- if (toolbarConfig) return
- if (toolBar) {
- if (!isBoolean(toolBar)) {
- console.info(2)
- options.toolbarConfig = toolBar
- return
- }
- } else if (topActionSlots != false) {
- options.toolbarConfig = {
- slots: { buttons: 'toolbar_buttons' }
- }
- } else {
- options.toolbarConfig = {
- enabled: true
- }
- }
- }
- // 刷新列表
- const reload = () => {
- const g = unref(xGrid)
- if (!g) {
- return
- }
- g.commitProxy('query')
- }
- // 删除
- const deleteData = async (id: string | number) => {
- const g = unref(xGrid)
- if (!g) {
- return
- }
- const options = innerProps.value || props.options
- if (!options.deleteApi) {
- console.error('未传入delListApi')
- return
- }
- return new Promise(async () => {
- message.delConfirm().then(async () => {
- await (options?.deleteApi && options?.deleteApi(id))
- message.success(t('common.delSuccess'))
- // 刷新列表
- reload()
- })
- })
- }
- // 批量删除
- const deleteBatch = async () => {
- const g = unref(xGrid)
- if (!g) {
- return
- }
- const rows = g.getCheckboxRecords() || g.getRadioRecord()
- let ids: any[] = []
- if (rows.length == 0) {
- message.error('请选择数据')
- return
- } else {
- rows.forEach((row) => {
- ids.push(row.id)
- })
- }
- const options = innerProps.value || props.options
- if (options.deleteListApi) {
- return new Promise(async () => {
- message.delConfirm().then(async () => {
- await (options?.deleteListApi && options?.deleteListApi(ids))
- message.success(t('common.delSuccess'))
- // 刷新列表
- reload()
- })
- })
- } else if (options.deleteApi) {
- return new Promise(async () => {
- message.delConfirm().then(async () => {
- ids.forEach(async (id) => {
- await (options?.deleteApi && options?.deleteApi(id))
- })
- message.success(t('common.delSuccess'))
- // 刷新列表
- reload()
- })
- })
- } else {
- console.error('未传入delListApi')
- return
- }
- }
- // 导出
- const exportList = async (fileName?: string) => {
- const g = unref(xGrid)
- if (!g) {
- return
- }
- const options = innerProps.value || props.options
- if (!options?.exportListApi) {
- console.error('未传入exportListApi')
- return
- }
- const queryParams = Object.assign({}, JSON.parse(JSON.stringify(g.getProxyInfo()?.form)))
- message.exportConfirm().then(async () => {
- const res = await (options?.exportListApi && options?.exportListApi(queryParams))
- download.excel(res as unknown as Blob, fileName ? fileName : 'excel.xls')
- })
- }
- // 获取查询参数
- const getSearchData = () => {
- const g = unref(xGrid)
- if (!g) {
- return
- }
- const queryParams = Object.assign({}, JSON.parse(JSON.stringify(g.getProxyInfo()?.form)))
- return queryParams
- }
- // 获取当前列
- const getCurrentColumn = () => {
- const g = unref(xGrid)
- if (!g) {
- return
- }
- return g.getCurrentColumn()
- }
- // 获取当前选中列,redio
- const getRadioRecord = () => {
- const g = unref(xGrid)
- if (!g) {
- return
- }
- return g.getRadioRecord(false)
- }
- // 获取当前选中列,checkbox
- const getCheckboxRecords = () => {
- const g = unref(xGrid)
- if (!g) {
- return
- }
- return g.getCheckboxRecords(false)
- }
- const setProps = (prop: Partial<XTableProps>) => {
- innerProps.value = { ...unref(innerProps), ...prop }
- }
- defineExpose({ reload, Ref: xGrid, getSearchData, deleteData, exportList })
- emit('register', {
- reload,
- getSearchData,
- setProps,
- deleteData,
- deleteBatch,
- exportList,
- getCurrentColumn,
- getRadioRecord,
- getCheckboxRecords
- })
- </script>
- <style lang="scss">
- @import './style/index.scss';
- </style>
|