售后单列表、spu销售统计、交易趋势、sku销量统计
This commit is contained in:
parent
618979614a
commit
7e3a5fed04
13565
resources/frontend/package-lock.json
generated
13565
resources/frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -10,13 +10,17 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
|
"dayjs": "^1.11.12",
|
||||||
|
"echarts": "^5.5.1",
|
||||||
"element-ui": "^2.15.6",
|
"element-ui": "^2.15.6",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
"luxon": "^3.4.4",
|
"luxon": "^3.4.4",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
"vue-router": "^3.2.0",
|
"vue-router": "^3.2.0",
|
||||||
"vue-socket.io": "^3.0.10",
|
"vue-socket.io": "^3.0.10",
|
||||||
"vuex": "^3.4.0"
|
"vuex": "^3.4.0",
|
||||||
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "^5.0.8",
|
"@vue/cli-plugin-babel": "^5.0.8",
|
||||||
@ -35,6 +39,7 @@
|
|||||||
"lint-staged": "^9.5.0",
|
"lint-staged": "^9.5.0",
|
||||||
"sass": "^1.26.5",
|
"sass": "^1.26.5",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
|
"script-loader": "^0.7.2",
|
||||||
"vue-template-compiler": "^2.6.11"
|
"vue-template-compiler": "^2.6.11"
|
||||||
},
|
},
|
||||||
"gitHooks": {
|
"gitHooks": {
|
||||||
|
|||||||
28
resources/frontend/src/api/dataCenter.js
vendored
28
resources/frontend/src/api/dataCenter.js
vendored
@ -4,6 +4,30 @@ export function getSalesReportData(params) {
|
|||||||
return http({
|
return http({
|
||||||
url: "/api/data_center/sales_report",
|
url: "/api/data_center/sales_report",
|
||||||
method: "get",
|
method: "get",
|
||||||
params,
|
params
|
||||||
});
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSkuSalesCount(params) {
|
||||||
|
return http({
|
||||||
|
url: "/api/data_center/sale_statistics",
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSpuSalesCount(params) {
|
||||||
|
return http({
|
||||||
|
url: "/api/data_center/spu_sale_statistics",
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGmvCount(params) {
|
||||||
|
return http({
|
||||||
|
url: "/api/data_center/gmv_statistics",
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
})
|
||||||
}
|
}
|
||||||
8
resources/frontend/src/api/plat.js
vendored
8
resources/frontend/src/api/plat.js
vendored
@ -70,3 +70,11 @@ export function printSuccess(params) {
|
|||||||
params
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAfterSaleOrders(params) {
|
||||||
|
return http({
|
||||||
|
url: "/api/plat_after_sale_orders",
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
16
resources/frontend/src/api/supplyChain.js
vendored
16
resources/frontend/src/api/supplyChain.js
vendored
@ -39,6 +39,22 @@ export function getPurchaseLog(params) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addPurchaseLog(data) {
|
||||||
|
return http({
|
||||||
|
url: "/api/supplier/purchase_record",
|
||||||
|
method: "post",
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updatePurchaseLog(id, data) {
|
||||||
|
return http({
|
||||||
|
url: `/api/supplier/purchase_record/${id}`,
|
||||||
|
method: "patch",
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export function getLossLog(params) {
|
export function getLossLog(params) {
|
||||||
return http({
|
return http({
|
||||||
url: "/api/supplier/loss_record",
|
url: "/api/supplier/loss_record",
|
||||||
|
|||||||
16
resources/frontend/src/api/user.js
vendored
16
resources/frontend/src/api/user.js
vendored
@ -44,3 +44,19 @@ export function userConfirm(id, data) {
|
|||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function websiteMessage(params) {
|
||||||
|
return http({
|
||||||
|
url: "/api/website_message",
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function messageRead(id, data) {
|
||||||
|
return http({
|
||||||
|
url: `/api/website_message/${id}`,
|
||||||
|
method: "patch",
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
20
resources/frontend/src/router/list.js
vendored
20
resources/frontend/src/router/list.js
vendored
@ -85,6 +85,11 @@ const list = [
|
|||||||
name: "货品列表",
|
name: "货品列表",
|
||||||
component: () => import("../views/plat/goodsList.vue"),
|
component: () => import("../views/plat/goodsList.vue"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "PLAT_AFTER_SALE_ORDER_LIST",
|
||||||
|
name: "售后单列表",
|
||||||
|
component: () => import("../views/plat/afterSaleOrder.vue"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "GROUP_MANAGEMENT",
|
path: "GROUP_MANAGEMENT",
|
||||||
name: "团购管理",
|
name: "团购管理",
|
||||||
@ -110,6 +115,21 @@ const list = [
|
|||||||
name: "销售数据",
|
name: "销售数据",
|
||||||
component: () => import("../views/dataCenter/salesReport.vue"),
|
component: () => import("../views/dataCenter/salesReport.vue"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "sale_statistics",
|
||||||
|
name: "sku销售统计",
|
||||||
|
component: () => import("../views/dataCenter/skuStatistics.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "spu_sale_statistics",
|
||||||
|
name: "spu销售统计",
|
||||||
|
component: () => import("../views/dataCenter/spuStatistics.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "gmv_statistics",
|
||||||
|
name: "spu销售统计",
|
||||||
|
component: () => import("../views/dataCenter/gmvStatistics.vue"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "SUPPLIER_MANAGE",
|
path: "SUPPLIER_MANAGE",
|
||||||
name: "供应商管理",
|
name: "供应商管理",
|
||||||
|
|||||||
220
resources/frontend/src/util/Export2Excel.js
vendored
Normal file
220
resources/frontend/src/util/Export2Excel.js
vendored
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
import { saveAs } from 'file-saver'
|
||||||
|
import * as XLSX from 'xlsx'
|
||||||
|
|
||||||
|
function generateArray(table) {
|
||||||
|
var out = [];
|
||||||
|
var rows = table.querySelectorAll('tr');
|
||||||
|
var ranges = [];
|
||||||
|
for (var R = 0; R < rows.length; ++R) {
|
||||||
|
var outRow = [];
|
||||||
|
var row = rows[R];
|
||||||
|
var columns = row.querySelectorAll('td');
|
||||||
|
for (var C = 0; C < columns.length; ++C) {
|
||||||
|
var cell = columns[C];
|
||||||
|
var colspan = cell.getAttribute('colspan');
|
||||||
|
var rowspan = cell.getAttribute('rowspan');
|
||||||
|
var cellValue = cell.innerText;
|
||||||
|
if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
|
||||||
|
|
||||||
|
//Skip ranges
|
||||||
|
ranges.forEach(function (range) {
|
||||||
|
if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
|
||||||
|
for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Handle Row Span
|
||||||
|
if (rowspan || colspan) {
|
||||||
|
rowspan = rowspan || 1;
|
||||||
|
colspan = colspan || 1;
|
||||||
|
ranges.push({
|
||||||
|
s: {
|
||||||
|
r: R,
|
||||||
|
c: outRow.length
|
||||||
|
},
|
||||||
|
e: {
|
||||||
|
r: R + rowspan - 1,
|
||||||
|
c: outRow.length + colspan - 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
//Handle Value
|
||||||
|
outRow.push(cellValue !== "" ? cellValue : null);
|
||||||
|
|
||||||
|
//Handle Colspan
|
||||||
|
if (colspan)
|
||||||
|
for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
|
||||||
|
}
|
||||||
|
out.push(outRow);
|
||||||
|
}
|
||||||
|
return [out, ranges];
|
||||||
|
};
|
||||||
|
|
||||||
|
function datenum(v, date1904) {
|
||||||
|
if (date1904) v += 1462;
|
||||||
|
var epoch = Date.parse(v);
|
||||||
|
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sheet_from_array_of_arrays(data, opts) {
|
||||||
|
var ws = {};
|
||||||
|
var range = {
|
||||||
|
s: {
|
||||||
|
c: 10000000,
|
||||||
|
r: 10000000
|
||||||
|
},
|
||||||
|
e: {
|
||||||
|
c: 0,
|
||||||
|
r: 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (var R = 0; R != data.length; ++R) {
|
||||||
|
for (var C = 0; C != data[R].length; ++C) {
|
||||||
|
if (range.s.r > R) range.s.r = R;
|
||||||
|
if (range.s.c > C) range.s.c = C;
|
||||||
|
if (range.e.r < R) range.e.r = R;
|
||||||
|
if (range.e.c < C) range.e.c = C;
|
||||||
|
var cell = {
|
||||||
|
v: data[R][C]
|
||||||
|
};
|
||||||
|
if (cell.v == null) continue;
|
||||||
|
var cell_ref = XLSX.utils.encode_cell({
|
||||||
|
c: C,
|
||||||
|
r: R
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typeof cell.v === 'number') cell.t = 'n';
|
||||||
|
else if (typeof cell.v === 'boolean') cell.t = 'b';
|
||||||
|
else if (cell.v instanceof Date) {
|
||||||
|
cell.t = 'n';
|
||||||
|
cell.z = XLSX.SSF._table[14];
|
||||||
|
cell.v = datenum(cell.v);
|
||||||
|
} else cell.t = 's';
|
||||||
|
|
||||||
|
ws[cell_ref] = cell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
|
||||||
|
return ws;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Workbook() {
|
||||||
|
if (!(this instanceof Workbook)) return new Workbook();
|
||||||
|
this.SheetNames = [];
|
||||||
|
this.Sheets = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
function s2ab(s) {
|
||||||
|
var buf = new ArrayBuffer(s.length);
|
||||||
|
var view = new Uint8Array(buf);
|
||||||
|
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function export_table_to_excel(id) {
|
||||||
|
var theTable = document.getElementById(id);
|
||||||
|
var oo = generateArray(theTable);
|
||||||
|
var ranges = oo[1];
|
||||||
|
|
||||||
|
/* original data */
|
||||||
|
var data = oo[0];
|
||||||
|
var ws_name = "SheetJS";
|
||||||
|
|
||||||
|
var wb = new Workbook(),
|
||||||
|
ws = sheet_from_array_of_arrays(data);
|
||||||
|
|
||||||
|
/* add ranges to worksheet */
|
||||||
|
// ws['!cols'] = ['apple', 'banan'];
|
||||||
|
ws['!merges'] = ranges;
|
||||||
|
|
||||||
|
/* add worksheet to workbook */
|
||||||
|
wb.SheetNames.push(ws_name);
|
||||||
|
wb.Sheets[ws_name] = ws;
|
||||||
|
|
||||||
|
var wbout = XLSX.write(wb, {
|
||||||
|
bookType: 'xlsx',
|
||||||
|
bookSST: false,
|
||||||
|
type: 'binary'
|
||||||
|
});
|
||||||
|
|
||||||
|
saveAs(new Blob([s2ab(wbout)], {
|
||||||
|
type: "application/octet-stream"
|
||||||
|
}), "test.xlsx")
|
||||||
|
}
|
||||||
|
|
||||||
|
export function export_json_to_excel({
|
||||||
|
multiHeader = [],
|
||||||
|
header,
|
||||||
|
data,
|
||||||
|
filename,
|
||||||
|
merges = [],
|
||||||
|
autoWidth = true,
|
||||||
|
bookType = 'xlsx'
|
||||||
|
} = {}) {
|
||||||
|
/* original data */
|
||||||
|
filename = filename || 'excel-list'
|
||||||
|
data = [...data]
|
||||||
|
data.unshift(header);
|
||||||
|
|
||||||
|
for (let i = multiHeader.length - 1; i > -1; i--) {
|
||||||
|
data.unshift(multiHeader[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
var ws_name = "SheetJS";
|
||||||
|
var wb = new Workbook(),
|
||||||
|
ws = sheet_from_array_of_arrays(data);
|
||||||
|
|
||||||
|
if (merges.length > 0) {
|
||||||
|
if (!ws['!merges']) ws['!merges'] = [];
|
||||||
|
merges.forEach(item => {
|
||||||
|
ws['!merges'].push(XLSX.utils.decode_range(item))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (autoWidth) {
|
||||||
|
/*设置worksheet每列的最大宽度*/
|
||||||
|
const colWidth = data.map(row => row.map(val => {
|
||||||
|
/*先判断是否为null/undefined*/
|
||||||
|
if (val == null) {
|
||||||
|
return {
|
||||||
|
'wch': 10
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/*再判断是否为中文*/
|
||||||
|
else if (val.toString().charCodeAt(0) > 255) {
|
||||||
|
return {
|
||||||
|
'wch': val.toString().length * 2
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
'wch': val.toString().length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
/*以第一行为初始值*/
|
||||||
|
let result = colWidth[0];
|
||||||
|
for (let i = 1; i < colWidth.length; i++) {
|
||||||
|
for (let j = 0; j < colWidth[i].length; j++) {
|
||||||
|
if (result[j]['wch'] < colWidth[i][j]['wch']) {
|
||||||
|
result[j]['wch'] = colWidth[i][j]['wch'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ws['!cols'] = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add worksheet to workbook */
|
||||||
|
wb.SheetNames.push(ws_name);
|
||||||
|
wb.Sheets[ws_name] = ws;
|
||||||
|
|
||||||
|
var wbout = XLSX.write(wb, {
|
||||||
|
bookType: bookType,
|
||||||
|
bookSST: false,
|
||||||
|
type: 'binary'
|
||||||
|
});
|
||||||
|
saveAs(new Blob([s2ab(wbout)], {
|
||||||
|
type: "application/octet-stream"
|
||||||
|
}), `${filename}.${bookType}`);
|
||||||
|
}
|
||||||
0
resources/frontend/src/util/time.js
vendored
Normal file
0
resources/frontend/src/util/time.js
vendored
Normal file
272
resources/frontend/src/views/dataCenter/gmvStatistics.vue
Normal file
272
resources/frontend/src/views/dataCenter/gmvStatistics.vue
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="cardBox">
|
||||||
|
<div class="searchBox">
|
||||||
|
<div class="row">
|
||||||
|
<span>统计时间:</span>
|
||||||
|
<el-select v-model="time_type" style="width: 100px;margin-right: 5px;" @change="changeTimeType">
|
||||||
|
<el-option v-for="item in timeTypeList" :key="item.value" :label="item.label" :value="item.value">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
<el-date-picker
|
||||||
|
v-if="time_type == 'day' || time_type == 'week' || time_type == 'seven' || time_type == 'thirty'"
|
||||||
|
v-model="dayValue"
|
||||||
|
:clearable="false"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择日期"
|
||||||
|
format="yyyy-MM-dd"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
@change="changeDayTime">
|
||||||
|
</el-date-picker>
|
||||||
|
|
||||||
|
<el-date-picker
|
||||||
|
v-else-if="time_type == 'month'"
|
||||||
|
v-model="monthValue"
|
||||||
|
type="month"
|
||||||
|
:clearable="false"
|
||||||
|
format="yyyy-MM"
|
||||||
|
value-format="yyyy-MM"
|
||||||
|
placeholder="选择月"
|
||||||
|
@change="changeMonthTime">
|
||||||
|
</el-date-picker>
|
||||||
|
|
||||||
|
<el-date-picker
|
||||||
|
v-else-if="time_type == 'custom'"
|
||||||
|
v-model="customValue"
|
||||||
|
type="datetimerange"
|
||||||
|
range-separator="-"
|
||||||
|
start-placeholder="开始时间"
|
||||||
|
end-placeholder="结束时间"
|
||||||
|
format="yyyy-MM-dd"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
:clearable="false"
|
||||||
|
style="width: 250px;"
|
||||||
|
@change="changeCustomTime">
|
||||||
|
</el-date-picker>
|
||||||
|
|
||||||
|
<div class="time">
|
||||||
|
<span>当前统计时间:</span>
|
||||||
|
<span v-if="startTime == endTime">{{ startTime }}</span>
|
||||||
|
<span v-else>{{ startTime }}~{{ endTime }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-card>
|
||||||
|
<div class="echartBox" id="myEchart">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getGmvCount } from "@/api/dataCenter.js"
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import * as echarts from 'echarts'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
time_type: 'day',
|
||||||
|
timeTypeList: [
|
||||||
|
{ label: '自然日', value: 'day' },
|
||||||
|
{ label: '自然周', value: 'week' },
|
||||||
|
{ label: '自然月', value: 'month' },
|
||||||
|
{ label: '近7天', value: 'seven' },
|
||||||
|
{ label: '近30天', value: 'thirty' },
|
||||||
|
{ label: '自定义', value: 'custom' }
|
||||||
|
],
|
||||||
|
dayValue: '',
|
||||||
|
monthValue: '',
|
||||||
|
customValue: [],
|
||||||
|
startTime: '',
|
||||||
|
endTime: '',
|
||||||
|
dateList: [],
|
||||||
|
Sales: [],
|
||||||
|
SaleCount: [],
|
||||||
|
myChart: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getInitList()
|
||||||
|
window.onresize = () => {
|
||||||
|
if(this.myChart) {
|
||||||
|
this.myChart.resize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getInitList() {
|
||||||
|
let time = this.getDayTime()
|
||||||
|
this.dayValue = this.startTime = this.endTime = time
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
changeTimeType() {
|
||||||
|
if(this.time_type == 'day') {
|
||||||
|
let time = this.getDayTime()
|
||||||
|
this.dayValue = this.startTime = this.endTime = time
|
||||||
|
} else if(this.time_type == 'week') {
|
||||||
|
this.dayValue = this.endTime = dayjs().format('YYYY-MM-DD')
|
||||||
|
this.startTime = dayjs(this.getFirstDay(this.dayValue)).format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'month') {
|
||||||
|
this.monthValue = dayjs().format('YYYY-MM')
|
||||||
|
this.startTime = this.monthValue + '-01'
|
||||||
|
this.endTime = this.monthValue + '-' + this.getDaysInMonth(this.monthValue)
|
||||||
|
} else if(this.time_type == 'seven') {
|
||||||
|
this.dayValue = this.endTime = dayjs().format('YYYY-MM-DD')
|
||||||
|
this.startTime = dayjs().subtract(7, 'day').format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'thirty') {
|
||||||
|
this.dayValue = this.endTime = dayjs().format('YYYY-MM-DD')
|
||||||
|
this.startTime = dayjs().subtract(30, 'day').format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'custom') {
|
||||||
|
this.startTime = this.endTime = dayjs().format('YYYY-MM-DD')
|
||||||
|
this.customValue = [this.startTime, this.startTime]
|
||||||
|
}
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
fetchData() {
|
||||||
|
this.loading = true
|
||||||
|
let params = {
|
||||||
|
type: this.time_type == 'day' ? 1 : 2,
|
||||||
|
start_day: this.startTime,
|
||||||
|
end_day: this.endTime
|
||||||
|
}
|
||||||
|
if(this.time_type == 'day') {
|
||||||
|
params.interval = 60
|
||||||
|
}
|
||||||
|
getGmvCount(params).then((res) => {
|
||||||
|
this.dateList = []
|
||||||
|
this.Sales = []
|
||||||
|
this.SaleCount = []
|
||||||
|
res.data.data.forEach((it) => {
|
||||||
|
this.dateList.push(it.day)
|
||||||
|
this.Sales.push(it.goods_total)
|
||||||
|
this.SaleCount.push(it.goods_total_amount)
|
||||||
|
})
|
||||||
|
this.renderChart()
|
||||||
|
}).catch(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
renderChart() {
|
||||||
|
this.myChart = echarts.init(document.getElementById('myEchart'))
|
||||||
|
this.myChart.setOption({
|
||||||
|
grid: {
|
||||||
|
left: '1%',
|
||||||
|
bottom: '2%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
color: ['#3cd08f', '#f89f34'],
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
icon: 'rect',
|
||||||
|
left: 30,
|
||||||
|
data: ['总销量', '总销售额']
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: this.dateList
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value'
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '总销量',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
data: this.Sales,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '总销售额',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
data: this.SaleCount
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
this.loading = false
|
||||||
|
},
|
||||||
|
// 获取当前日期
|
||||||
|
getDayTime() {
|
||||||
|
let time = dayjs().format('YYYY-MM-DD')
|
||||||
|
return time
|
||||||
|
},
|
||||||
|
// 获取所在周的周一
|
||||||
|
getFirstDay(date) {
|
||||||
|
let day = new Date(date).getDay() || 7
|
||||||
|
return new Date(new Date(date).getFullYear(), new Date(date).getMonth(), new Date(date).getDate() + 1 - day)
|
||||||
|
},
|
||||||
|
getDaysInMonth(date) {
|
||||||
|
let year = date.split('-')[0] * 1
|
||||||
|
let month = date.split('-')[1] * 1
|
||||||
|
const startOfMonth = dayjs(new Date(year, month - 1, 1))
|
||||||
|
const endOfMonth = startOfMonth.endOf('month')
|
||||||
|
return endOfMonth.date()
|
||||||
|
},
|
||||||
|
changeDayTime() {
|
||||||
|
if(this.time_type == 'day') {
|
||||||
|
this.startTime = this.endTime = this.dayValue
|
||||||
|
} else if(this.time_type == 'week') {
|
||||||
|
this.endTime = this.dayValue
|
||||||
|
this.startTime = dayjs(this.getFirstDay(this.dayValue)).format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'seven') {
|
||||||
|
this.endTime = this.dayValue
|
||||||
|
this.startTime = dayjs().subtract(7, 'day').format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'thirty') {
|
||||||
|
this.endTime = this.dayValue
|
||||||
|
this.startTime = dayjs().subtract(30, 'day').format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
changeMonthTime() {
|
||||||
|
this.startTime = this.monthValue + '-01'
|
||||||
|
this.endTime = this.monthValue + '-' + this.getDaysInMonth(this.monthValue)
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
changeCustomTime() {
|
||||||
|
this.startTime = this.customValue[0]
|
||||||
|
this.endTime = this.customValue[1]
|
||||||
|
this.fetchData()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (!this.myChart) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.myChart.dispose()
|
||||||
|
this.myChart = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.searchBox{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
white-space: nowrap;
|
||||||
|
.row{
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-right: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.time{
|
||||||
|
margin-left: 20px;
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.echartBox{
|
||||||
|
width: 100%;
|
||||||
|
height: 480px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
296
resources/frontend/src/views/dataCenter/skuStatistics.vue
Normal file
296
resources/frontend/src/views/dataCenter/skuStatistics.vue
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="cardBox">
|
||||||
|
<div class="searchBox">
|
||||||
|
<div class="row">
|
||||||
|
<span>统计时间:</span>
|
||||||
|
<el-select v-model="time_type" style="width: 100px;margin-right: 5px;" @change="changeTimeType">
|
||||||
|
<el-option v-for="item in timeTypeList" :key="item.value" :label="item.label" :value="item.value">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
<el-date-picker
|
||||||
|
v-if="time_type == 'day' || time_type == 'week' || time_type == 'seven' || time_type == 'thirty'"
|
||||||
|
v-model="dayValue"
|
||||||
|
:clearable="false"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择日期"
|
||||||
|
format="yyyy-MM-dd"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
@change="changeDayTime">
|
||||||
|
</el-date-picker>
|
||||||
|
|
||||||
|
<el-date-picker
|
||||||
|
v-else-if="time_type == 'month'"
|
||||||
|
v-model="monthValue"
|
||||||
|
type="month"
|
||||||
|
:clearable="false"
|
||||||
|
format="yyyy-MM"
|
||||||
|
value-format="yyyy-MM"
|
||||||
|
placeholder="选择月"
|
||||||
|
@change="changeMonthTime">
|
||||||
|
</el-date-picker>
|
||||||
|
|
||||||
|
<el-date-picker
|
||||||
|
v-else-if="time_type == 'custom'"
|
||||||
|
v-model="customValue"
|
||||||
|
type="datetimerange"
|
||||||
|
range-separator="-"
|
||||||
|
start-placeholder="开始时间"
|
||||||
|
end-placeholder="结束时间"
|
||||||
|
format="yyyy-MM-dd"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
:clearable="false"
|
||||||
|
style="width: 250px;"
|
||||||
|
@change="changeCustomTime">
|
||||||
|
</el-date-picker>
|
||||||
|
|
||||||
|
<div class="time">
|
||||||
|
<span>当前统计时间:</span>
|
||||||
|
<span v-if="startTime == endTime">{{ startTime }}</span>
|
||||||
|
<span v-else>{{ startTime }}~{{ endTime }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-card>
|
||||||
|
<div class="opaBox">
|
||||||
|
<el-button type="success" icon="el-icon-download" @click="handleExport" :loading="downloadLoading">导出</el-button>
|
||||||
|
</div>
|
||||||
|
<el-table v-loading="loading" border :data="saleList">
|
||||||
|
<el-table-column label="商品名称" prop="name"></el-table-column>
|
||||||
|
<el-table-column label="sku规格" prop="title"></el-table-column>
|
||||||
|
<el-table-column label="规格编码" prop="external_sku_id"></el-table-column>
|
||||||
|
<el-table-column label="销量" prop="goods_total"></el-table-column>
|
||||||
|
<el-table-column label="销售额" prop="goods_total_amount"></el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="昨日销量" prop="yesterday_avg_num" v-if="time_type == 'day'"></el-table-column>
|
||||||
|
<el-table-column label="3日内销量" prop="three_day_avg_num" v-if="time_type == 'day'"></el-table-column>
|
||||||
|
<el-table-column label="7日内销量" prop="seven_day_avg_num" v-if="time_type == 'day'"></el-table-column>
|
||||||
|
<el-table-column label="已发货数" prop="shipping_num" v-if="time_type == 'day'"></el-table-column>
|
||||||
|
<el-table-column label="未发货数" prop="unshipping_num" v-if="time_type == 'day'"></el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="库存" prop="stock"></el-table-column>
|
||||||
|
<el-table-column label="可售库存" prop="sale_stock"></el-table-column>
|
||||||
|
<el-table-column label="状态" prop="status"></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div class="page-pagination">
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="page"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
:page-size="pageSize"
|
||||||
|
layout="prev, pager, next, jumper, sizes, total"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getSkuSalesCount } from "@/api/dataCenter.js"
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
time_type: 'day',
|
||||||
|
timeTypeList: [
|
||||||
|
{ label: '自然日', value: 'day' },
|
||||||
|
{ label: '自然周', value: 'week' },
|
||||||
|
{ label: '自然月', value: 'month' },
|
||||||
|
{ label: '近7天', value: 'seven' },
|
||||||
|
{ label: '近30天', value: 'thirty' },
|
||||||
|
{ label: '自定义', value: 'custom' }
|
||||||
|
],
|
||||||
|
dayValue: '',
|
||||||
|
monthValue: '',
|
||||||
|
customValue: [],
|
||||||
|
startTime: '',
|
||||||
|
endTime: '',
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
saleList: [],
|
||||||
|
downloadLoading: false,
|
||||||
|
autoWidth: true,
|
||||||
|
bookType: 'xlsx'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getInitList()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getInitList() {
|
||||||
|
let time = this.getDayTime()
|
||||||
|
this.dayValue = this.startTime = this.endTime = time
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
changeTimeType() {
|
||||||
|
if(this.time_type == 'day') {
|
||||||
|
let time = this.getDayTime()
|
||||||
|
this.dayValue = this.startTime = this.endTime = time
|
||||||
|
} else if(this.time_type == 'week') {
|
||||||
|
this.dayValue = this.endTime = dayjs().format('YYYY-MM-DD')
|
||||||
|
this.startTime = dayjs(this.getFirstDay(this.dayValue)).format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'month') {
|
||||||
|
this.monthValue = dayjs().format('YYYY-MM')
|
||||||
|
this.startTime = this.monthValue + '-01'
|
||||||
|
this.endTime = this.monthValue + '-' + this.getDaysInMonth(this.monthValue)
|
||||||
|
} else if(this.time_type == 'seven') {
|
||||||
|
this.dayValue = this.endTime = dayjs().format('YYYY-MM-DD')
|
||||||
|
this.startTime = dayjs().subtract(7, 'day').format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'thirty') {
|
||||||
|
this.dayValue = this.endTime = dayjs().format('YYYY-MM-DD')
|
||||||
|
this.startTime = dayjs().subtract(30, 'day').format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'custom') {
|
||||||
|
this.startTime = this.endTime = dayjs().format('YYYY-MM-DD')
|
||||||
|
this.customValue = [this.startTime, this.startTime]
|
||||||
|
}
|
||||||
|
this.page = 1
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
fetchData() {
|
||||||
|
this.loading = true
|
||||||
|
let params = {
|
||||||
|
type: this.time_type == 'day' ? 1 : 2,
|
||||||
|
start_day: this.startTime,
|
||||||
|
end_day: this.endTime,
|
||||||
|
page: this.page,
|
||||||
|
per_page: this.pageSize
|
||||||
|
}
|
||||||
|
getSkuSalesCount(params).then((res) => {
|
||||||
|
this.saleList = res.data.data.data
|
||||||
|
this.total = res.data.data.total
|
||||||
|
this.loading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 获取当前日期
|
||||||
|
getDayTime() {
|
||||||
|
let time = dayjs().format('YYYY-MM-DD')
|
||||||
|
return time
|
||||||
|
},
|
||||||
|
// 获取所在周的周一
|
||||||
|
getFirstDay(date) {
|
||||||
|
let day = new Date(date).getDay() || 7
|
||||||
|
return new Date(new Date(date).getFullYear(), new Date(date).getMonth(), new Date(date).getDate() + 1 - day)
|
||||||
|
},
|
||||||
|
getDaysInMonth(date) {
|
||||||
|
let year = date.split('-')[0] * 1
|
||||||
|
let month = date.split('-')[1] * 1
|
||||||
|
const startOfMonth = dayjs(new Date(year, month - 1, 1))
|
||||||
|
const endOfMonth = startOfMonth.endOf('month')
|
||||||
|
return endOfMonth.date()
|
||||||
|
},
|
||||||
|
changeDayTime() {
|
||||||
|
if(this.time_type == 'day') {
|
||||||
|
this.startTime = this.endTime = this.dayValue
|
||||||
|
} else if(this.time_type == 'week') {
|
||||||
|
this.endTime = this.dayValue
|
||||||
|
this.startTime = dayjs(this.getFirstDay(this.dayValue)).format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'seven') {
|
||||||
|
this.endTime = this.dayValue
|
||||||
|
this.startTime = dayjs().subtract(7, 'day').format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'thirty') {
|
||||||
|
this.endTime = this.dayValue
|
||||||
|
this.startTime = dayjs().subtract(30, 'day').format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
this.page = 1
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
changeMonthTime() {
|
||||||
|
this.startTime = this.monthValue + '-01'
|
||||||
|
this.endTime = this.monthValue + '-' + this.getDaysInMonth(this.monthValue)
|
||||||
|
this.page = 1
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
changeCustomTime() {
|
||||||
|
this.startTime = this.customValue[0]
|
||||||
|
this.endTime = this.customValue[1]
|
||||||
|
this.page = 1
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
handleSizeChange(val) {
|
||||||
|
this.page = 1
|
||||||
|
this.pageSize = val
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
handleCurrentChange(val) {
|
||||||
|
this.page = val
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
handleExport() {
|
||||||
|
this.downloadLoading = true
|
||||||
|
let params = {
|
||||||
|
type: this.time_type == 'day' ? 1 : 2,
|
||||||
|
start_day: this.startTime,
|
||||||
|
end_day: this.endTime,
|
||||||
|
page: 1,
|
||||||
|
per_page: this.total
|
||||||
|
}
|
||||||
|
getSkuSalesCount(params).then((res) => {
|
||||||
|
if(!res.data.data.data.length) {
|
||||||
|
this.$message({
|
||||||
|
message: '暂无数据',
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
import('@/util/Export2Excel').then(excel => {
|
||||||
|
const tHeader = ['商品名称', 'sku规格', '规格编码', '销量', '销售额']
|
||||||
|
const filterVal = ['name', 'title', 'external_sku_id', 'goods_total', 'goods_total_amount']
|
||||||
|
const list = res.data.data.data
|
||||||
|
const data = this.formatJson(filterVal, list)
|
||||||
|
excel.export_json_to_excel({
|
||||||
|
header: tHeader,
|
||||||
|
data,
|
||||||
|
filename: 'sku销售统计数据',
|
||||||
|
autoWidth: this.autoWidth,
|
||||||
|
bookType: this.bookType
|
||||||
|
})
|
||||||
|
this.downloadLoading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.downloadLoading = false
|
||||||
|
})
|
||||||
|
}).catch(() => {
|
||||||
|
this.downloadLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
formatJson(filterVal, jsonData) {
|
||||||
|
return jsonData.map(v => filterVal.map(j => {
|
||||||
|
return v[j]
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.searchBox{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
white-space: nowrap;
|
||||||
|
.row{
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-right: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.time{
|
||||||
|
margin-left: 20px;
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.opaBox{
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
251
resources/frontend/src/views/dataCenter/spuStatistics.vue
Normal file
251
resources/frontend/src/views/dataCenter/spuStatistics.vue
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="cardBox">
|
||||||
|
<div class="searchBox">
|
||||||
|
<div class="row">
|
||||||
|
<span>统计时间:</span>
|
||||||
|
<el-select v-model="time_type" style="width: 100px;margin-right: 5px;" @change="changeTimeType">
|
||||||
|
<el-option v-for="item in timeTypeList" :key="item.value" :label="item.label" :value="item.value">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
<el-date-picker
|
||||||
|
v-if="time_type == 'day' || time_type == 'week' || time_type == 'seven' || time_type == 'thirty'"
|
||||||
|
v-model="dayValue"
|
||||||
|
:clearable="false"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择日期"
|
||||||
|
format="yyyy-MM-dd"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
@change="changeDayTime">
|
||||||
|
</el-date-picker>
|
||||||
|
|
||||||
|
<el-date-picker
|
||||||
|
v-else-if="time_type == 'month'"
|
||||||
|
v-model="monthValue"
|
||||||
|
type="month"
|
||||||
|
:clearable="false"
|
||||||
|
format="yyyy-MM"
|
||||||
|
value-format="yyyy-MM"
|
||||||
|
placeholder="选择月"
|
||||||
|
@change="changeMonthTime">
|
||||||
|
</el-date-picker>
|
||||||
|
|
||||||
|
<el-date-picker
|
||||||
|
v-else-if="time_type == 'custom'"
|
||||||
|
v-model="customValue"
|
||||||
|
type="datetimerange"
|
||||||
|
range-separator="-"
|
||||||
|
start-placeholder="开始时间"
|
||||||
|
end-placeholder="结束时间"
|
||||||
|
format="yyyy-MM-dd"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
:clearable="false"
|
||||||
|
style="width: 250px;"
|
||||||
|
@change="changeCustomTime">
|
||||||
|
</el-date-picker>
|
||||||
|
|
||||||
|
<div class="time">
|
||||||
|
<span>当前统计时间:</span>
|
||||||
|
<span v-if="startTime == endTime">{{ startTime }}</span>
|
||||||
|
<span v-else>{{ startTime }}~{{ endTime }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-card>
|
||||||
|
<div class="opaBox">
|
||||||
|
<el-button type="success" icon="el-icon-download" @click="handleExport" :loading="downloadLoading">导出</el-button>
|
||||||
|
</div>
|
||||||
|
<el-table v-loading="loading" border :data="saleList">
|
||||||
|
<el-table-column label="类型名称" prop="type_name"></el-table-column>
|
||||||
|
<el-table-column label="库存" prop="stock"></el-table-column>
|
||||||
|
<el-table-column label="可售库存" prop="sale_stock"></el-table-column>
|
||||||
|
<el-table-column label="销量" prop="goods_total"></el-table-column>
|
||||||
|
<el-table-column label="销售额" prop="goods_total_amount"></el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="已发货数" prop="shipping_num" v-if="time_type == 'day'"></el-table-column>
|
||||||
|
<el-table-column label="未发货数" prop="unshipping_num" v-if="time_type == 'day'"></el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="总销量" prop="goods_total"></el-table-column>
|
||||||
|
<el-table-column label="总销售金额" prop="goods_total_amount"></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getSpuSalesCount } from "@/api/dataCenter.js"
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
time_type: 'day',
|
||||||
|
timeTypeList: [
|
||||||
|
{ label: '自然日', value: 'day' },
|
||||||
|
{ label: '自然周', value: 'week' },
|
||||||
|
{ label: '自然月', value: 'month' },
|
||||||
|
{ label: '近7天', value: 'seven' },
|
||||||
|
{ label: '近30天', value: 'thirty' },
|
||||||
|
{ label: '自定义', value: 'custom' }
|
||||||
|
],
|
||||||
|
dayValue: '',
|
||||||
|
monthValue: '',
|
||||||
|
customValue: [],
|
||||||
|
startTime: '',
|
||||||
|
endTime: '',
|
||||||
|
saleList: [],
|
||||||
|
downloadLoading: false,
|
||||||
|
autoWidth: true,
|
||||||
|
bookType: 'xlsx'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getInitList()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getInitList() {
|
||||||
|
let time = this.getDayTime()
|
||||||
|
this.dayValue = this.startTime = this.endTime = time
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
changeTimeType() {
|
||||||
|
if(this.time_type == 'day') {
|
||||||
|
let time = this.getDayTime()
|
||||||
|
this.dayValue = this.startTime = this.endTime = time
|
||||||
|
} else if(this.time_type == 'week') {
|
||||||
|
this.dayValue = this.endTime = dayjs().format('YYYY-MM-DD')
|
||||||
|
this.startTime = dayjs(this.getFirstDay(this.dayValue)).format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'month') {
|
||||||
|
this.monthValue = dayjs().format('YYYY-MM')
|
||||||
|
this.startTime = this.monthValue + '-01'
|
||||||
|
this.endTime = this.monthValue + '-' + this.getDaysInMonth(this.monthValue)
|
||||||
|
} else if(this.time_type == 'seven') {
|
||||||
|
this.dayValue = this.endTime = dayjs().format('YYYY-MM-DD')
|
||||||
|
this.startTime = dayjs().subtract(7, 'day').format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'thirty') {
|
||||||
|
this.dayValue = this.endTime = dayjs().format('YYYY-MM-DD')
|
||||||
|
this.startTime = dayjs().subtract(30, 'day').format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'custom') {
|
||||||
|
this.startTime = this.endTime = dayjs().format('YYYY-MM-DD')
|
||||||
|
this.customValue = [this.startTime, this.startTime]
|
||||||
|
}
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
fetchData() {
|
||||||
|
this.loading = true
|
||||||
|
let params = {
|
||||||
|
type: this.time_type == 'day' ? 1 : 2,
|
||||||
|
start_day: this.startTime,
|
||||||
|
end_day: this.endTime
|
||||||
|
}
|
||||||
|
getSpuSalesCount(params).then((res) => {
|
||||||
|
this.saleList = res.data.data
|
||||||
|
this.loading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 获取当前日期
|
||||||
|
getDayTime() {
|
||||||
|
let time = dayjs().format('YYYY-MM-DD')
|
||||||
|
return time
|
||||||
|
},
|
||||||
|
// 获取所在周的周一
|
||||||
|
getFirstDay(date) {
|
||||||
|
let day = new Date(date).getDay() || 7
|
||||||
|
return new Date(new Date(date).getFullYear(), new Date(date).getMonth(), new Date(date).getDate() + 1 - day)
|
||||||
|
},
|
||||||
|
getDaysInMonth(date) {
|
||||||
|
let year = date.split('-')[0] * 1
|
||||||
|
let month = date.split('-')[1] * 1
|
||||||
|
const startOfMonth = dayjs(new Date(year, month - 1, 1))
|
||||||
|
const endOfMonth = startOfMonth.endOf('month')
|
||||||
|
return endOfMonth.date()
|
||||||
|
},
|
||||||
|
changeDayTime() {
|
||||||
|
if(this.time_type == 'day') {
|
||||||
|
this.startTime = this.endTime = this.dayValue
|
||||||
|
} else if(this.time_type == 'week') {
|
||||||
|
this.endTime = this.dayValue
|
||||||
|
this.startTime = dayjs(this.getFirstDay(this.dayValue)).format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'seven') {
|
||||||
|
this.endTime = this.dayValue
|
||||||
|
this.startTime = dayjs().subtract(7, 'day').format('YYYY-MM-DD')
|
||||||
|
} else if(this.time_type == 'thirty') {
|
||||||
|
this.endTime = this.dayValue
|
||||||
|
this.startTime = dayjs().subtract(30, 'day').format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
changeMonthTime() {
|
||||||
|
this.startTime = this.monthValue + '-01'
|
||||||
|
this.endTime = this.monthValue + '-' + this.getDaysInMonth(this.monthValue)
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
changeCustomTime() {
|
||||||
|
this.startTime = this.customValue[0]
|
||||||
|
this.endTime = this.customValue[1]
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
handleExport() {
|
||||||
|
if(!this.saleList.length) {
|
||||||
|
this.$message({
|
||||||
|
message: '暂无数据',
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.downloadLoading = true
|
||||||
|
import('@/util/Export2Excel').then(excel => {
|
||||||
|
const tHeader = ['类型名称', '库存', '可售库存', '未发货数', '未发货数', '总销量', '总销售金额']
|
||||||
|
const filterVal = ['type_name', 'stock', 'sale_stock', 'shipping_num', 'unshipping_num', 'goods_total', 'goods_total_amount']
|
||||||
|
const list = this.saleList
|
||||||
|
const data = this.formatJson(filterVal, list)
|
||||||
|
excel.export_json_to_excel({
|
||||||
|
header: tHeader,
|
||||||
|
data,
|
||||||
|
filename: 'sku销售统计数据',
|
||||||
|
autoWidth: this.autoWidth,
|
||||||
|
bookType: this.bookType
|
||||||
|
})
|
||||||
|
this.downloadLoading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.downloadLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
formatJson(filterVal, jsonData) {
|
||||||
|
return jsonData.map(v => filterVal.map(j => {
|
||||||
|
return v[j]
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.searchBox{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
white-space: nowrap;
|
||||||
|
.row{
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-right: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.time{
|
||||||
|
margin-left: 20px;
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.opaBox{
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
@ -42,8 +42,8 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div v-for="(item, i) in skus" :key="i">
|
<div v-for="(item, i) in skus" :key="i" class="skuBox">
|
||||||
<div>{{ i + 1 }}.</div>
|
<div class="tit">规格{{ i + 1 }}</div>
|
||||||
<el-form-item label="商品规格:">
|
<el-form-item label="商品规格:">
|
||||||
<el-input placeholder="商品规格" v-model="skus[i].title"></el-input>
|
<el-input placeholder="商品规格" v-model="skus[i].title"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -66,14 +66,22 @@
|
|||||||
<el-input v-model="skus[i].cost" placeholder="商品成本">
|
<el-input v-model="skus[i].cost" placeholder="商品成本">
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="在售库存:">
|
||||||
|
<el-input v-model="skus[i].sale_stock" placeholder="在售库存">
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
<el-button type="danger" @click="handleDelete(i)">删除</el-button>
|
<el-button type="danger" @click="handleDelete(i)">删除</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn">
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="success" @click="handleAdd()">增加规格</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<div style="margin-top: 30px;">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="handleSave()">保存</el-button>
|
<el-button type="primary" @click="handleSave()">保存</el-button>
|
||||||
<el-button plain @click="cancel()">取消</el-button>
|
<el-button plain @click="cancel()">取消</el-button>
|
||||||
<el-button type="success" @click="handleAdd()">增加规格</el-button>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -208,6 +216,7 @@ export default {
|
|||||||
status: "0",
|
status: "0",
|
||||||
num: "0",
|
num: "0",
|
||||||
cost: "0",
|
cost: "0",
|
||||||
|
sale_stock: 0,
|
||||||
reserve: "0",
|
reserve: "0",
|
||||||
};
|
};
|
||||||
this.skus.push(sku);
|
this.skus.push(sku);
|
||||||
@ -231,7 +240,20 @@ export default {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="scss">
|
||||||
|
.skuBox{
|
||||||
|
border: 1px solid #e5e5e5;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 15px 0;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
background-color: #f3f3f3;
|
||||||
|
.tit{
|
||||||
|
padding-left: 40px;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
.el-upload--picture-card {
|
.el-upload--picture-card {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-card class="box-card">
|
<el-card class="box-card">
|
||||||
<el-form ref="form" :inline="true" :model="goodsData">
|
<el-form ref="form" :inline="true" :model="goodsData" label-position="right" label-width="100px">
|
||||||
<div>
|
<div>
|
||||||
<el-form-item label="商品列表:">
|
<el-form-item label="商品列表:">
|
||||||
<el-select v-model="goodsData.goods_id" placeholder="选择商品" filterable :disabled="true">
|
<el-select v-model="goodsData.goods_id" placeholder="选择商品" filterable :disabled="true">
|
||||||
@ -62,6 +62,10 @@
|
|||||||
<el-input v-model="goodsData.cost" placeholder="商品成本">
|
<el-input v-model="goodsData.cost" placeholder="商品成本">
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="在售库存:">
|
||||||
|
<el-input v-model="goodsData.sale_stock" placeholder="在售库存">
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@ -110,6 +114,7 @@ export default {
|
|||||||
status: "",
|
status: "",
|
||||||
num: "",
|
num: "",
|
||||||
cost: "",
|
cost: "",
|
||||||
|
sale_stock: '',
|
||||||
sku_code: "",
|
sku_code: "",
|
||||||
thumb_url: [],
|
thumb_url: [],
|
||||||
goods: {
|
goods: {
|
||||||
@ -214,6 +219,7 @@ export default {
|
|||||||
status: this.goodsData.status,
|
status: this.goodsData.status,
|
||||||
num: this.goodsData.num,
|
num: this.goodsData.num,
|
||||||
cost: this.goodsData.cost,
|
cost: this.goodsData.cost,
|
||||||
|
sale_stock: this.goodsData.sale_stock,
|
||||||
thumb_url: this.goodsData.thumb_url
|
thumb_url: this.goodsData.thumb_url
|
||||||
};
|
};
|
||||||
if (sku.status == "下架") {
|
if (sku.status == "下架") {
|
||||||
@ -229,7 +235,10 @@ export default {
|
|||||||
sku,
|
sku,
|
||||||
};
|
};
|
||||||
updateGoods(this.skuId, updateData).then((res) => {
|
updateGoods(this.skuId, updateData).then((res) => {
|
||||||
this.$message(res.data.message);
|
this.$message({
|
||||||
|
type: "success",
|
||||||
|
message: "编辑成功"
|
||||||
|
})
|
||||||
this.$router.push("/GOODS_LIST");
|
this.$router.push("/GOODS_LIST");
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -13,8 +13,8 @@
|
|||||||
<template slot="title">
|
<template slot="title">
|
||||||
<span>{{ item.name }}</span>
|
<span>{{ item.name }}</span>
|
||||||
</template>
|
</template>
|
||||||
<el-menu-item :index="'/' + children.code" :key="children.id" v-for="children in item.children">{{
|
<el-menu-item :index="'/' + children.code" :key="children.id" v-for="children in item.children">
|
||||||
children.name }}
|
{{ children.name }}
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</el-submenu>
|
</el-submenu>
|
||||||
</div>
|
</div>
|
||||||
@ -31,12 +31,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<el-breadcrumb separator-class="el-icon-arrow-right">
|
<el-breadcrumb separator-class="el-icon-arrow-right">
|
||||||
<el-breadcrumb-item v-for="(item, index) in titie" :key="index">{{ item.name }}
|
<el-breadcrumb-item v-for="(item, index) in titie" :key="index">{{ item.name }}</el-breadcrumb-item>
|
||||||
</el-breadcrumb-item>
|
|
||||||
</el-breadcrumb>
|
</el-breadcrumb>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
<div class="msg" @click="openMessage">
|
||||||
|
<el-badge :hidden="noReadNum == 0" :value="noReadNum" :max="99"><i class="el-icon-message"></i></el-badge>
|
||||||
|
</div>
|
||||||
<div style="margin-right: 10px;">{{ usernmae }}</div>
|
<div style="margin-right: 10px;">{{ usernmae }}</div>
|
||||||
<div class="token" @click="hanleLogout">登出</div>
|
<div class="token" @click="hanleLogout">登出</div>
|
||||||
</li>
|
</li>
|
||||||
@ -49,18 +51,63 @@
|
|||||||
</el-main>
|
</el-main>
|
||||||
</el-container>
|
</el-container>
|
||||||
</el-container>
|
</el-container>
|
||||||
|
|
||||||
|
<el-dialog :visible.sync="showMsg" title="站内信" width="1100px" custom-class="vanmsgbox" @close="showMsg = false">
|
||||||
|
<div class="msgbox">
|
||||||
|
<el-tabs type="border-card" @tab-click="handleTabClick" v-model="curTopTab">
|
||||||
|
<el-tab-pane name="0">
|
||||||
|
<template #label>
|
||||||
|
<span>未读消息</span>
|
||||||
|
<span v-if="noReadNum !== 0" class="numtag">{{ noReadNum }}</span>
|
||||||
|
</template>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="已读消息" name="1"></el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<div class="listbox" v-loading="loading">
|
||||||
|
<div class="item" v-for="item in msgList">
|
||||||
|
<div class="title" :class="item.status ? '' : 'notread'">
|
||||||
|
<div class="tit">{{ item.title }}</div>
|
||||||
|
<span v-if="!item.status" class="not" @click="markRead(item)">标为已读</span>
|
||||||
|
<span v-else>已读</span>
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<div class="tit" v-if="item.content" v-html="item.content.replace(/\n/g,'<br/>')"></div>
|
||||||
|
<div class="time">{{ item.created_at }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="msgList.length == 0 && !loading">
|
||||||
|
<el-empty description="暂无消息" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bottom">
|
||||||
|
<el-pagination
|
||||||
|
:current-page="page"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
:page-size="pageSize"
|
||||||
|
layout="prev, pager, next, sizes, total"
|
||||||
|
:total="total"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
@size-change="handleSizeChange">
|
||||||
|
</el-pagination>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { removeToken } from "@/util/auth";
|
import { removeToken } from "@/util/auth"
|
||||||
import { getMenu } from "../api/menu.js";
|
import { getMenu } from "../api/menu.js"
|
||||||
|
import { websiteMessage, messageRead } from "../api/user.js"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mounted() {
|
mounted() {
|
||||||
getMenu().then((res) => {
|
getMenu().then((res) => {
|
||||||
this.menu = res.data.data;
|
this.menu = res.data.data
|
||||||
console.log(this.menu)
|
})
|
||||||
});
|
|
||||||
this.usernmae = localStorage.getItem('userName');
|
this.usernmae = localStorage.getItem('userName');
|
||||||
|
this.getNoReadNum()
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -71,8 +118,16 @@ export default {
|
|||||||
head: "", // 路由name
|
head: "", // 路由name
|
||||||
onindex: 0, // 索引
|
onindex: 0, // 索引
|
||||||
openeds: ["GOODS_MANAGE"],
|
openeds: ["GOODS_MANAGE"],
|
||||||
usernmae: ''
|
usernmae: '',
|
||||||
};
|
noReadNum: 0,
|
||||||
|
total: 0,
|
||||||
|
msgList: [],
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
showMsg: false,
|
||||||
|
curTopTab: '2',
|
||||||
|
loading: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
// table构造
|
// table构造
|
||||||
@ -93,8 +148,8 @@ export default {
|
|||||||
this.levelData = newArr;
|
this.levelData = newArr;
|
||||||
},
|
},
|
||||||
deep: true,
|
deep: true,
|
||||||
immediate: true,
|
immediate: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
next() {
|
next() {
|
||||||
@ -137,9 +192,59 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
getNoReadNum() {
|
||||||
|
let params = {
|
||||||
|
page: 1,
|
||||||
|
status: 0
|
||||||
|
}
|
||||||
|
websiteMessage(params).then((res) => {
|
||||||
|
this.noReadNum = res.data.meta.total
|
||||||
|
})
|
||||||
},
|
},
|
||||||
};
|
openMessage() {
|
||||||
|
this.curTopTab = '0'
|
||||||
|
this.showMsg = true
|
||||||
|
this.page = 1
|
||||||
|
this.getMsgList()
|
||||||
|
},
|
||||||
|
getMsgList() {
|
||||||
|
this.loading = true
|
||||||
|
let params = {
|
||||||
|
page: this.page,
|
||||||
|
per_page: this.pageSize,
|
||||||
|
status: this.curTopTab == '2' ? '' : this.curTopTab
|
||||||
|
}
|
||||||
|
websiteMessage(params).then((res) => {
|
||||||
|
this.msgList = res.data.data
|
||||||
|
this.total = res.data.meta.total
|
||||||
|
this.loading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleTabClick() {
|
||||||
|
this.page = 1
|
||||||
|
this.getMsgList()
|
||||||
|
},
|
||||||
|
markRead(item) {
|
||||||
|
messageRead(item.id, {status: 1}).then((res) => {
|
||||||
|
item.status = 1
|
||||||
|
this.getNoReadNum()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleCurrentChange(e) {
|
||||||
|
this.page = e
|
||||||
|
this.getMsgList()
|
||||||
|
},
|
||||||
|
handleSizeChange(e) {
|
||||||
|
this.page = 1
|
||||||
|
this.pageSize = e
|
||||||
|
this.getMsgList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.aside-show {
|
.aside-show {
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
@ -201,7 +306,7 @@ export default {
|
|||||||
|
|
||||||
.add {
|
.add {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 25px;
|
font-size: 20px;
|
||||||
color: #606266;
|
color: #606266;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,22 +315,26 @@ export default {
|
|||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-bottom: 1px solid #f6f6f6;
|
border-bottom: 1px solid #f6f6f6;
|
||||||
box-shadow: 0 1px 4px rgb(0 21 41 / 8%);
|
box-shadow: 0 1px 4px rgb(0 21 41 / 8%);
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.right {
|
.right {
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.token {
|
.token {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.msg{
|
||||||
|
margin-right: 15px;
|
||||||
|
font-size: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover{
|
||||||
|
color: #409EFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,4 +361,83 @@ export default {
|
|||||||
.el-menu-item-group__title {
|
.el-menu-item-group__title {
|
||||||
padding: 0 0 !important;
|
padding: 0 0 !important;
|
||||||
}
|
}
|
||||||
|
.msgbox{
|
||||||
|
padding: 20px;
|
||||||
|
.numtag{
|
||||||
|
padding: 1px 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
background: #f00;
|
||||||
|
color: #fff;
|
||||||
|
margin-left: 10px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.listbox{
|
||||||
|
height: 550px;
|
||||||
|
overflow: auto;
|
||||||
|
.item{
|
||||||
|
color: #555;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 20px 30px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-bottom: 1px solid #D7D7D7;
|
||||||
|
.title{
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
&.notread::after{
|
||||||
|
position: absolute;
|
||||||
|
left: -14px;
|
||||||
|
width: 7px;
|
||||||
|
height: 7px;
|
||||||
|
border-radius: 50%;
|
||||||
|
top: 8px;
|
||||||
|
content: '';
|
||||||
|
background: #f00;
|
||||||
|
}
|
||||||
|
.tit{
|
||||||
|
font-size: 16px;
|
||||||
|
width: calc(100% - 150px);
|
||||||
|
}
|
||||||
|
span{
|
||||||
|
font-size: 12px;
|
||||||
|
color: #777;
|
||||||
|
&.not{
|
||||||
|
color: #409eff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.info{
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
.tit{
|
||||||
|
font-size: 14px;
|
||||||
|
width: calc(100% - 200px);
|
||||||
|
}
|
||||||
|
.time{
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bottom{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 20px 0;
|
||||||
|
border-top: 1px solid #D7D7D7;
|
||||||
|
}
|
||||||
|
::v-deep .vanmsgbox .el-tabs__content{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
::v-deep .vanmsgbox .el-tabs--border-card{
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
::v-deep .vanmsgbox .el-dialog__body{
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
190
resources/frontend/src/views/plat/afterSaleOrder.vue
Normal file
190
resources/frontend/src/views/plat/afterSaleOrder.vue
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
<template>
|
||||||
|
<div class="pageBox">
|
||||||
|
<div class="cardBox">
|
||||||
|
<div class="searchBox">
|
||||||
|
<div class="row">
|
||||||
|
<span>店铺:</span>
|
||||||
|
<el-select v-model="filter.shop_id" placeholder="店铺">
|
||||||
|
<el-option v-for="item in shopsList" :key="item.id" :label="item.name" :value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<span>售后单状态:</span>
|
||||||
|
<el-select v-model="filter.after_sales_status" placeholder="请选择">
|
||||||
|
<el-option v-for="item in statusList" :key="item.id" :label="item.name" :value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<span>订单编号:</span>
|
||||||
|
<el-input v-model="filter.order_sn" clearable></el-input>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<span>售后单编号:</span>
|
||||||
|
<el-input v-model="filter.after_sales_biz_sn" clearable></el-input>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<span>创建时间:</span>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="addTime"
|
||||||
|
type="datetimerange"
|
||||||
|
range-separator="-"
|
||||||
|
start-placeholder="开始时间"
|
||||||
|
end-placeholder="结束时间"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
style="width: 340px">
|
||||||
|
</el-date-picker>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<el-button type="primary" icon="el-icon-search" @click="handleSearch">筛选</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-card>
|
||||||
|
<el-table v-loading="loading" :data="afterList" style="width: 100%" border>
|
||||||
|
<el-table-column prop="after_sales_biz_sn" label="售后单编号" />
|
||||||
|
<el-table-column prop="order_sn" label="父订单编号" />
|
||||||
|
<el-table-column label="门店id">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ Shops[scope.row.shop_id] }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="refund_amount" label="退款金额" />
|
||||||
|
<el-table-column prop="refund_shipping_amount" label="用户申请退运费金额" />
|
||||||
|
<el-table-column prop="reason" label="退款原因" />
|
||||||
|
<el-table-column prop="apply_type" label="申请类型" />
|
||||||
|
<el-table-column label="售后单状态">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ STATUS[scope.row.after_sales_status] }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="after_sale_created_at" label="售后单创建时间" />
|
||||||
|
</el-table>
|
||||||
|
<div class="page-pagination">
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="page"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
:page-size="pageSize"
|
||||||
|
layout="prev, pager, next, jumper, sizes, total"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getAfterSaleOrders } from "@/api/plat"
|
||||||
|
import { storeList } from "@/api/shop"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
afterList: [],
|
||||||
|
filter: {
|
||||||
|
shop_id: '',
|
||||||
|
after_sales_status: '',
|
||||||
|
order_sn: '',
|
||||||
|
after_sales_biz_sn: ''
|
||||||
|
},
|
||||||
|
shopsList: [],
|
||||||
|
Shops: {},
|
||||||
|
addTime: [],
|
||||||
|
statusList: [
|
||||||
|
{ id: 0, name: '未发起售后' },
|
||||||
|
{ id: 1, name: '退款中' },
|
||||||
|
{ id: 2, name: '退款成功' },
|
||||||
|
{ id: 3, name: '待处理' },
|
||||||
|
{ id: 4, name: '拒绝退款' },
|
||||||
|
{ id: 6, name: '待(顾客)退货' },
|
||||||
|
{ id: 7, name: '待(团长)确认退货' },
|
||||||
|
{ id: 8, name: '(顾客)撤销' },
|
||||||
|
{ id: 9, name: '(系统)关闭' }
|
||||||
|
],
|
||||||
|
STATUS: {
|
||||||
|
'0': '未发起售后',
|
||||||
|
'1': '退款中',
|
||||||
|
'2': '退款成功',
|
||||||
|
'3': '待处理',
|
||||||
|
'4': '拒绝退款',
|
||||||
|
'6': '待(顾客)退货',
|
||||||
|
'7': '待(团长)确认退货',
|
||||||
|
'8': '(顾客)撤销',
|
||||||
|
'9': '(系统)关闭',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetchList() {
|
||||||
|
this.loading = true
|
||||||
|
let params = {
|
||||||
|
page: this.page,
|
||||||
|
per_page: this.pageSize,
|
||||||
|
...this.filter,
|
||||||
|
created_at_start: this.addTime ? this.addTime[0] : '',
|
||||||
|
created_at_end: this.addTime ? this.addTime[1] : ''
|
||||||
|
}
|
||||||
|
getAfterSaleOrders(params).then((res) => {
|
||||||
|
this.afterList = res.data.data
|
||||||
|
this.total = res.data.meta.total
|
||||||
|
this.loading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSizeChange(val) {
|
||||||
|
this.page = 1
|
||||||
|
this.pageSize = val
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
handleCurrentChange(val) {
|
||||||
|
this.page = val
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
handleSearch() {
|
||||||
|
this.page = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
getShopsList() {
|
||||||
|
let params = {
|
||||||
|
page: 1,
|
||||||
|
per_page: 999
|
||||||
|
}
|
||||||
|
storeList(params).then((res) => {
|
||||||
|
this.shopsList = res.data.data
|
||||||
|
res.data.data.forEach((it) => {
|
||||||
|
this.Shops[it.id] = it.name
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.fetchList()
|
||||||
|
this.getShopsList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.searchBox{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
white-space: nowrap;
|
||||||
|
.row{
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-right: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -174,7 +174,7 @@ export default {
|
|||||||
const params = new FormData();
|
const params = new FormData();
|
||||||
params.append("inventoryFile", this.fileList[0].raw)
|
params.append("inventoryFile", this.fileList[0].raw)
|
||||||
let token = localStorage.getItem("token")
|
let token = localStorage.getItem("token")
|
||||||
axios.post("/api/daily_stock_record/purchase_import", params, {
|
axios.post("/api/supplier/daily_stock_record/inventory_import", params, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`
|
Authorization: `Bearer ${token}`
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,13 +61,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-dialog :title="curInfo.id ? '编辑' : '新增供应商'" :visible.sync="dialogVisible" width="500px">
|
<el-dialog :title="curInfo.id ? '编辑' : '新增'" :visible.sync="dialogVisible" width="500px">
|
||||||
<el-form label-width="90px">
|
<el-form label-width="90px">
|
||||||
<el-form-item label="规格编码">
|
<el-form-item label="规格编码">
|
||||||
<el-input v-model="curInfo.external_sku_id" clearable></el-input>
|
<el-input v-model="curInfo.external_sku_id" clearable></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="数量">
|
<el-form-item label="数量">
|
||||||
<el-input v-model="curInfo.num" clearable></el-input>
|
<el-input v-model="curInfo.num" clearable :disabled="curInfo.id ? true : false"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="成本">
|
<el-form-item label="成本">
|
||||||
<el-input v-model="curInfo.cost" clearable></el-input>
|
<el-input v-model="curInfo.cost" clearable></el-input>
|
||||||
|
|||||||
@ -28,6 +28,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-card>
|
<el-card>
|
||||||
|
<div class="opaBox">
|
||||||
|
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
|
||||||
|
<el-button type="warning" icon="el-icon-upload2" @click="handleImport">导入</el-button>
|
||||||
|
</div>
|
||||||
<el-table v-loading="loading" :data="procureList" style="width: 100%" border>
|
<el-table v-loading="loading" :data="procureList" style="width: 100%" border>
|
||||||
<el-table-column prop="sku_id" label="商品id" width="80" align="center" />
|
<el-table-column prop="sku_id" label="商品id" width="80" align="center" />
|
||||||
<el-table-column prop="goods_sku.title" label="商品标题" />
|
<el-table-column prop="goods_sku.title" label="商品标题" />
|
||||||
@ -43,6 +47,11 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="created_at" label="创建时间" align="center" />
|
<el-table-column prop="created_at" label="创建时间" align="center" />
|
||||||
|
<el-table-column label="操作" width="120" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button type="primary" @click="handleEdit(scope.row)" icon="el-icon-edit" size="mini">编辑</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<div class="page-pagination">
|
<div class="page-pagination">
|
||||||
<el-pagination
|
<el-pagination
|
||||||
@ -57,11 +66,59 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
<el-dialog :title="curInfo.id ? '编辑' : '新增'" :visible.sync="dialogVisible" width="500px">
|
||||||
|
<el-form label-width="90px">
|
||||||
|
<el-form-item label="规格编码">
|
||||||
|
<el-input v-model="curInfo.external_sku_id" clearable></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="数量">
|
||||||
|
<el-input v-model="curInfo.num" clearable></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="成本">
|
||||||
|
<el-input v-model="curInfo.cost" clearable></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="采购人">
|
||||||
|
<el-input v-model="curInfo.buyer_name" clearable></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="供应商">
|
||||||
|
<el-input v-model="curInfo.supplier_name" clearable></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="过期时间">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="curInfo.expire_time"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择日期"
|
||||||
|
format="yyyy-MM-dd"
|
||||||
|
value-format="yyyy-MM-dd">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="commitSupplier" :loading="commitloading">确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog title="导入" :visible.sync="showImport" width="500px">
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<el-upload class="upload-demo" drag action="" :limit="1" :multiple="false"
|
||||||
|
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
|
||||||
|
:file-list="fileList" :auto-upload="false" :on-change="importFileChange" :on-remove="fileRemove">
|
||||||
|
<i class="el-icon-upload"></i>
|
||||||
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||||
|
</el-upload>
|
||||||
|
</div>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="showImport = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="commitUpload" :loading="commitloading">上 传</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getPurchaseLog } from "@/api/supplyChain"
|
import { getPurchaseLog, addPurchaseLog, updatePurchaseLog } from "@/api/supplyChain"
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -74,7 +131,12 @@ export default {
|
|||||||
title: '',
|
title: '',
|
||||||
external_sku_id: ''
|
external_sku_id: ''
|
||||||
},
|
},
|
||||||
addTime: []
|
addTime: [],
|
||||||
|
commitloading: false,
|
||||||
|
dialogVisible: false,
|
||||||
|
curInfo: {},
|
||||||
|
showImport: false,
|
||||||
|
fileList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -107,6 +169,76 @@ export default {
|
|||||||
handleSearch() {
|
handleSearch() {
|
||||||
this.page = 1
|
this.page = 1
|
||||||
this.fetchList()
|
this.fetchList()
|
||||||
|
},
|
||||||
|
// 新增供应商
|
||||||
|
handleAdd() {
|
||||||
|
this.curInfo = {}
|
||||||
|
this.dialogVisible = true
|
||||||
|
},
|
||||||
|
handleEdit(row) {
|
||||||
|
this.curInfo = JSON.parse(JSON.stringify(row))
|
||||||
|
this.dialogVisible = true
|
||||||
|
},
|
||||||
|
commitSupplier() {
|
||||||
|
this.commitloading = true
|
||||||
|
if(this.curInfo.id) {
|
||||||
|
updatePurchaseLog(this.curInfo.id, this.curInfo).then((res) => {
|
||||||
|
this.fetchList()
|
||||||
|
this.$message({ type: "success", message: "更新成功!" })
|
||||||
|
this.dialogVisible = false
|
||||||
|
this.commitloading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.commitloading = false
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
addPurchaseLog(this.curInfo).then((res) => {
|
||||||
|
this.page = 1
|
||||||
|
this.fetchList()
|
||||||
|
this.$message({ type: "success", message: "新增成功!" })
|
||||||
|
this.dialogVisible = false
|
||||||
|
this.commitloading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.commitloading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleImport() {
|
||||||
|
this.fileList = []
|
||||||
|
this.showImport = true
|
||||||
|
},
|
||||||
|
importFileChange(file, fileList) {
|
||||||
|
console.log(fileList)
|
||||||
|
this.fileList = fileList
|
||||||
|
},
|
||||||
|
fileRemove() {
|
||||||
|
this.fileList = []
|
||||||
|
},
|
||||||
|
commitUpload() {
|
||||||
|
if(this.fileList.length) {
|
||||||
|
this.commitloading = true
|
||||||
|
const params = new FormData();
|
||||||
|
params.append("lossFile", this.fileList[0].raw)
|
||||||
|
let token = localStorage.getItem("token")
|
||||||
|
axios.post("/api/purchase_record/purchase_import", params, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
this.$message.success("导入成功")
|
||||||
|
this.page = 1
|
||||||
|
this.fetchList()
|
||||||
|
this.commitloading = false
|
||||||
|
this.showImport = false
|
||||||
|
} else {
|
||||||
|
this.commitloading = false
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
this.commitloading = false
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$message.error("请先上传文件");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -129,4 +261,7 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.opaBox{
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
3
resources/frontend/vue.config.js
vendored
3
resources/frontend/vue.config.js
vendored
@ -8,7 +8,8 @@ module.exports = {
|
|||||||
// 配置代理
|
// 配置代理
|
||||||
"/api": {
|
"/api": {
|
||||||
// target: "http://erp.local",
|
// target: "http://erp.local",
|
||||||
target: "http://erp.chutang66.com",
|
// target: "http://erp.chutang66.com",
|
||||||
|
target: "http://192.168.0.52:81",
|
||||||
changeOrigin: true, // 开启代理
|
changeOrigin: true, // 开启代理
|
||||||
pathRewrite: {
|
pathRewrite: {
|
||||||
// 重命名
|
// 重命名
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user