2025-05-18
This commit is contained in:
+1
-1
@@ -1,2 +1,2 @@
|
||||
VUE_APP_NAME=Ele Admin
|
||||
VUE_APP_NAME=后台管理
|
||||
VUE_APP_API_BASE_URL=https://v2.eleadmin.com/api
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
export default {
|
||||
name: 'CarModelSelector',
|
||||
props: {
|
||||
modelValue: {
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
brandId: null,
|
||||
@@ -80,11 +80,7 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
brandId: null,
|
||||
seriesId: null,
|
||||
modelId: null
|
||||
},
|
||||
form: { ...this.value }, // 初始化时深拷贝value,
|
||||
brandList: [],
|
||||
seriesList: [],
|
||||
modelList: [],
|
||||
@@ -94,43 +90,22 @@
|
||||
brandFilter: ''
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
modelValue: {
|
||||
deep: true,
|
||||
handler(newVal) {
|
||||
console.log(newVal);
|
||||
this.form = { ...newVal };
|
||||
this.syncFormWithProps();
|
||||
}
|
||||
},
|
||||
'$props.modelValue': {
|
||||
handler() {
|
||||
this.syncFormWithProps();
|
||||
}
|
||||
},
|
||||
'form.brandId'(val) {
|
||||
this.emitValue();
|
||||
if (!val) {
|
||||
this.seriesList = [];
|
||||
this.modelList = [];
|
||||
this.form.seriesId = null;
|
||||
this.form.modelId = null;
|
||||
}
|
||||
},
|
||||
'form.seriesId'(val) {
|
||||
this.emitValue();
|
||||
if (!val) this.modelList = this.form.modelId = null;
|
||||
},
|
||||
'form.modelId': {
|
||||
handler() {
|
||||
this.emitValue();
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadBrands();
|
||||
this.syncFormWithProps();
|
||||
if (this.form.brandId) {
|
||||
this.loadSeriesList(this.form.brandId);
|
||||
}
|
||||
if (this.form.seriesId) {
|
||||
this.loadModelList(this.form.seriesId);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
deep: true,
|
||||
handler(newVal) {
|
||||
this.form = { ...newVal }; // 外部值变化时更新内部form
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async loadBrands(filter = '') {
|
||||
@@ -138,6 +113,8 @@
|
||||
try {
|
||||
const res = await pageBrand({ nameLike: filter });
|
||||
this.brandList = res;
|
||||
this.seriesList = [];
|
||||
this.modelList = [];
|
||||
} catch (error) {
|
||||
this.$message.error('品牌加载失败');
|
||||
} finally {
|
||||
@@ -150,7 +127,7 @@
|
||||
try {
|
||||
const res = await pageSeries({ brandId });
|
||||
this.seriesList = res;
|
||||
this.form.seriesId = null;
|
||||
this.modelList = [];
|
||||
} catch (error) {
|
||||
this.$message.error('车系加载失败');
|
||||
} finally {
|
||||
@@ -163,7 +140,6 @@
|
||||
try {
|
||||
const res = await pageAutoCar({ seriesId });
|
||||
this.modelList = res;
|
||||
this.form.modelId = null;
|
||||
} catch (error) {
|
||||
this.$message.error('车型加载失败');
|
||||
} finally {
|
||||
@@ -172,41 +148,46 @@
|
||||
},
|
||||
|
||||
handleBrandChange(brandId) {
|
||||
if (brandId) this.loadSeriesList(brandId);
|
||||
if (brandId) {
|
||||
this.form.seriesId = null;
|
||||
this.loadSeriesList(brandId);
|
||||
}
|
||||
this.emitValue();
|
||||
},
|
||||
|
||||
handleSeriesChange(seriesId) {
|
||||
if (seriesId) this.loadModelList(seriesId);
|
||||
if (seriesId) {
|
||||
this.form.modelId = null;
|
||||
this.loadModelList(seriesId);
|
||||
}
|
||||
this.emitValue();
|
||||
},
|
||||
handleModelChange() {
|
||||
this.emitValue();
|
||||
},
|
||||
handleModelChange() {},
|
||||
handleBrandFilter(filter) {
|
||||
this.brandFilter = filter;
|
||||
this.loadBrands(filter);
|
||||
},
|
||||
|
||||
emitValue() {
|
||||
this.$emit('update:modelValue', {
|
||||
brandId: this.form.brandId,
|
||||
seriesId: this.form.seriesId,
|
||||
modelId: this.form.modelId
|
||||
});
|
||||
this.$emit('input', { ...this.form });
|
||||
},
|
||||
|
||||
syncFormWithProps() {
|
||||
// 重置所有数据
|
||||
this.brandList = [];
|
||||
this.seriesList = [];
|
||||
this.modelList = [];
|
||||
|
||||
const { brandId, seriesId, modelId } = this.modelValue;
|
||||
this.form = { brandId, seriesId, modelId };
|
||||
|
||||
if (brandId) {
|
||||
this.loadSeriesList(brandId);
|
||||
if (seriesId) {
|
||||
this.loadModelList(seriesId);
|
||||
}
|
||||
}
|
||||
// this.brandList = [];
|
||||
// this.seriesList = [];
|
||||
// this.modelList = [];
|
||||
//
|
||||
// const { brandId, seriesId, modelId } = this.modelValue;
|
||||
// this.form = { brandId, seriesId, modelId };
|
||||
//
|
||||
// if (brandId) {
|
||||
// this.loadSeriesList(brandId);
|
||||
// if (seriesId) {
|
||||
// this.loadModelList(seriesId);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -165,6 +165,29 @@
|
||||
v-model="form.descript"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="推广文案:">
|
||||
<div
|
||||
style="margin: 8px 0"
|
||||
v-for="(item, index) in form.promotion_text"
|
||||
:key="index"
|
||||
>
|
||||
<el-input
|
||||
clearable
|
||||
:maxlength="60"
|
||||
v-model="form.promotion_text[index]"
|
||||
placeholder="请输入推广文案"
|
||||
/>
|
||||
</div>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
size="small"
|
||||
icon="el-icon-plus"
|
||||
@click="addShareTitle"
|
||||
>
|
||||
新增推广文案
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template v-slot:footer>
|
||||
<el-button @click="updateVisible(false)">取消</el-button>
|
||||
@@ -301,6 +324,10 @@
|
||||
/* 更新visible */
|
||||
updateVisible(value) {
|
||||
this.$emit('update:visible', value);
|
||||
},
|
||||
/* 添加海报描述 */
|
||||
addShareTitle() {
|
||||
this.form.promotion_text.push('');
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -313,6 +340,9 @@
|
||||
...this.data
|
||||
});
|
||||
this.isUpdate = true;
|
||||
if (this.form.promotion_text.length <= 0) {
|
||||
this.addShareTitle();
|
||||
}
|
||||
} else {
|
||||
this.form.imgs = [];
|
||||
this.isUpdate = false;
|
||||
@@ -325,7 +355,7 @@
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
<style lang="scss" scoped>
|
||||
.ele-image-upload-list .ele-image-upload-item {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
<el-col :md="24" :sm="24">
|
||||
<car-model-selector
|
||||
type="brandSeries"
|
||||
v-model="this.where.selectedCar"
|
||||
@update:modelValue="handleCarChange"
|
||||
v-model="where.selectedCar"
|
||||
:key="componentKey"
|
||||
/>
|
||||
</el-col>
|
||||
@@ -67,11 +66,10 @@
|
||||
</template>
|
||||
<!-- 状态列 -->
|
||||
<template v-slot:title="{ row }">
|
||||
<el-image
|
||||
style="width: 80px; height: 80px"
|
||||
:src="row.imgs[0]['url']"
|
||||
></el-image>
|
||||
{{ row.title }}
|
||||
<div class="cell-content">
|
||||
<el-image :src="row.imgs[0]['url']" class="table-image" />
|
||||
<span class="table-text">{{ row.title }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:status="{ row }">
|
||||
<el-switch
|
||||
@@ -296,3 +294,18 @@
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.cell-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.table-image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.table-text {
|
||||
/* 文本样式 */
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="热门搜索">
|
||||
<v-chart
|
||||
ref="hotSearchChart"
|
||||
style="height: 303px"
|
||||
:option="hotSearchChartOption"
|
||||
/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { TooltipComponent } from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import 'echarts-wordcloud';
|
||||
import { wordCloudColor } from 'ele-admin';
|
||||
import { getWordCloudList } from '@/api/dashboard/analysis';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
|
||||
use([CanvasRenderer, TooltipComponent]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
mixins: [echartsMixin(['hotSearchChart'])],
|
||||
data() {
|
||||
return {
|
||||
// 词云图表配置
|
||||
hotSearchChartOption: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getWordCloudData();
|
||||
},
|
||||
methods: {
|
||||
/* 获取词云数据 */
|
||||
getWordCloudData() {
|
||||
getWordCloudList()
|
||||
.then((data) => {
|
||||
this.hotSearchChartOption = {
|
||||
tooltip: {
|
||||
show: true,
|
||||
confine: true,
|
||||
borderWidth: 1
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'wordCloud',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
sizeRange: [12, 24],
|
||||
gridSize: 6,
|
||||
textStyle: {
|
||||
color: wordCloudColor
|
||||
},
|
||||
emphasis: {
|
||||
textStyle: {
|
||||
shadowBlur: 8,
|
||||
shadowColor: 'rgba(0, 0, 0, .15)'
|
||||
}
|
||||
},
|
||||
data: data
|
||||
}
|
||||
]
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,119 @@
|
||||
<!-- 用户信息 -->
|
||||
<template>
|
||||
<el-card shadow="never" body-style="padding: 20px;">
|
||||
<div
|
||||
:class="[
|
||||
'ele-cell',
|
||||
'workplace-user-card',
|
||||
{ 'workplace-user-responsive': styleResponsive }
|
||||
]"
|
||||
>
|
||||
<div class="ele-cell-content ele-cell">
|
||||
<!--
|
||||
<el-avatar :size="68" :src="loginUser.avatar" />
|
||||
-->
|
||||
<div class="ele-cell-content">
|
||||
<h4 class="ele-elip"> Hi, {{ loginUser.nickname }} , 您好! </h4>
|
||||
<!--
|
||||
<div class="ele-text-secondary ele-elip" style="margin-top: 8px">
|
||||
<i class="el-icon-heavy-rain"></i>
|
||||
<em>今日阴转小雨, 22℃ - 32℃ , 出门记得带伞哦。</em>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
<div class="workplace-count-group">
|
||||
<div class="workplace-count-item">
|
||||
<div class="workplace-count-header">
|
||||
<el-tag size="small" class="ele-tag-round">
|
||||
<i class="el-icon-menu"></i>
|
||||
</el-tag>
|
||||
<span class="workplace-count-name">项目数</span>
|
||||
</div>
|
||||
<div class="workplace-count-num ele-text-heading">3</div>
|
||||
</div>
|
||||
<div class="workplace-count-item">
|
||||
<div class="workplace-count-header">
|
||||
<el-tag type="warning" size="small" class="ele-tag-round">
|
||||
<i class="el-icon-finished"></i>
|
||||
</el-tag>
|
||||
<span class="workplace-count-name">待办项</span>
|
||||
</div>
|
||||
<div class="workplace-count-num ele-text-heading">6 / 24</div>
|
||||
</div>
|
||||
<div class="workplace-count-item">
|
||||
<div class="workplace-count-header">
|
||||
<el-tag type="success" size="small" class="ele-tag-round">
|
||||
<i class="el-icon-bell"></i>
|
||||
</el-tag>
|
||||
<span class="workplace-count-name">消息</span>
|
||||
</div>
|
||||
<div class="workplace-count-num ele-text-heading">1,689</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
computed: {
|
||||
// 当前登录用户信息
|
||||
loginUser() {
|
||||
return this.$store.state.user.info;
|
||||
},
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.workplace-user-card {
|
||||
.ele-cell-content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.workplace-count-group {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.workplace-count-item {
|
||||
padding: 0 5px 0 25px;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.workplace-count-name {
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.workplace-count-num {
|
||||
font-size: 24px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 992px) {
|
||||
.workplace-user-responsive .workplace-count-item {
|
||||
padding: 0 5px 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.workplace-user-responsive.workplace-user-card {
|
||||
display: block;
|
||||
|
||||
.workplace-count-group {
|
||||
display: block;
|
||||
margin-top: 15px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,210 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" body-style="padding: 0;">
|
||||
<div class="ele-cell demo-monitor-tool">
|
||||
<div class="ele-cell-content">
|
||||
<el-tabs
|
||||
v-model="saleSearch.type"
|
||||
class="demo-monitor-tabs"
|
||||
@tab-click="onSaleTypeChange"
|
||||
>
|
||||
<el-tab-pane label="销售额" name="saleroom" />
|
||||
<el-tab-pane label="访问量" name="visits" />
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div :class="['ele-inline-block', { 'hidden-xs-only': styleResponsive }]">
|
||||
<el-radio-group v-model="saleSearch.dateType" size="small">
|
||||
<el-radio-button :label="0">今天</el-radio-button>
|
||||
<el-radio-button :label="1">本周</el-radio-button>
|
||||
<el-radio-button :label="2">本月</el-radio-button>
|
||||
<el-radio-button :label="3">本年</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div
|
||||
:class="['ele-inline-block', { 'hidden-sm-and-down': styleResponsive }]"
|
||||
style="width: 260px; margin-left: 10px"
|
||||
>
|
||||
<el-date-picker
|
||||
unlink-panels
|
||||
type="daterange"
|
||||
class="ele-fluid"
|
||||
end-placeholder="结束日期"
|
||||
start-placeholder="开始日期"
|
||||
v-model="saleSearch.datetime"
|
||||
range-separator="至"
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<el-divider />
|
||||
<el-row>
|
||||
<el-col v-bind="styleResponsive ? { lg: 18, md: 16 } : { span: 18 }">
|
||||
<div class="demo-monitor-title">
|
||||
<span v-if="saleSearch.type === 'saleroom'">销售额趋势</span>
|
||||
<span v-else>访问量趋势</span>
|
||||
</div>
|
||||
<v-chart
|
||||
ref="saleChart"
|
||||
style="height: 285px"
|
||||
:option="saleChartOption"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 8 } : { span: 6 }">
|
||||
<div class="demo-monitor-title" style="display: flex">
|
||||
<div>门店</div>
|
||||
<div>
|
||||
<span v-if="saleSearch.type === 'saleroom'">销售额</span>
|
||||
<span v-else>访问量</span>
|
||||
</div>
|
||||
<div>排名</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(item, index) in saleroomRankData"
|
||||
:key="index"
|
||||
class="demo-monitor-rank-item ele-cell"
|
||||
style="margin-bottom: 15px"
|
||||
>
|
||||
<el-tag
|
||||
size="mini"
|
||||
type="info"
|
||||
:effect="index < 3 ? 'dark' : 'light'"
|
||||
:color="index < 3 ? '#314659' : 'hsla(0, 0%, 60%, .2)'"
|
||||
style="border-color: transparent"
|
||||
class="ele-tag-round"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
</el-tag>
|
||||
<div class="ele-cell-content">{{ item.name }}</div>
|
||||
<div class="ele-text-secondary">{{ item.value }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { BarChart } from 'echarts/charts';
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import { getSaleroomList } from '@/api/dashboard/analysis';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
|
||||
use([CanvasRenderer, BarChart, GridComponent, TooltipComponent]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
mixins: [echartsMixin(['saleChart'])],
|
||||
data() {
|
||||
return {
|
||||
// 销售量搜索参数
|
||||
saleSearch: {
|
||||
type: 'saleroom',
|
||||
dateType: 0,
|
||||
datetime: ''
|
||||
},
|
||||
// 销售量趋势数据
|
||||
saleroomData1: [],
|
||||
// 访问量趋势数据
|
||||
saleroomData2: [],
|
||||
// 门店排名数据
|
||||
saleroomRankData: [
|
||||
{ name: '工专路 1 号店', value: '323,234' },
|
||||
{ name: '工专路 2 号店', value: '323,234' },
|
||||
{ name: '工专路 3 号店', value: '323,234' },
|
||||
{ name: '工专路 4 号店', value: '323,234' },
|
||||
{ name: '工专路 5 号店', value: '323,234' },
|
||||
{ name: '工专路 6 号店', value: '323,234' },
|
||||
{ name: '工专路 7 号店', value: '323,234' }
|
||||
],
|
||||
// 销售额柱状图配置
|
||||
saleChartOption: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getSaleroomData();
|
||||
},
|
||||
methods: {
|
||||
/* 获取销售量数据 */
|
||||
getSaleroomData() {
|
||||
getSaleroomList()
|
||||
.then((data) => {
|
||||
this.saleroomData1 = data.list1;
|
||||
this.saleroomData2 = data.list2;
|
||||
this.onSaleTypeChange();
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
|
||||
/* 销售量tab选择改变事件 */
|
||||
onSaleTypeChange() {
|
||||
const isSale = this.saleSearch.type === 'saleroom';
|
||||
const data = isSale ? this.saleroomData1 : this.saleroomData2;
|
||||
this.saleChartOption = {
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: data.map((d) => d.month)
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
type: 'bar',
|
||||
data: data.map((d) => d.value)
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 销售额、访问量工具栏 */
|
||||
.demo-monitor-tool {
|
||||
padding: 0 20px;
|
||||
|
||||
.demo-monitor-tabs {
|
||||
height: 51px;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item) {
|
||||
height: 51px;
|
||||
line-height: 51px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__nav-wrap:after) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* 小标题 */
|
||||
.demo-monitor-title {
|
||||
padding: 0 20px;
|
||||
margin: 15px 0 5px 0;
|
||||
}
|
||||
|
||||
/* 排名 item */
|
||||
.demo-monitor-rank-item {
|
||||
padding: 0 20px;
|
||||
line-height: 20px;
|
||||
margin-top: 18px;
|
||||
}
|
||||
</style>
|
||||
@@ -5,99 +5,33 @@
|
||||
<el-card class="analysis-chart-card" shadow="never">
|
||||
<template v-slot:header>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">总销售额</div>
|
||||
<el-tooltip content="指标说明" placement="top">
|
||||
<i
|
||||
class="el-icon-_question ele-text-placeholder"
|
||||
style="cursor: pointer"
|
||||
>
|
||||
</i>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<div class="analysis-chart-card-num ele-text-heading">¥ 126,560</div>
|
||||
<div class="analysis-chart-card-content" style="padding-top: 18px">
|
||||
<span class="ele-action">
|
||||
<span>周同比12%</span>
|
||||
<i class="el-icon-caret-top ele-text-danger"></i>
|
||||
</span>
|
||||
<span class="ele-action">
|
||||
<span>日同比11%</span>
|
||||
<i class="el-icon-caret-bottom ele-text-success"></i>
|
||||
</span>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div class="analysis-chart-card-text">日销售额 ¥12,423</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
|
||||
<el-card class="analysis-chart-card" shadow="never">
|
||||
<template v-slot:header>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">访问量</div>
|
||||
<div class="ele-cell-content">今日新增线索</div>
|
||||
<el-tag size="mini" type="danger">日</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
<div class="analysis-chart-card-num ele-text-heading">8,846</div>
|
||||
<div class="analysis-chart-card-content">
|
||||
<v-chart
|
||||
ref="visitChart"
|
||||
style="height: 40px"
|
||||
:option="visitChartOption"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="analysis-chart-card-num ele-text-heading"
|
||||
style="margin-bottom: 10px"
|
||||
>101条</div
|
||||
>
|
||||
<el-divider />
|
||||
<div class="analysis-chart-card-text">日访问量 1,234</div>
|
||||
<div class="analysis-chart-card-text">累计线索:100000条</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
|
||||
<el-card class="analysis-chart-card" shadow="never">
|
||||
<template v-slot:header>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">支付笔数</div>
|
||||
<el-tag size="mini">月</el-tag>
|
||||
<div class="ele-cell-content">当前团队成员</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="analysis-chart-card-num ele-text-heading">6,560</div>
|
||||
<div class="analysis-chart-card-content">
|
||||
<v-chart
|
||||
ref="payNumChart"
|
||||
style="height: 40px"
|
||||
:option="payNumChartOption"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="analysis-chart-card-num ele-text-heading"
|
||||
style="margin-bottom: 10px"
|
||||
>2323人</div
|
||||
>
|
||||
<el-divider />
|
||||
<div class="analysis-chart-card-text">转化率 60%</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
|
||||
<el-card class="analysis-chart-card" shadow="never">
|
||||
<template v-slot:header>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">运营活动效果</div>
|
||||
<el-tag size="mini" type="success">周</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
<div class="analysis-chart-card-num ele-text-heading">78%</div>
|
||||
<div class="analysis-chart-card-content" style="padding-top: 25px">
|
||||
<el-progress
|
||||
:percentage="78"
|
||||
:show-text="false"
|
||||
:stroke-width="10"
|
||||
color="#13c2c2"
|
||||
/>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div class="analysis-chart-card-text">
|
||||
<span class="ele-action">
|
||||
<span>周同比12%</span>
|
||||
<i class="el-icon-caret-top ele-text-danger"></i>
|
||||
</span>
|
||||
<span class="ele-action">
|
||||
<span>日同比11%</span>
|
||||
<i class="el-icon-caret-bottom ele-text-success"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="analysis-chart-card-text">历史成交:100000单</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -108,14 +42,13 @@
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { LineChart, BarChart } from 'echarts/charts';
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import { getPayNumList } from '@/api/dashboard/analysis';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
|
||||
use([CanvasRenderer, LineChart, BarChart, GridComponent, TooltipComponent]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
components: {},
|
||||
mixins: [echartsMixin(['visitChart', 'payNumChart'])],
|
||||
data() {
|
||||
return {
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
<template>
|
||||
<el-card
|
||||
shadow="never"
|
||||
header="最近1小时访问情况"
|
||||
body-style="padding: 14px 5px 0 0;"
|
||||
>
|
||||
<v-chart
|
||||
ref="visitHourChart"
|
||||
style="height: 323px"
|
||||
:option="visitHourChartOption"
|
||||
/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { LineChart } from 'echarts/charts';
|
||||
import {
|
||||
GridComponent,
|
||||
TooltipComponent,
|
||||
LegendComponent
|
||||
} from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import { getVisitHourList } from '@/api/dashboard/analysis';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
|
||||
use([
|
||||
CanvasRenderer,
|
||||
LineChart,
|
||||
GridComponent,
|
||||
TooltipComponent,
|
||||
LegendComponent
|
||||
]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
mixins: [echartsMixin(['visitHourChart'])],
|
||||
data() {
|
||||
return {
|
||||
// 最近1小时访问情况折线图配置
|
||||
visitHourChartOption: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getVisitHourData();
|
||||
},
|
||||
methods: {
|
||||
/* 获取最近1小时访问情况数据 */
|
||||
getVisitHourData() {
|
||||
getVisitHourList()
|
||||
.then((data) => {
|
||||
this.visitHourChartOption = {
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
data: ['浏览量', '访问量'],
|
||||
right: 20
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: data.map((d) => d.time)
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '浏览量',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
areaStyle: {
|
||||
opacity: 0.5
|
||||
},
|
||||
data: data.map((d) => d.views)
|
||||
},
|
||||
{
|
||||
name: '访问量',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
areaStyle: {
|
||||
opacity: 0.5
|
||||
},
|
||||
data: data.map((d) => d.visits)
|
||||
}
|
||||
]
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,37 +1,33 @@
|
||||
<template>
|
||||
<div class="ele-body ele-body-card">
|
||||
<profile-card />
|
||||
<statistics-card />
|
||||
<sale-card />
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { lg: 18, md: 16 } : { span: 18 }">
|
||||
<visit-hour />
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 8 } : { span: 6 }">
|
||||
<hot-search />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProfileCard from './components/profile-card.vue';
|
||||
import StatisticsCard from './components/statistics-card.vue';
|
||||
import SaleCard from './components/sale-card.vue';
|
||||
import VisitHour from './components/visit-hour.vue';
|
||||
import HotSearch from './components/hot-search.vue';
|
||||
|
||||
export default {
|
||||
name: 'HomeAnalysis',
|
||||
name: 'DashboardWorkplace',
|
||||
components: {
|
||||
StatisticsCard,
|
||||
SaleCard,
|
||||
VisitHour,
|
||||
HotSearch
|
||||
ProfileCard,
|
||||
StatisticsCard
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
data: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
export async function pageBrand(params) {
|
||||
const res = await request.get('/common/autoBrand', {
|
||||
params
|
||||
});
|
||||
return res.data;
|
||||
}
|
||||
|
||||
export async function pageSeries(params) {
|
||||
const res = await request.get('/common/autoSeries', {
|
||||
params
|
||||
});
|
||||
return res.data;
|
||||
}
|
||||
|
||||
export async function pageAutoCar(params) {
|
||||
const res = await request.get('/common/autoCar', {
|
||||
params
|
||||
});
|
||||
return res.data;
|
||||
}
|
||||
@@ -60,3 +60,16 @@ export async function removeProduct(ids) {
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id 产品id
|
||||
*/
|
||||
export async function getProduct(id) {
|
||||
const res = await request.get('/car/product/', {
|
||||
id: id
|
||||
});
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<div class="car-model-selector">
|
||||
<el-form-item label="品牌">
|
||||
<el-select
|
||||
v-model="form.brandId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请输入品牌名称搜索"
|
||||
:loading="brandLoading"
|
||||
@change="handleBrandChange"
|
||||
@filter-change="handleBrandFilter"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in brandList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
<template v-if="type !== 'brand'">
|
||||
-
|
||||
<el-select
|
||||
v-model="form.seriesId"
|
||||
placeholder="请选择车系"
|
||||
clearable
|
||||
:disabled="!form.brandId"
|
||||
:loading="seriesLoading"
|
||||
@change="handleSeriesChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in seriesList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-if="!type">
|
||||
-
|
||||
<el-select
|
||||
v-model="form.modelId"
|
||||
placeholder="请选择车型"
|
||||
clearable
|
||||
:disabled="!form.seriesId"
|
||||
:loading="modelLoading"
|
||||
@change="handleModelChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in modelList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { pageBrand, pageSeries, pageAutoCar } from '@/api/auto';
|
||||
|
||||
export default {
|
||||
name: 'CarModelSelector',
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
brandId: null,
|
||||
seriesId: null,
|
||||
modelId: null
|
||||
})
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
validator: (type) => {
|
||||
return !type || ['brandSeries', 'brand'].includes(type);
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: { ...this.value }, // 初始化时深拷贝value,
|
||||
brandList: [],
|
||||
seriesList: [],
|
||||
modelList: [],
|
||||
brandLoading: false,
|
||||
seriesLoading: false,
|
||||
modelLoading: false,
|
||||
brandFilter: ''
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.loadBrands();
|
||||
if (this.form.brandId) {
|
||||
this.loadSeriesList(this.form.brandId);
|
||||
}
|
||||
if (this.form.seriesId) {
|
||||
this.loadModelList(this.form.seriesId);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
deep: true,
|
||||
handler(newVal) {
|
||||
this.form = { ...newVal }; // 外部值变化时更新内部form
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async loadBrands(filter = '') {
|
||||
this.brandLoading = true;
|
||||
try {
|
||||
const res = await pageBrand({ nameLike: filter });
|
||||
this.brandList = res;
|
||||
this.seriesList = [];
|
||||
this.modelList = [];
|
||||
} catch (error) {
|
||||
this.$message.error('品牌加载失败');
|
||||
} finally {
|
||||
this.brandLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
async loadSeriesList(brandId) {
|
||||
this.seriesLoading = true;
|
||||
try {
|
||||
const res = await pageSeries({ brandId });
|
||||
this.seriesList = res;
|
||||
this.modelList = [];
|
||||
} catch (error) {
|
||||
this.$message.error('车系加载失败');
|
||||
} finally {
|
||||
this.seriesLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
async loadModelList(seriesId) {
|
||||
this.modelLoading = true;
|
||||
try {
|
||||
const res = await pageAutoCar({ seriesId });
|
||||
this.modelList = res;
|
||||
} catch (error) {
|
||||
this.$message.error('车型加载失败');
|
||||
} finally {
|
||||
this.modelLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
handleBrandChange(brandId) {
|
||||
if (brandId) {
|
||||
this.form.seriesId = null;
|
||||
this.loadSeriesList(brandId);
|
||||
}
|
||||
this.emitValue();
|
||||
},
|
||||
|
||||
handleSeriesChange(seriesId) {
|
||||
if (seriesId) {
|
||||
this.form.modelId = null;
|
||||
this.loadModelList(seriesId);
|
||||
}
|
||||
this.emitValue();
|
||||
},
|
||||
handleModelChange() {
|
||||
this.emitValue();
|
||||
},
|
||||
handleBrandFilter(filter) {
|
||||
this.brandFilter = filter;
|
||||
this.loadBrands(filter);
|
||||
},
|
||||
emitValue() {
|
||||
this.$emit('input', { ...this.form });
|
||||
},
|
||||
|
||||
syncFormWithProps() {
|
||||
// 重置所有数据
|
||||
// this.brandList = [];
|
||||
// this.seriesList = [];
|
||||
// this.modelList = [];
|
||||
//
|
||||
// const { brandId, seriesId, modelId } = this.modelValue;
|
||||
// this.form = { brandId, seriesId, modelId };
|
||||
//
|
||||
// if (brandId) {
|
||||
// this.loadSeriesList(brandId);
|
||||
// if (seriesId) {
|
||||
// this.loadModelList(seriesId);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -7,10 +7,10 @@ export default {
|
||||
logout: '退出登录'
|
||||
},
|
||||
footer: {
|
||||
website: '官网',
|
||||
document: '文档',
|
||||
authorization: '授权',
|
||||
copyright: 'Copyright © 2022 武汉易云智科技有限公司'
|
||||
website: '',
|
||||
document: '',
|
||||
authorization: '',
|
||||
copyright: 'Copyright © 2022 好店云(厦门)科技有限公司'
|
||||
},
|
||||
logout: {
|
||||
title: '提示',
|
||||
|
||||
@@ -50,7 +50,9 @@
|
||||
<i class="el-icon-_more"></i>
|
||||
</div>
|
||||
<!-- 修改密码弹窗 -->
|
||||
<!--
|
||||
<password-modal :visible.sync="passwordVisible" />
|
||||
-->
|
||||
<!-- 主题设置抽屉 -->
|
||||
<setting-drawer :visible.sync="settingVisible" />
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div class="ele-body ele-body-card">
|
||||
<el-card shadow="never pd10">
|
||||
<el-row class="pd10">
|
||||
<el-col :span="24"><h2>概况</h2></el-col>
|
||||
</el-row>
|
||||
<el-row class="pd10">
|
||||
<el-col :span="6">品牌</el-col>
|
||||
<el-col :span="6">车型</el-col>
|
||||
<el-col :span="6">官方售价</el-col>
|
||||
<el-col :span="6"></el-col>
|
||||
</el-row>
|
||||
<el-row class="pd10">
|
||||
<el-col :span="24"><h2>优惠</h2></el-col>
|
||||
</el-row>
|
||||
<el-row class="pd10">
|
||||
<el-col :span="6">置换补贴</el-col>
|
||||
<el-col :span="6">报废补贴</el-col>
|
||||
<el-col :span="6">优惠金额</el-col>
|
||||
<el-col :span="6"></el-col>
|
||||
</el-row>
|
||||
<el-row class="pd10">
|
||||
<el-col :span="24"><h2>客户画像</h2></el-col>
|
||||
</el-row>
|
||||
<el-row class="pd10">
|
||||
<el-col :span="6">男性占比</el-col>
|
||||
<el-col :span="6">年龄区间</el-col>
|
||||
<el-col :span="6">人群标签</el-col>
|
||||
<el-col :span="6"></el-col>
|
||||
</el-row>
|
||||
<el-row class="pd10">
|
||||
<el-col :span="24"><h2>车型卖点</h2></el-col>
|
||||
</el-row>
|
||||
<el-row class="pd10">
|
||||
<el-col :span="24">范围访问量附件为冷风机微辣</el-col>
|
||||
</el-row>
|
||||
<el-row class="pd10">
|
||||
<el-col :span="24"><h2>推广文案</h2></el-col>
|
||||
</el-row>
|
||||
<el-row class="pd10">
|
||||
<el-col :span="20">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
value="呢哦if我饿了覅就为了"
|
||||
></el-input>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-button style="margin-left: 5px" type="primary" size="small"
|
||||
>复制</el-button
|
||||
>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row class="pd10">
|
||||
<el-col :span="24"><h2>购车链接</h2></el-col>
|
||||
</el-row>
|
||||
<el-row class="pd10">
|
||||
<el-col :span="20">
|
||||
<el-input value="呢哦if我饿了覅就为了"></el-input
|
||||
></el-col>
|
||||
<el-col :span="4">
|
||||
<el-button style="margin-left: 5px" type="primary" size="small"
|
||||
>复制</el-button
|
||||
>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getProduct } from '@/api/car/product';
|
||||
const ROUTE_PATH = '/car/product/detail';
|
||||
export default {
|
||||
name: 'carProductDetail',
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
promotionText:
|
||||
'东风日产N7,官方售价11.99万起,现享10000元置换补贴和报废补贴,至高优惠10000元!适合都市白领家庭,25-40岁人群首选新能源车型。'
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
query() {
|
||||
const id = this.$route.params.id;
|
||||
if (!id || this.user.userId === Number(id)) {
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
getProduct(Number(id))
|
||||
.then((data) => {
|
||||
this.loading = false;
|
||||
this.$util.assignObject(this.user, {
|
||||
...data,
|
||||
createTime: this.$util.toDateString(data.createTime)
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route: {
|
||||
handler(route) {
|
||||
const { fullPath } = route;
|
||||
if (!fullPath.startsWith(ROUTE_PATH)) {
|
||||
return;
|
||||
}
|
||||
this.query();
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.pd10 {
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -13,6 +13,13 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :md="24" :sm="24">
|
||||
<car-model-selector
|
||||
type="brandSeries"
|
||||
v-model="where.selectedCar"
|
||||
:key="componentKey"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :md="6" :sm="12">
|
||||
<div class="ele-form-actions">
|
||||
<el-button
|
||||
@@ -37,87 +44,85 @@
|
||||
cache-key="syliveActivityTable"
|
||||
>
|
||||
<!-- 表头工具栏 -->
|
||||
<template v-slot:toolbar>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
icon="el-icon-plus"
|
||||
class="ele-btn-icon"
|
||||
@click="edit()"
|
||||
>
|
||||
新建
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="danger"
|
||||
icon="el-icon-delete"
|
||||
class="ele-btn-icon"
|
||||
@click="removeBatch"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-slot:toolbar> </template>
|
||||
<!-- 状态列 -->
|
||||
<template v-slot:title="{ row }">
|
||||
<div class="cell-content">
|
||||
<el-image :src="row.imgs[0]['url']" class="table-image" />
|
||||
<el-link
|
||||
type="primary"
|
||||
:underline="false"
|
||||
class="table-text"
|
||||
@click="goDetail(row)"
|
||||
>{{ row.title }}</el-link
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:price="{ row }">
|
||||
<div class="ele-text-danger">
|
||||
<div>L {{ row.firstLevelClues }}</div>
|
||||
<div>S {{ row.firstLevelDeal }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:timeBetween="{ row }">
|
||||
<div>{{ row.timeStart.split(' ')[0] }}~</div>
|
||||
<div>{{ row.timeEnd.split(' ')[0] }}</div>
|
||||
</template>
|
||||
<template v-slot:status="{ row }">
|
||||
<el-switch
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
v-model="row.status"
|
||||
@change="editStatus(row)"
|
||||
/>
|
||||
<span v-if="row.status" class="ele-text-success">已上架</span>
|
||||
<span v-else class="ele-text-danger">未上架</span>
|
||||
</template>
|
||||
<!-- 操作列 -->
|
||||
<template v-slot:action="{ row }">
|
||||
<el-link
|
||||
type="primary"
|
||||
:underline="false"
|
||||
@click="edit(row)"
|
||||
icon="el-icon-edit"
|
||||
@click="showPromotionText(row)"
|
||||
>
|
||||
修改
|
||||
文案
|
||||
</el-link>
|
||||
<el-popconfirm
|
||||
class="ele-action"
|
||||
title="确定要删除此数据吗?"
|
||||
@confirm="remove(row)"
|
||||
>
|
||||
<template v-slot:reference>
|
||||
<el-link type="danger" :underline="false" icon="el-icon-delete">
|
||||
删除
|
||||
</el-link>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<el-link type="primary" :underline="false"> 购车券 </el-link>
|
||||
<el-link type="primary" :underline="false"> 海报 </el-link>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
<!-- 推广文案 -->
|
||||
<el-dialog :visible.sync="showPromotion" title="推广文案" width="30%">
|
||||
<template v-if="current && current.promotion_text">
|
||||
<div v-for="(item, index) in current.promotion_text" :key="index">
|
||||
<el-input :value="item" type="textarea" :rows="3" />
|
||||
<div style="margin: 5px 0 5px 0; text-align: right">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
v-clipboard:copy="item"
|
||||
v-clipboard:success="onCopy"
|
||||
>复制</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
<!-- 编辑弹窗 -->
|
||||
<edit
|
||||
:data="current"
|
||||
:visible.sync="showEdit"
|
||||
:organization-list="organizationList"
|
||||
@done="reload"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
pageProduct,
|
||||
removeProduct,
|
||||
updateProductStatus
|
||||
} from '@/api/car/product';
|
||||
import edit from './components/edit.vue';
|
||||
import { pageProduct } from '@/api/car/product';
|
||||
import CarModelSelector from '@/components/CarSelector/index.vue';
|
||||
|
||||
export default {
|
||||
name: 'carProduct',
|
||||
components: { edit },
|
||||
components: { CarModelSelector },
|
||||
data() {
|
||||
return {
|
||||
where: {
|
||||
title: ''
|
||||
title: '',
|
||||
selectedCar: {
|
||||
brandId: '',
|
||||
seriesId: '',
|
||||
modelId: ''
|
||||
}
|
||||
},
|
||||
// 门店数据
|
||||
organizationList: [],
|
||||
// 表格列配置
|
||||
columns: [
|
||||
{
|
||||
@@ -127,17 +132,10 @@
|
||||
align: 'center',
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
prop: 'id',
|
||||
label: 'ID',
|
||||
minWidth: 40,
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
prop: 'title',
|
||||
label: '产品信息',
|
||||
slot: 'title',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 200
|
||||
},
|
||||
@@ -148,11 +146,11 @@
|
||||
minWidth: 80
|
||||
},
|
||||
{
|
||||
prop: 'timeLaunch',
|
||||
label: '上架时间',
|
||||
sortable: 'custom',
|
||||
prop: '',
|
||||
label: '佣金',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 100
|
||||
minWidth: 80,
|
||||
slot: 'price'
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
@@ -163,40 +161,46 @@
|
||||
slot: 'status',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'timeBetween',
|
||||
label: '推广周期',
|
||||
showOverflowTooltip: true,
|
||||
slot: 'timeBetween',
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
columnKey: 'action',
|
||||
label: '操作',
|
||||
width: 380,
|
||||
label: '推广',
|
||||
width: 150,
|
||||
align: 'center',
|
||||
resizable: false,
|
||||
slot: 'action'
|
||||
},
|
||||
{
|
||||
columnKey: '',
|
||||
label: '浏览数',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
resizable: false
|
||||
},
|
||||
{
|
||||
columnKey: '',
|
||||
label: '留资数',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
resizable: false
|
||||
}
|
||||
],
|
||||
// 表格选中数据
|
||||
selection: [],
|
||||
// 当前编辑数据
|
||||
current: null,
|
||||
// 是否显示编辑弹窗
|
||||
showEdit: false,
|
||||
// 是否显示编辑商品弹窗
|
||||
showEditItem: false,
|
||||
// 是否显示编辑券弹窗
|
||||
showEditCoupon: false,
|
||||
// 是否显示编辑券弹窗
|
||||
showEditDraw: false,
|
||||
showEditVisitTag: false,
|
||||
// 是否显示二维码弹窗
|
||||
showCode: false
|
||||
showPromotion: false,
|
||||
componentKey: ''
|
||||
};
|
||||
},
|
||||
created() {
|
||||
//this.organizationQuery();
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
edit(row) {
|
||||
this.current = row;
|
||||
this.showEdit = true;
|
||||
},
|
||||
/* 表格数据源 */
|
||||
datasource({ page, limit, where, order }) {
|
||||
return pageProduct({ ...where, ...order, page, limit });
|
||||
@@ -205,62 +209,49 @@
|
||||
reload() {
|
||||
this.$refs.table.reload({ page: 1, where: this.where });
|
||||
},
|
||||
/* 删除 */
|
||||
remove(row) {
|
||||
const loading = this.$loading({ lock: true });
|
||||
removeProduct(row.id)
|
||||
.then((msg) => {
|
||||
loading.close();
|
||||
this.$message.success(msg);
|
||||
this.reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 批量删除 */
|
||||
removeBatch() {
|
||||
if (!this.selection.length) {
|
||||
this.$message.error('请至少选择一条数据');
|
||||
return;
|
||||
}
|
||||
this.$confirm('确定要删除选中数据吗?', '提示', {
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
const loading = this.$loading({ lock: true });
|
||||
removeProduct(this.selection.map((d) => d.id))
|
||||
.then((msg) => {
|
||||
loading.close();
|
||||
this.$message.success(msg);
|
||||
this.reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
/* 更改状态 */
|
||||
editStatus(row) {
|
||||
const loading = this.$loading({ lock: true });
|
||||
updateProductStatus(row.id, row.status)
|
||||
.then((msg) => {
|
||||
loading.close();
|
||||
this.$message.success(msg);
|
||||
this.reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 重置搜索 */
|
||||
reset() {
|
||||
this.where = {};
|
||||
this.where = {
|
||||
selectedCar: {
|
||||
brandId: null,
|
||||
seriesId: null,
|
||||
modelId: null
|
||||
}
|
||||
};
|
||||
// 更新 key 强制组件重新渲染
|
||||
this.componentKey = Date.now();
|
||||
},
|
||||
showPromotionText(row) {
|
||||
this.current = row;
|
||||
this.showPromotion = true;
|
||||
},
|
||||
onCopy() {
|
||||
this.$message.success('复制成功!');
|
||||
},
|
||||
goDetail(row) {
|
||||
const path = '/car/product/detail';
|
||||
this.$nextTick(() => {
|
||||
this.$router.push({
|
||||
path,
|
||||
query: row ? { id: row.id } : undefined
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.cell-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.table-image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.table-text {
|
||||
/* 文本样式 */
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="热门搜索">
|
||||
<v-chart
|
||||
ref="hotSearchChart"
|
||||
style="height: 303px"
|
||||
:option="hotSearchChartOption"
|
||||
/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { TooltipComponent } from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import 'echarts-wordcloud';
|
||||
import { wordCloudColor } from 'ele-admin';
|
||||
import { getWordCloudList } from '@/api/dashboard/analysis';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
|
||||
use([CanvasRenderer, TooltipComponent]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
mixins: [echartsMixin(['hotSearchChart'])],
|
||||
data() {
|
||||
return {
|
||||
// 词云图表配置
|
||||
hotSearchChartOption: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getWordCloudData();
|
||||
},
|
||||
methods: {
|
||||
/* 获取词云数据 */
|
||||
getWordCloudData() {
|
||||
getWordCloudList()
|
||||
.then((data) => {
|
||||
this.hotSearchChartOption = {
|
||||
tooltip: {
|
||||
show: true,
|
||||
confine: true,
|
||||
borderWidth: 1
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'wordCloud',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
sizeRange: [12, 24],
|
||||
gridSize: 6,
|
||||
textStyle: {
|
||||
color: wordCloudColor
|
||||
},
|
||||
emphasis: {
|
||||
textStyle: {
|
||||
shadowBlur: 8,
|
||||
shadowColor: 'rgba(0, 0, 0, .15)'
|
||||
}
|
||||
},
|
||||
data: data
|
||||
}
|
||||
]
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,119 @@
|
||||
<!-- 用户信息 -->
|
||||
<template>
|
||||
<el-card shadow="never" body-style="padding: 20px;">
|
||||
<div
|
||||
:class="[
|
||||
'ele-cell',
|
||||
'workplace-user-card',
|
||||
{ 'workplace-user-responsive': styleResponsive }
|
||||
]"
|
||||
>
|
||||
<div class="ele-cell-content ele-cell">
|
||||
<!--
|
||||
<el-avatar :size="68" :src="loginUser.avatar" />
|
||||
-->
|
||||
<div class="ele-cell-content">
|
||||
<h4 class="ele-elip"> Hi, {{ loginUser.nickname }} , 您好! </h4>
|
||||
<!--
|
||||
<div class="ele-text-secondary ele-elip" style="margin-top: 8px">
|
||||
<i class="el-icon-heavy-rain"></i>
|
||||
<em>今日阴转小雨, 22℃ - 32℃ , 出门记得带伞哦。</em>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
<div class="workplace-count-group">
|
||||
<div class="workplace-count-item">
|
||||
<div class="workplace-count-header">
|
||||
<el-tag size="small" class="ele-tag-round">
|
||||
<i class="el-icon-menu"></i>
|
||||
</el-tag>
|
||||
<span class="workplace-count-name">项目数</span>
|
||||
</div>
|
||||
<div class="workplace-count-num ele-text-heading">3</div>
|
||||
</div>
|
||||
<div class="workplace-count-item">
|
||||
<div class="workplace-count-header">
|
||||
<el-tag type="warning" size="small" class="ele-tag-round">
|
||||
<i class="el-icon-finished"></i>
|
||||
</el-tag>
|
||||
<span class="workplace-count-name">待办项</span>
|
||||
</div>
|
||||
<div class="workplace-count-num ele-text-heading">6 / 24</div>
|
||||
</div>
|
||||
<div class="workplace-count-item">
|
||||
<div class="workplace-count-header">
|
||||
<el-tag type="success" size="small" class="ele-tag-round">
|
||||
<i class="el-icon-bell"></i>
|
||||
</el-tag>
|
||||
<span class="workplace-count-name">消息</span>
|
||||
</div>
|
||||
<div class="workplace-count-num ele-text-heading">1,689</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
computed: {
|
||||
// 当前登录用户信息
|
||||
loginUser() {
|
||||
return this.$store.state.user.info;
|
||||
},
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.workplace-user-card {
|
||||
.ele-cell-content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.workplace-count-group {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.workplace-count-item {
|
||||
padding: 0 5px 0 25px;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.workplace-count-name {
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.workplace-count-num {
|
||||
font-size: 24px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 992px) {
|
||||
.workplace-user-responsive .workplace-count-item {
|
||||
padding: 0 5px 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.workplace-user-responsive.workplace-user-card {
|
||||
display: block;
|
||||
|
||||
.workplace-count-group {
|
||||
display: block;
|
||||
margin-top: 15px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,210 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" body-style="padding: 0;">
|
||||
<div class="ele-cell demo-monitor-tool">
|
||||
<div class="ele-cell-content">
|
||||
<el-tabs
|
||||
v-model="saleSearch.type"
|
||||
class="demo-monitor-tabs"
|
||||
@tab-click="onSaleTypeChange"
|
||||
>
|
||||
<el-tab-pane label="销售额" name="saleroom" />
|
||||
<el-tab-pane label="访问量" name="visits" />
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div :class="['ele-inline-block', { 'hidden-xs-only': styleResponsive }]">
|
||||
<el-radio-group v-model="saleSearch.dateType" size="small">
|
||||
<el-radio-button :label="0">今天</el-radio-button>
|
||||
<el-radio-button :label="1">本周</el-radio-button>
|
||||
<el-radio-button :label="2">本月</el-radio-button>
|
||||
<el-radio-button :label="3">本年</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div
|
||||
:class="['ele-inline-block', { 'hidden-sm-and-down': styleResponsive }]"
|
||||
style="width: 260px; margin-left: 10px"
|
||||
>
|
||||
<el-date-picker
|
||||
unlink-panels
|
||||
type="daterange"
|
||||
class="ele-fluid"
|
||||
end-placeholder="结束日期"
|
||||
start-placeholder="开始日期"
|
||||
v-model="saleSearch.datetime"
|
||||
range-separator="至"
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<el-divider />
|
||||
<el-row>
|
||||
<el-col v-bind="styleResponsive ? { lg: 18, md: 16 } : { span: 18 }">
|
||||
<div class="demo-monitor-title">
|
||||
<span v-if="saleSearch.type === 'saleroom'">销售额趋势</span>
|
||||
<span v-else>访问量趋势</span>
|
||||
</div>
|
||||
<v-chart
|
||||
ref="saleChart"
|
||||
style="height: 285px"
|
||||
:option="saleChartOption"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 8 } : { span: 6 }">
|
||||
<div class="demo-monitor-title" style="display: flex">
|
||||
<div>门店</div>
|
||||
<div>
|
||||
<span v-if="saleSearch.type === 'saleroom'">销售额</span>
|
||||
<span v-else>访问量</span>
|
||||
</div>
|
||||
<div>排名</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(item, index) in saleroomRankData"
|
||||
:key="index"
|
||||
class="demo-monitor-rank-item ele-cell"
|
||||
style="margin-bottom: 15px"
|
||||
>
|
||||
<el-tag
|
||||
size="mini"
|
||||
type="info"
|
||||
:effect="index < 3 ? 'dark' : 'light'"
|
||||
:color="index < 3 ? '#314659' : 'hsla(0, 0%, 60%, .2)'"
|
||||
style="border-color: transparent"
|
||||
class="ele-tag-round"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
</el-tag>
|
||||
<div class="ele-cell-content">{{ item.name }}</div>
|
||||
<div class="ele-text-secondary">{{ item.value }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { BarChart } from 'echarts/charts';
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import { getSaleroomList } from '@/api/dashboard/analysis';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
|
||||
use([CanvasRenderer, BarChart, GridComponent, TooltipComponent]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
mixins: [echartsMixin(['saleChart'])],
|
||||
data() {
|
||||
return {
|
||||
// 销售量搜索参数
|
||||
saleSearch: {
|
||||
type: 'saleroom',
|
||||
dateType: 0,
|
||||
datetime: ''
|
||||
},
|
||||
// 销售量趋势数据
|
||||
saleroomData1: [],
|
||||
// 访问量趋势数据
|
||||
saleroomData2: [],
|
||||
// 门店排名数据
|
||||
saleroomRankData: [
|
||||
{ name: '工专路 1 号店', value: '323,234' },
|
||||
{ name: '工专路 2 号店', value: '323,234' },
|
||||
{ name: '工专路 3 号店', value: '323,234' },
|
||||
{ name: '工专路 4 号店', value: '323,234' },
|
||||
{ name: '工专路 5 号店', value: '323,234' },
|
||||
{ name: '工专路 6 号店', value: '323,234' },
|
||||
{ name: '工专路 7 号店', value: '323,234' }
|
||||
],
|
||||
// 销售额柱状图配置
|
||||
saleChartOption: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getSaleroomData();
|
||||
},
|
||||
methods: {
|
||||
/* 获取销售量数据 */
|
||||
getSaleroomData() {
|
||||
getSaleroomList()
|
||||
.then((data) => {
|
||||
this.saleroomData1 = data.list1;
|
||||
this.saleroomData2 = data.list2;
|
||||
this.onSaleTypeChange();
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
|
||||
/* 销售量tab选择改变事件 */
|
||||
onSaleTypeChange() {
|
||||
const isSale = this.saleSearch.type === 'saleroom';
|
||||
const data = isSale ? this.saleroomData1 : this.saleroomData2;
|
||||
this.saleChartOption = {
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: data.map((d) => d.month)
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
type: 'bar',
|
||||
data: data.map((d) => d.value)
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 销售额、访问量工具栏 */
|
||||
.demo-monitor-tool {
|
||||
padding: 0 20px;
|
||||
|
||||
.demo-monitor-tabs {
|
||||
height: 51px;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item) {
|
||||
height: 51px;
|
||||
line-height: 51px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__nav-wrap:after) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* 小标题 */
|
||||
.demo-monitor-title {
|
||||
padding: 0 20px;
|
||||
margin: 15px 0 5px 0;
|
||||
}
|
||||
|
||||
/* 排名 item */
|
||||
.demo-monitor-rank-item {
|
||||
padding: 0 20px;
|
||||
line-height: 20px;
|
||||
margin-top: 18px;
|
||||
}
|
||||
</style>
|
||||
@@ -5,99 +5,33 @@
|
||||
<el-card class="analysis-chart-card" shadow="never">
|
||||
<template v-slot:header>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">总销售额</div>
|
||||
<el-tooltip content="指标说明" placement="top">
|
||||
<i
|
||||
class="el-icon-_question ele-text-placeholder"
|
||||
style="cursor: pointer"
|
||||
>
|
||||
</i>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<div class="analysis-chart-card-num ele-text-heading">¥ 126,560</div>
|
||||
<div class="analysis-chart-card-content" style="padding-top: 18px">
|
||||
<span class="ele-action">
|
||||
<span>周同比12%</span>
|
||||
<i class="el-icon-caret-top ele-text-danger"></i>
|
||||
</span>
|
||||
<span class="ele-action">
|
||||
<span>日同比11%</span>
|
||||
<i class="el-icon-caret-bottom ele-text-success"></i>
|
||||
</span>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div class="analysis-chart-card-text">日销售额 ¥12,423</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
|
||||
<el-card class="analysis-chart-card" shadow="never">
|
||||
<template v-slot:header>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">访问量</div>
|
||||
<div class="ele-cell-content">今日新增线索</div>
|
||||
<el-tag size="mini" type="danger">日</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
<div class="analysis-chart-card-num ele-text-heading">8,846</div>
|
||||
<div class="analysis-chart-card-content">
|
||||
<v-chart
|
||||
ref="visitChart"
|
||||
style="height: 40px"
|
||||
:option="visitChartOption"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="analysis-chart-card-num ele-text-heading"
|
||||
style="margin-bottom: 10px"
|
||||
>101条</div
|
||||
>
|
||||
<el-divider />
|
||||
<div class="analysis-chart-card-text">日访问量 1,234</div>
|
||||
<div class="analysis-chart-card-text">累计线索:100000条</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
|
||||
<el-card class="analysis-chart-card" shadow="never">
|
||||
<template v-slot:header>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">支付笔数</div>
|
||||
<el-tag size="mini">月</el-tag>
|
||||
<div class="ele-cell-content">当前团队成员</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="analysis-chart-card-num ele-text-heading">6,560</div>
|
||||
<div class="analysis-chart-card-content">
|
||||
<v-chart
|
||||
ref="payNumChart"
|
||||
style="height: 40px"
|
||||
:option="payNumChartOption"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="analysis-chart-card-num ele-text-heading"
|
||||
style="margin-bottom: 10px"
|
||||
>2323人</div
|
||||
>
|
||||
<el-divider />
|
||||
<div class="analysis-chart-card-text">转化率 60%</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
|
||||
<el-card class="analysis-chart-card" shadow="never">
|
||||
<template v-slot:header>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">运营活动效果</div>
|
||||
<el-tag size="mini" type="success">周</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
<div class="analysis-chart-card-num ele-text-heading">78%</div>
|
||||
<div class="analysis-chart-card-content" style="padding-top: 25px">
|
||||
<el-progress
|
||||
:percentage="78"
|
||||
:show-text="false"
|
||||
:stroke-width="10"
|
||||
color="#13c2c2"
|
||||
/>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div class="analysis-chart-card-text">
|
||||
<span class="ele-action">
|
||||
<span>周同比12%</span>
|
||||
<i class="el-icon-caret-top ele-text-danger"></i>
|
||||
</span>
|
||||
<span class="ele-action">
|
||||
<span>日同比11%</span>
|
||||
<i class="el-icon-caret-bottom ele-text-success"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="analysis-chart-card-text">历史成交:100000单</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -108,14 +42,13 @@
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { LineChart, BarChart } from 'echarts/charts';
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import { getPayNumList } from '@/api/dashboard/analysis';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
|
||||
use([CanvasRenderer, LineChart, BarChart, GridComponent, TooltipComponent]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
components: {},
|
||||
mixins: [echartsMixin(['visitChart', 'payNumChart'])],
|
||||
data() {
|
||||
return {
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
<template>
|
||||
<el-card
|
||||
shadow="never"
|
||||
header="最近1小时访问情况"
|
||||
body-style="padding: 14px 5px 0 0;"
|
||||
>
|
||||
<v-chart
|
||||
ref="visitHourChart"
|
||||
style="height: 323px"
|
||||
:option="visitHourChartOption"
|
||||
/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { LineChart } from 'echarts/charts';
|
||||
import {
|
||||
GridComponent,
|
||||
TooltipComponent,
|
||||
LegendComponent
|
||||
} from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import { getVisitHourList } from '@/api/dashboard/analysis';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
|
||||
use([
|
||||
CanvasRenderer,
|
||||
LineChart,
|
||||
GridComponent,
|
||||
TooltipComponent,
|
||||
LegendComponent
|
||||
]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
mixins: [echartsMixin(['visitHourChart'])],
|
||||
data() {
|
||||
return {
|
||||
// 最近1小时访问情况折线图配置
|
||||
visitHourChartOption: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getVisitHourData();
|
||||
},
|
||||
methods: {
|
||||
/* 获取最近1小时访问情况数据 */
|
||||
getVisitHourData() {
|
||||
getVisitHourList()
|
||||
.then((data) => {
|
||||
this.visitHourChartOption = {
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
data: ['浏览量', '访问量'],
|
||||
right: 20
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: data.map((d) => d.time)
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '浏览量',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
areaStyle: {
|
||||
opacity: 0.5
|
||||
},
|
||||
data: data.map((d) => d.views)
|
||||
},
|
||||
{
|
||||
name: '访问量',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
areaStyle: {
|
||||
opacity: 0.5
|
||||
},
|
||||
data: data.map((d) => d.visits)
|
||||
}
|
||||
]
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,37 +1,33 @@
|
||||
<template>
|
||||
<div class="ele-body ele-body-card">
|
||||
<profile-card />
|
||||
<statistics-card />
|
||||
<sale-card />
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { lg: 18, md: 16 } : { span: 18 }">
|
||||
<visit-hour />
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 8 } : { span: 6 }">
|
||||
<hot-search />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProfileCard from './components/profile-card.vue';
|
||||
import StatisticsCard from './components/statistics-card.vue';
|
||||
import SaleCard from './components/sale-card.vue';
|
||||
import VisitHour from './components/visit-hour.vue';
|
||||
import HotSearch from './components/hot-search.vue';
|
||||
|
||||
export default {
|
||||
name: 'HomeAnalysis',
|
||||
name: 'DashboardWorkplace',
|
||||
components: {
|
||||
StatisticsCard,
|
||||
SaleCard,
|
||||
VisitHour,
|
||||
HotSearch
|
||||
ProfileCard,
|
||||
StatisticsCard
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
data: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
Reference in New Issue
Block a user