|
|
@@ -29,12 +29,15 @@ type InventoryDistributionResponse = {
|
|
|
storageNameInventoryPair?: Record<string, number>
|
|
|
}
|
|
|
|
|
|
+type InventoryAgingResponse = Record<string, number>
|
|
|
+
|
|
|
type ActivePanel = 'distribution' | 'trend'
|
|
|
|
|
|
const activePanel = ref<ActivePanel>('distribution')
|
|
|
const DEFAULT_DATE = dayjs().subtract(1, 'day').format('YYYY-MM-DD')
|
|
|
const selectedDate = ref(DEFAULT_DATE)
|
|
|
const inventoryResult = ref<InventoryDistributionResponse | null>(null)
|
|
|
+const inventoryAgingResult = ref<InventoryAgingResponse>({})
|
|
|
const distributionChartRef = ref<HTMLDivElement>()
|
|
|
const trendChartRef = ref<HTMLDivElement>()
|
|
|
|
|
|
@@ -46,9 +49,7 @@ const panelOptions: Array<{ label: string; value: ActivePanel }> = [
|
|
|
{ label: '趋势', value: 'trend' }
|
|
|
]
|
|
|
|
|
|
-const activeTitle = computed(() =>
|
|
|
- activePanel.value === 'distribution' ? '存货分布' : '积压趋势'
|
|
|
-)
|
|
|
+const activeTitle = computed(() => (activePanel.value === 'distribution' ? '存货分布' : '积压趋势'))
|
|
|
|
|
|
const yuanToWan = (value: number) => Number((value / 10000).toFixed(2))
|
|
|
|
|
|
@@ -442,6 +443,88 @@ function initChart(
|
|
|
return nextChart
|
|
|
}
|
|
|
|
|
|
+function getInventoryAgingOption(data: InventoryAgingResponse): echarts.EChartsOption {
|
|
|
+ const layout = getChartLayout(trendChartRef)
|
|
|
+ const months = Object.keys(data).sort()
|
|
|
+ const values = months.map((month) => yuanToWan(data[month]))
|
|
|
+
|
|
|
+ return {
|
|
|
+ ...ANIMATION,
|
|
|
+ grid: {
|
|
|
+ ...THEME.grid,
|
|
|
+ top: layout.trendGridTop,
|
|
|
+ right: layout.trendGridRight,
|
|
|
+ bottom: layout.trendGridBottom
|
|
|
+ },
|
|
|
+ tooltip: createTooltip({
|
|
|
+ trigger: 'axis',
|
|
|
+ valueFormatter(value: number) {
|
|
|
+ return `${formatAmount(value)}万元`
|
|
|
+ }
|
|
|
+ }),
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ boundaryGap: false,
|
|
|
+ data: months,
|
|
|
+ axisTick: { show: false },
|
|
|
+ axisLabel: {
|
|
|
+ color: THEME.text.regular,
|
|
|
+ fontSize: layout.axisFontSize,
|
|
|
+ fontFamily: FONT_FAMILY
|
|
|
+ }
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'value',
|
|
|
+ name: '万元',
|
|
|
+ min: 0,
|
|
|
+ axisTick: { show: false },
|
|
|
+ axisLabel: {
|
|
|
+ color: THEME.text.regular,
|
|
|
+ fontSize: layout.axisFontSize,
|
|
|
+ fontFamily: FONT_FAMILY
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: THEME.split,
|
|
|
+ type: 'dashed'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '积压库存',
|
|
|
+ type: 'line',
|
|
|
+ smooth: true,
|
|
|
+ data: values,
|
|
|
+ symbol: 'circle',
|
|
|
+ symbolSize: layout.compact ? 6 : 8,
|
|
|
+ lineStyle: {
|
|
|
+ width: layout.compact ? 2 : 3,
|
|
|
+ color: THEME.color.orange.line
|
|
|
+ },
|
|
|
+ itemStyle: {
|
|
|
+ color: THEME.color.orange.line
|
|
|
+ },
|
|
|
+ areaStyle: {
|
|
|
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
+ { offset: 0, color: 'rgb(255 161 79 / 28%)' },
|
|
|
+ { offset: 1, color: 'rgb(255 161 79 / 2%)' }
|
|
|
+ ])
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ color: THEME.color.orange.line,
|
|
|
+ fontSize: layout.labelFontSize,
|
|
|
+ fontFamily: FONT_FAMILY,
|
|
|
+ formatter(params: any) {
|
|
|
+ return formatAmount(Number(params.value))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
function renderDistributionChart() {
|
|
|
const data = getFactoryInventoryData(inventoryResult.value)
|
|
|
distributionChart?.setOption(
|
|
|
@@ -451,7 +534,7 @@ function renderDistributionChart() {
|
|
|
}
|
|
|
|
|
|
function renderTrendChart() {
|
|
|
- trendChart?.setOption(getTrendOption(getFactoryInventoryData(inventoryResult.value)), true)
|
|
|
+ trendChart?.setOption(getInventoryAgingOption(inventoryAgingResult.value), true)
|
|
|
}
|
|
|
|
|
|
function initDistributionChart() {
|
|
|
@@ -467,7 +550,7 @@ function initTrendChart() {
|
|
|
trendChart = initChart(
|
|
|
trendChartRef,
|
|
|
trendChart,
|
|
|
- getTrendOption(getFactoryInventoryData(inventoryResult.value))
|
|
|
+ getInventoryAgingOption(inventoryAgingResult.value)
|
|
|
)
|
|
|
}
|
|
|
|
|
|
@@ -492,19 +575,39 @@ watch(activePanel, (value) => {
|
|
|
renderDistributionChart()
|
|
|
} else {
|
|
|
if (!trendChart) initTrendChart()
|
|
|
- renderTrendChart()
|
|
|
+ requestInventoryAging()
|
|
|
}
|
|
|
resizeCharts()
|
|
|
})
|
|
|
})
|
|
|
|
|
|
+async function requestInventoryAging() {
|
|
|
+ if (deptId.value === null || !selectedDate.value) return
|
|
|
+
|
|
|
+ try {
|
|
|
+ const response = await IotStatApi.getInventoryAging({
|
|
|
+ fdate: selectedDate.value,
|
|
|
+ dept: deptId.value
|
|
|
+ })
|
|
|
+ const data = response?.data ?? response
|
|
|
+
|
|
|
+ if (data && typeof data === 'object') {
|
|
|
+ inventoryAgingResult.value = data as InventoryAgingResponse
|
|
|
+ if (!trendChart) initTrendChart()
|
|
|
+ renderTrendChart()
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取库存积压趋势数据失败', error)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
async function requestInventoryDistribution() {
|
|
|
if (deptId.value === null || !selectedDate.value) return
|
|
|
|
|
|
try {
|
|
|
const response = await IotStatApi.getInventoryDistribution({
|
|
|
fdate: selectedDate.value,
|
|
|
- dept: '157'
|
|
|
+ dept: deptId.value
|
|
|
})
|
|
|
const data = response
|
|
|
|
|
|
@@ -524,16 +627,18 @@ onMounted(() => {
|
|
|
window.addEventListener('rhkb:resize', resizeCharts)
|
|
|
})
|
|
|
|
|
|
-let deptId = ref<number | null>(null)
|
|
|
+let deptId = ref<number | string>('157')
|
|
|
|
|
|
onMounted(async () => {
|
|
|
- const users = await getUserProfile()
|
|
|
- deptId.value = users.dept.id
|
|
|
await requestInventoryDistribution()
|
|
|
})
|
|
|
|
|
|
watch(selectedDate, () => {
|
|
|
- requestInventoryDistribution()
|
|
|
+ if (activePanel.value === 'distribution') {
|
|
|
+ requestInventoryDistribution()
|
|
|
+ } else {
|
|
|
+ requestInventoryAging()
|
|
|
+ }
|
|
|
})
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
@@ -560,6 +665,7 @@ onUnmounted(() => {
|
|
|
type="date"
|
|
|
placeholder="选择日期"
|
|
|
:clearable="false"
|
|
|
+ style="width: 120px"
|
|
|
class="inventory-date-picker" />
|
|
|
<el-segmented
|
|
|
v-model="activePanel"
|