|
|
@ -37,7 +37,7 @@ |
|
|
<span style="cursor: pointer" slot="label" @click="getBaseList(520)"><a href="javascript:void(0)">供应商编码</a></span> |
|
|
<span style="cursor: pointer" slot="label" @click="getBaseList(520)"><a href="javascript:void(0)">供应商编码</a></span> |
|
|
<el-input |
|
|
<el-input |
|
|
v-model="searchData.supplierId" |
|
|
v-model="searchData.supplierId" |
|
|
placeholder="不填则按物料查询" |
|
|
|
|
|
|
|
|
placeholder="不填则按产品查询" |
|
|
style="width: 160px" |
|
|
style="width: 160px" |
|
|
clearable |
|
|
clearable |
|
|
@keyup.enter.native="handleSearch" |
|
|
@keyup.enter.native="handleSearch" |
|
|
@ -49,6 +49,27 @@ |
|
|
</el-form-item> |
|
|
</el-form-item> |
|
|
</el-form> |
|
|
</el-form> |
|
|
|
|
|
|
|
|
|
|
|
<el-form v-if="showProductInfo" :inline="true" label-position="top" class="pi-product-form"> |
|
|
|
|
|
<el-form-item label="产品编码"> |
|
|
|
|
|
<el-input :value="displayText(productInfo.partNo || searchData.partNo)" disabled style="width: 160px" /> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<el-form-item label="产品名称"> |
|
|
|
|
|
<el-input :value="displayText(productInfo.partDesc)" disabled style="width: 220px" /> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<el-form-item label="Item"> |
|
|
|
|
|
<el-input :value="displayText(productInfo.item)" disabled style="width: 120px" /> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<el-form-item label="SKU"> |
|
|
|
|
|
<el-input :value="displayText(productInfo.sku)" disabled style="width: 120px" /> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<el-form-item label="物料分类"> |
|
|
|
|
|
<el-input :value="displayText(productInfo.categoryName)" disabled style="width: 160px" /> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<el-form-item label="物料二级分类"> |
|
|
|
|
|
<el-input :value="displayText(productInfo.categoryLevel2Name)" disabled style="width: 160px" /> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
</el-form> |
|
|
|
|
|
|
|
|
<el-table |
|
|
<el-table |
|
|
:data="dataList" |
|
|
:data="dataList" |
|
|
:height="tableHeight" |
|
|
:height="tableHeight" |
|
|
@ -58,9 +79,12 @@ |
|
|
style="width: 100%" |
|
|
style="width: 100%" |
|
|
empty-text="请填写查询条件后点击查询" |
|
|
empty-text="请填写查询条件后点击查询" |
|
|
> |
|
|
> |
|
|
<el-table-column prop="partNo" label="产品编码" min-width="80" header-align="center" align="left" show-overflow-tooltip /> |
|
|
|
|
|
<el-table-column prop="partDesc" label="物料名称" min-width="250" header-align="center" align="left" show-overflow-tooltip /> |
|
|
|
|
|
<el-table-column prop="price" label="报价" min-width="80" header-align="center" align="right"> |
|
|
|
|
|
|
|
|
<el-table-column fixed="left" label="操作" width="90" header-align="center" align="center"> |
|
|
|
|
|
<template slot-scope="scope"> |
|
|
|
|
|
<el-link style="cursor: pointer" @click="openPriceSheet(scope.row)">价格表</el-link> |
|
|
|
|
|
</template> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column prop="price" label="价格" min-width="80" header-align="center" align="right"> |
|
|
<template slot-scope="scope"> |
|
|
<template slot-scope="scope"> |
|
|
{{ formatMoney(scope.row.price) }} |
|
|
{{ formatMoney(scope.row.price) }} |
|
|
</template> |
|
|
</template> |
|
|
@ -72,21 +96,78 @@ |
|
|
</span> |
|
|
</span> |
|
|
</template> |
|
|
</template> |
|
|
</el-table-column> |
|
|
</el-table-column> |
|
|
<el-table-column prop="createdDate" label="报价时间" min-width="160" header-align="center" align="center" /> |
|
|
|
|
|
<el-table-column prop="supplierId" label="报价供应商编码" min-width="120" header-align="center" align="left" show-overflow-tooltip /> |
|
|
|
|
|
<el-table-column prop="supplierName" label="报价供应商名称" min-width="200" header-align="center" align="left" show-overflow-tooltip /> |
|
|
|
|
|
<el-table-column prop="categoryName" label="物料分类" min-width="100" header-align="center" align="left" show-overflow-tooltip /> |
|
|
|
|
|
<el-table-column prop="categoryLevel2Name" label="物料二级分类" min-width="100" header-align="center" align="left" show-overflow-tooltip /> |
|
|
|
|
|
<el-table-column prop="categoryLevel3Name" label="物料三级分类" min-width="100" header-align="center" align="left" show-overflow-tooltip /> |
|
|
|
|
|
|
|
|
<el-table-column prop="priceDate" label="价格日期" min-width="160" header-align="center" align="center"> |
|
|
|
|
|
<template slot-scope="scope"> |
|
|
|
|
|
{{ formatDateOnly(scope.row.priceDate) }} |
|
|
|
|
|
</template> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column prop="supplierId" label="供应商编码" min-width="120" header-align="center" align="left" show-overflow-tooltip /> |
|
|
|
|
|
<el-table-column prop="supplierName" label="供应商名称" min-width="200" header-align="center" align="left" show-overflow-tooltip /> |
|
|
</el-table> |
|
|
</el-table> |
|
|
|
|
|
|
|
|
<el-card shadow="never" class="chart-card"> |
|
|
<el-card shadow="never" class="chart-card"> |
|
|
<div slot="header" class="chart-card__header"> |
|
|
<div slot="header" class="chart-card__header"> |
|
|
<span>价格趋势(已接受报价)</span> |
|
|
|
|
|
|
|
|
<span>价格趋势(供应商历史价格)</span> |
|
|
</div> |
|
|
</div> |
|
|
<div id="partPriceChart" class="chart-box" :style="{ height: chartHeight + 'px' }"></div> |
|
|
<div id="partPriceChart" class="chart-box" :style="{ height: chartHeight + 'px' }"></div> |
|
|
</el-card> |
|
|
</el-card> |
|
|
|
|
|
|
|
|
|
|
|
<el-dialog |
|
|
|
|
|
title="价格表" |
|
|
|
|
|
:visible.sync="priceSheetDialogVisible" |
|
|
|
|
|
width="600px" |
|
|
|
|
|
:close-on-click-modal="false" |
|
|
|
|
|
v-drag |
|
|
|
|
|
append-to-body |
|
|
|
|
|
> |
|
|
|
|
|
<el-form :inline="true" label-position="top" class="pi-price-sheet-form"> |
|
|
|
|
|
<el-form-item label="产品"> |
|
|
|
|
|
<el-input :value="displayText(priceSheetHeader.productText)" disabled style="width: 190px" /> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<el-form-item label="价格日期"> |
|
|
|
|
|
<el-input :value="displayText(formatDateOnly(priceSheetHeader.priceDate))" disabled style="width: 80px" /> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<!-- <el-form-item label="供应商编码">--> |
|
|
|
|
|
<!-- <el-input :value="displayText(priceSheetHeader.supplierId)" disabled style="width: 100px" />--> |
|
|
|
|
|
<!-- </el-form-item>--> |
|
|
|
|
|
<el-form-item label="供应商名称"> |
|
|
|
|
|
<el-input :value="displayText(priceSheetHeader.supplierName)" disabled style="width: 180px" /> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<el-form-item label="币种"> |
|
|
|
|
|
<el-input :value="displayText(priceSheetHeader.currency)" disabled style="width: 70px" /> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
</el-form> |
|
|
|
|
|
|
|
|
|
|
|
<el-table |
|
|
|
|
|
:data="priceSheetDetailList" |
|
|
|
|
|
:height="300" |
|
|
|
|
|
border |
|
|
|
|
|
stripe |
|
|
|
|
|
v-loading="priceSheetLoading" |
|
|
|
|
|
style="width: 100%" |
|
|
|
|
|
> |
|
|
|
|
|
<el-table-column prop="qtyStart" label="开始数量" min-width="80" header-align="center" align="right"> |
|
|
|
|
|
<template slot-scope="scope"> |
|
|
|
|
|
{{ formatNumber(scope.row.qtyStart) }} |
|
|
|
|
|
</template> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column prop="qtyEnd" label="结束数量" min-width="80" header-align="center" align="right"> |
|
|
|
|
|
<template slot-scope="scope"> |
|
|
|
|
|
{{ formatNumber(scope.row.qtyEnd) }} |
|
|
|
|
|
</template> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column prop="unitPrice" label="单价" min-width="80" header-align="center" align="right"> |
|
|
|
|
|
<template slot-scope="scope"> |
|
|
|
|
|
{{ formatNumber(scope.row.unitPrice) }} |
|
|
|
|
|
</template> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column prop="remark" label="备注" min-width="150" header-align="center" align="left" show-overflow-tooltip /> |
|
|
|
|
|
</el-table> |
|
|
|
|
|
<div slot="footer" class="dialog-footer"> |
|
|
|
|
|
<el-button type="primary" @click="priceSheetDialogVisible = false">关闭</el-button> |
|
|
|
|
|
</div> |
|
|
|
|
|
</el-dialog> |
|
|
|
|
|
|
|
|
<Chooselist |
|
|
<Chooselist |
|
|
ref="baseList" |
|
|
ref="baseList" |
|
|
@getBaseData="getBaseData"> |
|
|
@getBaseData="getBaseData"> |
|
|
@ -97,6 +178,7 @@ |
|
|
<script> |
|
|
<script> |
|
|
import echarts from 'echarts' |
|
|
import echarts from 'echarts' |
|
|
import { searchPartPriceAnalysis } from '@/api/supplier/partPriceAnalysis' |
|
|
import { searchPartPriceAnalysis } from '@/api/supplier/partPriceAnalysis' |
|
|
|
|
|
import { listTierPriceHistoryDetail } from '@/api/supplier/supplierPartMoqPrice' |
|
|
import Chooselist from '@/views/modules/common/Chooselist_eam' |
|
|
import Chooselist from '@/views/modules/common/Chooselist_eam' |
|
|
|
|
|
|
|
|
function getDefaultStartDate () { |
|
|
function getDefaultStartDate () { |
|
|
@ -106,6 +188,17 @@ function getDefaultStartDate () { |
|
|
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` |
|
|
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function createEmptyProductInfo () { |
|
|
|
|
|
return { |
|
|
|
|
|
partNo: '', |
|
|
|
|
|
partDesc: '', |
|
|
|
|
|
item: '', |
|
|
|
|
|
sku: '', |
|
|
|
|
|
categoryName: '', |
|
|
|
|
|
categoryLevel2Name: '' |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
export default { |
|
|
export default { |
|
|
name: 'PartPriceAnalysis', |
|
|
name: 'PartPriceAnalysis', |
|
|
components: { |
|
|
components: { |
|
|
@ -123,6 +216,19 @@ export default { |
|
|
partNo: '', |
|
|
partNo: '', |
|
|
supplierId: '' |
|
|
supplierId: '' |
|
|
}, |
|
|
}, |
|
|
|
|
|
showProductInfo: false, |
|
|
|
|
|
productInfo: createEmptyProductInfo(), |
|
|
|
|
|
priceSheetDialogVisible: false, |
|
|
|
|
|
priceSheetLoading: false, |
|
|
|
|
|
priceSheetHeader: { |
|
|
|
|
|
productText: '', |
|
|
|
|
|
priceDate: '', |
|
|
|
|
|
supplierId: '', |
|
|
|
|
|
supplierName: '', |
|
|
|
|
|
currency: '', |
|
|
|
|
|
historyMainId: null |
|
|
|
|
|
}, |
|
|
|
|
|
priceSheetDetailList: [], |
|
|
tableHeight: 280, |
|
|
tableHeight: 280, |
|
|
chartHeight: 320, |
|
|
chartHeight: 320, |
|
|
chartInstance: null |
|
|
chartInstance: null |
|
|
@ -178,6 +284,8 @@ export default { |
|
|
partNo: '', |
|
|
partNo: '', |
|
|
supplierId: '' |
|
|
supplierId: '' |
|
|
} |
|
|
} |
|
|
|
|
|
this.showProductInfo = false |
|
|
|
|
|
this.productInfo = createEmptyProductInfo() |
|
|
this.dataList = [] |
|
|
this.dataList = [] |
|
|
this.renderChart([]) |
|
|
this.renderChart([]) |
|
|
}, |
|
|
}, |
|
|
@ -232,10 +340,14 @@ export default { |
|
|
} |
|
|
} |
|
|
searchPartPriceAnalysis(params).then(({ data }) => { |
|
|
searchPartPriceAnalysis(params).then(({ data }) => { |
|
|
if (data && data.code === 0) { |
|
|
if (data && data.code === 0) { |
|
|
|
|
|
this.showProductInfo = true |
|
|
|
|
|
this.productInfo = Object.assign(createEmptyProductInfo(), data.productInfo || {}, { |
|
|
|
|
|
partNo: (data.productInfo && data.productInfo.partNo) || params.partNo |
|
|
|
|
|
}) |
|
|
this.dataList = data.list || [] |
|
|
this.dataList = data.list || [] |
|
|
this.renderChart(this.dataList) |
|
|
this.renderChart(this.dataList) |
|
|
if (this.dataList.length === 0) { |
|
|
if (this.dataList.length === 0) { |
|
|
this.$message.info('未查询到已接受报价记录') |
|
|
|
|
|
|
|
|
this.$message.info('未查询到历史价格记录') |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
this.$message.error((data && data.msg) || '查询失败') |
|
|
this.$message.error((data && data.msg) || '查询失败') |
|
|
@ -246,14 +358,49 @@ export default { |
|
|
this.$message.error('请求失败') |
|
|
this.$message.error('请求失败') |
|
|
}) |
|
|
}) |
|
|
}, |
|
|
}, |
|
|
|
|
|
openPriceSheet (row) { |
|
|
|
|
|
if (!row || !row.historyMainId) { |
|
|
|
|
|
this.$message.warning('当前记录未找到关联价格表') |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
const productText = [row.partNo, row.partDesc].filter(Boolean).join(' / ') |
|
|
|
|
|
this.priceSheetHeader = { |
|
|
|
|
|
productText, |
|
|
|
|
|
priceDate: row.priceDate || '', |
|
|
|
|
|
supplierId: row.supplierId || '', |
|
|
|
|
|
supplierName: row.supplierName || '', |
|
|
|
|
|
currency: row.currency || '', |
|
|
|
|
|
historyMainId: row.historyMainId |
|
|
|
|
|
} |
|
|
|
|
|
this.priceSheetDetailList = [] |
|
|
|
|
|
this.priceSheetDialogVisible = true |
|
|
|
|
|
this.priceSheetLoading = true |
|
|
|
|
|
const params = { |
|
|
|
|
|
site: this.$store.state.user.site, |
|
|
|
|
|
historyMainId: row.historyMainId |
|
|
|
|
|
} |
|
|
|
|
|
listTierPriceHistoryDetail(params).then(({ data }) => { |
|
|
|
|
|
if (data && data.code === 0) { |
|
|
|
|
|
this.priceSheetDetailList = data.rows || [] |
|
|
|
|
|
} else { |
|
|
|
|
|
this.priceSheetDetailList = [] |
|
|
|
|
|
this.$message.error((data && data.msg) || '获取价格表明细失败') |
|
|
|
|
|
} |
|
|
|
|
|
this.priceSheetLoading = false |
|
|
|
|
|
}).catch(() => { |
|
|
|
|
|
this.priceSheetLoading = false |
|
|
|
|
|
this.priceSheetDetailList = [] |
|
|
|
|
|
this.$message.error('获取价格表明细失败') |
|
|
|
|
|
}) |
|
|
|
|
|
}, |
|
|
renderChart (list) { |
|
|
renderChart (list) { |
|
|
if (!this.chartInstance) { |
|
|
if (!this.chartInstance) { |
|
|
this.initChart() |
|
|
this.initChart() |
|
|
} |
|
|
} |
|
|
const chartData = [...list].sort((a, b) => { |
|
|
const chartData = [...list].sort((a, b) => { |
|
|
return new Date(a.createdDate).getTime() - new Date(b.createdDate).getTime() |
|
|
|
|
|
|
|
|
return new Date(a.priceDate).getTime() - new Date(b.priceDate).getTime() |
|
|
}) |
|
|
}) |
|
|
const xAxisData = chartData.map(item => this.formatChartDate(item.createdDate)) |
|
|
|
|
|
|
|
|
const xAxisData = chartData.map(item => this.formatChartDate(item.priceDate)) |
|
|
const seriesData = chartData.map(item => item.price) |
|
|
const seriesData = chartData.map(item => item.price) |
|
|
const titleSuffix = this.searchData.supplierId |
|
|
const titleSuffix = this.searchData.supplierId |
|
|
? `${this.searchData.partNo} / ${this.searchData.supplierId}` |
|
|
? `${this.searchData.partNo} / ${this.searchData.supplierId}` |
|
|
@ -261,7 +408,7 @@ export default { |
|
|
|
|
|
|
|
|
const option = { |
|
|
const option = { |
|
|
title: { |
|
|
title: { |
|
|
text: chartData.length ? `物料价格趋势 - ${titleSuffix}` : '暂无数据', |
|
|
|
|
|
|
|
|
text: chartData.length ? `产品价格趋势 - ${titleSuffix}` : '暂无数据', |
|
|
left: 'center', |
|
|
left: 'center', |
|
|
textStyle: { |
|
|
textStyle: { |
|
|
fontSize: 14, |
|
|
fontSize: 14, |
|
|
@ -277,8 +424,8 @@ export default { |
|
|
const index = params[0].dataIndex |
|
|
const index = params[0].dataIndex |
|
|
const row = chartData[index] || {} |
|
|
const row = chartData[index] || {} |
|
|
return [ |
|
|
return [ |
|
|
`报价时间:${this.formatDateTime(row.createdDate)}`, |
|
|
|
|
|
`报价:${this.formatMoney(row.price)}`, |
|
|
|
|
|
|
|
|
`价格日期:${this.formatDateOnly(row.priceDate)}`, |
|
|
|
|
|
`价格:${this.formatMoney(row.price)}`, |
|
|
`供应商:${row.supplierId || '-'} ${row.supplierName || ''}` |
|
|
`供应商:${row.supplierId || '-'} ${row.supplierName || ''}` |
|
|
].join('<br/>') |
|
|
].join('<br/>') |
|
|
} |
|
|
} |
|
|
@ -303,7 +450,7 @@ export default { |
|
|
scale: true |
|
|
scale: true |
|
|
}, |
|
|
}, |
|
|
series: [{ |
|
|
series: [{ |
|
|
name: '报价', |
|
|
|
|
|
|
|
|
name: '价格', |
|
|
type: 'line', |
|
|
type: 'line', |
|
|
smooth: true, |
|
|
smooth: true, |
|
|
symbol: 'circle', |
|
|
symbol: 'circle', |
|
|
@ -328,6 +475,19 @@ export default { |
|
|
maximumFractionDigits: 2 |
|
|
maximumFractionDigits: 2 |
|
|
}).format(value) |
|
|
}).format(value) |
|
|
}, |
|
|
}, |
|
|
|
|
|
displayText (value) { |
|
|
|
|
|
return value === null || value === undefined || value === '' ? '-' : value |
|
|
|
|
|
}, |
|
|
|
|
|
formatNumber (value) { |
|
|
|
|
|
if (value === null || value === undefined || value === '') { |
|
|
|
|
|
return '-' |
|
|
|
|
|
} |
|
|
|
|
|
const num = Number(value) |
|
|
|
|
|
if (Number.isNaN(num)) { |
|
|
|
|
|
return value |
|
|
|
|
|
} |
|
|
|
|
|
return String(Object.is(num, -0) ? 0 : num) |
|
|
|
|
|
}, |
|
|
getPriceChangeClass (value) { |
|
|
getPriceChangeClass (value) { |
|
|
if (!value || value === '-') { |
|
|
if (!value || value === '-') { |
|
|
return '' |
|
|
return '' |
|
|
@ -362,6 +522,17 @@ export default { |
|
|
} |
|
|
} |
|
|
const pad = num => String(num).padStart(2, '0') |
|
|
const pad = num => String(num).padStart(2, '0') |
|
|
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}` |
|
|
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}` |
|
|
|
|
|
}, |
|
|
|
|
|
formatDateOnly (value) { |
|
|
|
|
|
if (!value) { |
|
|
|
|
|
return '' |
|
|
|
|
|
} |
|
|
|
|
|
const date = new Date(value) |
|
|
|
|
|
if (Number.isNaN(date.getTime())) { |
|
|
|
|
|
return value |
|
|
|
|
|
} |
|
|
|
|
|
const pad = num => String(num).padStart(2, '0') |
|
|
|
|
|
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
@ -372,6 +543,15 @@ export default { |
|
|
margin-top: 12px; |
|
|
margin-top: 12px; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.part-price-analysis .pi-product-form { |
|
|
|
|
|
margin-top: 2px; |
|
|
|
|
|
margin-bottom: 10px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.part-price-analysis .pi-price-sheet-form { |
|
|
|
|
|
margin-top: 2px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
.part-price-analysis .chart-card__header { |
|
|
.part-price-analysis .chart-card__header { |
|
|
font-size: 14px; |
|
|
font-size: 14px; |
|
|
font-weight: 500; |
|
|
font-weight: 500; |
|
|
|