|
@@ -1,52 +1,52 @@
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
-import { Delete, Edit } from '@element-plus/icons-vue'
|
|
|
|
-import * as echarts from 'echarts'
|
|
|
|
-import { ElMessage } from 'element-plus'
|
|
|
|
-import { inject, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
|
|
|
-import emitter from '/@/utils/emitter'
|
|
|
|
-import { getProductCardData, postDeleteProductLine } from '/@/views/productCenter/productList/api'
|
|
|
|
|
|
+import { Delete, Edit } from '@element-plus/icons-vue';
|
|
|
|
+import * as echarts from 'echarts';
|
|
|
|
+import { ElMessage } from 'element-plus';
|
|
|
|
+import { inject, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
|
|
|
+import emitter from '/@/utils/emitter';
|
|
|
|
+import { getProductCardData, postDeleteProductLine } from '/@/views/productCenter/productList/api';
|
|
|
|
|
|
emitter.on('ProductList-updateCardData', (value: any) => {
|
|
emitter.on('ProductList-updateCardData', (value: any) => {
|
|
if (value.isUpdate) {
|
|
if (value.isUpdate) {
|
|
- cardData.value.splice(0)
|
|
|
|
- fetchProductCardData()
|
|
|
|
|
|
+ cardData.value.splice(0);
|
|
|
|
+ fetchProductCardData();
|
|
}
|
|
}
|
|
-})
|
|
|
|
|
|
+});
|
|
|
|
|
|
emitter.on('TopFilters-selectValue', (value: any) => {
|
|
emitter.on('TopFilters-selectValue', (value: any) => {
|
|
- const newIndex = cardData.value.findIndex((item) => item.productlineId === value.selectValue)
|
|
|
|
|
|
+ const newIndex = cardData.value.findIndex((item) => item.productlineId === value.selectValue);
|
|
if (newIndex !== -1) {
|
|
if (newIndex !== -1) {
|
|
- selectedCardIndex.value = newIndex
|
|
|
|
|
|
+ selectedCardIndex.value = newIndex;
|
|
}
|
|
}
|
|
-})
|
|
|
|
|
|
+});
|
|
|
|
|
|
-const profile = <any>inject('profile')
|
|
|
|
-const dateRange = <any>inject('dateRange')
|
|
|
|
-const loading = ref(false)
|
|
|
|
-const cardData = ref([])
|
|
|
|
-const pieChartRefs = ref<HTMLDivElement[]>([])
|
|
|
|
|
|
+const profile = <any>inject('profile');
|
|
|
|
+const dateRange = <any>inject('dateRange');
|
|
|
|
+const loading = ref(false);
|
|
|
|
+const cardData = ref([]);
|
|
|
|
+const pieChartRefs = ref<HTMLDivElement[]>([]);
|
|
|
|
|
|
-const selectedCardIndex = ref(0)
|
|
|
|
|
|
+const selectedCardIndex = ref(0);
|
|
|
|
|
|
async function fetchProductCardData() {
|
|
async function fetchProductCardData() {
|
|
try {
|
|
try {
|
|
const { data } = await getProductCardData({
|
|
const { data } = await getProductCardData({
|
|
profileId: profile.value.profile_id,
|
|
profileId: profile.value.profile_id,
|
|
startDate: dateRange.value[0],
|
|
startDate: dateRange.value[0],
|
|
- endDate: dateRange.value[1]
|
|
|
|
- })
|
|
|
|
- cardData.value = data
|
|
|
|
|
|
+ endDate: dateRange.value[1],
|
|
|
|
+ });
|
|
|
|
+ cardData.value = data;
|
|
} catch (error) {
|
|
} catch (error) {
|
|
- console.log('error:', error)
|
|
|
|
|
|
+ console.log('error:', error);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
function initChart() {
|
|
function initChart() {
|
|
cardData.value.forEach((item, index) => {
|
|
cardData.value.forEach((item, index) => {
|
|
- const chartId = `chart${index}-${item.productlineId}`
|
|
|
|
- const el = document.getElementById(chartId)
|
|
|
|
|
|
+ const chartId = `chart${index}-${item.productlineId}`;
|
|
|
|
+ const el = document.getElementById(chartId);
|
|
if (el) {
|
|
if (el) {
|
|
- const pieChart = echarts.init(el)
|
|
|
|
|
|
+ const pieChart = echarts.init(el);
|
|
const option = {
|
|
const option = {
|
|
animation: false,
|
|
animation: false,
|
|
series: [
|
|
series: [
|
|
@@ -91,64 +91,65 @@ function initChart() {
|
|
],
|
|
],
|
|
},
|
|
},
|
|
],
|
|
],
|
|
- }
|
|
|
|
- pieChart.setOption(option)
|
|
|
|
- pieChartRefs.value[chartId] = pieChart
|
|
|
|
|
|
+ };
|
|
|
|
+ pieChart.setOption(option);
|
|
|
|
+ pieChartRefs.value[chartId] = pieChart;
|
|
}
|
|
}
|
|
- })
|
|
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
function selectCard(index: number, item: any) {
|
|
function selectCard(index: number, item: any) {
|
|
- selectedCardIndex.value = index
|
|
|
|
- const productlineId = item.productlineId
|
|
|
|
- emitter.emit('ProductSelectCard-cardId', { productlineId: productlineId })
|
|
|
|
|
|
+ selectedCardIndex.value = index;
|
|
|
|
+ const productlineId = item.productlineId;
|
|
|
|
+ emitter.emit('ProductSelectCard-cardId', { productlineId: productlineId });
|
|
}
|
|
}
|
|
|
|
|
|
function editCard(item) {
|
|
function editCard(item) {
|
|
- emitter.emit('ProductTab-editProductCard', { isVisible: true, data: item })
|
|
|
|
|
|
+ emitter.emit('ProductTab-editProductCard', { isVisible: true, data: item });
|
|
}
|
|
}
|
|
|
|
|
|
async function deleteProductLine(item) {
|
|
async function deleteProductLine(item) {
|
|
const obj = {
|
|
const obj = {
|
|
productlineId: item.productlineId,
|
|
productlineId: item.productlineId,
|
|
- }
|
|
|
|
|
|
+ };
|
|
try {
|
|
try {
|
|
- const response = await postDeleteProductLine(obj)
|
|
|
|
|
|
+ const response = await postDeleteProductLine(obj);
|
|
if (response.data.code == 'success') {
|
|
if (response.data.code == 'success') {
|
|
- ElMessage({ message: '已删除', type: 'success' })
|
|
|
|
- await fetchProductCardData()
|
|
|
|
- emitter.emit('ProductSelectCard-reloading', { reloading: true })
|
|
|
|
|
|
+ ElMessage({ message: '已删除', type: 'success' });
|
|
|
|
+ await fetchProductCardData();
|
|
|
|
+ emitter.emit('ProductSelectCard-reloading', { reloading: true });
|
|
} else {
|
|
} else {
|
|
- ElMessage({ message: '删除失败', type: 'error' })
|
|
|
|
|
|
+ ElMessage({ message: '删除失败', type: 'error' });
|
|
}
|
|
}
|
|
} catch (error) {
|
|
} catch (error) {
|
|
- console.log('error:', error)
|
|
|
|
|
|
+ console.log('error:', error);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-watch(dateRange, async() => {
|
|
|
|
- loading.value = true
|
|
|
|
- await fetchProductCardData()
|
|
|
|
- loading.value = false
|
|
|
|
-})
|
|
|
|
|
|
+watch(dateRange, async () => {
|
|
|
|
+ loading.value = true;
|
|
|
|
+ await fetchProductCardData();
|
|
|
|
+ loading.value = false;
|
|
|
|
+});
|
|
|
|
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
- await fetchProductCardData()
|
|
|
|
- initChart()
|
|
|
|
-})
|
|
|
|
|
|
+ await fetchProductCardData();
|
|
|
|
+ initChart();
|
|
|
|
+});
|
|
|
|
|
|
onBeforeUnmount(() => {
|
|
onBeforeUnmount(() => {
|
|
- emitter.all.clear()
|
|
|
|
-})
|
|
|
|
|
|
+ emitter.all.clear();
|
|
|
|
+});
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<template>
|
|
<template>
|
|
<div class="out-container" v-loading="loading">
|
|
<div class="out-container" v-loading="loading">
|
|
<el-scrollbar>
|
|
<el-scrollbar>
|
|
- <div class="scrollbar-flex-content">
|
|
|
|
|
|
+ <div class="scrollbar-flex-content" v-show="cardData">
|
|
<el-card
|
|
<el-card
|
|
v-for="(item, index) in cardData"
|
|
v-for="(item, index) in cardData"
|
|
:key="item.productlineId"
|
|
:key="item.productlineId"
|
|
|
|
+ shadow="hover"
|
|
body-style="padding: 0;box-sizing: border-box; position: relative; width: 100%;"
|
|
body-style="padding: 0;box-sizing: border-box; position: relative; width: 100%;"
|
|
class="scrollbar-demo-item"
|
|
class="scrollbar-demo-item"
|
|
:class="{ selected: selectedCardIndex === index }"
|
|
:class="{ selected: selectedCardIndex === index }"
|
|
@@ -156,7 +157,9 @@ onBeforeUnmount(() => {
|
|
<div class="pct-chart" :id="`chart${index}-${item.productlineId}`"></div>
|
|
<div class="pct-chart" :id="`chart${index}-${item.productlineId}`"></div>
|
|
<el-popover v-if="index !== 0" placement="bottom" :width="150" trigger="click">
|
|
<el-popover v-if="index !== 0" placement="bottom" :width="150" trigger="click">
|
|
<template #reference>
|
|
<template #reference>
|
|
- <el-icon class="custom-icon" @click.stop=""><Setting /></el-icon>
|
|
|
|
|
|
+ <el-icon class="custom-icon" @click.stop="">
|
|
|
|
+ <Setting />
|
|
|
|
+ </el-icon>
|
|
</template>
|
|
</template>
|
|
<div class="custom-popoer">
|
|
<div class="custom-popoer">
|
|
<el-button :icon="Edit" text size="small" @click="editCard(item)">编辑</el-button>
|
|
<el-button :icon="Edit" text size="small" @click="editCard(item)">编辑</el-button>
|
|
@@ -173,6 +176,16 @@ onBeforeUnmount(() => {
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</el-card>
|
|
</div>
|
|
</div>
|
|
|
|
+ <el-card
|
|
|
|
+ shadow="hover"
|
|
|
|
+ body-style="padding: 0;box-sizing: border-box; position: relative; width: 100%;"
|
|
|
|
+ class="scrollbar-demo-item">
|
|
|
|
+ <el-empty description=" ">
|
|
|
|
+ <template #image>
|
|
|
|
+ <div style="color: #919398">暂无数据</div>
|
|
|
|
+ </template>
|
|
|
|
+ </el-empty>
|
|
|
|
+ </el-card>
|
|
</el-scrollbar>
|
|
</el-scrollbar>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
@@ -182,21 +195,25 @@ onBeforeUnmount(() => {
|
|
width: 100%;
|
|
width: 100%;
|
|
padding: 5px 12px 0 12px;
|
|
padding: 5px 12px 0 12px;
|
|
}
|
|
}
|
|
|
|
+
|
|
.scrollbar-flex-content {
|
|
.scrollbar-flex-content {
|
|
display: flex;
|
|
display: flex;
|
|
}
|
|
}
|
|
|
|
+
|
|
.scrollbar-demo-item {
|
|
.scrollbar-demo-item {
|
|
flex-shrink: 0;
|
|
flex-shrink: 0;
|
|
display: flex;
|
|
display: flex;
|
|
|
|
+ gap: 5px;
|
|
width: 202px;
|
|
width: 202px;
|
|
height: 92px;
|
|
height: 92px;
|
|
- margin: 10px 5px;
|
|
|
|
|
|
+ margin: 10px 0;
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
border: 1px solid transparent; /* 添加透明边框 */
|
|
border: 1px solid transparent; /* 添加透明边框 */
|
|
transition: border-color 0.3s; /* 可选,使边框颜色改变更平滑 */
|
|
transition: border-color 0.3s; /* 可选,使边框颜色改变更平滑 */
|
|
cursor: pointer;
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
|
|
+
|
|
.product-line-name {
|
|
.product-line-name {
|
|
position: relative;
|
|
position: relative;
|
|
padding: 0 12px 8px 0;
|
|
padding: 0 12px 8px 0;
|
|
@@ -208,19 +225,23 @@ onBeforeUnmount(() => {
|
|
white-space: nowrap;
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
text-overflow: ellipsis;
|
|
}
|
|
}
|
|
|
|
+
|
|
.custom-part {
|
|
.custom-part {
|
|
padding-top: 8px;
|
|
padding-top: 8px;
|
|
}
|
|
}
|
|
|
|
+
|
|
.total-sales {
|
|
.total-sales {
|
|
color: #4e5969;
|
|
color: #4e5969;
|
|
font-size: 13px;
|
|
font-size: 13px;
|
|
font-weight: 700;
|
|
font-weight: 700;
|
|
}
|
|
}
|
|
|
|
+
|
|
.label {
|
|
.label {
|
|
padding-right: 4px;
|
|
padding-right: 4px;
|
|
color: #c9cdd4;
|
|
color: #c9cdd4;
|
|
font-size: 12px;
|
|
font-size: 12px;
|
|
}
|
|
}
|
|
|
|
+
|
|
.pct-chart {
|
|
.pct-chart {
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
position: absolute;
|
|
position: absolute;
|
|
@@ -229,9 +250,11 @@ onBeforeUnmount(() => {
|
|
width: 50px;
|
|
width: 50px;
|
|
height: 50px;
|
|
height: 50px;
|
|
}
|
|
}
|
|
|
|
+
|
|
.selected {
|
|
.selected {
|
|
border: 1px solid #3359b5;
|
|
border: 1px solid #3359b5;
|
|
}
|
|
}
|
|
|
|
+
|
|
.custom-icon {
|
|
.custom-icon {
|
|
position: absolute;
|
|
position: absolute;
|
|
top: 8px;
|
|
top: 8px;
|
|
@@ -241,10 +264,12 @@ onBeforeUnmount(() => {
|
|
/* padding: 4px; */
|
|
/* padding: 4px; */
|
|
transform: rotate(90deg);
|
|
transform: rotate(90deg);
|
|
}
|
|
}
|
|
|
|
+
|
|
.custom-popoer {
|
|
.custom-popoer {
|
|
display: flex;
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
}
|
|
}
|
|
|
|
+
|
|
.left-part-container {
|
|
.left-part-container {
|
|
padding: 10px;
|
|
padding: 10px;
|
|
position: relative;
|
|
position: relative;
|