0
点赞
收藏
分享

微信扫一扫

[RocketMQ] Producer发送消息的总体流程 (七)

NicoalsNC 2023-07-01 阅读 74

1.对表格复用的查询、重置、分页等方法进行抽取封装hooks

import { ref, reactive, onMounted } from 'vue'
// 表格通用代码抽取hook,具体用法参考财务管理-发票台账或者合同管理-合同台账
export default function () {
// 搜索按钮加载
const searchLoading = ref(false)
// 重置按钮加载
const resetLoading = ref(false)
// 表格高度
const height = ref(500)
// 表格加载标志
const tableLoading = ref(false)
// 分页数据
const pagination = reactive({
current: 1,
total: 0,
size: 20,
})
onMounted(() => {
// 根据表格上方的el-form行数,动态减取高度,换行请使用el-form包裹
const line = document.querySelectorAll('.el-form').length
height.value = window.innerHeight - (280 + (line - 1) * 45)
})
// 搜索
const handleSearch = (getData: () => void) => {
searchLoading.value = true
pagination.current = 1
getData()
}
// 重置
const handleReset = (queryParam: any, getData: () => void) => {
resetLoading.value = true
pagination.size = 20
pagination.current = 1
// ------只适用全部重置为空字符串的场景--------
const keys = Object.keys(queryParam)
const obj: { [proName: string]: string } = {}
keys.forEach((item) => {
obj[item] = ''
})
Object.assign(queryParam, obj)
getData()
}
// 改变每页条数
const handleSizeChange = (val: number, getData: () => void) => {
pagination.size = val
getData()
}

// 改变页数
const handleCurrentChange = (val: number, getData: () => void) => {
pagination.current = val
getData()
}
// 表格行样式控制
const tableRowClassName = ({ rowIndex }: any) => {
if (rowIndex % 2 == 0) {
return 'warning-row'
} else {
return 'success-row'
}
}
const returnObj = {
searchLoading,
resetLoading,
height,
pagination,
tableLoading,
handleSearch,
handleReset,
tableRowClassName,
handleSizeChange,
handleCurrentChange,
}
return returnObj
}

页面使用

	import useTableCode from '@/hooks/useTableCode'	

   const {
		searchLoading,
		resetLoading,
		height,
		pagination,
		tableLoading,
		handleSearch,
		handleReset,
		tableRowClassName,
		handleSizeChange,
		handleCurrentChange,
	} = useTableCode()


<template>

<div class="herded_box">
			<el-form :inline="true" style="height: 44px" @keyup.enter="handleSearch(getData)">
				<el-form-item>
					<el-input size="small" clearable v-model="queryParam.invoiceNo" placeholder="请输入发票号码"></el-input>
				</el-form-item>
				<el-form-item v-if="systemType == '2'">
					<el-input size="small" clearable v-model="queryParam.buyerName" placeholder="请输入发票抬头"></el-input>
				</el-form-item>
				<el-form-item v-if="systemType == '2'">
					<el-select v-model="queryParam.status" placeholder="请选择发票状态" clearable>
						<el-option
							v-for="(item, index) in $getDictOptions('INVOICE_STATUS')"
							:key="index"
							:label="item.name"
							:value="item.code"></el-option>
					</el-select>
				</el-form-item>
				<!-- --------- -->
				<el-form-item>
					<el-button type="primary" @click="handleSearch(getData)" :loading="searchLoading">查询 </el-button>
					<el-button @click="handleReset(queryParam, getData)" type="info" :loading="resetLoading">重置</el-button>
				</el-form-item>
			</el-form>
		</div>

		<div class="content">
			<el-table
				size="small"
				header-cell-class-name="headerCell"
				:cell-style="{ height: '37px' }"
				:data="data"
				highlight-current-row
				:row-class-name="tableRowClassName"
				:height="newHeight"
				v-loading="tableLoading"
				border
				element-loading-text="拼命加载中"
				style="width: 100%">
				<el-table-column :resizable="false" type="index" width="50" label="序号"></el-table-column>
				<el-table-column prop="applyInfo.code" label="申请单号"> </el-table-column>
				<el-table-column prop="applicantName" label="申请方"> </el-table-column>
				<el-table-column prop="handlerName" label="开票方"></el-table-column>
				<el-table-column prop="applyInfo.buyerName" label="发票抬头"></el-table-column>
				<el-table-column prop="applyInfo.orderNo" label="订单编号">
					<template #default="{ row }">
						<a class="blueCell" @click="tableOperation(row.applyInfo.orderNo, 'order')">{{ row.applyInfo.orderNo }}</a>
					</template>
				</el-table-column>
				<el-table-column prop="invoiceAmount" label="开票金额(元)">
					<template #default="{ row }">
						{{ row.amountTax || row.applyInfo.actualAmount }}
					</template>
				</el-table-column>
				<el-table-column prop="applyInfo.createTime" label="申请时间"> </el-table-column>
				<el-table-column prop="invoiceTime" label="开票日期">
					<template #default="{ row }">
						{{ row.invoiceTime && $dayjs.toD(row.invoiceTime) }}
					</template>
				</el-table-column>
				<el-table-column prop="invoiceStatus" label="状态">
					<template #default="{ row }">
						{{ $transDictName('INVOICE_STATUS', row.invoiceStatus) }}
					</template>
				</el-table-column>
				<el-table-column prop="invoiceNo" label="发票号码">
					<template #default="{ row }">
						<a class="blueCell" @click="tableOperation(row.invoiceUrl, 'invoice')">{{ row.invoiceNo }}</a>
					</template>
				</el-table-column>
				<el-table-column prop="originalInvoiceNo" label="原发票号码"></el-table-column>
				<el-table-column label="电话/邮箱">
					<template #default="{ row }">
						{{ $transList2String([row.applyInfo.buyerPhone, row.applyInfo.buyerEmail], '/') }}
					</template>
				</el-table-column>
			</el-table>
			<div class="footerBox">
				<el-pagination
					v-model:page-size="pagination.size"
					@size-change="handleSizeChange($event, getData)"
					@current-change="handleCurrentChange($event, getData)"
					:current-page="pagination.current"
					:page-sizes="$page.pageSizes"
					layout="total, sizes, prev, pager, next, jumper"
					:total="pagination.total"
					background>
				</el-pagination>
			</div>
		</div>


</template>

2.表格封装

页面使用

<script setup lang="ts">
	import { ref, reactive, getCurrentInstance } from 'vue'
	import { getPostsale, getPostsaleMake } from '@/api/postsale/index'
	import { PostsaleItem } from '@/types/api/postsale/postsale'
	import OrderDetail from '@/views/order/components/Info.vue'
	import OrderDetailMake from '@/views/order/components/InfoMake.vue'
	import PostsaleDetail from './components/postsaleDetail/index.vue'
	import PostsaleHandler from './components/postsaleHandler/index.vue'
	import useTableCode from '@/hooks/useTableCode'
	import { DictEnum } from '@/enums/DictEnum'
	const { searchLoading, resetLoading, pagination, tableLoading, handleSearch, handleReset, handleSizeChange, handleCurrentChange } =
		useTableCode()
	// 订单详情组件实例
	const orderDetailRef = ref<InstanceType<typeof OrderDetail>>()
	const orderDetailMakeRef = ref<InstanceType<typeof OrderDetailMake>>()
	// 售后详情组件实例
	const postsaleDetailRef = ref<InstanceType<typeof PostsaleDetail>>()
	// 售后处理组件实例
	const postsaleHandlerRef = ref<InstanceType<typeof PostsaleHandler>>()
	// 表格数据
	const data = ref<PostsaleItem[]>([])
	// 查询参数
	let queryParam = reactive({
		code: '',
		status: '',
		type: '',
		size: 20,
	})
	const height = ref(500)
	height.value = window.innerHeight - 280 - 65
	// 列数据
	const columnData = reactive([
		{ text: true, prop: 'applyTime', label: '申请时间' },
		{ open: true, prop: 'code', label: '售后编号', query: 'id', type: 'code' },
		{ open: true, prop: 'orderNo', label: '关联订单', query: 'orderNo', type: 'orderNo' },
		{ text: true, prop: 'orderAmount', label: '订单金额(元)' },
		{ transDictName: true, prop: 'type', label: '售后类型', color: '#8400ff', query: DictEnum.AFTER_SALE_TYPE },
		{ transDictName: true, prop: 'requirement', label: '售后要求', color: '#8400ff', query: DictEnum.AFTER_SALE_REQUIREMENT },
		{ text: true, prop: 'problemDesc', label: '问题描述' },
		{ text: true, prop: 'demandTenantName', label: '需求方' },
		{ text: true, prop: 'serviceTenantName', label: '供应方' },
		{ slot: true, label: '售后状态', slotName: 'status' },
	])
	// 系统类型
	const systemType = ref('1')
	// 请求数据
	const nowTime = new Date().getTime()
	const getData = () => {
		tableLoading.value = true
		queryParam.size = pagination.size
		let apiFn = null as any
		if (systemType.value == '1') {
			apiFn = getPostsale
		} else if (systemType.value == '2') {
			apiFn = getPostsaleMake
		}
		apiFn(pagination.current, queryParam)
			.then((res: any) => {
				res.data.list.map((item: any) => {
					// 是否显示倒计时  超过48小时则不显示   item.updateTime为客服介入的时间
					item.time = Date.parse(item.updateTime) + 48 * 60 * 60 * 1000 - nowTime > 0 ? true : false
				})
				data.value = res.data.list
				pagination.total = res.data.total
				Loading()
			})
			.catch(() => {
				Loading()
			})
	}
	getData()
	// 重置loading
	const Loading = () => {
		tableLoading.value = false
		searchLoading.value = false
		resetLoading.value = false
	}
	// 表格操作
	const tableOperation = (id: string, type: string) => {
		const operationTypeMap: { [propName: string]: () => void } = {
			code: () => postsaleDetailRef.value?.openDialog(id), // 打开售后详情弹框
			orderNo: () => {
				if (systemType.value == '1') {
					orderDetailRef.value?.openDialog(null, id)
				} else if (systemType.value == '2') {
					orderDetailMakeRef.value?.openDialog(null, id)
				}
			}, // 打开订单详情弹框
			handler: () => postsaleHandlerRef.value?.openDialog(id), // 打开售后处理弹框
		}
		operationTypeMap[type] ? operationTypeMap[type]() : ''
	}

	const toHHmmss = (data: any) => {
		let s
		let hours = parseInt(((data % (1000 * 60 * 60 * 48)) / (1000 * 60 * 60)).toString())
		let minutes = parseInt(((data % (1000 * 60 * 60)) / (1000 * 60)).toString())
		let seconds = parseInt(((data % (1000 * 60)) / 1000).toString())
		s =
			(hours < 10 ? '0' + hours : hours) +
			'h:' +
			(minutes < 10 ? '0' + minutes : minutes) +
			'm:' +
			(seconds < 10 ? '0' + seconds : seconds) +
			's'
		return s
	}

	const setTimeoutXX = (data: any, successTime: any) => {
		setTimeout(() => {
			data.updateTimeStr = toHHmmss(successTime)
			successTime -= 1000
			if (successTime > 0) {
				setTimeoutXX(data, successTime)
			}
		}, 1000)
	}
	// 倒计时时间转换
	const timeFormat = (data: PostsaleItem) => {
		if (data.updateTime && !data.updateTimeStr && data.time) {
			const kTime = Date.parse(data.updateTime)
			let successTime = kTime + 48 * 60 * 60 * 1000 - nowTime
			setTimeoutXX(data, successTime)
		}
	}
</script>
<template>
	<div class="box-card">
		<el-radio-group v-model="systemType" class="typeRadioButton" @change="handleReset(queryParam, getData)">
			<el-radio-button
				v-for="item in $getDictOptions(DictEnum.SYSTEM_TYPE)"
				:key="item.code"
				:label="item.code"
				style="margin-bottom: 0"
				>{{ item.name + '订单' }}
			</el-radio-button>
		</el-radio-group>
		<!-- 表格封装 具体用法 '@/components/FsTable/index.vue'  @/components/FsPagination/index.vue-->
		<FsTable
			:table-loading="tableLoading"
			:table-data="data"
			:pagination-obj="pagination"
			:column-data="columnData"
			:table-height="height"
			@open-dialog-or-blank="tableOperation">
			<template #search-form>
				<el-form :inline="true" style="height: 44px" @keyup.enter="handleSearch(getData)">
					<el-form-item>
						<el-select v-model="queryParam.type" placeholder="请选择售后类型" size="small">
							<el-option
								v-for="(item, index) in $getDictOptions(DictEnum.AFTER_SALE_TYPE)"
								:key="index"
								:label="item.foregroundName"
								:value="item.code" />
						</el-select>
					</el-form-item>
					<el-form-item>
						<el-select v-model="queryParam.status" placeholder="请选择售后状态" size="small">
							<el-option
								v-for="(item, index) in $getDictOptions(DictEnum.AFTER_SALE_STATUS)"
								:key="index"
								:label="item.foregroundName"
								:value="item.code" />
						</el-select>
					</el-form-item>
					<el-form-item>
						<el-input size="small" clearable v-model="queryParam.code" placeholder="请输入售后编号"></el-input>
					</el-form-item>
					<el-form-item>
						<el-button type="primary" @click="handleSearch(getData)" :loading="searchLoading">查询 </el-button>
						<el-button @click="handleReset(queryParam, getData)" type="info" :loading="resetLoading">重置</el-button>
					</el-form-item>
				</el-form>
			</template>
			<template v-slot:status="{ data }">
				<span :style="{ color: data.status == '6' ? '#91D28B' : '#e6757d' }">{{
					$transDictName(DictEnum.AFTER_SALE_STATUS, data.status)
				}}</span>
				<div v-if="data.status == '8' && data.updateTime && data.time" style="color: #e6757d">
					倒计时:{{ timeFormat(data) }} {{ data.updateTimeStr }}
				</div>
			</template>
			<template #operation>
				<el-table-column label="操作" width="128">
					<template #default="{ row }">
						<el-button size="small" type="danger" @click="tableOperation(row.id, 'handler')" v-if="row.status == '8'"
							>处理</el-button
						>
						<el-button size="small" type="primary" @click="tableOperation(row.id, 'code')">详情</el-button>
					</template>
				</el-table-column>
			</template>
			<template #pagination>
				<FsPagination
					:pagination-obj="pagination"
					@sizeChange="handleSizeChange($event, getData)"
					@currentChange="handleCurrentChange($event, getData)"></FsPagination>
			</template>
		</FsTable>
		<OrderDetail ref="orderDetailRef" />
		<OrderDetailMake ref="orderDetailMakeRef" />
		<PostsaleDetail ref="postsaleDetailRef" />
		<PostsaleHandler ref="postsaleHandlerRef" @getPageData="handleSearch(getData)" />
	</div>
</template>

<style lang="scss" scoped></style>

表格组件

<script setup lang="ts">
	import { ref, onMounted, getCurrentInstance } from 'vue'
	import { ElInput } from 'element-plus'
	const inputRef = ref<InstanceType<typeof ElInput>>()
	const props = defineProps<{
		tableData: Array<{ [propName: string]: any }> //表格数据
		tableLoading: boolean //表格加载
		selection?: boolean //是否显示表格多选列
		columnData: Array<{ [propName: string]: any }> //列的数据
		paginationObj: { current: number; total: number; size: number } //分页数据
		tableHeight?: number
	}>()
	/**
	 * columnData用法
	 *
	 * text:文本、 open:打开弹窗或者网页、 time:时间、 transDictName:数据字典转状态、 transList2String:传递数组和分隔符 分割文字
	 * label:列标题
	 * prop: 列数据 (复杂情况,如深层次prop:applyInfo.code,请传递函数 (row: any) => row.applyInfo.code)
	 * query:需要传递的数据,例:1.open为true时,传递query: (row: any) => row.applyInfo.orderNo, 2.transDictName为true时,传递query: DictEnum.INVOICE_STATUS, 3.transList2String为true时,传递query:  (row: any) => [row.applyInfo.buyerPhone, row.applyInfo.buyerEmail],
	 * type:区分类型,例: open为true时,传递type: 'orderNo',区分点击的是哪列
	 *
	 * 	const columnData = reactive([
	 *
	 * ---------文本用法--------
	 * { text: true, prop: 'applicantName', label: '申请方' },
	 * { text: true, label: '发票抬头', prop: (row: any) => row.applyInfo.buyerName },
	 * {
	 *	text: true,
	 *	prop: (row: ContractTemplateTable) => (row.status == 0 ? '停用' : '启用'),
	 *	label: '状态',
	 *	color: (row: ContractTemplateTable) => (row.status == 0 ? '#f59a23' : '#22a417'),
	 *	},
	 * { text: true, label: '申请单号', prop: (row: any) => [{ text: '10', color: 'red', fontSize: '16px' },{ text: '12', color: 'blue',  fontSize: '16px' },{ text: '12', color: 'blue', fontSize: '16px' }] ,separator: ' / '},
	 *
	 *  ---------点击打开用法--------
	 *  { open: true, prop: 'code', label: '合同模板编号', query: (row: ContractTemplateTable) => row },
	 *  {
	 * 	open: true,
	 *  prop: (row: any) => row.applyInfo.orderNo,
	 *	label: '订单编号',
	 * 	query: (row: any) => row.applyInfo.orderNo,
	 * 	type: 'orderNo',
	 *	},
	 *  // 下载文件 query传数组
	 *  {
	 * 	open: true,
	 *  prop: fileName,
	 *	label: '订单编号',
	 * 	query: (row: any) => [row.fileUrl,row.fileName],
	 *	},

	 * ---------时间用法--------
	 * { time: true, label: '申请时间', prop: (row: any) => row.applyInfo.createTime },
	 * { time: true, prop: 'invoiceTime', label: '开票日期' },
	 *
	 * ---------转换分隔符用法--------
	 * { transList2String: true,label: '合同类型', query: (row: ContractTemplateTable) => [row.typePName, row.typeName],	separator: '/',},
	 *
	 * ---------数据字典用法--------
	 * { transDictName: true, prop: 'invoiceStatus', label: '状态', query: DictEnum.INVOICE_STATUS },
	 * { transDictName: true, prop: (row: any) => row.applyInfo.invoiceStatus , label: '状态', query: DictEnum.INVOICE_STATUS },
	 *
	 * ---------数据字典与转换分隔符结合用法---------
	 *  prop为['0','1']
	 * {transList2StringAndDictName:true, prop:'typeList',label:'发布范围', query: DictEnum.INVOICE_STATUS, separator: ',',}
	 *
	 * ----------switch用法------------
	 * 	{ switch: true, prop: 'status', label: '是否禁用', query: ['1', '0'], switchFlag: (row: any) => row ,type:'switch'},
	 *
	 *  ----------tag用法------------
	 * { tag: true, prop: (row:any)=>row.type == 0  ? '菜单' :row.type == 1 ?'按钮':'外链', label: '菜单类型', query:  (row:any)=>row.type == 0  ? 'success' :row.type == 1 ?'danger':'info', },
	 *
	 * ----------图片用法------------
	 * { picture: true, prop: 'avatar', label: '头像' },
	 *
	 * ----------复杂列 使用插槽--------
	 * { slot: true, prop: 'applicantName', label: '申请方', slotName: 'tag' },
	 *    // =>父组件使用插槽,data接收数据
	 * 	  <template v-slot:tag="{ data }">
	 * 			<el-tag v-if="data.applyInfo.actualAmount == 200000">123</el-tag> {{ data.applicantName }}
	 * 		</template>
	 *
	 *
	])
	 */
	const emits = defineEmits(['openDialogOrBlank', 'switchChange', 'editCellInput', 'selectionArr'])
	/**
	 * 表格高度
	 */
	const height = ref(500)
	/**
	 * 根据表格上方的el-form行数,动态减取高度,换行请使用el-form包裹
	 */
	onMounted(() => {
		const line = document.querySelectorAll('.el-form').length
		height.value = window.innerHeight - (280 + (line - 1) * 45)
	})
	/**
	 * 表格行样式控制
	 */
	const tableRowClassName = ({ rowIndex }: any) => {
		if (rowIndex % 2 == 0) {
			return 'warning-row'
		} else {
			return 'success-row'
		}
	}
	/**
	 * 打开弹窗或者网页
	 *
	 * @param query 打开时需要传递的东西
	 * @param type  如果有多个点击的,传递类型去判断点击的是哪个
	 */
	const openDialogOrBlank = (query: any, type: string) => {
		emits('openDialogOrBlank', query, type)
	}

	/**
	 * switch按钮切换
	 *
	 */
	const switchChange = (status: number | boolean | string, row: any) => {
		emits('switchChange', status, row)
	}

	/**
	 * 图片预览
	 *
	 */
	const showViewer = ref(false)
	const ImgUrlList = ref<Array<string>>([])
	const closeImg = () => {
		ImgUrlList.value = []
		showViewer.value = false
	}

	/**
	 * 点击图片
	 *
	 */
	const clickImage = (url: string) => {
		// 如果url为空,不打开预览
		if (!url) {
			return
		}
		ImgUrlList.value.push(url)
		showViewer.value = true
	}
	/**
	 * 表格单元格双击触发
	 *
	 * @param row 单元格所在行
	 * @param column 单元格所在列
	 */
	const currentCell = ref<string | null>(null)
	const cellClick = (row: any, column: any) => {
		currentCell.value = row.id + ',' + column.id
		// nextTick(() => {
		// 	inputRef.value[0]?.focus()
		// })
	}
	/**
	 * 更新表格数据
	 *
	 * @param event.target.value 为输入框的值
	 */
	const hideInput = (event: any, row: any) => {
		currentCell.value = null
		emits('editCellInput', event.target?.value, row)
	}
	/**
	 * 表格多选
	 *
	 * @param selectionArr 选中的每一行全部数据组成的数组
	 */
	const handleSelectionChange = (selectionArr: any) => {
		emits('selectionArr', selectionArr)
	}
	/**
	 * 根据数据字典转换为数组
	 *
	 * @param propArr 传过来的状态值 数组
	 * @param dictType 数据字典类型
	 */
	const transDitNameArr = (propArr: string[] | any, dictType: string) => {
		let dictArr = []
		dictArr = propArr?.map((propItem: string) => getCurrentInstance()?.proxy?.$transDictName(dictType, propItem))
		return dictArr
	}
</script>

<template>
	<div>
		<div class="herded_box">
			<slot name="search-form"></slot>
		</div>

		<div class="content">
			<el-table
				size="small"
				header-cell-class-name="headerCell"
				highlight-current-row
				v-loading="props.tableLoading"
				border
				element-loading-text="拼命加载中"
				style="width: 100%"
				:cell-style="{ height: '37px' }"
				:data="props.tableData"
				:row-class-name="tableRowClassName"
				:height="tableHeight ? tableHeight : height"
				@cell-dblclick="cellClick"
				@selection-change="handleSelectionChange">
				<el-table-column type="selection" width="50" v-if="props.selection" />
				<el-table-column :resizable="false" type="index" width="50" label="序号"></el-table-column>
				<!-- 列封装 -->
				<el-table-column
					v-for="(columnItem, columIndex) in columnData"
					:key="columIndex"
					:label="columnItem.label"
					:width="columnItem?.width">
					<template #default="{ row, column }">
						<!-- 1.纯文字 -->
						<template v-if="columnItem.text">
							<!-- 1.1深层次prop  例如传递的prop是applyInfo.code-->
							<template v-if="typeof columnItem?.prop == 'function'">
								<!-- 1.1.1 需要根据状态去显示不同颜色的文本,需要传递prop函数:[{text:'文本',color:'red',fontSize:'16px'}]  多个文本-->
								<template v-if="columnItem?.prop(row) instanceof Array">
									<a
										v-for="(item, index) in columnItem?.prop(row)"
										:key="index"
										:style="{ color: item.color, 'font-size': item.fontSize }">
										{{ item.text }}
										<span v-if="index + 1 != columnItem?.prop(row).length" style="color: #334155 !important">{{
											columnItem?.separator
										}}</span>
									</a>
								</template>
								<!-- 1.1.2 需要根据状态去显示不同颜色的文本,需要传递color函数  单个文本-->
								<span
									v-else
									:style="{ color: typeof columnItem.color == 'function' ? columnItem.color(row) : columnItem.color }"
									>{{ columnItem.prop(row) }}</span
								>
							</template>
							<!-- 1.2单层prop -->
							<template v-else>
								<!-- 1.2.1 需要根据状态去显示不同颜色的文本,需要传递color函数 -->
								<span
									:style="{ color: typeof columnItem.color == 'function' ? columnItem.color(row) : columnItem.color }"
									>{{ row[columnItem.prop] }}</span
								>
							</template>
						</template>

						<!-- 2.蓝色文字可点击 -->
						<a v-if="columnItem.open" class="blueCell">
							<!-- 2.1深层次prop  例如传递的prop是applyInfo.code,	deepQuery:如果需要传递的-->
							<span
								v-if="typeof columnItem?.prop == 'function'"
								@click="
									openDialogOrBlank(
										typeof columnItem.query == 'function' ? columnItem.query(row) : row[columnItem.query],
										columnItem.type
									)
								">
								{{ columnItem.prop(row) }}
							</span>
							<!-- 2.2单层prop -->
							<span
								v-else
								@click="
									openDialogOrBlank(
										typeof columnItem.query == 'function' ? columnItem.query(row) : row[columnItem.query],
										columnItem.type
									)
								"
								>{{ row[columnItem.prop] }}</span
							>
						</a>

						<!-- 3.时间文本 -->
						<template v-if="columnItem.time">
							<span>
								{{
									typeof columnItem?.prop == 'function'
										? columnItem.prop(row) && $dayjs.toM(columnItem.prop(row))
										: row[columnItem.prop] && $dayjs.toM(row[columnItem.prop])
								}}
							</span>
						</template>

						<!-- 4.根据数据字典转换 -->
						<template v-if="columnItem.transDictName">
							<span :style="{ color: typeof columnItem.color == 'function' ? columnItem.color(row) : columnItem.color }">
								{{
									$transDictName(
										columnItem.query,
										typeof columnItem?.prop == 'function' ? columnItem.prop(row) : row[columnItem.prop]
									)
								}}
							</span>
						</template>

						<!-- 5.根据数组去使用分隔符转换为文本 -->
						<template v-if="columnItem.transList2String">{{
							$transList2String(columnItem.query(row), columnItem.separator)
						}}</template>
						<!-- 5.1 根据数据字典转换成数组 再转换为文本 -->
						<template v-if="columnItem.transList2StringAndDictName">{{
							$transList2String(transDitNameArr(row[columnItem.prop], columnItem.query), columnItem.separator)
						}}</template>

						<!-- 6.switch切换 -->
						<template v-if="columnItem.switch">
							<el-switch
								style="--el-switch-on-color: #f56c6c"
								:active-value="columnItem.query[0]"
								:inactive-value="columnItem.query[1]"
								v-model="row[columnItem.prop]"
								@change="switchChange($event, columnItem.switchFlag(row))" />
						</template>

						<!-- 7.el-tag -->
						<template v-if="columnItem.tag">
							<el-tag :type="columnItem.query">{{ columnItem.prop }} </el-tag>
						</template>

						<!-- 8.图片 -->
						<span v-if="columnItem.picture" @click="clickImage(row[columnItem.prop])" class="span-image">
							<el-image class="click-image" :src="row[columnItem.prop]">
								<template #error>
									<img src="@/assets/images/avatar-default.png" />
								</template>
							</el-image>
						</span>

						<!-- 9.单元格编辑 -->
						<template v-if="columnItem.cellClick">
							<!--v-if去判断双击的是不是当前单元格-->
							<el-input
								@blur="hideInput($event, row)"
								size="small"
								ref="inputRef"
								v-model="row[columnItem.prop]"
								style="margin-left: 10px; width: calc(100% - 20px)"
								v-if="row.id + ',' + column.id == currentCell">
							</el-input>
							<span v-else style="margin-left: 15px">{{ row[columnItem.prop] }}</span>
						</template>

						<!-- 10.复杂列 使用插槽 -->
						<slot v-if="columnItem.slot" :name="columnItem.slotName" :data="row"> </slot>
					</template>
				</el-table-column>
				<!-- 操作列 -->
				<slot name="operation"></slot>
			</el-table>
			<!-- 分页 -->
			<div class="footerBox">
				<slot name="pagination"></slot>
			</div>
		</div>
		<el-image-viewer v-if="showViewer" :url-list="ImgUrlList" @close="closeImg" />
	</div>
</template>

<style lang="scss" scoped>
	.span-image {
		width: 30px;
		display: inline-block;
		.click-image {
			width: 30px;
			height: 30px;
			border-radius: 50%;
			cursor: pointer;
		}
	}
</style>

分页组件

<script setup lang="ts">
const props = defineProps<{
paginationObj: { current: number; total: number; size: number }
}>()
const emits = defineEmits(['sizeChange', 'currentChange'])
// 改变每页条数
const handleSizeChange = (val: number) => {
emits('sizeChange', val)
}
// 改变页数
const handleCurrentChange = (val: number) => {
emits('currentChange', val)
}
</script>

<template>
<el-pagination
:page-size="props.paginationObj.size"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="props.paginationObj.current"
:page-sizes="$page.pageSizes"
layout="total, sizes, prev, pager, next, jumper"
:total="props.paginationObj.total"
background>
</el-pagination>
</template>

<style lang="scss" scoped></style>
举报

相关推荐

0 条评论