大提交一版
This commit is contained in:
@@ -61,7 +61,7 @@ Vue.prototype.$marketBoard = Vue.observable({
|
||||
search: {"groupCodeList": ["20011061"], "currentDate": "20240701", "compareDate": "20240630", "hourNum": "18"}
|
||||
})
|
||||
Vue.prototype.$multipleStoreBoard = Vue.observable({
|
||||
search: {}
|
||||
search: {"groupCodeList": [], "hourNum": "", type: "1"}
|
||||
})
|
||||
Vue.prototype.$storeBoard = Vue.observable({
|
||||
search: {}
|
||||
|
||||
28
src/views/AppMultipleStoreBoard.vue
Normal file
28
src/views/AppMultipleStoreBoard.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<script>
|
||||
import AppMultipleStoreBoardFilter from "@/views/AppMultipleStoreBoardFilter.vue";
|
||||
import AppStoresTable from "@/views/AppStoresTable.vue";
|
||||
import AppNavbar from "@/views/AppNavbar.vue";
|
||||
|
||||
export default {
|
||||
name: "AppMultipleStoreBoard",
|
||||
components: {AppNavbar, AppStoresTable, AppMultipleStoreBoardFilter},
|
||||
label: "多店看板"
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="AppMultipleStoreBoard">
|
||||
<app-navbar/>
|
||||
<app-multiple-store-board-filter/>
|
||||
<app-stores-table class="fill"/>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.AppMultipleStoreBoard {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
</style>
|
||||
91
src/views/AppMultipleStoreBoardFilter.vue
Normal file
91
src/views/AppMultipleStoreBoardFilter.vue
Normal file
@@ -0,0 +1,91 @@
|
||||
<script>
|
||||
export default {
|
||||
name: "AppMultipleStoreBoardFilter",
|
||||
label: "多店看板-筛选条",
|
||||
data() {
|
||||
return {
|
||||
form: {},
|
||||
options: [],
|
||||
dateOptions: Array(24).fill(0).map((v, i) => ({label: `${++i}:00`, value: i}))
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
dicts: v => window.$dicts || {}
|
||||
},
|
||||
methods: {
|
||||
getOptions() {
|
||||
return $http.get("/data-boot/ca/screen/scStoreInfo/listGroup").then(res => {
|
||||
if (res?.data) {
|
||||
return this.options = res.data.map(e => ({label: e.supervisorName, value: e.groupCode}))
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getOptions().then(() => {
|
||||
setTimeout(() => {
|
||||
const hourNum = new Date().getHours(),
|
||||
groupCodeList = this.options?.[0].value
|
||||
this.form = {hourNum, groupCodeList, type: "1"}
|
||||
this.$set(this.$multipleStoreBoard, 'search', {hourNum, groupCodeList: [groupCodeList], type: "1"})
|
||||
}, 500)
|
||||
})
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-form class="AppMultipleStoreBoardFilter flex" size="small" label-width="70px">
|
||||
<el-form-item label="品类">
|
||||
<el-select v-model="form.categoryId" @change="v=>$multipleStoreBoard.search.categoryId=v" clearable placeholder="全部">
|
||||
<el-option v-for="item in dicts.品类" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型">
|
||||
<el-select v-model="form.type" @change="v=>$multipleStoreBoard.search.type=v" clearable placeholder="全部">
|
||||
<el-option v-for="item in dicts.类型" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div class="fill"/>
|
||||
<el-form-item label="课长">
|
||||
<el-select v-model="form.groupCodeList" @change="v=>$multipleStoreBoard.search.groupCodeList=[v]" clearable placeholder="全部">
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="时段">
|
||||
<el-select v-model="form.hourNum" size="small" format="HH:mm" value-format="H" @change="v=>$multipleStoreBoard.search.hourNum=v" clearable placeholder="全部">
|
||||
<el-option v-for="item in dateOptions" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="切换方式">
|
||||
<el-select v-model="form.changeWay" clearable placeholder="全部">
|
||||
<!-- <el-option v-for="item in dateOptions" :key="item.value" :label="item.label" :value="item.value"/>-->
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.AppMultipleStoreBoardFilter {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.AppMultipleStoreBoardFilter .el-input__inner {
|
||||
background: linear-gradient(180deg, rgba(12, 53, 111, 0) 0%, #0C356F 100%);
|
||||
border: 1px solid #1760AE;
|
||||
border-radius: 0;
|
||||
color: #fff;
|
||||
min-width: 100px;
|
||||
max-width: 140px;
|
||||
}
|
||||
|
||||
.AppMultipleStoreBoardFilter .el-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.AppMultipleStoreBoardFilter .el-form-item__label {
|
||||
white-space: nowrap;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
@@ -36,8 +36,9 @@ export default {
|
||||
},
|
||||
getValue(item) {
|
||||
let result = this.info[item.prop]
|
||||
if (item.unit == "%") result = (result * 100 || 0) + "%"
|
||||
if (item.unit == "%") result = (result * 100 || 0).toFixed(2)+ "%"
|
||||
if (item.calc) result = item.calc()
|
||||
if (/^-?\d+(\.\d+)?$/.test(result)) result = Number(result).toFixed(2)
|
||||
return result
|
||||
}
|
||||
},
|
||||
|
||||
@@ -38,11 +38,6 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
height: '600px',
|
||||
search: {
|
||||
type: '1',
|
||||
categoryId: '',
|
||||
hourNum: ""
|
||||
},
|
||||
stores: [],
|
||||
cameras: [],
|
||||
storeKeyGoods: [],
|
||||
@@ -50,17 +45,17 @@ export default {
|
||||
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: "currentSaleAmt", width: 70},
|
||||
{label: "库存金额", prop: "currentStockAmt", width: 80},
|
||||
{label: "同/环比销售额", prop: "compareSaleAmt", width: 70},
|
||||
{label: "同/环比库存金额", prop: "compareStockAmt", width: 70},
|
||||
{label: "前四周日军销售额", prop: "avg4WeekSaleAmt", width: 70},
|
||||
],
|
||||
重点单品情况: [
|
||||
{label: "重点单品", prop: "name"},
|
||||
{label: "当日目标", prop: "targetNum", width: "70px"},
|
||||
{label: "销售数量", prop: "saleNum", width: "70px"},
|
||||
{label: "库存数量", prop: "stockNum", width: "70px"},
|
||||
{label: "当日目标", prop: "targetNum", width: 70},
|
||||
{label: "销售数量", prop: "saleNum", width: 70},
|
||||
{label: "库存数量", prop: "stockNum", width: 70},
|
||||
{label: "剩余时间预计销售数量", prop: "preSaleNum"},
|
||||
{label: "提醒", custom: 1, width: 70, align: 'center', prop: "remind"},
|
||||
]
|
||||
@@ -69,6 +64,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
refs: v => v.$parent.getItemRefs(),
|
||||
search: v => v.$multipleStoreBoard.search,
|
||||
storeList: v => {
|
||||
const list = []
|
||||
let group = []
|
||||
@@ -82,27 +78,35 @@ export default {
|
||||
}
|
||||
if (group.length > 0) list.push(group.reverse())
|
||||
return list
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
search: {
|
||||
immediate: true, deep: true, handler() {
|
||||
this.getData()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getData() {
|
||||
const {$http, $waitFor} = window
|
||||
console.log("筛选条件:", this.search)
|
||||
$waitFor($http).then(() => this.getStores())
|
||||
.then(() => Promise.all([this.getCameras(), this.getStoreKeyGoods(), this.getCategorySales()]))
|
||||
.then(() => {
|
||||
this.stores = this.stores?.map(storeCode => {
|
||||
$waitFor($http && this.search.groupCodeList.length > 0).then(() => this.getStores())
|
||||
.then(codes => Promise.all([this.getCameras(), this.getStoreKeyGoods(), this.getCategorySales()]).then(() => codes))
|
||||
.then((codes = []) => {
|
||||
this.stores = codes?.map(storeCode => {
|
||||
const {storeCameraVOList = [], storeName} = this.cameras.find(e => e.storeCode == storeCode) || {}
|
||||
const keyGoods = this.storeKeyGoods.filter(e => e.storeCode == storeCode) || []
|
||||
const categorySale = this.categorySales.filter(e => e.storeCode == storeCode) || []
|
||||
return {storeCode, storeName, camera: storeCameraVOList.map(e => e.cameraUrl), keyGoods, categorySale}
|
||||
}) || []
|
||||
}).filter(e => !!e.storeName) || []
|
||||
})
|
||||
},
|
||||
getStores() {
|
||||
return $http.get(`/data-boot/ca/screen/scStoreInfo/group/${this.search.groupCodeList}`).then(res => {
|
||||
const {groupCodeList = []} = this.search
|
||||
return $http.get(`/data-boot/ca/screen/scStoreInfo/group/${groupCodeList[0]}`).then(res => {
|
||||
if (res?.data) {
|
||||
this.stores = res.data || []
|
||||
return res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -137,12 +141,29 @@ export default {
|
||||
$glob.query = {storeCode: store.storeCode}
|
||||
const sid = "9f299712-5549-413b-a93b-7c3e3b5bfadb"
|
||||
$glob.group = sid
|
||||
this.refs["ff6a5ca5-8cca-4fad-8058-a2ab2388236c"].$refs.main.groupId = sid
|
||||
this.$storeBoard.query.storeCode = sid
|
||||
},
|
||||
getTableData(item, tag) {
|
||||
const v = this
|
||||
const datasource = {
|
||||
重点单品情况: "keyGoods",
|
||||
品类销售情况: "categorySale",
|
||||
}
|
||||
return {
|
||||
headerBGC: 'rgba(13, 48, 99, 0.6)',
|
||||
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"),
|
||||
data: item[datasource[tag]].map(e => v.columns[tag].map(column => column.custom == 1 ? `<div style="color:${e.preSaleNum > e.stockNum ? 'red' : '#fff'}">周边库存情况</div>` : e[column.prop])),
|
||||
}
|
||||
},
|
||||
getNearbyStores(evt) {
|
||||
console.log(evt)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.height = `${this.$el.clientHeight}px`
|
||||
this.getData()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -153,25 +174,16 @@ export default {
|
||||
<el-carousel-item v-for="(group,i) in storeList" :key="i">
|
||||
<div class="layout">
|
||||
<div class="store" v-for="store in group" :key="store.storeCode">
|
||||
<div class="header" v-text="store.storeName" @click="gotoDetail(store)"/>
|
||||
<div class="headerTitle" v-text="store.storeName" @click="gotoDetail(store)"/>
|
||||
<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="subTitle" 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>
|
||||
<dv-scroll-board :config="getTableData(store, '品类销售情况')"/>
|
||||
<div class="subTitle" 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>
|
||||
<dv-scroll-board :config="getTableData(store, '重点单品情况')" @click="getNearbyStores"/>
|
||||
</div>
|
||||
</div>
|
||||
</el-carousel-item>
|
||||
@@ -179,12 +191,17 @@ export default {
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
<style>
|
||||
.AppStoresTable {
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.AppStoresTable .dv-scroll-board {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.tableHeader {
|
||||
background: rgba(13, 48, 99, 0.6) !important;
|
||||
color: #fff;
|
||||
@@ -209,7 +226,7 @@ export default {
|
||||
border-color: transparent !important;
|
||||
}
|
||||
|
||||
.AppStoresTable .header {
|
||||
.AppStoresTable .headerTitle {
|
||||
height: 48px;
|
||||
padding: 8px 0 8px 38px;
|
||||
margin-bottom: 24px;
|
||||
|
||||
Reference in New Issue
Block a user