Files
kengee-data-screen/src/views/AppStoresTable.vue

256 lines
9.1 KiB
Vue
Raw Normal View History

2024-06-17 18:20:13 +08:00
<script>
export default {
2024-06-18 17:09:25 +08:00
name: "AppStoresTable",
2024-06-17 23:18:11 +08:00
label: "多店监控",
data() {
return {
2024-06-18 18:03:52 +08:00
height: '600px',
2024-06-18 22:23:45 +08:00
stores: [],
2024-06-20 18:31:15 +08:00
cameras: [],
storeKeyGoods: [],
categorySales: [],
2024-07-08 12:15:10 +08:00
aroundStock: [],
dialog: false,
2024-06-17 23:18:11 +08:00
columns: {
品类销售情况: [
2024-06-18 22:23:45 +08:00
{label: "品类", prop: "secondCategoryName"},
2024-07-07 11:27:52 +08:00
{label: "销售额", prop: "currentSaleAmt", width: 70},
{label: "库存金额", prop: "currentStockAmt", width: 80},
{label: "同/环比销售额", prop: "compareSaleAmt", width: 70},
{label: "同/环比库存金额", prop: "compareStockAmt", width: 70},
2024-08-01 23:48:46 +08:00
{label: "前四周日均销售额", prop: "avg4WeekSaleAmt", width: 70},
2024-06-17 23:18:11 +08:00
],
重点单品情况: [
2024-06-18 22:23:45 +08:00
{label: "重点单品", prop: "name"},
2024-07-07 11:27:52 +08:00
{label: "当日目标", prop: "targetNum", width: 70},
{label: "销售数量", prop: "saleNum", width: 70},
{label: "库存数量", prop: "stockNum", width: 70},
2024-06-18 22:23:45 +08:00
{label: "剩余时间预计销售数量", prop: "preSaleNum"},
{label: "提醒", custom: 1, width: 70, align: 'center', prop: "remind"},
2024-07-08 12:15:10 +08:00
],
周边库存情况: [
{label: "门店名称", prop: "storeName"},
{label: "直线距离", prop: "distance", width: 70},
{label: "库存数量", prop: "stockNum", width: 70},
{label: "销售数量", prop: "saleNum", width: 70},
{label: "剩余时间预计销售数量", prop: "preSaleNum", width: 70},
{label: "店长姓名/电话", prop: "shopMangerName", format: v => `${v.shopMangerName}(${v.shopownerPhone})`},
2024-06-17 23:18:11 +08:00
]
},
2024-07-25 11:33:56 +08:00
curI: 0,
2024-08-23 18:09:52 +08:00
curJ: {},
2024-06-17 23:18:11 +08:00
}
2024-06-18 18:03:52 +08:00
},
computed: {
2024-07-07 11:27:52 +08:00
search: v => v.$multipleStoreBoard.search,
2024-06-18 18:03:52 +08:00
storeList: v => {
const list = []
let group = []
2024-06-18 22:23:45 +08:00
for (const e of v.stores) {
2024-08-23 18:30:47 +08:00
v.$set(v.curJ, e.storeCode, 0)
2024-06-18 18:03:52 +08:00
if (group.length < 4) {
group.push(e)
} else {
2024-06-18 22:23:45 +08:00
list.push(group.reverse())
2024-06-18 18:03:52 +08:00
group = [e]
}
2024-06-18 22:23:45 +08:00
}
2024-08-23 18:09:52 +08:00
if (group.length > 0) {
list.push(group.reverse())
}
2024-06-18 18:03:52 +08:00
return list
2024-07-07 11:27:52 +08:00
},
},
watch: {
search: {
2024-08-28 01:24:31 +08:00
immediate: true, deep: true, handler(v) {
this.getData().then(() => {
if (v.interval > 0 && v.changeWay == '1') {
this.$refs.carousel?.$forceUpdate()
}
})
2024-07-07 11:27:52 +08:00
}
2024-06-18 18:03:52 +08:00
}
},
2024-06-18 22:23:45 +08:00
methods: {
getData() {
2024-06-21 16:42:57 +08:00
const {$http, $waitFor} = window
2024-07-08 23:03:11 +08:00
const {groupCodeList, type, compareDate} = this.search
2024-06-24 11:10:40 +08:00
console.log("筛选条件:", this.search)
2024-08-28 01:24:31 +08:00
return $waitFor($http && (type != 3 || compareDate)).then(() => this.getStores())
2024-07-07 11:27:52 +08:00
.then(codes => Promise.all([this.getCameras(), this.getStoreKeyGoods(), this.getCategorySales()]).then(() => codes))
.then((codes = []) => {
this.stores = codes?.map(storeCode => {
2024-07-08 12:15:10 +08:00
const {storeCameraVOList = [], storeName, longitude, latitude} = this.cameras.find(e => e.storeCode == storeCode) || {}
2024-06-21 18:02:03 +08:00
const keyGoods = this.storeKeyGoods.filter(e => e.storeCode == storeCode) || []
const categorySale = this.categorySales.filter(e => e.storeCode == storeCode) || []
2024-07-28 16:36:05 +08:00
return {storeCode, storeName, longitude, latitude, camera: [...new Set(storeCameraVOList.map(e => e.cameraUrl))], keyGoods, categorySale}
2024-07-07 11:27:52 +08:00
}).filter(e => !!e.storeName) || []
2024-06-21 18:02:03 +08:00
})
},
getStores() {
const {groupCodeList: [groupCode] = []} = this.search
return $http.get(`/data-boot/ca/screen/scStoreInfo/group${groupCode ? `/${groupCode}` : ""}`).then(res => {
2024-06-21 18:02:03 +08:00
if (res?.data) {
2024-07-07 11:27:52 +08:00
return res.data
2024-06-21 18:02:03 +08:00
}
2024-06-18 22:23:45 +08:00
})
2024-06-20 18:31:15 +08:00
},
getCameras() {
2024-06-21 15:59:59 +08:00
return $http.post("/data-boot/la/screen/multipleStoreBoard/storeCamera", {
2024-07-07 22:47:46 +08:00
type: "1", ...this.search, limit: 999
2024-06-20 18:31:15 +08:00
}).then(res => {
if (res?.data) {
2024-06-21 18:02:03 +08:00
this.cameras = res.data?.records || []
2024-06-20 18:31:15 +08:00
}
})
},
getStoreKeyGoods() {
2024-06-21 15:59:59 +08:00
return $http.post("/data-boot/la/screen/multipleStoreBoard/storeKeyGoods", {
2024-07-23 19:58:23 +08:00
type: "1", ...this.search,
2024-06-20 18:31:15 +08:00
}).then(res => {
if (res?.data) {
this.storeKeyGoods = res.data
}
})
},
getCategorySales() {
2024-06-21 15:59:59 +08:00
return $http.post("/data-boot/la/screen/multipleStoreBoard/categorySale", {
2024-07-07 22:47:46 +08:00
type: "1", ...this.search,
2024-06-20 18:31:15 +08:00
}).then(res => {
if (res?.data) {
this.categorySales = res.data
}
})
},
2024-06-21 15:59:59 +08:00
gotoDetail(store) {
2024-07-15 11:06:07 +08:00
this.$storeBoard.search.storeCode = store.storeCode
this.$marketBoard.screenId = 'a90522ef-869b-40ea-8542-d1fc9674a1e8'
2024-06-21 15:59:59 +08:00
},
2024-07-08 12:15:10 +08:00
getTableData(item = {}, tag) {
2024-07-07 11:27:52 +08:00
const v = this
const datasource = {
2024-07-08 12:15:10 +08:00
重点单品情况: item.keyGoods,
品类销售情况: item.categorySale,
周边库存情况: v.aroundStock,
2024-07-07 11:27:52 +08:00
}
return {
2024-07-08 12:15:10 +08:00
headerBGC: 'rgba(13, 48, 99, 0.6)', rowNum: arguments?.[2] || 2,
2024-07-07 11:27:52 +08:00
oddRowBGC: window.evenRowBGC(), evenRowBGC: "transparent",
header: v.columns[tag].map(e => e.label),
columnWidth: v.columns[tag].map(e => e.width || "0;flex:1;min-width:0;"),
align: v.columns[tag].map(e => e.align || "left"),
2024-07-08 12:15:10 +08:00
data: datasource[tag]?.map(e => v.columns[tag].map(column => column.custom == 1 ? `<div class="pointer" style="color:${e.preSaleNum > e.stockNum ? 'red' : '#fff'}">周边库存</div>` :
column.format ? column.format(e) : e[column.prop])) || [],
2024-07-07 11:27:52 +08:00
}
},
2024-08-15 11:01:20 +08:00
openNearbyStores({thirdGoodsCode}, store) {
const {storeCode, longitude, latitude} = store
2024-07-08 12:15:10 +08:00
return $http.post("/data-boot/la/screen/multipleStoreBoard/aroundStock", {
2024-07-23 19:58:23 +08:00
type: "1", ...this.search, storeCode, longitude, latitude, thirdGoodsCode,
2024-07-08 12:15:10 +08:00
}).then(res => {
if (res?.data) {
this.aroundStock = res.data
this.$nextTick(() => this.dialog = true)
}
})
2024-07-25 11:33:56 +08:00
},
2024-08-28 00:45:32 +08:00
handleHotKey(e) {
if (e.code == "ArrowLeft") {
this.$refs.carousel.prev()
} else if (e.code == "ArrowRight") {
this.$refs.carousel.next()
}
}
2024-06-18 22:23:45 +08:00
},
2024-06-21 15:59:59 +08:00
mounted() {
2024-08-15 11:01:20 +08:00
this.height = `${this.$el.clientHeight - 30}px`
2024-08-28 00:45:32 +08:00
document.onkeyup = this.handleHotKey
},
beforeDestroy() {
document.onkeyup = null
2024-06-17 23:18:11 +08:00
}
2024-06-17 18:20:13 +08:00
}
</script>
<template>
2024-07-08 12:15:10 +08:00
<section class="AppStoresTable" @click="dialog=false">
2024-08-28 01:24:31 +08:00
<el-carousel ref="carousel" indicator-position="outside" :height="height" :autoplay="search.changeWay==1" @change="v=>curI=(v||0)" :interval="search.interval">
2024-06-18 18:03:52 +08:00
<el-carousel-item v-for="(group,i) in storeList" :key="i">
<div class="layout">
2024-06-21 15:59:59 +08:00
<div class="store" v-for="store in group" :key="store.storeCode">
2024-07-07 11:27:52 +08:00
<div class="headerTitle" v-text="store.storeName" @click="gotoDetail(store)"/>
2024-08-23 18:30:47 +08:00
<el-carousel indicator-position="none" height="250px" @change="v=>$set(curJ,store.storeCode,v||0)" :autoplay="false">
2024-06-18 22:23:45 +08:00
<el-carousel-item v-for="(url,j) in store.camera" :key="[i,j].join('_')">
2024-08-23 18:09:52 +08:00
<hls-player v-if="`${i}_${j}`==`${curI}_${curJ[store.storeCode]}`" :id="`hls_player_${store.storeCode}_${i}_${j}`" :url="url"/>
2024-06-18 22:23:45 +08:00
</el-carousel-item>
2024-06-18 18:03:52 +08:00
</el-carousel>
2024-06-21 11:51:14 +08:00
<div class="subTitle" v-text="'品类销售情况'"/>
2024-08-05 03:28:19 +08:00
<scroll-table :table-data="store.categorySale" :columns="columns['品类销售情况']"/>
<!--<dv-scroll-board :config="getTableData(store, '品类销售情况')"/>-->
2024-06-21 11:51:14 +08:00
<div class="subTitle" v-text="'重点单品情况'"/>
2024-08-05 03:28:19 +08:00
<scroll-table :table-data="store.keyGoods" :columns="columns['重点单品情况']" @click="v=>openNearbyStores(v,store)" @click.native.stop/>
<!--<dv-scroll-board :config="getTableData(store, '重点单品情况')" @click="v=>openNearbyStores(v,store)" @click.native.stop/>-->
2024-06-18 18:03:52 +08:00
</div>
</div>
</el-carousel-item>
</el-carousel>
2024-08-05 03:28:19 +08:00
<div class="dialogTable" v-if="dialog" @click.stop>
<scroll-table :table-data="aroundStock" :columns="columns['周边库存情况']"/>
</div>
<!--<dv-scroll-board v-if="dialog" class="dialogTable" :config="getTableData({}, '周边库存情况',5)" @click.native.stop/>-->
2024-06-17 21:55:16 +08:00
</section>
2024-06-17 18:20:13 +08:00
</template>
2024-07-07 11:27:52 +08:00
<style>
2024-06-18 17:09:25 +08:00
.AppStoresTable {
2024-07-07 11:27:52 +08:00
width: 100%;
2024-06-17 23:18:11 +08:00
color: #fff;
box-sizing: border-box;
2024-07-08 12:15:10 +08:00
position: relative;
2024-06-17 23:18:11 +08:00
}
2024-08-05 03:28:19 +08:00
.AppStoresTable .dv-scroll-board, .AppStoresTable .scrollTable {
height: 130px !important;
2024-06-17 23:18:11 +08:00
}
2024-07-07 11:27:52 +08:00
.AppStoresTable .headerTitle {
2024-06-17 23:18:11 +08:00
height: 48px;
padding: 8px 0 8px 38px;
margin-bottom: 24px;
box-sizing: border-box;
line-height: 32px;
2024-06-18 17:09:25 +08:00
background-image: url("http://10.0.97.209/img/kengee/kengee4.png");
background-repeat: no-repeat;
background-size: 100% 100%;
2024-06-17 23:18:11 +08:00
}
2024-06-17 21:55:16 +08:00
2024-06-21 11:51:14 +08:00
.AppStoresTable .subTitle {
2024-06-17 23:18:11 +08:00
line-height: 20px;
2024-06-18 17:09:25 +08:00
width: fit-content;
2024-06-17 23:18:11 +08:00
margin: 24px auto 12px;
2024-06-18 17:09:25 +08:00
background-image: url("http://10.0.97.209/img/kengee/kengee5.png");
background-repeat: no-repeat;
background-size: 100% 2px;
background-position: center bottom;
}
2024-06-18 22:23:45 +08:00
.AppStoresTable .layout {
2024-06-18 17:09:25 +08:00
display: flex;
gap: 24px;
width: 100%;
overflow-x: auto;
}
2024-06-18 22:23:45 +08:00
.AppStoresTable .store {
2024-06-18 17:09:25 +08:00
width: calc(25% - 18px);
2024-06-17 18:20:13 +08:00
}
2024-08-28 00:45:32 +08:00
.AppStoresTable .el-carousel__arrow {
font-size: 24px;
width: 48px;
height: 48px;
background-color: rgba(31, 45, 61, .6);
}
2024-06-17 18:20:13 +08:00
</style>