Commit 076ce683 by 李金轩

ljx

1 parent 430b72bd
window._baseUrl = ['localhost', '192.168.1.104'].includes(window.location.hostname) ? 'http://store.keliuyun.com:9998' : ''
// window._baseUrl = ['localhost', '192.168.1.104'].includes(window.location.hostname) ? 'http://store.keliuyun.com:9998' : ''
window._baseUrl = 'http://36.112.68.214:9999'
const log = console.log.bind(console)
......@@ -15,7 +15,7 @@ axiosInstance.interceptors.request.use(
config => {
if (['localhost', '192.168.1.104'].includes(window.location.hostname))
{
config.headers.Authorization = 'a1c28c12-cb12-439a-ae1e-e816e3f8f809'
config.headers.Authorization = '2c74d6cb-e060-4fbf-9ebe-60f67313de91'
}
else
{
......
......@@ -42,6 +42,10 @@ const route = [
path: '/',
redirect: '/Main/DataRerun',
},
{
path: '/test',
component: () => import("@/views/Test/Test.vue"),
},
...menuRoute
]
......
.success {
color: #26ff29;
}
.failed {
color: red;
}
import axiosInstance from "@/Request/PublicAxiosInstance"
import {filterEmptyValueInObject} from "@/PublicUtil/PublicUtil"
class DataRepairApi {
getGateList(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/gates`,
params: data
}
)
}
getChannelList(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/channels`,
params: data
}
)
}
preview(data) {
return axiosInstance.request(
{
method: 'POST',
url: `/preview/viewCountData`,
data: data
}
)
}
repair(data) {
return axiosInstance.request(
{
method: 'POST',
url: `/preview/updateCountData`,
data: data
}
)
}
}
const dataRepairApi = new DataRepairApi()
export default dataRepairApi
import axiosInstance from "@/Request/PublicAxiosInstance"
import {filterEmptyValueInObject} from "@/PublicUtil/PublicUtil"
class SnapshotRecordApi {
getGateList(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/gates/gateByInfo`,
params: filterEmptyValueInObject(
{
account_id: data.account_id,
plaza_id: data.plaza_id,
zone_id: data.zone_id,
type: data.type,
},
)
}
)
}
}
const snapshotRecordApi = new SnapshotRecordApi()
export default snapshotRecordApi
.single-image {
height: 300px;
width: 100%;
}
<template>
</template>
<script>
export default {
setup() {
return {}
}
}
</script>
<style lang="less" scoped>
@import "./FaceData";
</style>
<template>
<a-form :model="queryForm" layout="inline">
<a-form-item label="集团:">
<a-select v-model:value="queryForm.account_id"
style="width: 200px"
mode="multiple"
:maxTagCount="1"
@change="onAccountChange"
>
<a-select-option
v-for="item in accountList"
:value="item.id"
>
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="广场:">
<a-select v-model:value="queryForm.plaza_id"
style="width: 200px"
mode="multiple"
:maxTagCount="1"
@change="onPlazaChange"
>
<a-select-option
v-for="item in plazaList"
:value="item.id">
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="监控点:">
<a-select v-model:value="queryForm.gate_id"
style="width: 200px"
mode="multiple"
:maxTagCount="1">
<a-select-option
v-for="item in gateList"
:value="item.id"
>
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="开始日期:">
<a-date-picker v-model:value="queryForm.startDate"/>
</a-form-item>
<a-form-item label="结束日期:">
<a-date-picker v-model:value="queryForm.endDate"/>
</a-form-item>
<a-form-item>
<a-button type="primary" @click="confirmSearch">开始</a-button>
</a-form-item>
</a-form>
</template>
<script>
import {reactive, ref, toRaw} from 'vue'
import moment from 'moment'
import snapshotRecordApi from '@/views/SnapshotCluster/SnapshotRecord/SnapshotRecordApi'
import {isArray} from '@/PublicUtil/Judgment'
import {formatDate, formatTime} from '@/PublicUtil/PublicUtil'
import InformationDisplay from '@/component/InformationDisplay/InformationDisplay'
import dataRerunApi from '@/views/DataRerun/DataRerunApi'
import passengerFlowDataApi from '@/views/DataRepair/PassengerFlowData/PassengerFlowData'
export default {
components: {
InformationDisplay,
},
setup() {
const resultList = ref([])
const informationList = ref([])
// sequence
const accountList = ref([])
const plazaList = ref([])
const zoneList = ref([])
const gateList = ref([])
let webSocketMap = {
mallcountData: undefined,
floorcountData: undefined,
zonecountData: undefined,
gatecountData: undefined,
mallfaceSta: undefined,
floorfaceSta: undefined,
zonefaceSta: undefined,
gatefaceSta: undefined,
}
// mapping
const progressMap = {
mallcountData: "商场客流",
floorcountData: "楼层客流",
zonecountData: "店铺客流",
gatecountData: "监控点客流",
mallfaceSta: "商场人脸",
floorfaceSta: "楼层人脸",
zonefaceSta: "店铺人脸",
gatefaceSta: "监控点人脸"
}
const queryForm = reactive(
{
account_id: [],
plaza_id: [],
gate_id: [],
channel: [],
startDate: moment(moment().format('YYYY-MM-DD'), 'YYYY-MM-DD'),
endDate: moment(moment().format('YYYY-MM-DD'), 'YYYY-MM-DD'),
}
)
const onAccountChange = function() {
getPlazaList()
}
const onPlazaChange = function() {
getGateList()
}
const getGateList = function() {
queryForm.gate_id = []
gateList.value = []
passengerFlowDataApi.getGateList(
{
accountIds: queryForm.account_id.toString(),
mallIds: queryForm.plaza_id.toString(),
}
).then(
(r) => {
if (isArray(r))
{
gateList.value = r
}
}
)
}
const getPlazaList = function() {
queryForm.plaza_id = []
plazaList.value = []
snapshotRecordApi.getPlazaList(
{
account_id: queryForm.account_id.toString()
}
).then(
(r) => {
if (isArray(r))
{
plazaList.value = r
}
}
)
}
const getAccountList = function() {
queryForm.account_id = []
accountList.value = []
snapshotRecordApi.getAccountList().then(
(r) => {
if (isArray(r))
{
accountList.value = r
}
}
)
}
const floatToPercent = function(floatNum) {
if (!floatNum)
{
return 0
}
let formatNum = Math.floor(floatNum * 100)
return formatNum >= 100 ? 100 : formatNum
}
const dealMessage = function(message) {
// scheduleType
const {dates, mallIds, mallNames, status, stepCount, scheduleType, counter} = message
let resObj = {}
resObj.dates = dates
resObj.mallIds = mallIds
resObj.mallNames = mallNames
resObj.status = status
resObj.progress = floatToPercent(stepCount)
resObj.totalNum = 0
resObj.totalPage = 0
resObj.current = 0
resObj.curPageSize = 0
resObj.currentPage = 0
resObj.scheduleType = scheduleType
if (counter)
{
// dataNum dateMallNum step totalData totalDate totalMall totalMallDateProduct allDataCount
resObj.totalNum = counter.allDataCount
resObj.totalPage = counter.totalMallDateProduct
resObj.current = counter.dataNum
resObj.curPageSize = counter.totalData
resObj.currentPage = counter.dateMallNum
}
if (resultList.value.length)
{
const isSameScheduleType = resultList.value.some(item => item.scheduleType === scheduleType)
isSameScheduleType
? resultList.value.forEach(item => {
//
item.progress = floatToPercent(stepCount)
if (counter)
{
item.totalNum = counter.allDataCount
item.totalPage = counter.totalMallDateProduct
item.current = counter.dataNum
item.curPageSize = counter.totalData
item.currentPage = counter.dateMallNum
}
})
: resultList.value.push(resObj)
resObj = {}
}
else
{
resultList.value.push(resObj)
resObj = {}
}
}
const initializeWebSocket = function(scheduleType) {
if (webSocketMap[scheduleType] !== undefined)
{
webSocketMap[scheduleType].close()
}
webSocketMap[scheduleType] = new WebSocket(`ws://store.keliuyun.com:9998/recal/schedule/${scheduleType}`)
webSocketMap[scheduleType].onopen = () => {
queryData(scheduleType)
}
webSocketMap[scheduleType].onmessage = function(event) {
let message = JSON.parse(event.data)
dealMessage(message)
if (message.stepCount === 1)
{
webSocketMap[scheduleType].close()
}
}
}
const queryData = function(scheduleType) {
const rawData = toRaw(queryForm)
const data = {
mallIds: rawData.plaza_id,
scheduleType: scheduleType,
startDate: formatDate(rawData.startDate) + ' ' + '00:00:00',
endDate: formatDate(rawData.endDate) + ' ' + '00:00:00',
}
dataRerunApi.getResult(data, scheduleType).then(
(r) => {
informationList.value.push(r)
}
)
}
const confirmSearch = function() {
passengerFlowDataApi.preview()
}
const __main = function() {
getAccountList()
}
__main()
return {
// sequence
accountList,
plazaList,
zoneList,
gateList,
resultList,
informationList,
// mapping
progressMap,
queryForm,
onAccountChange,
initializeWebSocket,
confirmSearch,
onPlazaChange,
}
}
}
</script>
<style lang="less" scoped>
@import "./PassengerFlowData.less";
</style>
<template>
132231
</template>
<a-table :dataSource="dataList" v-loading="isLoading" :columns="[
{
title: '集团名称',
dataIndex: 'accountname',
align:'center',
slots: {
customRender: 'accountname',
},
},
{
title: '商场名称',
dataIndex: 'mallname',
align:'center',
},
{
title: '监控点名称',
dataIndex: 'gatename',
align:'center',
},
{
title: '设备号',
dataIndex: 'serialnum',
align:'center',
},
{
title: 'IP',
dataIndex: 'local_ip',
align:'center',
},
{
title: 'mac地址',
dataIndex: 'mac',
align:'center',
},
{
title: '发送的错误的数据日期',
dataIndex: 'errordate',
align:'center',
},
{
title: '统计日期',
dataIndex: 'countdate',
align:'center',
}
]" :pagination="false">
</a-table>
</template>
<script>
export default {
import {defineComponent, ref} from 'vue'
import equipmentTimeErrorVerificationApi from '@/views/EquipmentTimeErrorVerification/EquipmentTimeErrorVerificationApi'
export default defineComponent({
setup() {
return {}
}
}
</script>
const dataList = ref([])
const isLoading = ref(false)
<style scoped>
const __main = function() {
equipmentTimeErrorVerificationApi.getList().then(
(r) => {
dataList.value = r.data
}
)
}
</style>
__main()
return {
isLoading,
dataList,
}
},
})
</script>
import axiosInstance from "@/Request/PublicAxiosInstance"
import {filterEmptyValueInObject} from "@/PublicUtil/PublicUtil"
class PassengerFlowDataApi {
preview(data) {
class EquipmentTimeErrorVerificationApi {
getList(data) {
return axiosInstance.request(
{
method: 'POST',
url: `/preview/viewCountData`,
method: 'GET',
url: `/devices/deviceInfo`,
}
)
}
}
const passengerFlowDataApi = new PassengerFlowDataApi()
const equipmentTimeErrorVerificationApi = new EquipmentTimeErrorVerificationApi()
export default passengerFlowDataApi
export default equipmentTimeErrorVerificationApi
<template>
<el-container>
<el-aside style="background: black" width="200px">
<a-menu mode="inline" theme="dark" @click="onClick">
<a-menu-item :key="'/Main/DataRerun'">
<span>数据重跑</span>
</a-menu-item>
<a-menu-item :key="'/Main/DataRepair'">
<span>数据修补</span>
</a-menu-item>
<a-menu-item :key="'/Main/FeatureReExtract'">
<span>特征重提</span>
</a-menu-item>
<a-menu-item :key="'/Main/FeatureLibraryRebuild'">
<span>特征库重建</span>
</a-menu-item>
<a-menu-item :key="'/Main/PeopleReContrast'">
<span>人员重新比对</span>
</a-menu-item>
<a-menu-item :key="'/Main/SnapshotCluster'">
<span>抓拍聚类</span>
</a-menu-item>
<a-menu-item :key="'/Main/EquipmentTimeErrorVerification'">
<span>设备时间错误校验</span>
</a-menu-item>
</a-menu>
</el-aside>
<el-main>
<router-view :key="$route.fullPath"></router-view>
<el-header style="background: black">
<el-row style="height: 100%">
<el-col :span="2">
<div class="flex-vertical-center" style="height: 100%">
<img :src="require('./Icons/logo.svg')" style="height: auto;width:210px"/>
</div>
</el-col>
<el-col :span="22">
<div class="flex-vertical-center" style="font-size: 17px;display: flex;height: 100%;color: white; justify-content: flex-end">
<span style="margin: 0 20px">{{ currentTime }}</span>
<span>{{ getWeek() }}</span>
</div>
</el-col>
</el-row>
</el-header>
<el-main style="padding: 0">
<el-container>
<el-aside style="background: black" width="190px">
<a-menu mode="inline" theme="dark" @click="onClick">
<a-menu-item :key="'/Main/DataRerun'">
<span>数据重跑</span>
</a-menu-item>
<a-menu-item :key="'/Main/DataRepair'">
<span>数据修补</span>
</a-menu-item>
<a-menu-item :key="'/Main/FeatureReExtract'">
<span>特征重提</span>
</a-menu-item>
<a-menu-item :key="'/Main/FeatureLibraryRebuild'">
<span>特征库重建</span>
</a-menu-item>
<a-menu-item :key="'/Main/PeopleReContrast'">
<span>人员重新比对</span>
</a-menu-item>
<a-menu-item :key="'/Main/SnapshotCluster'">
<span>抓拍聚类</span>
</a-menu-item>
<a-menu-item :key="'/Main/EquipmentTimeErrorVerification'">
<span>设备时间错误校验</span>
</a-menu-item>
</a-menu>
</el-aside>
<el-main>
<router-view :key="$route.fullPath"></router-view>
</el-main>
</el-container>
</el-main>
</el-container>
</template>
<script>
import {defineComponent, ref} from 'vue'
import {useRouter} from 'vue-router'
import moment from "moment"
export default defineComponent({
setup() {
const router = useRouter()
const currentTime = ref(moment().format("YYYY-MM-DD HH:mm:ss"))
const goto = function(path) {
router.push(path)
......@@ -57,20 +78,45 @@ export default defineComponent({
)
}
const getWeek = function(date) {
let week = moment(date).day()
switch (week)
{
case 1:
return '星期一'
case 2:
return '星期二'
case 3:
return '星期三'
case 4:
return '星期四'
case 5:
return '星期五'
case 6:
return '星期六'
case 0:
return '星期天'
}
}
const __main = function() {
// log(accessedMenu)
setInterval(() => {
currentTime.value = moment().format("YYYY-MM-DD HH:mm:ss")
}, 1000)
}
__main()
return {
// scalar
currentTime,
// sequence
// mapping
// function
goto,
getOpeneds,
onClick,
getWeek,
}
},
})
......
<template>
<a-form :model="queryForm" layout="inline" :label-col="{span: 4}" :wrapper-col="{span: 14}">
<a-form-item label="集团:">
<a-form :model="queryForm" layout="inline" :label-col="{ style: { width: '70px' } }">
<a-form-item label="集团:" style="padding: 5px 0">
<a-select v-model:value="queryForm.account_id"
style="width: 200px"
style="width: 280px"
mode="multiple"
:maxTagCount="1"
@change="onAccountChange"
......@@ -15,9 +15,9 @@
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="广场:">
<a-form-item label="广场:" style="padding: 5px 0">
<a-select v-model:value="queryForm.plaza_id"
style="width: 200px"
style="width: 280px"
mode="multiple"
:maxTagCount="1"
@change="onPlazaChange"
......@@ -29,8 +29,8 @@
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="出入类型:">
<a-select v-model:value="queryForm.type" style="width: 200px">
<a-form-item label="出入类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.type" style="width: 280px">
<a-select-option :value="0">全场</a-select-option>
<a-select-option :value="1">广场出入口</a-select-option>
<a-select-option :value="2">楼层出入口</a-select-option>
......@@ -38,9 +38,9 @@
<a-select-option :value="4">其他</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="区域信息:">
<a-form-item label="区域信息:" style="padding: 5px 0">
<a-select v-model:value="queryForm.zone_id"
style="width: 200px"
style="width: 280px"
mode="multiple"
:maxTagCount="1"
@change="onZoneChange">
......@@ -52,9 +52,9 @@
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="监控点:">
<a-form-item label="监控点:" style="padding: 5px 0">
<a-select v-model:value="queryForm.gate_id"
style="width: 200px"
style="width: 280px"
mode="multiple"
:maxTagCount="1">
<a-select-option
......@@ -65,44 +65,44 @@
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="方向:">
<a-form-item label="方向:" style="padding: 5px 0">
<a-select v-model:value="queryForm.direction"
mode="multiple"
:maxTagCount="1"
style="width: 200px">
style="width: 280px">
<a-select-option :value="1"></a-select-option>
<a-select-option :value="-1"></a-select-option>
<a-select-option :value="0">横穿</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="抓怕类型:">
<a-select v-model:value="queryForm.picType" style="width: 200px">
<a-form-item label="抓怕类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.picType" style="width: 280px">
<a-select-option :value="1">半身照</a-select-option>
<a-select-option :value="2">全身照</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="人员类型:">
<a-form-item label="人员类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.personType"
mode="multiple"
:maxTagCount="1"
style="width: 200px">
style="width: 280px">
<a-select-option :value="1">店员</a-select-option>
<a-select-option :value="2">顾客</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="选择日期:">
<a-date-picker v-model:value="queryForm.date" :format="'YYYY-MM-DD'"/>
<a-form-item label="选择日期:" style="padding: 5px 0">
<a-date-picker v-model:value="queryForm.date" :format="'YYYY-MM-DD'" style="width: 280px"/>
</a-form-item>
<a-form-item label="选择时间:">
<a-time-picker v-model:value="queryForm.startTime"/>
<a-time-picker v-model:value="queryForm.endTime"/>
<a-form-item label="选择时间:" style="padding: 5px 0">
<a-time-picker v-model:value="queryForm.startTime" style="width: 140px"/>
<a-time-picker v-model:value="queryForm.endTime" style="width: 140px"/>
</a-form-item>
<a-form-item label="图片数量:">
<a-input v-model:value="queryForm.minPic" style="width: 100px"/>
<a-form-item label="图片数量:" style="padding: 5px 0">
<a-input v-model:value="queryForm.minPic" style="width: 129px"/>
<a-input v-model:value="queryForm.maxPic" style="width: 100px"/>
<a-input v-model:value="queryForm.maxPic" style="width: 129px"/>
</a-form-item>
<a-form-item>
<a-form-item style="padding: 5px 0">
<a-button type="primary" @click="confirmSearch" :loading="isLoading">查询</a-button>
</a-form-item>
</a-form>
......
<template>
<a-form :model="queryForm" layout="inline">
<a-form-item label="集团:">
<a-form :model="queryForm" layout="inline" :label-col="{ style: { width: '70px' } }">
<a-form-item label="集团:" style="padding: 5px 0">
<a-select v-model:value="queryForm.account_id"
style="width: 200px"
style="width: 280px"
mode="multiple"
:maxTagCount="1"
@change="onAccountChange"
......@@ -15,9 +15,9 @@
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="广场:">
<a-form-item label="广场:" style="padding: 5px 0">
<a-select v-model:value="queryForm.plaza_id"
style="width: 200px"
style="width: 280px"
mode="multiple"
:maxTagCount="1"
@change="onPlazaChange"
......@@ -29,8 +29,8 @@
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="出入类型:">
<a-select v-model:value="queryForm.type" style="width: 200px">
<a-form-item label="出入类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.type" style="width: 280px">
<a-select-option :value="0">全场</a-select-option>
<a-select-option :value="1">广场出入口</a-select-option>
<a-select-option :value="2">楼层出入口</a-select-option>
......@@ -38,9 +38,9 @@
<a-select-option :value="4">其他</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="区域信息:">
<a-form-item label="区域信息:" style="padding: 5px 0">
<a-select v-model:value="queryForm.zone_id"
style="width: 200px"
style="width: 280px"
mode="multiple"
:maxTagCount="1"
@change="onZoneChange">
......@@ -52,9 +52,9 @@
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="监控点:">
<a-form-item label="监控点:" style="padding: 5px 0">
<a-select v-model:value="queryForm.gate_id"
style="width: 200px"
style="width: 280px"
mode="multiple"
:maxTagCount="1">
<a-select-option
......@@ -65,39 +65,39 @@
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="方向:">
<a-form-item label="方向:" style="padding: 5px 0">
<a-select v-model:value="queryForm.direction"
mode="multiple"
:maxTagCount="1"
style="width: 200px">
style="width: 280px">
<a-select-option :value="1"></a-select-option>
<a-select-option :value="-1"></a-select-option>
<a-select-option :value="0">横穿</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="抓怕类型:">
<a-select v-model:value="queryForm.picType" style="width: 200px">
<a-form-item label="抓怕类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.picType" style="width: 280px">
<a-select-option :value="1">半身照</a-select-option>
<a-select-option :value="2">全身照</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="人员类型:">
<a-form-item label="人员类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.personType"
mode="multiple"
:maxTagCount="1"
style="width: 200px">
style="width: 280px">
<a-select-option :value="1">店员</a-select-option>
<a-select-option :value="2">顾客</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="选择日期:">
<a-date-picker v-model:value="queryForm.date" :format="'YYYY-MM-DD'"/>
<a-form-item label="选择日期:" style="padding: 5px 0">
<a-date-picker v-model:value="queryForm.date" :format="'YYYY-MM-DD'" style="width: 280px"/>
</a-form-item>
<a-form-item label="选择时间:">
<a-time-picker v-model:value="queryForm.startTime"/>
<a-time-picker v-model:value="queryForm.endTime"/>
<a-form-item label="选择时间:" style="padding: 5px 0">
<a-time-picker v-model:value="queryForm.startTime" style="width: 140px"/>
<a-time-picker v-model:value="queryForm.endTime" style="width: 140px"/>
</a-form-item>
<a-form-item>
<a-form-item style="padding: 5px 0">
<a-button type="primary" @click="confirmSearch" :loading="isLoading">查询</a-button>
</a-form-item>
</a-form>
......
<template>
<div class="container" ref="container" :style="{ height: containerHeight }">
<div class="empty" :style="{ height: emptyHeight }"></div>
<ul class="list" :style="{ transform: `translateY(${translateY})` }">
<li v-for="item in listData" :key="item" class="item" :style="{ height: itemHeight }">{{ item }}</li>
</ul>
</div>
<a-table :columns="columns" :data-source="data">
<template #name="{ text }">
<a>{{ text }}</a>
</template>
<template #customTitle>
<span>
<smile-outlined/>
Name
</span>
</template>
<template #tags="{ text: tags }">
<span>
<a-tag
v-for="tag in tags"
:key="tag"
:color="tag === 'loser' ? 'volcano' : tag.length > 5 ? 'geekblue' : 'green'"
>
{{ tag.toUpperCase() }}
</a-tag>
</span>
</template>
<template #action="{ record }">
<span>
<a>Invite 一 {{ record.name }}</a>
<a-divider type="vertical"/>
<a>Delete</a>
<a-divider type="vertical"/>
<a class="ant-dropdown-link">
More actions
<down-outlined/>
</a>
</span>
</template>
</a-table>
</template>
<script>
import {computed, onMounted, ref} from 'vue'
import {SmileOutlined, DownOutlined} from '@ant-design/icons-vue'
import {defineComponent} from 'vue'
export default {
const columns = [
{
dataIndex: 'name',
key: 'name',
slots: {
title: 'customTitle',
customRender: 'name',
},
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
},
{
title: 'Tags',
key: 'tags',
dataIndex: 'tags',
slots: {
customRender: 'tags',
},
},
{
title: 'Action',
key: 'action',
slots: {
customRender: 'action',
},
},
]
const data = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
tags: ['nice', 'developer'],
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
tags: ['loser'],
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
tags: ['cool', 'teacher'],
},
]
export default defineComponent({
setup() {
const oriData = Array.from({length: 100}, (v, k) => k)
const itemHeight = 20
const emptyHeight = itemHeight * oriData.length
const containerHeight = window.innerHeight
const itemCount = Math.ceil(containerHeight / itemHeight)
const container = ref(null)
const start = ref(0)
const translateY = ref(0)
const listData = computed(() => {
return oriData.slice(start.value, start.value + itemCount + 1)
})
onMounted(
() => {
container.value.addEventListener(
'scroll',
e => {
const {scrollTop} = e.target
start.value = Math.floor(scrollTop / itemHeight)
translateY.value = scrollTop + 'px'
}
)
}
)
return {
listData,
container,
translateY,
containerHeight: containerHeight + 'px',
itemHeight: itemHeight + 'px',
emptyHeight: emptyHeight + 'px'
data,
columns,
}
}
}
},
components: {
SmileOutlined,
DownOutlined,
},
})
</script>
<style lang="less" scoped>
.container {
overflow: auto;
display: flex;
}
</style>
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!