Files
kengee-data-screen/src/views/AppStoresTable.vue
aixianling 67aa5264ef 提交
2024-06-20 18:31:15 +08:00

225 lines
7.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script>
export default {
name: "AppStoresTable",
label: "多店监控",
components: {
HlsPlayer: {
render: (h) => h('div', {style: {width: '100%', height: '100%'}}),
props: {
url: {default: "https://open.ys7.com/v3/openlive/155715496_1_1.m3u8?expire=1747359002&id=712960386311127040&t=c9c6ad362940b1fb4ea7a736cec78980aa9ad1d27d6e3eddf75788c0564e9d7b&ev=100"}
},
mounted() {
const {Clappr} = window
if (Clappr && this.url) {
const player = new Clappr.Player({
source: this.url,
mute: true, //静音为true
width: '100%',
height: '100%',
// poster:'http://clappr.io/poster.png', //设置封面图
autoPlay: true,
disableCanAutoPlay: true, //禁用检测浏览器是否可以自动播放视频
hideMediaControl: true, //禁用媒体控制自动隐藏
hideMediaControlDelay: 100, //更改默认的媒体控件自动隐藏超时值
hideVolumeBar: true, //当嵌入的宽度小于320时音量条将被隐藏
exitFullscreenOnEnd: false, //禁用播放器将在媒体结束时自动退出全屏显示,即播放结束后不会退出全屏
mediacontrol: {seekbar: "#000", buttons: "#FFF"}, //定义进度条和底部暂停等图标的颜色
events: {
onError: function () { //当播放出错时
alert("播放出错!")
},
}
});
player.attachTo(this.$el);
}
}
}
},
data() {
return {
height: '600px',
stores: [],
cameras: [],
storeKeyGoods: [],
categorySales: [],
columns: {
品类销售情况: [
{label: "品类", prop: "secondCategoryName"},
{label: "销售额", prop: "currentSaleAmt", width: '70px'},
{label: "库存金额", prop: "currentStockAmt", width: '80px'},
{label: "同/环比销售额", prop: "compareSaleAmt", width: '70px'},
{label: "同/环比库存金额", prop: "compareStockAmt", width: '70px'},
{label: "前四周日军销售额", prop: "avg4WeekSaleAmt", width: '70px'},
],
重点单品情况: [
{label: "重点单品", prop: "name"},
{label: "当日目标", prop: "targetNum", width: "70px"},
{label: "销售数量", prop: "saleNum", width: "70px"},
{label: "库存数量", prop: "stockNum", width: "70px"},
{label: "剩余时间预计销售数量", prop: "preSaleNum"},
{label: "提醒", custom: 1, width: 70, align: 'center', prop: "remind"},
]
},
}
},
computed: {
refs: v => v.$parent.getItemRefs(),
storeList: v => {
const list = []
let group = []
for (const e of v.stores) {
if (group.length < 4) {
group.push(e)
} else {
list.push(group.reverse())
group = [e]
}
}
if (group.length > 0) list.push(group.reverse())
return list
}
},
methods: {
getData() {
this.stores = this.stores.map(store => {
const cameraStore = this.cameras.find(e => e.storeCode == store)
const {storeName = "仟吉门店", storeCameraVOList: camera = []} = cameraStore
const keyGoods = this.storeKeyGoods.filter(e => e.storeCode == store)
const categorySale = this.categorySales.filter(e => e.storeCode == store)
return {storeName, camera: camera.map(e => e.url), keyGoods, categorySale}
})
},
getCameras() {
return $http.post("/api/store/camera/list", {
storeCodes: this.stores
}).then(res => {
if (res?.data) {
this.cameras = res.data?.records || []
}
})
},
getStoreKeyGoods() {
return $http.post("/api/store/camera/list", {
storeCodes: this.stores
}).then(res => {
if (res?.data) {
this.storeKeyGoods = res.data
}
})
},
getCategorySales() {
return $http.post("/api/store/camera/list", {
storeCodes: this.stores
}).then(res => {
if (res?.data) {
this.categorySales = res.data
}
})
},
},
async mounted() {
this.height = `${this.$el.clientHeight}px`
this.stores = JSON.parse(window.$glob.stores || "[]")
while (!$http) await $wait()
Promise.all([this.getCameras(), this.getStoreKeyGoods(), this.getCategorySales()]).then(() => this.getData())
}
}
</script>
<template>
<section class="AppStoresTable">
<el-carousel indicator-position="none" :height="height" :autoplay="false">
<el-carousel-item v-for="(group,i) in storeList" :key="i">
<div class="layout">
<div class="store" v-for="store in group" :key="store.id">
<div class="header" v-text="store.storeName"/>
<el-carousel indicator-position="none" height="250px">
<el-carousel-item v-for="(url,j) in store.camera" :key="[i,j].join('_')">
<hls-player :url="url"/>
</el-carousel-item>
</el-carousel>
<div class="subTiltle" v-text="'品类销售情况'"/>
<el-table :data="store.categorySale" size="mini" header-cell-class-name="tableHeader" cell-class-name="tableCell" max-height="275px">
<el-table-column v-for="column in columns.品类销售情况" v-bind="column" :key="column.prop"/>
</el-table>
<div class="subTiltle" v-text="'重点单品情况'"/>
<el-table :data="store.keyGoods" size="mini" header-cell-class-name="tableHeader" cell-class-name="tableCell" max-height="275px">
<el-table-column v-for="column in columns.重点单品情况" v-bind="column" :key="column.prop">
<template v-slot="{row}">
<div v-if="column.custom" :style="{color: row.preSaleNum > row.stockNum ? 'red' : '#fff'}" v-text="'周边库存情况'"/>
<span v-else v-text="row[column.prop] || ''"/>
</template>
</el-table-column>
</el-table>
</div>
</div>
</el-carousel-item>
</el-carousel>
</section>
</template>
<style scoped>
.AppStoresTable {
color: #fff;
box-sizing: border-box;
}
.tableHeader {
background: rgba(13, 48, 99, 0.6) !important;
color: #fff;
border-color: transparent !important;
}
.AppStoresTable .el-table tr {
background: transparent;
}
.AppStoresTable .el-table {
background: transparent;
border-color: transparent;
}
.AppStoresTable .el-table:before {
background: transparent;
}
.tableCell {
color: #fff;
border-color: transparent !important;
}
.AppStoresTable .header {
height: 48px;
padding: 8px 0 8px 38px;
margin-bottom: 24px;
box-sizing: border-box;
line-height: 32px;
background-image: url("http://10.0.97.209/img/kengee/kengee4.png");
background-repeat: no-repeat;
background-size: 100% 100%;
}
.AppStoresTable .subTiltle {
line-height: 20px;
width: fit-content;
margin: 24px auto 12px;
background-image: url("http://10.0.97.209/img/kengee/kengee5.png");
background-repeat: no-repeat;
background-size: 100% 2px;
background-position: center bottom;
}
.AppStoresTable .layout {
display: flex;
gap: 24px;
width: 100%;
overflow-x: auto;
}
.AppStoresTable .store {
width: calc(25% - 18px);
}
</style>