| | |
| | | // é¦é¡µæ¥å£ |
| | | import request from '@/utils/request' |
| | | import request from "@/utils/request"; |
| | | |
| | | // éå®-éè´-åºåæ°æ® |
| | | export const getBusiness = () => { |
| | | return request({ |
| | | url: '/home/business', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/business", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | // 客æ·ååéé¢åæ |
| | | export const analysisCustomerContractAmounts = () => { |
| | | return request({ |
| | | url: '/home/analysisCustomerContractAmounts', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/analysisCustomerContractAmounts", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | // è´¨æ£åæ |
| | | export const qualityStatistics = () => { |
| | | return request({ |
| | | url: '/home/qualityStatistics', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/qualityStatistics", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | // åºæ¶åºä»ç»è®¡ |
| | | export const statisticsReceivablePayable = (query) => { |
| | | return request({ |
| | | url: '/home/statisticsReceivablePayable', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/statisticsReceivablePayable", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | }; |
| | | // å¾
åäºé¡¹ |
| | | export const homeTodos = () => { |
| | | return request({ |
| | | url: '/home/todos', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/todos", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | // çº¿å½¢å¾ |
| | | export const getAmountHalfYear = () => { |
| | | return request({ |
| | | url: '/sales/ledger/getAmountHalfYear', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/sales/ledger/getAmountHalfYear", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | // åç产订åç宿è¿åº¦ç»è®¡ |
| | | // /home/progressStatistics |
| | | export const getProgressStatistics = ()=>{ |
| | | return request({ |
| | | url: '/home/progressStatistics', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | export const getProgressStatistics = () => { |
| | | return request({ |
| | | url: "/home/progressStatistics", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | //å¨å¶åå¨è½¬æ
åµ |
| | | //home/workInProcessTurnover |
| | | export const getWorkInProcessTurnover = () => { |
| | | return request({ |
| | | url: '/home/workInProcessTurnover', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/workInProcessTurnover", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | // 客æ·è¥æ¶è´¡ç®æ°å¼åæ |
| | | export const customerRevenueAnalysis = (params) => { |
| | | return request({ |
| | | url: '/home/customerRevenueAnalysis', |
| | | method: 'get', |
| | | params |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/customerRevenueAnalysis", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // åå·¥-客æ·-ä¾åºåæ»æ° |
| | | export const summaryStatistics = () => { |
| | | return request({ |
| | | url: '/home/summaryStatistics', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/summaryStatistics", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | // åé¨é¨äººååå¸ |
| | | export const deptStaffDistribution = () => { |
| | | return request({ |
| | | url: '/home/deptStaffDistribution', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/deptStaffDistribution", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | // ä¾åºåéè´æå |
| | | export const supplierPurchaseRanking = (query) => { |
| | | return request({ |
| | | url: '/home/supplierPurchaseRanking', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/supplierPurchaseRanking", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | }; |
| | | |
| | | // 客æ·éé¢è´¡ç®æå |
| | | export const customerContributionRanking = (query) => { |
| | | return request({ |
| | | url: '/home/customerContributionRanking', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/customerContributionRanking", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | }; |
| | | |
| | | // å产å大类åå¸ |
| | | export const productCategoryDistribution = () => { |
| | | return request({ |
| | | url: '/home/productCategoryDistribution', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/productCategoryDistribution", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | // 产åéå®éé¢åæ |
| | | export const productSalesAnalysis = () => { |
| | | return request({ |
| | | url: '/home/productSalesAnalysis', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/productSalesAnalysis", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | // åææéè´éé¢å æ¯ |
| | | export const rawMaterialPurchaseAmountRatio = () => { |
| | | return request({ |
| | | url: '/home/rawMaterialPurchaseAmountRatio', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/rawMaterialPurchaseAmountRatio", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | // éå®/éè´/å¨åäº§åæ° |
| | | export const salesPurchaseStorageProductCount = () => { |
| | | return request({ |
| | | url: '/home/salesPurchaseStorageProductCount', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/salesPurchaseStorageProductCount", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | // 产ååºå
¥åºåæï¼å¯ä¼ productType: 1 åææ 2 åæå 3 æåï¼ |
| | | export const productInOutAnalysis = (params) => { |
| | | return request({ |
| | | url: '/home/productInOutAnalysis', |
| | | method: 'get', |
| | | params |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/productInOutAnalysis", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // 产åå¨è½¬å¤©æ° |
| | | export const productTurnoverDays = () => { |
| | | return request({ |
| | | url: '/home/productTurnoverDays', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | return request({ |
| | | url: "/home/productTurnoverDays", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | // æ¶æ¯å¯¹æ¯åæ |
| | | export const incomeExpenseAnalysis = () => { |
| | | return request({ |
| | | url: "/home/incomeExpenseAnalysis", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | // 婿¶¦è¶å¿åæ |
| | | export const profitTrendAnalysis = () => { |
| | | return request({ |
| | | url: "/home/profitTrendAnalysis", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | // æåº¦æ¶å
¥ |
| | | export const getMonthlyIncome = () => { |
| | | return request({ |
| | | url: "/home/monthlyIncome", |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | // æåº¦æ¯åº |
| | | export const getMonthlyExpenditure = () => { |
| | | return request({ |
| | | url: "/home/monthlyExpenditure", |
| | | method: "get", |
| | | }); |
| | | }; |
| | |
| | | class="product-type-switch" |
| | | @change="handleChange" |
| | | > |
| | | <el-radio-button :label="1">åææ</el-radio-button> |
| | | <el-radio-button :label="3">åæå</el-radio-button> |
| | | <el-radio-button :label="2">æå</el-radio-button> |
| | | <el-radio-button |
| | | v-for="opt in options" |
| | | :key="opt.label" |
| | | :label="opt.label" |
| | | > |
| | | {{ opt.text }} |
| | | </el-radio-button> |
| | | </el-radio-group> |
| | | </template> |
| | | |
| | |
| | | |
| | | const props = defineProps({ |
| | | modelValue: { |
| | | type: Number, |
| | | default: 1, // é»è®¤éä¸"åææ" |
| | | type: [Number, String], |
| | | default: 1, // é»è®¤éä¸ç¬¬ä¸ä¸ª |
| | | }, |
| | | // å¯é
ç½®é项ï¼é»è®¤æ¯åç»ä»¶çãåææ / åæå / æåã |
| | | options: { |
| | | type: Array, |
| | | default: () => [ |
| | | { label: 1, text: 'åææ' }, |
| | | { label: 3, text: 'åæå' }, |
| | | { label: 2, text: 'æå' }, |
| | | ], |
| | | }, |
| | | }) |
| | | |
| | |
| | | import { ref, onMounted } from 'vue' |
| | | import Echarts from '@/components/Echarts/echarts.vue' |
| | | import PanelHeader from './PanelHeader.vue' |
| | | import { profitTrendAnalysis } from '@/api/viewIndex.js' |
| | | |
| | | const chartStyle = { width: '100%', height: '150%' } |
| | | const grid = { left: '3%', right: '4%', bottom: '3%', top: '4%', containLabel: true } |
| | |
| | | |
| | | const yAxis1 = [{ type: 'value', axisLabel: { color: '#B8C8E0' } }] |
| | | |
| | | const fetchData = () => { |
| | | profitTrendAnalysis() |
| | | .then((res) => { |
| | | if (res.code === 200 && Array.isArray(res.data)) { |
| | | const list = res.data |
| | | xAxis1.value[0].data = list.map((d) => d.name) |
| | | barSeries1.value[0].data = list.map((d) => parseFloat(d.value) || 0) |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | console.error('è·å婿¶¦è¶å¿åæå¤±è´¥:', err) |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | // å
ç¨æ¬å°åæ°æ®ï¼åç»å¦ææ¥å£å¯æ¿æ¢ï¼ |
| | | xAxis1.value[0].data = ['1æ', '2æ', '3æ', '4æ', '5æ', '6æ'] |
| | | barSeries1.value[0].data = [12000, 18000, 9000, 16000, 14000, 20000] |
| | | fetchData() |
| | | }) |
| | | </script> |
| | | |
| | |
| | | import { ref, onMounted } from 'vue' |
| | | import * as echarts from 'echarts' |
| | | import Echarts from '@/components/Echarts/echarts.vue' |
| | | import { incomeExpenseAnalysis } from '@/api/viewIndex.js' |
| | | |
| | | const chartStyle = { width: '100%', height: '100%' } |
| | | const grid = { |
| | |
| | | }, |
| | | } |
| | | |
| | | // å
ç¨æ¬å°åæ°æ®ï¼åç»å¦ææ¥å£å¯ç´æ¥æ¿æ¢è¿éï¼ |
| | | const setMockData = () => { |
| | | const dates = ['1/22', '1/23', '1/24', '1/25', '1/26', '1/27', '1/28'] |
| | | xAxis1.value[0].data = dates |
| | | lineSeries.value[0].data = [1200, 1800, 900, 1600, 1400, 2000, 1700] // æ¶å
¥ |
| | | lineSeries.value[1].data = [800, 1100, 700, 1200, 1000, 1500, 1300] // æ¯åº |
| | | const fetchData = () => { |
| | | incomeExpenseAnalysis() |
| | | .then((res) => { |
| | | if (res.code === 200 && Array.isArray(res.data)) { |
| | | const list = res.data |
| | | xAxis1.value[0].data = list.map((d) => d.date) |
| | | lineSeries.value[0].data = list.map((d) => Number(d.income) || 0) |
| | | lineSeries.value[1].data = list.map((d) => Number(d.expense) || 0) |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | console.error('è·åæ¶æ¯å¯¹æ¯åæå¤±è´¥:', err) |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | setMockData() |
| | | fetchData() |
| | | }) |
| | | </script> |
| | | |
| | |
| | | <div class="card-body"> |
| | | <div class="card-left"> |
| | | <div class="card-title">æåº¦æ¶å
¥</div> |
| | | <div class="card-amount">{{ income.amount }}</div> |
| | | <div class="card-amount"> |
| | | <span>{{ formatAmountWanNumber(income.amount) }}</span> |
| | | <span v-if="isWanAmount(income.amount)" class="card-amount-unit">ä¸</span> |
| | | </div> |
| | | </div> |
| | | <div class="card-right"> |
| | | <div class="metric-row"> |
| | |
| | | </div> |
| | | <div class="metric-row"> |
| | | <span class="metric-label">龿æ°</span> |
| | | <span class="metric-value metric-up">{{ income.overdueCount }}</span> |
| | | <span class="metric-value metric-up"> |
| | | {{ formatAmountWanNumber(income.overdueCount) }} |
| | | <span |
| | | v-if="isWanAmount(income.overdueCount)" |
| | | class="metric-unit" |
| | | > |
| | | ä¸ |
| | | </span> |
| | | </span> |
| | | </div> |
| | | <div class="metric-row"> |
| | | <span class="metric-label">龿ç</span> |
| | |
| | | <div class="card-body"> |
| | | <div class="card-left"> |
| | | <div class="card-title">æåº¦æ¯åº</div> |
| | | <div class="card-amount">{{ expense.amount }}</div> |
| | | <div class="card-amount"> |
| | | <span>{{ formatAmountWanNumber(expense.amount) }}</span> |
| | | <span v-if="isWanAmount(expense.amount)" class="card-amount-unit">ä¸</span> |
| | | </div> |
| | | </div> |
| | | <div class="card-right"> |
| | | <div class="metric-row"> |
| | | <span class="metric-label">仿¬¾ç</span> |
| | | <span class="metric-value metric-down">{{ expense.netProfit }}</span> |
| | | <span class="metric-value" :class="metricClass(expense.netProfit)"> |
| | | {{ formatPercent(expense.netProfit.value) }} |
| | | <span class="arrow">{{ metricArrow(expense.netProfit) }}</span> |
| | | </span> |
| | | </div> |
| | | <div class="metric-row"> |
| | | <span class="metric-label">æ¯å©æ¶¦</span> |
| | | <span class="metric-value metric-down">{{ expense.grossProfit }}</span> |
| | | <span class="metric-value metric-down"> |
| | | {{ formatAmountWanNumber(expense.grossProfit) }} |
| | | <span |
| | | v-if="isWanAmount(expense.grossProfit)" |
| | | class="metric-unit" |
| | | > |
| | | ä¸ |
| | | </span> |
| | | </span> |
| | | </div> |
| | | <div class="metric-row"> |
| | | <span class="metric-label">婿¶¦ç</span> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue' |
| | | import { onMounted, ref } from 'vue' |
| | | import { getMonthlyIncome, getMonthlyExpenditure } from '@/api/viewIndex' |
| | | |
| | | // ææ¶ä½¿ç¨æ¬å°ç¤ºä¾æ°æ®ï¼åç»å¯æ¥ç宿¥å£è¦ç |
| | | const income = ref({ |
| | | amount: 102, |
| | | repayRate: { value: 52, trend: 1 }, // æ£å â |
| | | overdueCount: 10092, |
| | | overdueRate: { value: 12, trend: 1 }, |
| | | amount: 0, |
| | | repayRate: { value: 0, trend: 0 }, |
| | | overdueCount: 0, |
| | | overdueRate: { value: 0, trend: 0 }, |
| | | }) |
| | | |
| | | const expense = ref({ |
| | | amount: 102, |
| | | netProfit: 291013, |
| | | grossProfit: 10092, |
| | | profitRate: { value: 12, trend: -1 }, // è´å â |
| | | amount: 0, |
| | | netProfit: { value: 0, trend: 0 }, |
| | | grossProfit: 0, |
| | | profitRate: { value: 0, trend: 0 }, |
| | | }) |
| | | |
| | | const fetchMonthlyIncome = async () => { |
| | | const res = await getMonthlyIncome() |
| | | const data = res?.data || {} |
| | | |
| | | income.value.amount = data.monthlyIncome ?? 0 |
| | | const collectionRate = Number(data.collectionRate ?? 0) |
| | | const overdueRate = Number(data.overdueRate ?? 0) |
| | | income.value.repayRate = { |
| | | value: collectionRate, |
| | | trend: collectionRate >= 0 ? 1 : -1, |
| | | } |
| | | income.value.overdueCount = data.overdueNum ?? 0 |
| | | income.value.overdueRate = { |
| | | value: overdueRate, |
| | | trend: overdueRate >= 0 ? 1 : -1, |
| | | } |
| | | } |
| | | |
| | | const fetchMonthlyExpenditure = async () => { |
| | | const res = await getMonthlyExpenditure() |
| | | const data = res?.data || {} |
| | | |
| | | expense.value.amount = data.monthlyExpenditure ?? 0 |
| | | const paymentRate = Number(data.paymentRate ?? 0) |
| | | expense.value.netProfit = { |
| | | value: paymentRate, |
| | | trend: paymentRate >= 0 ? 1 : -1, |
| | | } |
| | | expense.value.grossProfit = data.grossProfit ?? 0 |
| | | |
| | | const profitMarginRate = Number(data.profitMarginRate ?? 0) |
| | | expense.value.profitRate = { |
| | | value: profitMarginRate, |
| | | trend: profitMarginRate >= 0 ? 1 : -1, |
| | | } |
| | | } |
| | | |
| | | const isWanAmount = (val) => { |
| | | const num = Number(val) || 0 |
| | | return Math.abs(num) >= 10000 |
| | | } |
| | | |
| | | const formatAmountWanNumber = (val) => { |
| | | const num = Number(val) || 0 |
| | | if (Math.abs(num) >= 10000) { |
| | | return (num / 10000).toFixed(2) |
| | | } |
| | | return num.toFixed(2) |
| | | } |
| | | |
| | | const formatPercent = (val) => { |
| | | const num = Number(val) || 0 |
| | | return `${num.toFixed(2)}%` |
| | | // ç¾åæ¯å±ç¤ºå§ç»ç¨ç»å¯¹å¼ï¼å°æ°ä¿çä¸¤ä½ |
| | | return `${Math.abs(num).toFixed(2)}%` |
| | | } |
| | | |
| | | const metricClass = (metric) => |
| | | Number(metric.trend) >= 0 ? 'metric-up' : 'metric-down' |
| | | const metricClass = (metric) => { |
| | | if (metric?.trend === undefined || metric?.trend === null) return 'metric-up' |
| | | return Number(metric.trend) >= 0 ? 'metric-up' : 'metric-down' |
| | | } |
| | | |
| | | const metricArrow = (metric) => |
| | | Number(metric.trend) >= 0 ? 'â' : 'â' |
| | | const metricArrow = (metric) => { |
| | | if (metric?.trend === undefined || metric?.trend === null) return '' |
| | | return Number(metric.trend) >= 0 ? 'â' : 'â' |
| | | } |
| | | |
| | | onMounted(() => { |
| | | fetchMonthlyIncome() |
| | | fetchMonthlyExpenditure() |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 18px 24px; |
| | | padding: 18px 10px; |
| | | background-image: url('@/assets/BI/border@2x.png'); |
| | | background-size: 100% 100%; |
| | | background-position: center; |
| | |
| | | font-size: 36px; |
| | | line-height: 1.1; |
| | | margin-top: 8px; |
| | | display: inline-flex; |
| | | align-items: baseline; |
| | | white-space: nowrap; |
| | | background: linear-gradient(360deg, #008bfd 0%, #ffffff 100%); |
| | | -webkit-background-clip: text; |
| | | -webkit-text-fill-color: transparent; |
| | | background-clip: text; |
| | | } |
| | | |
| | | .card-amount-unit { |
| | | font-size: 20px; |
| | | margin-left: 4px; |
| | | } |
| | | |
| | | .card-right { |
| | |
| | | align-items: center; |
| | | } |
| | | |
| | | .metric-unit { |
| | | font-size: 12px; |
| | | margin-left: 2px; |
| | | } |
| | | |
| | | .metric-value .arrow { |
| | | font-size: 13px; |
| | | margin-left: 4px; |
| | |
| | | <template> |
| | | <div> |
| | | <PanelHeader title="æ¯åºææåæ" /> |
| | | <PanelHeader title="ææåæ" /> |
| | | <div class="main-panel panel-item-customers"> |
| | | <div class="filters-row"> |
| | | <ProductTypeSwitch |
| | | v-model="amountType" |
| | | :options="amountTypeOptions" |
| | | @change="handleTypeChange" |
| | | /> |
| | | </div> |
| | | <!-- <CarouselCards :items="cardItems" :visible-count="3" /> --> |
| | | <div class="pie-chart-wrapper"> |
| | | <div class="pie-background"></div> |
| | |
| | | import { ref, onMounted, computed } from 'vue' |
| | | import Echarts from '@/components/Echarts/echarts.vue' |
| | | import PanelHeader from './PanelHeader.vue' |
| | | import CarouselCards from './CarouselCards.vue' |
| | | import ProductTypeSwitch from './ProductTypeSwitch.vue' |
| | | import { rawMaterialPurchaseAmountRatio } from '@/api/viewIndex.js' |
| | | |
| | | /** |
| | |
| | | } |
| | | return resObj |
| | | } |
| | | |
| | | // å½åç±»åï¼1=æ¯åº 2=æ¶å
¥ |
| | | const amountType = ref(1) |
| | | |
| | | const amountTypeOptions = [ |
| | | { label: 1, text: 'æ¯åº' }, |
| | | { label: 2, text: 'æ¶å
¥' }, |
| | | ] |
| | | |
| | | // æ°æ®åè¡¨ï¼æ¥èªæ¥å£ï¼ |
| | | const dataList = ref([]) |
| | |
| | | top: 'center', |
| | | left: '52%', |
| | | itemGap: 30, |
| | | show: false, |
| | | show: true, |
| | | data: data, |
| | | formatter: function (name) { |
| | | const item = landObjData.value[name] |
| | |
| | | } |
| | | |
| | | // åå±ç¯å½¢é¥¼å¾ |
| | | // åå±ç¯å½¢é¥¼å¾ |
| | | const landSeries = ref([ |
| | | { |
| | | name: '产åéè´éé¢åæ', |
| | | name: 'ææåæ', |
| | | type: 'pie', |
| | | radius: ['50%', '75%'], |
| | | center: ['50%', '60%'], |
| | | radius: ['40%', '60%'], |
| | | center: ['25%', '50%'], |
| | | itemStyle: { |
| | | borderColor: '#0a1c3a', |
| | | borderWidth: 2, |
| | |
| | | }, |
| | | }, |
| | | label: { |
| | | show: true, |
| | | position: 'outside', |
| | | color: '#fff', |
| | | fontSize: 12, |
| | | lineHeight: 18, |
| | | // rich: { |
| | | // ...dotRich, |
| | | // parent: { fontSize: 14, fontWeight: 600, color: '#fff', lineHeight: 20, overflow: 'break' }, |
| | | // child: { fontSize: 12, color: '#fff', lineHeight: 18 }, |
| | | // }, |
| | | show: false |
| | | }, |
| | | minAngle: 15, |
| | | data: dataList.value, |
| | |
| | | { |
| | | // å
å |
| | | type: 'pie', |
| | | radius: ['50%', '60%'], |
| | | center: ['50%', '60%'], |
| | | radius: ['40%', '45%'], |
| | | center: ['25%', '50%'], |
| | | silent: true, |
| | | label: { |
| | | show: false, |
| | |
| | | } |
| | | |
| | | const fetchData = () => { |
| | | // ç®åæ¥å£åªææ¯åºææå æ¯ï¼å
忽ç¥ç±»ååæ° |
| | | // é¢çæ©å±ï¼åç»å¯æ ¹æ® amountType åä¸åæ¥å£ |
| | | rawMaterialPurchaseAmountRatio() |
| | | .then((res) => { |
| | | if (res.code === 200 && Array.isArray(res.data)) { |
| | |
| | | }) |
| | | } |
| | | |
| | | const handleTypeChange = () => { |
| | | fetchData() |
| | | } |
| | | |
| | | onMounted(() => { |
| | | fetchData() |
| | | }) |
| | |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20px; |
| | | } |
| | | |
| | | .filters-row { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | align-items: center; |
| | | gap: 12px; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .panel-item-customers { |
| | |
| | | |
| | | .pie-background { |
| | | position: absolute; |
| | | left: 50%; |
| | | top: 60%; |
| | | left: 25%; |
| | | top: 50%; |
| | | transform: translate(-51.5%, -50%); |
| | | width: 380px; |
| | | height: 380px; |
| | | width: 310px; |
| | | height: 310px; |
| | | background-image: url('@/assets/BI/ç«ç°å¾è¾¹æ¡.png'); |
| | | background-size: contain; |
| | | background-position: center; |
| | |
| | | |
| | | <script setup> |
| | | import { ref, onMounted } from 'vue' |
| | | import { productSalesAnalysis } from '@/api/viewIndex.js' |
| | | import { getAmountHalfYear } from '@/api/viewIndex.js' |
| | | import PanelHeader from './PanelHeader.vue' |
| | | import Echarts from '@/components/Echarts/echarts.vue' |
| | | |
| | |
| | | } |
| | | |
| | | const grid = { left: '3%', right: '4%', bottom: '3%', top: '10%', containLabel: true } |
| | | const barLegend = { show: true, textStyle: { color: '#B8C8E0' }, data: ['éé¢'] } |
| | | const barLegend = { |
| | | show: true, |
| | | textStyle: { color: '#B8C8E0' }, |
| | | data: ['å¼ç¥¨éé¢', '忬¾éé¢'], |
| | | } |
| | | const barSeries1 = ref([ |
| | | { |
| | | name: 'éé¢', |
| | | name: 'å¼ç¥¨éé¢', |
| | | type: 'bar', |
| | | barGap: 0, |
| | | barWidth: 30, |
| | | barWidth: 20, |
| | | emphasis: { focus: 'series' }, |
| | | itemStyle: { |
| | | color: { |
| | |
| | | x2: 0, |
| | | y2: 1, |
| | | colorStops: [ |
| | | { offset: 1, color: '#00A4ED' }, |
| | | { offset: 0, color: '#4EE4FF' }, |
| | | { offset: 1, color: 'rgba(0, 164, 237, 0)' }, |
| | | { offset: 0, color: 'rgba(78, 228, 255, 1)' }, |
| | | ], |
| | | }, |
| | | }, |
| | | data: [], |
| | | }, |
| | | { |
| | | name: '忬¾éé¢', |
| | | type: 'bar', |
| | | barGap: '40%', |
| | | barWidth: 20, |
| | | emphasis: { focus: 'series' }, |
| | | itemStyle: { |
| | | color: { |
| | | type: 'linear', |
| | | x: 0, |
| | | y: 0, |
| | | x2: 0, |
| | | y2: 1, |
| | | colorStops: [ |
| | | { offset: 1, color: 'rgba(83, 126, 245, 0.19)' }, |
| | | { offset: 0, color: 'rgba(144, 97, 248, 1)' }, |
| | | ], |
| | | }, |
| | | }, |
| | |
| | | const yAxis1 = [{ type: 'value', axisLabel: { color: '#B8C8E0' } }] |
| | | |
| | | const fetchData = () => { |
| | | productSalesAnalysis() |
| | | getAmountHalfYear() |
| | | .then((res) => { |
| | | if (res.code === 200 && Array.isArray(res.data)) { |
| | | const items = res.data |
| | | xAxis1.value[0].data = items.map((item) => item.name) |
| | | barSeries1.value[0].data = items.map((item) => parseFloat(item.value) || 0) |
| | | xAxis1.value[0].data = items.map((item) => item.month) |
| | | barSeries1.value[0].data = items.map( |
| | | (item) => parseFloat(item.invoiceAmount) || 0 |
| | | ) |
| | | barSeries1.value[1].data = items.map( |
| | | (item) => parseFloat(item.receiptAmount) || 0 |
| | | ) |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | console.error('è·å产åéå®éé¢åæå¤±è´¥:', err) |
| | | console.error('è·åè¿å年忬¾ä¸å¼ç¥¨æ°æ®å¤±è´¥:', err) |
| | | }) |
| | | } |
| | | |