轮播图接口对接成功

This commit is contained in:
13218645326 2023-12-12 17:54:52 +08:00
parent 961480060f
commit fdb390a574
8 changed files with 574 additions and 324 deletions

1
components.d.ts vendored
View File

@ -19,6 +19,7 @@ declare module 'vue' {
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElImage: typeof import('element-plus/es')['ElImage']
ElInput: typeof import('element-plus/es')['ElInput']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']

3
env/.env.dev vendored
View File

@ -6,5 +6,6 @@ VITE_BUILD_MODE = 'dev'
VITE_API_URL = '/proxyApi'
# VITE_proxyTarget = 'http://10.40.92.16:8080'
VITE_proxyTarget = 'http://10.40.92.186:8080'
# VITE_proxyTarget = 'http://10.40.92.186:8080'
VITE_proxyTarget = 'http://10.40.92.64:8080'
# 9502 9206

View File

@ -1,40 +1,43 @@
<template>
<div class="upload_ss_c">
<div class="upload_ss_c" :class="{ hideBtn: props.fileList.length >= props.maxLimit }">
<!--action="/api/abk/web/v1/resource/file" -->
<el-upload
:action="props.actionUrl"
:auto-upload="props.autoUpload"
style="width: 100%"
:on-success="(response, file) => successUpload(response, file)"
:on-error="errorUpload"
:accept="props.acceptTypeList.join(',')"
:before-upload="beforeUpload"
:multiple="props.multiple"
:limit="props.maxLimit"
:on-exceed="handleExceed"
:file-list="props.fileList"
:disabled="props.disabledFlag"
:on-remove="(file, fileList) => removeFile(file, fileList)"
:on-preview="(file) => preview(file)"
:on-progress="(event, file, fileList) => onProgressFn(event, file, fileList)"
<el-upload :action="actionUrl" :auto-upload="props.autoUpload" :headers="headerInfo" style="width: 100%"
:on-success="(response: any, file: any) => successUpload(response, file)" :on-error="errorUpload"
:accept="props.acceptTypeList.join(',')" :before-upload="beforeUpload" :multiple="props.multiple"
:limit="props.maxLimit" :on-exceed="handleExceed" :file-list="props.fileList" :disabled="props.disabledFlag"
:on-change="changeFileFn" :on-remove="(file: any, fileList: any) => removeFile(file, fileList)"
:on-preview="(file: any) => preview(file)"
:on-progress="(event: any, file: any, fileList: any) => onProgressFn(event, file, fileList)"
:list-type="props.listType">
<!-- 上传的按钮 或者 icon 通过具名插槽的方式 -->
<div>
<slot name="default"></slot>
</div>
<slot name="textContent"></slot>
</el-upload>
<el-progress v-if="showProcessFlag && processFlag" :percentage="loadProcess"></el-progress>
</div>
</template>
<script lang="ts" setup>
import { ref, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { Base64 } from 'js-base64'
const props = defineProps({
actionUrl: {
//
type: String,
default: ''
},
import { ref, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
// import { Base64 } from 'js-base64'
const tmpUploadUrl = import.meta.env.VITE_API_URL + '/zlpt-file/file/cos/upload'
import { useStore } from 'store/main'
const store = useStore()
const headerInfo = reactive({
Authorization: store.token
})
console.log('tmpUploadUrl', tmpUploadUrl)
const actionUrl = ref(tmpUploadUrl)
const props = defineProps({
// actionUrl: {
// //
// type: String,
// default: ""
// },
width: {
//
type: String,
@ -90,11 +93,12 @@
default: 'picture'
},
extraData: {}, // name
/*
{
{
name:'12321'
}
*/
}
*/
dragFlag: {
type: Boolean,
default: true // element
@ -122,40 +126,50 @@
//
type: Boolean,
default: false
},
scuccesCallback: {
type: Function,
default: () => { }
},
successResultCallBack: {
type: Function,
default: () => { }
}
})
// office
// https://view.officeapps.live.com/op/view.aspx?src=
// https://view.officeapps.live.com/op/view.aspx?src=
//
})
// office
// https://view.officeapps.live.com/op/view.aspx?src=
// https://view.officeapps.live.com/op/view.aspx?src=
//
const officeOnlineAddress = 'https://view.officeapps.live.com/op/view.aspx?src='
const officeType = ['doc', 'docx', 'xlsx', 'xls']
let processFlag = ref(false) //
let loadProcess = ref(0) //
const officeOnlineAddress = 'https://view.officeapps.live.com/op/view.aspx?src='
const officeType = ['doc', 'docx', 'xlsx', 'xls']
let processFlag = ref(false) //
let loadProcess = ref(0) //
//
const successUpload = (response: any, file: any) => {
//
const successUpload = (response: any, file: any) => {
console.log('successUpload', response, file)
if (response.rt.status === 200) {
if (response.code === 200) {
props.fileList.push({
url: response.data,
name: file.name
})
props.successResultCallBack(response)
} else {
ElMessage({
type: 'warning',
message: response.data
})
}
}
const errorUpload = (res: any) => {
}
const errorUpload = (res: any) => {
ElMessage({
type: 'warning',
message: '上传失败请重试!'
})
}
const beforeUpload = (file) => {
}
const beforeUpload = (file: any) => {
console.log('file', file)
const { name = '', size } = file
if (size > props.maxSize * 1024 * 1000) {
ElMessage({
@ -164,30 +178,36 @@
})
return false
}
if (!props.acceptTypeList.includes(name.split('.').pop()) + '.') {
let names = name.split('.')
let currentName = names[names.length - 1]
console.log('acceptTypeListacceptTypeList', props.acceptTypeList, currentName)
console.log('name.split().pop()')
if (!props.acceptTypeList.includes('.' + currentName)) {
ElMessage({
type: 'warning',
message: `文件格式仅支持${props.acceptTypeList.join(',')}M`
message: `文件格式仅支持${props.acceptTypeList.join(',')}`
})
return false
}
}
const handleExceed = (files, fileList) => {
}
const handleExceed = (files: any, fileList: any) => {
ElMessage({
type: 'warning',
message: `当前限制选择 10 个文件,本次选择了 ${files.length} 个文件,共选择了 ${
files.length + fileList.length
message: `当前限制选择 10 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length
} 个文件`
})
}
//
const removeFile = (file, data) => {
}
//
const removeFile = (file: any, data: any) => {
console.log(file, data)
props.fileList = data
}
//
const preview = (data) => {
// props.fileList = data
}
//
const preview = (data: any) => {
console.log(data, '****预览文件')
window.open(data.response.msg)
return
const { url, response = {} } = data || {}
let name = data.name
const downLoadTypeList = props.downLoadTypeList
@ -199,13 +219,12 @@
if (downLoadTypeList.includes(suffixFileType)) {
// 'doc', 'docx', 'xlsx', 'xls', 'txt'
name = name.replace(/&/g, '') // &
const target = encodeURIComponent(
Base64.encode(
`${location.origin}/api/abk/web/v1/resource/file?fileId=${
url || response.data
}&fullfilename=${name}&sid=4AC67ADB4E264AB0A8B899A671072875`
)
)
const target = encodeURIComponent()
// Base64.encode(
// `${location.origin}/api/abk/web/v1/resource/file?fileId=${
// url || response.data
// }&fullfilename=${name}&sid=4AC67ADB4E264AB0A8B899A671072875`
// )
if (props.officePreviewFlag && officeType.includes(suffixFileType)) {
// office
const preveiewURL = officeOnlineAddress + target
@ -218,9 +237,9 @@
//
window.open('/api/abk/web/v1/resource/file?fileId=' + (url || response.data), '_blank')
}
}
}
const onProgressFn = (event, file, fileList) => {
const onProgressFn = (event: any, file: any, fileList: any) => {
processFlag.value = true
loadProcess.value = event.percent.toFixed(2)
if (loadProcess.value >= 100) {
@ -229,17 +248,31 @@
processFlag.value = false
})
}
}
}
const changeFileFn = (ev: any) => {
props.scuccesCallback(ev)
}
</script>
<style lang="scss" scoped>
:deep(.el-upload) {
:deep(.el-upload) {
width: v-bind('props.width') !important;
height: v-bind('props.height') !important;
}
:deep(.el-upload-list__item) {
}
:deep(.el-upload-list__item) {
width: v-bind('props.width') !important;
height: v-bind('props.height') !important;
}
}
</style>
<style>
.el-form {
.hideBtn {
.el-upload-list {
.el-upload {
display: none !important;
}
}
}
}
</style>
<style></style>

70
src/http/api/config.ts Normal file
View File

@ -0,0 +1,70 @@
/* GET
/bmCarouselSet/{id}
id查询轮播图信息
DELETE
/bmCarouselSet/{id}
POST
/bmCarouselSet/addorupdate
/
POST
*/
import { post, get, detele } from '../index'
// 根据id查询轮播图信息
export const apiBmCarouselSetsById = (id: any) => {
return get(`/zlpt-home/bmCarouselSet/${id}`, {})
}
// 删除轮播图信息
export const apiBmCarouselSetsListDelete = (id: any) => {
return detele(`/zlpt-home/bmCarouselSet/${id}`, {})
}
// 新增/修改轮播图信息
export const apiBmCarouselSetsAddorupdate = (params: any) => {
return post(`/zlpt-home/bmCarouselSet/addorupdate`, params)
}
// 获取轮播图列表
export const apiBmCarouselSetList = (params: any) => {
return post(`/zlpt-home/bmCarouselSet/list`, params)
}
// 根据id查询资讯信息
export const apiBmTopicInfoById = (id: any) => {
return post(`/bmTopicInfo/${id}`, {})
}
// 删除专题资讯信息
export const apiDeleteBmTopicInfoById = (id: any) => {
return detele(`/bmTopicInfo/${id}`, {})
}
// 新增/修改专题资讯信息
export const apiBmTopicInfoAddorupdate = (params: any) => {
return post(`/bmTopicInfo/addorupdate`, params)
}
// 导出专题资讯信息
export const apiBmTopicInfoExport = (params: any) => {
return post(`/bmTopicInfo/export`, params)
}
// 获取专题资讯列表
export const apiBmTopicInfoList = (params: any) => {
return post(`/bmTopicInfo/list`, params)
}

View File

@ -0,0 +1,57 @@
public class BmCarouselSet {
//id
@Excel(name = "轮播图id")
@ApiModelProperty(value = "轮播图id", required = true)
private Integer id;
//
@Excel(name = "轮播图名称")
@ApiModelProperty(value = "轮播图名称", required = true)
private String carName;
//
@Excel(name = "轮播图图片地址")
@ApiModelProperty(value = "轮播图图片地址", required = true)
private String carUrl;
//01
@Excel(name = "配置类型0资讯1跳转地址考虑用数据字典管理配置轮播图类型")
@ApiModelProperty(value = "配置类型0资讯1跳转地址", required = true)
private String type;
//
@Excel(name = "配置跳转地址")
@ApiModelProperty(value = "配置跳转地址", required = true)
private String openUrl;
//01
@Excel(name = "是否启用0不启用1启用")
@ApiModelProperty(value = "是否启用0不启用1启用", required = true)
private String status;
//
@Excel(name = "创建时间")
@ApiModelProperty(value = "创建时间", required = true)
private String createTime;
//id
@Excel(name = "创建人id")
@ApiModelProperty(value = "创建人id", required = true)
private Integer creator;
//
@Excel(name = "创建人")
@ApiModelProperty(value = "创建人", required = true)
private String createBy;
//
@Excel(name = "排序")
@ApiModelProperty(value = "排序", required = true)
private String sort;
//(0 , 1 )
@Excel(name = "是否删除(0 是, 1 否)")
@ApiModelProperty(value = "是否删除(0 是, 1 否)", required = true)
private String isActive;
}

View File

@ -1,21 +1,22 @@
<template>
<el-dialog v-model.trim="addShow" :title="title" width="30%" draggable :close-on-click-modal="false" >
<el-form :model="form" ref="ruleFormRef" label-width="88px" :rules="formRules" style="padding: 0 80px 0px 0;" >
<el-form-item label="标题:" prop="title">
<el-input v-model.trim="form.title" placeholder="请输入标题" clearable maxlength="30" />
<el-dialog v-model.trim="addShow" :title="title" width="620px" draggable :close-on-click-modal="false">
<el-form :model="form" ref="ruleFormRef" label-width="88px" :rules="formRules" style="padding: 0 0px 0px 0;">
<el-form-item label="标题:" prop="carName">
<el-input v-model.trim="form.carName" placeholder="请输入标题" clearable maxlength="30" />
</el-form-item>
<el-form-item label="图片:" prop="picture">
<uploadCom :maxLimit="3" listType="picture-card" :acceptTypeList="['.jpg','.jpeg','.png']" width="72px" height="72px">
<el-form-item label="图片:" prop="carUrl">
<uploadCom :maxLimit="1" listType="picture-card" :acceptTypeList="['.jpg', '.jpeg', '.png']" width="120px"
height="120px" :autoUpload="true" :successResultCallBack="successResultCallBackFn" :fileList="fileList">
<template v-slot:default>
<el-icon size="48" color="#aaa"><Plus /></el-icon>
<el-icon size="48" color="#aaa">
<Plus />
</el-icon>
</template>
</uploadCom>
</el-form-item>
<el-form-item label="跳转链接:" prop="linkUrl">
<el-input v-model.trim="form.linkUrl" clearable />
<el-form-item label="跳转链接:" prop="openUrl">
<el-input v-model.trim="form.openUrl" clearable />
</el-form-item>
</el-form>
@ -35,15 +36,19 @@ import uploadCom from "components/com/uploadCom.vue"
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import { linkReg } from "utils/reg"
import { apiBmCarouselSetsById, apiBmCarouselSetsAddorupdate } from "http/api/config"
const emits = defineEmits(['send'])
const addShow = ref(false)
let title = ref("新增")
let title: any = ref("新增")
const ruleFormRef: any = ref()
const form = reactive({
title: '',
picture: '',
linkUrl: ''
carName: '',
carUrl: '',
openUrl: '',
id: ''
})
const fileList: any = ref([])
// const validatorLink = (rule: any, value: any, callback: any) => {
// if (linkReg.test(value)) {
// callback()
@ -52,13 +57,13 @@ const form = reactive({
// }
// }
const formRules = reactive<FormRules<any>>({
title: [
carName: [
{ required: true, message: '请输入标题', trigger: 'blur' },
],
picture: [
carUrl: [
{ required: true, message: '请上传图片', trigger: 'blur' },
],
// linkUrl: [
// openUrl: [
// {
// required: true,
// message: '',
@ -76,11 +81,13 @@ const publishFn = () => {
if (!ruleFormRef) return
ruleFormRef.value.validate((valid: any) => {
if (valid) {
if (form.linkUrl&&linkReg.test(form.linkUrl)) {
if (form.openUrl && !linkReg.test(form.openUrl)) {
ElMessage({
type:'warning',
message:"请输入正确格式的跳转链接"
type: 'warning',
message: "请输入正确格式的跳转链接"
})
} else {
updateFn()
}
console.log('submit!')
} else {
@ -93,17 +100,47 @@ const publishFn = () => {
const cancelFn = (formEl: FormInstance | undefined) => {
if (!ruleFormRef) return
ruleFormRef.value.resetFields()
addShow.value =false
fileList.value = []
addShow.value = false
}
const open = (val:any) => {
const open = (val: any) => {
title.value = "新增"
addShow.value = true
}
const edit = () => {
const edit = (id: any) => {
title.value = "编辑"
addShow.value = true
form.id = id
initApiBmCarouselSetsById(id)
}
const initApiBmCarouselSetsById = async (id: any) => {
const res: any = await apiBmCarouselSetsById(id)
Object.assign(form, res.data)
const fileItem = {
url: res.data.carUrl,
name: ""
}
fileList.value = [fileItem]
// console.log("res-apiBmCarouselSetsById22222", fileList.value)
}
const successResultCallBackFn = (val: any) => {
console.log("successResultCallBackFnval", val)
form.carUrl = val.msg
}
const updateFn = async () => {
let params = Object.assign({}, form)
const res = await apiBmCarouselSetsAddorupdate(params)
console.log("apiBmCarouselSetsAddorupdate", res)
ElMessage({
type: 'success',
message: title.value + '成功'
})
addShow.value = false
}
defineExpose({

View File

@ -3,7 +3,7 @@
<el-form :inline="true" :model="filterForm" class="demo-form-inline">
<el-form-item label="关键字">
<el-input v-model.trim="filterForm.keyword" placeholder="请输入关键字" clearable />
<el-input v-model.trim="filterForm.carName" placeholder="请输入关键字" clearable />
</el-form-item>
<el-form-item label="时间范围">
<el-date-picker v-model.trim="filterForm.dataRange" type="daterange" range-separator="To" start-placeholder="Start date"
@ -23,9 +23,9 @@
<script lang="ts" setup>
const emits = defineEmits(['search','reset','sort','add'])
const filterForm = reactive({
keyword: '',
import { getdatatime } from "utils/time"
const filterForm:any = reactive({
carName: '',
dataRange:''
})
@ -35,7 +35,9 @@ const serachFn = () => {
}
const resetFn=()=>{
emits('reset')
filterForm.carName = ''
filterForm.dataRange = getdatatime()
emits('reset',filterForm)
}
const sortFn =()=>{
@ -45,7 +47,9 @@ const addFn =()=>{
emits('add')
}
onMounted(() => {
filterForm.dataRange = getdatatime()
})
</script>
<style scoped lang="scss"></style>

View File

@ -1,18 +1,36 @@
<template>
<headerTop @search="searchFn" @reset="resetFn" @sort="sortFn" @add="addFn"></headerTop>
<addCom ref="addComRef"></addCom>
<addCom ref="addComRef" @send="initTableList"></addCom>
<el-card shadow="always" class="content_body_row">
<div class="content_body_table">
<el-table :data="tableListInfo.list" border style="width: 100%" show-overflow-tooltip
:max-height="'calc(100vh - 72px - 48px - 65px - 12px - 60px - 48px)'"
:height="'calc(100vh - 72px - 48px - 65px - 12px - 60px - 48px)'">
<el-table-column type="index" width="72" label="序号" />
<el-table-column prop="date" label="标题" min-width="150" />
<el-table-column prop="name" label="轮播图" min-width="120" />
<el-table-column prop="state" label="跳转页面" min-width="120" />
<el-table-column prop="city" label="是否启用" min-width="320" />
<el-table-column prop="address" label="创建人" min-width="400" />
<el-table-column prop="zip" label="创建日期" min-width="120" />
<!-- <el-table-column prop="date" label="标题" min-width="150" /> -->
<el-table-column prop="name" label="轮播图" min-width="120">
<template #default="scope">
<el-image :preview-teleported="true" style="width: 32px; height:32px" :src="scope.row.carUrl"
:zoom-rate="1.2" :max-scale="7" :min-scale="0.2" :preview-src-list="[scope.row.carUrl]"
:z-index="100" fit="cover" />
</template>
</el-table-column>
<el-table-column prop="state" label="跳转页面" min-width="120">
<template #default="scope">
<el-button type="text" @click="openFn(scope.row)">
链接
</el-button>
</template>
</el-table-column>
<el-table-column label="是否启用" min-width="320">
<template #default="scope">
<el-switch v-model.trim="scope.row.status" :before-change="beforeChange.bind(this, scope.row)" />
</template>
</el-table-column>
<el-table-column prop="createBy" label="创建人" min-width="400" />
<el-table-column prop="createTime" label="创建日期" min-width="120" />
<el-table-column prop="zip" label="操作" align="center" min-width="180">
<template #default="scope">
@ -26,8 +44,8 @@
</el-table-column>
</el-table>
<div class="paination_out">
<Pagination :currentPage="paginationInfo.currentPage" :pageSize="paginationInfo.pageSize"
@sendPage="getPageFn"></Pagination>
<Pagination :currentPage="paginationInfo.pageNum" :pageSize="paginationInfo.pageSize" @sendPage="getPageFn">
</Pagination>
</div>
</div>
</el-card>
@ -37,75 +55,42 @@
import headerTop from "./com/headerTop.vue"
import addCom from "./com/addCom.vue"
import { ElConfirmBeforeOpert } from "utils/elementCom"
import { apiBmCarouselSetsListDelete, apiBmCarouselSetList, apiBmCarouselSetsAddorupdate } from "http/api/config"
import { ElMessage } from 'element-plus'
import moment from "moment";
import { status } from "nprogress"
const addComRef = ref()
const paginationInfo = reactive({
currentPage: 1,
pageNum: 1,
pageSize: 15
})
const tableData = [
{
v_id: '1',
date: '2016-05-03',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
},
{
v_id: '2',
date: '2016-05-02',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
},
{
v_id: '3',
date: '2016-05-04',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
},
{
v_id: '4',
date: '2016-05-01',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
},
{
v_id: '5',
date: '2016-05-08',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
},
let total = ref(0)
]
let tableListInfo = reactive({
list: tableData
list: []
})
const editRowFn = (row: any) => {
addComRef.value.edit({
a: "111"
})
addComRef.value.edit(row.id)
}
const deleteItem = (row: any) => {
const itemID = row.v_id
console.log("ITEMid", row)
const deleteItem = async (row: any) => {
const itemID = row.id
const index = tableListInfo.list.findIndex((ele: any) => ele.id == itemID)
const res = await apiBmCarouselSetsListDelete(itemID)
let tipMessage = "删除成功"
tableListInfo.list.splice(index, 1)
ElMessage({
type: 'success',
message: tipMessage
})
}
const deleteRowFn = (row: any) => {
@ -120,12 +105,35 @@ const deleteRowFn = (row: any) => {
}
const searchFn = () => {
const openFn = (row: any) => {
if (!row.openUrl) {
ElMessage({
type: 'warning',
message: "跳转链接不能为空"
})
return
}
window.open(row.openUrl, "_blank")
}
const resetFn = () => {
let searchParams: any = {
carName: ''
}
const searchFn = (params: any) => {
searchParams = params
console.log("searchParams", params)
searchParams.beginTime = moment(params.dataRange[0]).format('yyyy-MM-DD')
searchParams.endTime = moment(params.dataRange[1]).format('yyyy-MM-DD')
initTableList()
}
const resetFn = (params: any) => {
searchParams = params
console.log("searchParams", params)
searchParams.beginTime = moment(params.dataRange[0]).format('yyyy-MM-DD')
searchParams.endTime = moment(params.dataRange[1]).format('yyyy-MM-DD')
initTableList()
}
const sortFn = () => {
@ -138,16 +146,55 @@ const addFn = () => {
})
}
const getPageFn = (val: any) => {
paginationInfo.currentPage = val.currentPage
paginationInfo.pageNum = val.pageNum
paginationInfo.pageSize = val.pageSize
initTableList()
}
const initTableList = () => {
const initTableList = async () => {
const params = {
...searchParams,
...paginationInfo
}
const res: any = await apiBmCarouselSetList(params)
console.log("apiGetCompanyInfoSelectList", res)
tableListInfo.list = res.rows.map((ele: any) => {
return {
...ele,
status: ele.status == 1 ? true : false
}
})
// tableListInfo.list =
total.value = res.total
}
const beforeChange = (ev: any) => {
console.log("evbeforeChange", ev)
return new Promise((resolve, reject) => {
apiBmCarouselSetsAddorupdate({
// 0 1
status: ev.status ? 0 : 1,
id: ev.id
}).then((res: any) => {
console.log("apiBmCarouselSetsAddorupdate",res)
if (res.code == 200) {
resolve(true)
} else {
resolve(false)
}
}).catch(err => {
resolve(false)
})
})
}
onMounted(() => {
initTableList()
})
</script>
<style scoped lang="scss"></style>