From f01487dc504b5118697a1f47b1c22d662f0ad48c Mon Sep 17 00:00:00 2001 From: ljx <15723110242@139.com> Date: Thu, 21 Aug 2025 20:03:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9F=B1=E7=8A=B6=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/tender/index.ts | 49 ++++++++ src/views/contract/limitPrice/index.vue | 13 ++- .../largeScreen/components/optionList.ts | 107 +++++++++++------- .../largeScreen/components/rightPage.vue | 96 +++++++++++++++- src/views/tender/plan/index.vue | 79 ++++++++++--- 5 files changed, 285 insertions(+), 59 deletions(-) diff --git a/src/api/tender/index.ts b/src/api/tender/index.ts index 2ebb22b..65a71a6 100644 --- a/src/api/tender/index.ts +++ b/src/api/tender/index.ts @@ -42,3 +42,52 @@ export const importExcelFile = (query: any, data: any): AxiosPromise => { data }); }; + +//招标计划列表 + +export const tenderPlanList = (query: any): AxiosPromise => { + return request({ + url: '/tender/biddingPlan/list', + method: 'get', + params: query + }); +}; +//新增招标计划 +export const addTenderPlan = (query: any): AxiosPromise => { + return request({ + url: '/tender/biddingPlan', + method: 'post', + data: query + }); +}; +//删除招标计划 +export const delTenderPlan = (query: any): AxiosPromise => { + return request({ + url: '/tender/biddingPlan/' + query.ids, + method: 'delete' + }); +}; +//修改招标计划 +export const updateTenderPlan = (query: any): AxiosPromise => { + return request({ + url: '/tender/biddingPlan', + method: 'put', + data: query + }); +}; +//弹窗数据 +export const treeList = (query: any): AxiosPromise => { + return request({ + url: '/tender/tenderPlanLimitList/getTree', + method: 'get', + params: query + }); +}; +//获取招标计划详情 +export const getTenderPlanDetail = (query: any): AxiosPromise => { + return request({ + url: '/tender/biddingPlan/getMore', + method: 'get', + params: query + }); +}; diff --git a/src/views/contract/limitPrice/index.vue b/src/views/contract/limitPrice/index.vue index 8f5b608..21233d1 100644 --- a/src/views/contract/limitPrice/index.vue +++ b/src/views/contract/limitPrice/index.vue @@ -3,11 +3,11 @@ - + @@ -100,6 +100,7 @@ const getVersionNums = async () => { try { const params = { projectId: currentProject.value?.id, + workOrderType: '1', pageSize: 1000, pageNum: 1 }; @@ -140,8 +141,8 @@ const changeSheet = () => { const getSheetName = async () => { try { const params = { - projectId: currentProject.value?.id - // versions: queryForm.value.versions + projectId: currentProject.value?.id, + versions: queryForm.value.versions }; const res = await sheetList(params); if (res.code == 200) { @@ -268,8 +269,8 @@ onUnmounted(() => { listeningProject(); }); onMounted(() => { - // getVersionNums(); - getSheetName(); + getVersionNums(); + // getSheetName(); }); diff --git a/src/views/largeScreen/components/optionList.ts b/src/views/largeScreen/components/optionList.ts index b0ba838..ceffe50 100644 --- a/src/views/largeScreen/components/optionList.ts +++ b/src/views/largeScreen/components/optionList.ts @@ -303,7 +303,10 @@ export const getLineOption = (lineData: any) => { show: false }, axisTick: { - show: true + show: false + }, + splitLine: { + show: false }, axisLabel: { textStyle: { @@ -316,7 +319,7 @@ export const getLineOption = (lineData: any) => { type: 'value', max: maxData, splitLine: { - show: true, + show: false, lineStyle: { type: 'solid', color: 'rgba(73, 169, 191, 0.2)' @@ -693,16 +696,16 @@ export const getBarOptions = (data: any) => { const option = { backgroundColor: '', grid: { - left: '7%', + left: '8%', top: '4%', - bottom: '25%', + bottom: '8%', right: '2%' }, tooltip: { show: true, backgroundColor: '', trigger: 'axis', - formatter: '{b0}:{c0}元', + formatter: '{b0}:{c0}万元', textStyle: { color: '#fff' } @@ -727,7 +730,7 @@ export const getBarOptions = (data: any) => { // show: true, }, splitLine: { - show: true, + show: false, lineStyle: { color: 'rgba(108, 128, 151, 0.3)', type: 'dashed' @@ -739,9 +742,7 @@ export const getBarOptions = (data: any) => { { axisLabel: { formatter: function (value) { - if (value >= 1000) { - value = (value / 1000).toFixed(1) + 'k'; // 大于等于1000的数字显示为1k、2.5k等 - } + value = value + '万'; return value; }, color: 'rgba(255, 255, 255, 0.8)' @@ -755,7 +756,7 @@ export const getBarOptions = (data: any) => { } }, splitLine: { - show: true, + show: false, lineStyle: { color: 'rgba(108, 128, 151, 0.3)', type: 'dashed' @@ -763,24 +764,25 @@ export const getBarOptions = (data: any) => { } } ], - dataZoom: [ - { - // show: true, - start: 0, - end: 30, - bottom: 2, // 下滑块距离x轴底部的距离 - height: 23 - }, - { - type: 'inside' - } - ], + // dataZoom: [ + // { + // // show: true, + // start: 0, + // end: 30, + // bottom: 2, // 下滑块距离x轴底部的距离 + // height: 23 + // }, + // { + // type: 'inside' + // } + // ], series: [ { type: 'bar', - data: data.value, - stack: '合并', - barWidth: '15', + data: data.value[0], + // stack: '合并', + barWidth: '5', + barGap: '100%', itemStyle: { color: new echarts.graphic.LinearGradient( 0, @@ -790,22 +792,60 @@ export const getBarOptions = (data: any) => { [ { offset: 0, - color: 'rgba(0, 111, 255, 0)' // 0% 处的颜色 + color: ' rgba(29, 214, 255, 1)' // 0% 处的颜色 }, { offset: 0.7, - color: 'rgba(0, 111, 255, 0.5)' // 0% 处的颜色 + color: ' rgba(29, 214, 255, 0.5)' // 0% 处的颜色 }, { offset: 1, - color: 'rgba(0, 111, 255, 1)' // 100% 处的颜色 + color: ' rgba(29, 214, 255, 0.1)' // 100% 处的颜色 } ], false ) }, label: { - show: true, + show: false, + formatter: '{c}', + position: 'top', + color: '#fff', + fontSize: 10 + // padding: 5 + } + }, + { + type: 'bar', + data: data.value[1], + // stack: '合并', + barWidth: '5', + barGap: '100%', + itemStyle: { + color: new echarts.graphic.LinearGradient( + 0, + 0, + 0, + 1, + [ + { + offset: 0, + color: ' rgba(255, 77, 79, 1)' // 0% 处的颜色 + }, + { + offset: 0.7, + color: ' rgba(255, 77, 79, 0.5)' // 0% 处的颜色 + }, + { + offset: 1, + color: ' rgba(255, 77, 79, 0.1)' // 100% 处的颜色 + } + ], + false + ) + }, + label: { + show: false, formatter: '{c}', position: 'top', color: '#fff', @@ -813,15 +853,6 @@ export const getBarOptions = (data: any) => { // padding: 5 } } - // { - // type: 'bar', - // stack: '合并', - // data: topData, - // barWidth: '15', - // itemStyle: { - // color: 'rgba(252, 217, 18, 1)' - // } - // } ] }; return option; diff --git a/src/views/largeScreen/components/rightPage.vue b/src/views/largeScreen/components/rightPage.vue index a87ed17..0df2f6d 100644 --- a/src/views/largeScreen/components/rightPage.vue +++ b/src/views/largeScreen/components/rightPage.vue @@ -8,6 +8,32 @@
+
+
+
现金流入
+
1000000
+
万元
+
+
+
现金流出
+
1000000
+
万元
+
+
+
净现金流
+
1000000
+
万元
+
+
+
+ +
+
+
+
项目进度
+
100%
+
+
@@ -18,6 +44,8 @@ import EchartBox from '@/components/EchartBox/index.vue'; import { getLineOption, getBarOptions } from './optionList'; const lineOption = ref(); +const barOption = ref(); + const getCapitalData = (data?: any) => { // const xData = data.map((item) => item.time); // const yData = data.map((item) => item.content); @@ -33,8 +61,26 @@ const getCapitalData = (data?: any) => { }; lineOption.value = getLineOption(lineData); }; +const getTurnoverList = (data?: any) => { + // const xData = data.map((item) => item.time); + // const yData = data.map((item) => { + // // 先将content转换为数字,再调用toFixed + // const num = Number(item.content); + // return isNaN(num) ? 0 : Number(num.toFixed(2)); + // }); + + const barData = { + name: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], + value: [ + [2, 5, 15, 30, 25, 35, 40, 35, 45, 50, 40, 55], + [4, 3, 6, 11, 15, 22, 30, 14, 48, 22, 25, 60] + ] + }; + barOption.value = getBarOptions(barData); +}; onMounted(() => { getCapitalData(); + getTurnoverList(); }); //资金KPI @@ -57,7 +103,7 @@ onMounted(() => { } .funds_echarts { width: 100%; - height: 35vh; + height: 25vh; padding: 10px 0 0 0; } .cashFlow { @@ -68,4 +114,52 @@ onMounted(() => { padding: 10px 5px; margin-top: 20px; } +.inflowData { + width: 100%; + height: 12vh; + // background: #fff; + padding-top: 20px; + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-gap: 10px; + .inflow { + width: 100%; + height: 100%; + // background: #f5f5f5; + padding: 10px; + box-sizing: border-box; + background: rgba(29, 214, 255, 0.1); + border-left: 1px solid rgba(29, 214, 255, 1); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + .title { + font-size: 14px; + // font-weight: 500; + color: #fff; + padding-bottom: 10px; + } + .number { + font-size: 24px; + // font-weight: 500; + color: #fff; + padding-bottom: 10px; + } + .unit { + font-size: 12px; + // font-weight: 500; + color: rgba(255, 255, 255, 0.5); + } + } +} +.inflow_echarts { + width: 100%; + height: 25vh; + margin-top: 20px; +} +.progress { + width: 100%; +} diff --git a/src/views/tender/plan/index.vue b/src/views/tender/plan/index.vue index 806a616..a7d5883 100644 --- a/src/views/tender/plan/index.vue +++ b/src/views/tender/plan/index.vue @@ -64,6 +64,11 @@ + + + + + @@ -146,7 +151,16 @@ import { useUserStoreHook } from '@/store/modules/user'; import { getDicts } from '@/api/system/dict/data'; import { Plus } from '@element-plus/icons-vue'; import { FormInstance } from 'element-plus'; -import { treeList, sheetList, segmentedIndicatorPlanning, getPlanningList, updatePlanning, delPlanning, getDetailsList } from '@/api/contract/index'; +import { + sheetList, + tenderPlanList, + addTenderPlan, + delTenderPlan, + updateTenderPlan, + treeList, + getTenderPlanDetail, + obtainAllVersionNumbers +} from '@/api/tender/index'; const userStore = useUserStoreHook(); const currentProject = computed(() => userStore.selectedProject); @@ -175,6 +189,9 @@ const rules = ref({ content: [{ required: true, message: '请输入内容', trigger: 'blur' }] }); const loading = ref(false); +const planType = computed(() => { + return activeTab.value == '2' ? '3' : '2'; +}); //字典获取数据 const getTabsList = async () => { @@ -198,9 +215,10 @@ const getList = async () => { projectId: currentProject.value?.id, ...queryParams.value, ...queryForm.value, - dictName: activeTab.value + dictName: activeTab.value, + type: planType.value }; - const res = await getPlanningList(params); + const res = await tenderPlanList(params); if (res.code == 200) { tableData.value = res.rows; total.value = res.total; @@ -234,7 +252,7 @@ const resetQuery = () => { const openDialog = () => { dialogVisible.value = true; - getSheetName(); + getVersionNums(); }; const closeDialog = () => { dialogVisible.value = false; @@ -246,19 +264,50 @@ const closeDialog = () => { }; const treeData = ref([]); const treeForm = ref({ - sheet: '' + sheet: '', + versions: '' }); const sheets = ref([]); const treeTableRef = ref(); const isExpandAll = ref(false); const treeLoading = ref(false); const selectionData = ref([]); +const options = ref([]); +//切换版本 +const changeVersions = () => { + getSheetName(); +}; +//获取版本号 +const getVersionNums = async () => { + try { + const params = { + projectId: currentProject.value?.id, + workOrderType: planType.value, + pageSize: 1000, + pageNum: 1 + }; + + const res = await obtainAllVersionNumbers(params); + if (res.code == 200) { + options.value = res.data; + if (res.data.length > 0) { + treeForm.value.versions = res.data[0].versions; + getSheetName(); + } else { + treeForm.value.versions = ''; + getSheetName(); + } + } + } catch (error) { + console.log(error); + } +}; //获取表名 const getSheetName = async () => { try { const params = { - projectId: currentProject.value?.id - // versions: queryForm.value.versions + projectId: currentProject.value?.id, + versions: treeForm.value.versions }; const res = await sheetList(params); if (res.code == 200) { @@ -333,7 +382,9 @@ const getTreeList = async () => { treeLoading.value = true; const params = { projectId: currentProject.value?.id, - sheet: treeForm.value.sheet + sheet: treeForm.value.sheet, + versions: treeForm.value.versions, + type: planType.value }; const res = await treeList(params); if (res.code == 200) { @@ -381,10 +432,10 @@ const submitForm = async (formEl: FormInstance | undefined) => { ...form.value, dictName: activeTab.value, limitListBos, - type: activeTab.value == '2' ? '3' : '2' + type: planType.value }; - return; - const res = await segmentedIndicatorPlanning(params); + + const res = await addTenderPlan(params); if (res.code == 200) { ElMessage({ message: '新增成功', @@ -411,7 +462,7 @@ const handleSave = (row: any) => { }); return; } - updatePlanning(row).then((res) => { + updateTenderPlan({ ...row, type: planType.value }).then((res) => { if (res.code == 200) { ElMessage({ message: '修改成功', @@ -432,7 +483,7 @@ const handleSave = (row: any) => { const delHandle = (row: any) => { try { const params = { ids: row.id }; - delPlanning(params).then((res) => { + delTenderPlan(params).then((res) => { if (res.code == 200) { ElMessage({ message: '删除成功', @@ -459,7 +510,7 @@ const handleDetail = (row: any) => { getDetails(row); }; const getDetails = (row: any) => { - getDetailsList({ id: row.id }).then((res) => { + getTenderPlanDetail({ id: row.id }).then((res) => { if (res.code == 200) { detailData.value = res.data; }