Merge branch 'fs' of http://xny.yj-3d.com:3000/taoge/mk_system into tcy
This commit is contained in:
@ -34,6 +34,7 @@
|
||||
"diagram-js": "12.3.0",
|
||||
"didi": "9.0.2",
|
||||
"echarts": "5.5.0",
|
||||
"echarts-gl": "^2.0.9",
|
||||
"element-plus": "2.8.8",
|
||||
"esbuild": "^0.25.0",
|
||||
"ezuikit-js": "^8.1.10",
|
||||
|
44
src/api/tender/index.ts
Normal file
44
src/api/tender/index.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
|
||||
//获取版本
|
||||
export const obtainAllVersionNumbers = (query: any): AxiosPromise<any> => {
|
||||
return request({
|
||||
url: '/tender/tenderPlanLimitList/obtainAllVersionNumbers',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
//获取sheet
|
||||
export const sheetList = (query: any): AxiosPromise<any> => {
|
||||
return request({
|
||||
url: '/tender/tenderPlanLimitList/sheetList',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
//获取表格数据
|
||||
export const getTableList = (query: any): AxiosPromise<any> => {
|
||||
return request({
|
||||
url: '/tender/tenderPlanLimitList/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
//修改单价数据
|
||||
export const updatePrice = (query: any): AxiosPromise<any> => {
|
||||
return request({
|
||||
url: '/tender/tenderPlanLimitList',
|
||||
method: 'put',
|
||||
data: query
|
||||
});
|
||||
};
|
||||
//导入
|
||||
export const importExcelFile = (query: any, data: any): AxiosPromise<any> => {
|
||||
return request({
|
||||
url: '/tender/tenderPlanLimitList/importExcelFile',
|
||||
method: 'post',
|
||||
params: query,
|
||||
data
|
||||
});
|
||||
};
|
169
src/components/EchartBox/index.vue
Normal file
169
src/components/EchartBox/index.vue
Normal file
@ -0,0 +1,169 @@
|
||||
<template>
|
||||
<div ref="echartBox" class="echarts"></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import china from '@/assets/china.json';
|
||||
import cq from '@/assets/cq.json';
|
||||
import { ref, onMounted, watchEffect, onBeforeUnmount } from 'vue';
|
||||
import * as echarts from 'echarts/core';
|
||||
import {
|
||||
BarChart, // 柱状图
|
||||
// 系列类型的定义后缀都为 SeriesOption
|
||||
BarSeriesOption,
|
||||
LineChart, // 折线图
|
||||
LineSeriesOption,
|
||||
PieChart, // 饼图
|
||||
PieSeriesOption,
|
||||
PictorialBarChart,
|
||||
MapChart,
|
||||
ScatterChart,
|
||||
EffectScatterChart,
|
||||
LinesChart
|
||||
} from 'echarts/charts';
|
||||
import {
|
||||
// 组件类型的定义后缀都为 ComponentOption
|
||||
// 标题
|
||||
TitleComponent,
|
||||
TitleComponentOption,
|
||||
// 提示框
|
||||
TooltipComponent,
|
||||
TooltipComponentOption,
|
||||
// 直角坐标系
|
||||
GridComponent,
|
||||
GridComponentOption,
|
||||
// 图例
|
||||
LegendComponent,
|
||||
LegendComponentOption,
|
||||
// 数据集组件
|
||||
DatasetComponent,
|
||||
DatasetComponentOption,
|
||||
// 内置数据转换器组件 (filter, sort)
|
||||
TransformComponent,
|
||||
DataZoomComponent,
|
||||
DataZoomComponentOption,
|
||||
// 极坐标
|
||||
PolarComponent,
|
||||
PolarComponentOption,
|
||||
MarkLineComponentOption,
|
||||
MarkLineComponent,
|
||||
// MarkPoint
|
||||
MarkPointComponent,
|
||||
MarkPointComponentOption,
|
||||
// VisualMap
|
||||
VisualMapComponent,
|
||||
VisualMapComponentOption,
|
||||
// GeoComponent
|
||||
GeoComponent,
|
||||
GeoComponentOption
|
||||
} from 'echarts/components';
|
||||
import { LabelLayout, UniversalTransition } from 'echarts/features';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import 'echarts-gl';
|
||||
|
||||
// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
|
||||
type ECOption = echarts.ComposeOption<
|
||||
| BarSeriesOption
|
||||
| LineSeriesOption
|
||||
| PieSeriesOption
|
||||
| TitleComponentOption
|
||||
| TooltipComponentOption
|
||||
| GridComponentOption
|
||||
| DatasetComponentOption
|
||||
| LegendComponentOption
|
||||
| DataZoomComponentOption
|
||||
| PolarComponentOption
|
||||
| MarkLineComponentOption
|
||||
| MarkPointComponentOption
|
||||
| VisualMapComponentOption
|
||||
| GeoComponentOption
|
||||
>;
|
||||
|
||||
// 注册必须的组件
|
||||
echarts.use([
|
||||
TitleComponent,
|
||||
TooltipComponent,
|
||||
GridComponent,
|
||||
DatasetComponent,
|
||||
TransformComponent,
|
||||
LegendComponent,
|
||||
DataZoomComponent,
|
||||
PolarComponent,
|
||||
MarkLineComponent,
|
||||
MarkPointComponent,
|
||||
LabelLayout,
|
||||
UniversalTransition,
|
||||
CanvasRenderer,
|
||||
BarChart,
|
||||
LineChart,
|
||||
PieChart,
|
||||
VisualMapComponent,
|
||||
PictorialBarChart,
|
||||
GeoComponent,
|
||||
MapChart,
|
||||
ScatterChart,
|
||||
EffectScatterChart,
|
||||
LinesChart
|
||||
]);
|
||||
const props = defineProps({
|
||||
option: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
const emit = defineEmits(['echartsEvent']);
|
||||
const echartBox = ref(null);
|
||||
let chart!: echarts.ECharts;
|
||||
|
||||
const setChart = (option: ECOption): void => {
|
||||
if (!props.option || !echartBox.value) {
|
||||
return;
|
||||
}
|
||||
chart.resize();
|
||||
chart.setOption(option);
|
||||
};
|
||||
|
||||
const resetChart = (): void => {
|
||||
const option = chart.getOption();
|
||||
if (!option || !echartBox.value) {
|
||||
return;
|
||||
}
|
||||
chart.resize();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
(echarts as any).registerMap('china', { geoJSON: china });
|
||||
(echarts as any).registerMap('cq', { geoJSON: cq });
|
||||
chart = echarts.init(echartBox.value as any);
|
||||
|
||||
emit('echartsEvent', chart);
|
||||
setChart(props.option);
|
||||
// 界面拉伸后重设
|
||||
window.addEventListener('resize', () => {
|
||||
resetChart();
|
||||
});
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (chart) {
|
||||
chart.clear();
|
||||
}
|
||||
setChart(props.option);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (chart) {
|
||||
chart.dispose();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.echarts {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: all;
|
||||
}
|
||||
</style>
|
@ -463,7 +463,16 @@ const getDetails = (row: any) => {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//监听项目id刷新数据
|
||||
const listeningProject = watch(
|
||||
() => currentProject.value?.id,
|
||||
(nid, oid) => {
|
||||
getTabsList();
|
||||
}
|
||||
);
|
||||
onUnmounted(() => {
|
||||
listeningProject();
|
||||
});
|
||||
onMounted(() => {
|
||||
getTabsList();
|
||||
});
|
||||
|
@ -72,7 +72,7 @@ const percentageClass = computed(() => {
|
||||
.progress_component {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
margin-bottom: 10px;
|
||||
:deep(.el-progress-bar__outer) {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
@ -2,36 +2,72 @@
|
||||
<div class="leftPage">
|
||||
<!-- -->
|
||||
<div class="kpi_box">
|
||||
<TitleComponent :title="'支付KPI'"/>
|
||||
<div style="height: 100px;"></div>
|
||||
<TitleComponent :title="'支付KPI'" style="margin-bottom: 20px;"/>
|
||||
<ProgressComponent
|
||||
title="营业收入"
|
||||
title="应收账款"
|
||||
value="123,456.78"
|
||||
percentageChange="+25.30%"
|
||||
progressPercentage="75"
|
||||
progressColor="rgba(255, 77, 79, 1)"
|
||||
/>
|
||||
<ProgressComponent
|
||||
title="应付账款"
|
||||
value="123,456.78"
|
||||
percentageChange="+25.30%"
|
||||
progressPercentage="25"
|
||||
progressColor="rgba(29, 214, 255, 1)"
|
||||
/>
|
||||
<ProgressComponent
|
||||
title="本月付款"
|
||||
value="123,456.78"
|
||||
percentageChange="+25.30%"
|
||||
progressPercentage="45"
|
||||
progressColor="rgba(0, 227, 150, 1)"
|
||||
/>
|
||||
<ProgressComponent
|
||||
title="本月收款"
|
||||
value="123,456.78"
|
||||
percentageChange="+25.30%"
|
||||
progressPercentage="10"
|
||||
progressColor="rgba(255, 147, 42, 1)"
|
||||
/>
|
||||
</div>
|
||||
<div class="contract_box">
|
||||
<EchartBox :option="barOption" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, computed, toRefs, getCurrentInstance, nextTick } from 'vue';
|
||||
// import echarts from 'echarts';
|
||||
import TitleComponent from './TitleComponent.vue';
|
||||
import ProgressComponent from './ProgressComponent.vue';
|
||||
import EchartBox from '@/components/EchartBox/index.vue';
|
||||
import { getBarOptions2 } from './optionList';
|
||||
const barOption = ref();
|
||||
const getCapitalData = (data) => {
|
||||
barOption.value = getBarOptions2();
|
||||
};
|
||||
onMounted(() => {
|
||||
getCapitalData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.leftPage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #0c1e35;
|
||||
|
||||
.kpi_box{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.contract_box{
|
||||
height: 35vh;
|
||||
}
|
||||
.kpi_box,.contract_box {
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid rgba(29, 214, 255, 0.3);
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import * as echarts from 'echarts/core';
|
||||
import { text } from 'stream/consumers';
|
||||
// import { PictorialBarChart } from 'echarts/charts'
|
||||
// 客流量图
|
||||
export const getOption = (xData: any, yData: any) => {
|
||||
@ -249,9 +250,10 @@ export const getOption2 = (data: any) => {
|
||||
};
|
||||
return option;
|
||||
};
|
||||
//食堂周报图
|
||||
//z折线
|
||||
export const getLineOption = (lineData: any) => {
|
||||
const maxData = Math.ceil(Math.max(...lineData.line1));
|
||||
const maxData = Math.max(...lineData.line1.flat());
|
||||
|
||||
const option = {
|
||||
backgroundColor: '',
|
||||
tooltip: {
|
||||
@ -263,37 +265,41 @@ export const getLineOption = (lineData: any) => {
|
||||
},
|
||||
borderColor: '#7ec7ff'
|
||||
},
|
||||
// legend: {
|
||||
// align: 'left',
|
||||
// right: '5%',
|
||||
// top: '1%',
|
||||
// type: 'plain',
|
||||
// textStyle: {
|
||||
// color: '#fff',
|
||||
// fontSize: 12
|
||||
// },
|
||||
// // icon:'rect',
|
||||
// itemGap: 15,
|
||||
// itemWidth: 18,
|
||||
// data: [
|
||||
// {
|
||||
// name: '上周销售量'
|
||||
// },
|
||||
// {
|
||||
// name: '本周销售量'
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
legend: {
|
||||
align: 'left',
|
||||
right: '5%',
|
||||
top: '1%',
|
||||
type: 'plain',
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 12
|
||||
},
|
||||
// icon:'rect',
|
||||
itemGap: 15,
|
||||
itemWidth: 18,
|
||||
data: [
|
||||
{
|
||||
name: '收款金额'
|
||||
},
|
||||
{
|
||||
name: '付款金额'
|
||||
},
|
||||
{
|
||||
name: '净现金流'
|
||||
}
|
||||
]
|
||||
},
|
||||
grid: {
|
||||
top: '12%',
|
||||
left: '1%',
|
||||
right: '3%',
|
||||
bottom: '12%',
|
||||
bottom: '5%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: lineData.xLabel,
|
||||
boundaryGap: false,
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
@ -318,21 +324,21 @@ export const getLineOption = (lineData: 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: [
|
||||
{
|
||||
name: '逆变器功率',
|
||||
name: '收款金额',
|
||||
type: 'line',
|
||||
symbol: 'circle', // 默认是空心圆(中间是白色的),改成实心圆
|
||||
showAllSymbol: false,
|
||||
@ -373,7 +379,95 @@ export const getLineOption = (lineData: any) => {
|
||||
shadowColor: 'rgba(25,163,223, 0.5)', //阴影颜色
|
||||
shadowBlur: 20 //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
|
||||
},
|
||||
data: lineData.line1
|
||||
data: lineData.line1[0]
|
||||
},
|
||||
{
|
||||
name: '付款金额',
|
||||
type: 'line',
|
||||
symbol: 'none', // 默认是空心圆(中间是白色的),改成实心圆
|
||||
showAllSymbol: false,
|
||||
symbolSize: 0,
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: 'rgba(255, 224, 179, 1)', // 线条颜色
|
||||
borderColor: 'rgba(0,0,0,.4)'
|
||||
},
|
||||
itemStyle: {
|
||||
color: 'rgba(255, 224, 179, 1)',
|
||||
borderWidth: 2,
|
||||
show: true
|
||||
},
|
||||
tooltip: {
|
||||
show: true
|
||||
},
|
||||
areaStyle: {
|
||||
//线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
|
||||
color: new echarts.graphic.LinearGradient(
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
[
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(255, 224, 179, 0.4)'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(255, 224, 179, 0)'
|
||||
}
|
||||
],
|
||||
false
|
||||
),
|
||||
shadowColor: 'rgba(255, 224, 179, 0.6)', //阴影颜色
|
||||
shadowBlur: 20 //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
|
||||
},
|
||||
data: lineData.line1[1]
|
||||
},
|
||||
{
|
||||
name: '净现金流',
|
||||
type: 'line',
|
||||
symbol: 'none', // 默认是空心圆(中间是白色的),改成实心圆
|
||||
showAllSymbol: false,
|
||||
symbolSize: 0,
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: 'rgba(39, 255, 252, 1)', // 线条颜色
|
||||
borderColor: 'rgba(0,0,0,.4)'
|
||||
},
|
||||
itemStyle: {
|
||||
color: 'rgba(39, 255, 252, 1)',
|
||||
borderWidth: 2,
|
||||
show: false
|
||||
},
|
||||
tooltip: {
|
||||
show: true
|
||||
},
|
||||
areaStyle: {
|
||||
//线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
|
||||
color: new echarts.graphic.LinearGradient(
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
[
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(39, 255, 252, 0.4)'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(39, 255, 252, 0)'
|
||||
}
|
||||
],
|
||||
false
|
||||
),
|
||||
shadowColor: 'rgba(39, 255, 252, 0.5)', //阴影颜色
|
||||
shadowBlur: 20 //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
|
||||
},
|
||||
data: lineData.line1[2]
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -733,3 +827,62 @@ export const getBarOptions = (data: any) => {
|
||||
};
|
||||
return option;
|
||||
};
|
||||
|
||||
// 收支合同分析
|
||||
export const getBarOptions2 = (data: any) => {
|
||||
const option = {
|
||||
color:['#FF932A', '#678FE6', '#1DD6FF', '#00E396'],
|
||||
title: {
|
||||
text: '数量(个)',
|
||||
subtext: '16',
|
||||
bottom: 'center',
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
color: '#9DADB7',
|
||||
fontSize: 16
|
||||
},
|
||||
subtextStyle:{
|
||||
color: '#707070',
|
||||
fontSize: 32,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
top: '5%',
|
||||
left: 'center'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'Access From',
|
||||
type: 'pie',
|
||||
radius: ['50%', '60%'],
|
||||
avoidLabelOverlap: false,
|
||||
padAngle: 5,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: false,
|
||||
fontSize: 40,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 3, name: '100万一下' },
|
||||
{ value: 4, name: '100-500万' },
|
||||
{ value: 5, name: '500-1000万' },
|
||||
{ value: 4, name: '1000万以上' },
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
return option;
|
||||
}
|
@ -1,13 +1,71 @@
|
||||
<template>
|
||||
<div class="rightPage">右边</div>
|
||||
<div class="rightPage">
|
||||
<div class="funds">
|
||||
<TitleComponent :title="'资金KPI'" />
|
||||
<div class="funds_echarts">
|
||||
<EchartBox :option="lineOption" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="cashFlow">
|
||||
<TitleComponent :title="'现金流概述'" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
import TitleComponent from './TitleComponent.vue';
|
||||
import EchartBox from '@/components/EchartBox/index.vue';
|
||||
import { getLineOption, getBarOptions } from './optionList';
|
||||
|
||||
const lineOption = ref();
|
||||
const getCapitalData = (data?: any) => {
|
||||
// const xData = data.map((item) => item.time);
|
||||
// const yData = data.map((item) => item.content);
|
||||
const lineData = {
|
||||
xLabel: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
|
||||
line1: [
|
||||
[100, 200, 150, 300, 250, 350, 400, 350, 450, 500, 400, 550],
|
||||
[220, 250, 230, 280, 270, 300, 350, 320, 380, 400, 450, 500],
|
||||
[300, 350, 320, 380, 400, 450, 500, 480, 520, 550, 600, 650]
|
||||
]
|
||||
|
||||
// line2: ['20', '50', '12', '65', '30', '60']
|
||||
};
|
||||
lineOption.value = getLineOption(lineData);
|
||||
};
|
||||
onMounted(() => {
|
||||
getCapitalData();
|
||||
});
|
||||
|
||||
//资金KPI
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.rightPage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #0c1e35;
|
||||
box-sizing: border-box;
|
||||
// padding: 5px;
|
||||
}
|
||||
.funds {
|
||||
width: 100%;
|
||||
// height: 40%;
|
||||
border: 1px solid rgba(29, 214, 255, 0.3);
|
||||
box-sizing: border-box;
|
||||
padding: 10px 5px;
|
||||
}
|
||||
.funds_echarts {
|
||||
width: 100%;
|
||||
height: 35vh;
|
||||
padding: 10px 0 0 0;
|
||||
}
|
||||
.cashFlow {
|
||||
width: 100%;
|
||||
// height: 50%;
|
||||
border: 1px solid rgba(29, 214, 255, 0.3);
|
||||
box-sizing: border-box;
|
||||
padding: 10px 5px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
|
279
src/views/tender/bidd/index.vue
Normal file
279
src/views/tender/bidd/index.vue
Normal file
@ -0,0 +1,279 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<el-tabs type="border-card" @tab-change="handleTabChange" v-model="activeTab">
|
||||
<el-tab-pane v-for="(item, index) in tabList" :key="index" :label="item.label" :name="item.value">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<el-card shadow="always">
|
||||
<el-form :model="queryForm" :inline="true">
|
||||
<el-form-item label="版本号" prop="versions">
|
||||
<el-select v-model="queryForm.versions" placeholder="选择版本号" @change="changeVersions">
|
||||
<el-option v-for="item in options" :key="item.versions" :label="item.versions" :value="item.versions" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="表名" prop="sheet">
|
||||
<el-select v-model="queryForm.sheet" placeholder="选择表名" @change="changeSheet">
|
||||
<el-option v-for="item in sheets" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="toggleExpandAll(true)">一键展开</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="toggleExpandAll(false)">一键收起</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
class="upload-demo"
|
||||
:http-request="importExcel"
|
||||
:show-file-list="false"
|
||||
v-hasPermi="['tender:billofquantitiesLimitList:importExcelFile']"
|
||||
>
|
||||
<template #trigger>
|
||||
<el-button type="primary">导入excel</el-button>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleExport()" v-hasPermi="['tender:billofquantitiesLimitList:export']">导出excel</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</transition>
|
||||
<el-card shadow="never" class="mb8">
|
||||
<el-table ref="tableRef" v-loading="loading" :data="tableData" row-key="id" border lazy default-expand-all>
|
||||
<el-table-column prop="num" label="编号" />
|
||||
<el-table-column prop="name" label="工程或费用名称" />
|
||||
<el-table-column prop="unit" label="单位" />
|
||||
<el-table-column prop="quantity" label="数量" />
|
||||
<el-table-column prop="remark" label="单价" align="center">
|
||||
<template #default="scope">
|
||||
<el-input-number
|
||||
:model-value="scope.row.unitPrice"
|
||||
@change="(val) => (scope.row.unitPrice = val)"
|
||||
:precision="2"
|
||||
:step="0.1"
|
||||
:controls="false"
|
||||
v-if="scope.row.quantity && scope.row.quantity != 0"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="price" label="总价" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.price }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="price" label="操作" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleSave(scope.row)"
|
||||
v-if="scope.row.quantity && scope.row.quantity != 0"
|
||||
v-hasPermi="['tender:billofquantitiesLimitList:edit']"
|
||||
>确定</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { obtainAllVersionNumbers, sheetList, getTableList, updatePrice, importExcelFile } from '@/api/tender/index';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const userStore = useUserStoreHook();
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
const tabList = [
|
||||
{
|
||||
label: '招采工程量清单',
|
||||
value: '2'
|
||||
},
|
||||
{
|
||||
label: '物资设备清单',
|
||||
value: '3'
|
||||
}
|
||||
];
|
||||
const queryForm = ref({
|
||||
versions: '',
|
||||
sheet: ''
|
||||
});
|
||||
|
||||
const activeTab = ref('2');
|
||||
const sheets = ref([]);
|
||||
const options = ref([]);
|
||||
const tableData = ref([]);
|
||||
const tableRef = ref();
|
||||
const isExpandAll = ref(false);
|
||||
const loading = ref(false);
|
||||
|
||||
// 切换tab
|
||||
const handleTabChange = (tab: string) => {
|
||||
activeTab.value = tab;
|
||||
getVersionNums();
|
||||
};
|
||||
//切换版本
|
||||
const changeVersions = () => {
|
||||
getSheetName();
|
||||
};
|
||||
//切换表格
|
||||
const changeSheet = (val: any) => {
|
||||
getTableData();
|
||||
};
|
||||
//展开树
|
||||
const toggleExpandAll = (isExpand: boolean) => {
|
||||
tableData.value.forEach((row) => {
|
||||
tableRef.value.toggleRowExpansion(row, isExpand);
|
||||
});
|
||||
isExpandAll.value = isExpand;
|
||||
};
|
||||
|
||||
//获取版本号
|
||||
const getVersionNums = async () => {
|
||||
try {
|
||||
const params = {
|
||||
projectId: currentProject.value?.id,
|
||||
workOrderType: activeTab.value,
|
||||
pageSize: 1000,
|
||||
pageNum: 1
|
||||
};
|
||||
|
||||
const res = await obtainAllVersionNumbers(params);
|
||||
if (res.code == 200) {
|
||||
options.value = res.data;
|
||||
if (res.data.length > 0) {
|
||||
queryForm.value.versions = res.data[0].versions;
|
||||
getSheetName();
|
||||
} else {
|
||||
queryForm.value.versions = '';
|
||||
getSheetName();
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
//获取表名
|
||||
const getSheetName = async () => {
|
||||
try {
|
||||
const params = {
|
||||
projectId: currentProject.value?.id,
|
||||
versions: queryForm.value.versions
|
||||
};
|
||||
const res = await sheetList(params);
|
||||
if (res.code == 200) {
|
||||
sheets.value = res.data;
|
||||
if (res.data.length > 0) {
|
||||
queryForm.value.sheet = res.data[0];
|
||||
} else {
|
||||
queryForm.value.sheet = '';
|
||||
}
|
||||
getTableData();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
//获取表格数据
|
||||
const getTableData = async () => {
|
||||
try {
|
||||
const params = {
|
||||
projectId: currentProject.value?.id,
|
||||
versions: queryForm.value.versions,
|
||||
sheet: queryForm.value.sheet,
|
||||
type: activeTab.value
|
||||
};
|
||||
const res = await getTableList(params);
|
||||
if (res.code == 200) {
|
||||
tableData.value = res.data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
//导入
|
||||
const importExcel = (options: any): any => {
|
||||
let formData = new FormData();
|
||||
formData.append('file', options.file);
|
||||
loading.value = true;
|
||||
importExcelFile(
|
||||
{ projectId: currentProject.value?.id, sheet: queryForm.value.sheet, versions: queryForm.value.versions, type: activeTab.value },
|
||||
formData
|
||||
)
|
||||
.then((res) => {
|
||||
const { code } = res;
|
||||
if (code == 200) {
|
||||
proxy.$modal.msgSuccess(res.msg || '导入成功');
|
||||
getTableData();
|
||||
} else {
|
||||
proxy.$modal.msgError(res.msg || '导入失败');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
proxy.$modal.msgError(err.msg || '导入失败');
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
//导出
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'/tender/tenderPlanLimitList/export',
|
||||
{
|
||||
projectId: currentProject.value?.id,
|
||||
sheet: queryForm.value.sheet,
|
||||
versions: queryForm.value.versions,
|
||||
type: activeTab.value
|
||||
},
|
||||
`招标一览表${queryForm.value.sheet}.xlsx`
|
||||
);
|
||||
};
|
||||
//确认修改
|
||||
const handleSave = (row: any) => {
|
||||
try {
|
||||
if (!row.unitPrice) {
|
||||
ElMessage({
|
||||
message: '请输入单价',
|
||||
type: 'warning'
|
||||
});
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
updatePrice(row).then((res) => {
|
||||
if (res.code == 200) {
|
||||
ElMessage({
|
||||
message: '修改成功',
|
||||
type: 'success'
|
||||
});
|
||||
getTableData();
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
loading.value = false;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
//监听项目id刷新数据
|
||||
const listeningProject = watch(
|
||||
() => currentProject.value?.id,
|
||||
(nid, oid) => {
|
||||
getVersionNums();
|
||||
}
|
||||
);
|
||||
onUnmounted(() => {
|
||||
listeningProject();
|
||||
});
|
||||
onMounted(() => {
|
||||
getVersionNums();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<<<<<<< HEAD <transition :enter-active-class="proxy?.animate.searchAnimate.enter"
|
||||
:leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="110px">
|
||||
@ -11,16 +12,12 @@
|
||||
<el-input v-model="queryParams.name" placeholder="请输入名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="计划招标时间" prop="plannedBiddingTime">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.plannedBiddingTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择计划招标时间"
|
||||
/>
|
||||
<el-date-picker clearable v-model="queryParams.plannedBiddingTime" type="date" value-format="YYYY-MM-DD"
|
||||
placeholder="请选择计划招标时间" />
|
||||
</el-form-item>
|
||||
<el-form-item label="招标方式" prop="plannedBiddingMethod">
|
||||
<el-select v-model="queryParams.plannedBiddingMethod" placeholder="请选择招标方式" clearable @change="handleQuery">
|
||||
<el-select v-model="queryParams.plannedBiddingMethod" placeholder="请选择招标方式" clearable
|
||||
@change="handleQuery">
|
||||
<el-option label="公招" value="公招"></el-option>
|
||||
<el-option label="邀标" value="邀标"></el-option>
|
||||
</el-select>
|
||||
@ -33,11 +30,23 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="合同额" prop="contractPrice">
|
||||
<el-input v-model="queryParams.contractPrice" placeholder="请输入合同额" clearable @keyup.enter="handleQuery" />
|
||||
=======
|
||||
<el-tabs type="border-card" @tab-change="handleTabChange" v-model="activeTab">
|
||||
<el-tab-pane v-for="(item, index) in tabList" :key="item.index" :label="item.label" :name="item.value">
|
||||
<el-card shadow="always">
|
||||
<el-form :model="queryForm" :inline="true" ref="queryFormRef">
|
||||
<el-form-item label="名称" prop="versions">
|
||||
<el-input v-model="queryForm.name" placeholder="请输入名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="内容" prop="sheet">
|
||||
<el-input v-model="queryForm.content" placeholder="请输入内容" clearable
|
||||
@keyup.enter="handleQuery" />
|
||||
>>>>>>> aab67593ebb8d9116738d0d867a6119ba61615c8
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
<<<<<<< HEAD </el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
@ -47,14 +56,17 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['plan:plan:edit']">修改</el-button>
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()"
|
||||
v-hasPermi="['plan:plan:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<!-- 多文件上传按钮 -->
|
||||
<el-col :span="2">
|
||||
<el-button type="primary" plain icon="Upload" @click="openFileUploadDialog()" v-hasPermi="['plan:plan:upload']"> 上传文件 </el-button>
|
||||
<el-button type="primary" plain icon="Upload" @click="openFileUploadDialog()"
|
||||
v-hasPermi="['plan:plan:upload']"> 上传文件 </el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['plan:plan:export']">导出</el-button>
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport"
|
||||
v-hasPermi="['plan:plan:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
@ -93,35 +105,29 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="招标通知书" align="center" prop="tenderFile">
|
||||
<template #default="scope">
|
||||
<el-link @click="handleView(scope.row, 'tenderFile')" type="primary" v-if="scope.row.tenderFile">查看</el-link>
|
||||
<el-link @click="handleView(scope.row, 'tenderFile')" type="primary"
|
||||
v-if="scope.row.tenderFile">查看</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['plan:plan:edit']"></el-button>
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['plan:plan:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 多文件上传对话框 -->
|
||||
<el-dialog :title="fileUploadDialog.title" v-model="fileUploadDialog.visible" width="600px" append-to-body>
|
||||
<div class="upload-container">
|
||||
<el-upload
|
||||
class="upload-demo"
|
||||
drag
|
||||
action=""
|
||||
:http-request="handleFileUpload"
|
||||
:multiple="true"
|
||||
:on-preview="handleFilePreview"
|
||||
:on-remove="handleFileRemove"
|
||||
:file-list="fileList"
|
||||
:auto-upload="false"
|
||||
>
|
||||
<el-upload class="upload-demo" drag action="" :http-request="handleFileUpload" :multiple="true"
|
||||
:on-preview="handleFilePreview" :on-remove="handleFileRemove" :file-list="fileList" :auto-upload="false">
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">点击或拖拽文件到此处上传</div>
|
||||
<template #tip>
|
||||
@ -140,7 +146,8 @@
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="planFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
<!-- 调整项目ID表单项:与目标代码一致,自动关联当前项目并显示提示 -->
|
||||
<el-input v-model="form.projectId" placeholder="请输入项目ID" :readonly="!!currentProjectId" :disabled="!!currentProjectId" v-if="false" />
|
||||
<el-input v-model="form.projectId" placeholder="请输入项目ID" :readonly="!!currentProjectId"
|
||||
:disabled="!!currentProjectId" v-if="false" />
|
||||
<template #help>
|
||||
<span v-if="currentProjectId" class="text-success">已自动关联当前选中项目</span>
|
||||
</template>
|
||||
@ -154,7 +161,8 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="计划招标时间" prop="plannedBiddingTime" v-if="false">
|
||||
<el-date-picker clearable v-model="form.plannedBiddingTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择计划招标时间" />
|
||||
<el-date-picker clearable v-model="form.plannedBiddingTime" type="date" value-format="YYYY-MM-DD"
|
||||
placeholder="请选择计划招标时间" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 核心修改:招标方式改为下拉框,根据限价自动赋值 -->
|
||||
@ -171,7 +179,8 @@
|
||||
|
||||
<!-- 限价输入:添加@input事件,实时触发招标方式判断 -->
|
||||
<el-form-item label="限价(单位万元)" prop="limitPrice">
|
||||
<el-input v-model.number="form.limitPrice" placeholder="请输入限价(单位万元)" type="number" @input="autoSetBiddingMethod" />
|
||||
<el-input v-model.number="form.limitPrice" placeholder="请输入限价(单位万元)" type="number"
|
||||
@input="autoSetBiddingMethod" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="合同额" prop="contractPrice">
|
||||
@ -211,6 +220,117 @@
|
||||
<el-button type="primary" @click="viewVisible = false">关闭</el-button>
|
||||
</span>
|
||||
</template>
|
||||
=======
|
||||
<el-button type="primary" plain :icon="Plus" @click="openDialog"
|
||||
v-hasPermi="['tender:segmentedIndicatorPlanning:add']">新增</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-table :data="tableData" row-key="id" border v-loading="loading">
|
||||
<el-table-column label="序号" width="80" align="center">
|
||||
<template #default="scope">
|
||||
{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="名称" />
|
||||
<el-table-column prop="content" label="内容" />
|
||||
<el-table-column prop="plannedBiddingTime" label="计划招标时间" align="center">
|
||||
<template #default="scope">
|
||||
<el-date-picker v-model="scope.row.plannedBiddingTime" type="date" value-format="YYYY-MM-DD"
|
||||
placeholder="选择时间" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="price" label="操作" align="center">
|
||||
<template #default="scope">
|
||||
<el-button type="warning" size="small" @click="handleDetail(scope.row)"
|
||||
v-hasPermi="['tender:segmentedIndicatorPlanning:getMore']">详情</el-button>
|
||||
<el-button type="primary" size="small" @click="handleSave(scope.row)"
|
||||
v-hasPermi="['tender:segmentedIndicatorPlanning:edit']">修改</el-button>
|
||||
<el-button type="danger" size="small" @click="delHandle(scope.row)"
|
||||
v-hasPermi="['tender:segmentedIndicatorPlanning:remove']">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-dialog title="新增" v-model="dialogVisible" width="75%" draggable>
|
||||
<el-row>
|
||||
<el-col :span="11">
|
||||
<el-form :model="form" :rules="rules" ref="formRef" label-width="80px">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="内容" prop="content">
|
||||
<el-input v-model="form.content" placeholder="请输入内容" type="textarea" clearable :rows="4" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row style="margin-top: 20px">
|
||||
<el-col :span="24">
|
||||
<el-card shadow="never">
|
||||
<el-form :model="treeForm" :inline="true">
|
||||
<el-form-item label="表名" prop="sheet">
|
||||
<el-select v-model="treeForm.sheet" placeholder="选择表名" @change="changeSheet">
|
||||
<el-option v-for="item in sheets" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="toggleExpandAll(true)">一键展开</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="toggleExpandAll(false)">一键收起</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-table :data="treeData" ref="treeTableRef" v-loading="treeLoading" row-key="id" border lazy
|
||||
default-expand-all @selection-change="handleSelection">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="num" label="编号" />
|
||||
<el-table-column prop="name" label="工程或费用名称" />
|
||||
<el-table-column prop="unit" label="单位" />
|
||||
<!-- <el-table-column prop="quantity" label="数量" /> -->
|
||||
<el-table-column prop="selectNum" label="选择数量" align="center">
|
||||
<template #default="scope">
|
||||
<el-input-number :model-value="scope.row.selectNum" @change="
|
||||
(val) => {
|
||||
scope.row.selectNum = val;
|
||||
handleNumberChange(scope.row);
|
||||
}
|
||||
" :precision="2" :step="1" :controls="false" :max="Math.floor(scope.row.quantity)"
|
||||
v-if="scope.row.quantity && scope.row.quantity != 0" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="unitPrice" label="单价" align="center" />
|
||||
<!-- <el-table-column prop="price" label="总价" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.price }}
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<template #footer>
|
||||
<el-button @click="closeDialog">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm(formRef)">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog title="详情" v-model="detailDialog" width="75%" draggable>
|
||||
<el-table :data="detailData" v-loading="detailLoading" row-key="id" border lazy default-expand-all>
|
||||
<el-table-column prop="num" label="编号" />
|
||||
<el-table-column prop="name" label="工程或费用名称" />
|
||||
<el-table-column prop="unit" label="单位" />
|
||||
<el-table-column prop="quantity" label="数量" />
|
||||
<el-table-column prop="unitPrice" label="单价" align="center" />
|
||||
<el-table-column prop="price" label="总价" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.price }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
>>>>>>> aab67593ebb8d9116738d0d867a6119ba61615c8
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
@ -221,6 +341,7 @@ import { PlanVO, PlanQuery, PlanForm } from '@/api/plan/plan/types';
|
||||
import { getCurrentInstance, onMounted, ref, reactive, toRefs, computed, watch } from 'vue';
|
||||
import type { ElFormInstance } from 'element-plus';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
<<<<<<< HEAD
|
||||
import { UploadFilled } from '@element-plus/icons-vue';
|
||||
import type { UploadFile, UploadRawFile } from 'element-plus';
|
||||
import { listByIds } from '@/api/system/oss';
|
||||
@ -336,10 +457,81 @@ const getList = async () => {
|
||||
} catch (error) {
|
||||
console.error('获取招标计划列表失败', error);
|
||||
proxy?.$modal.msgError('获取招标计划列表失败');
|
||||
=======
|
||||
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';
|
||||
|
||||
const userStore = useUserStoreHook();
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
const tabList = ref<any[]>([]);
|
||||
const tableData = ref<any[]>([]);
|
||||
const queryFormRef = ref();
|
||||
const formRef = ref();
|
||||
const activeTab = ref();
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
});
|
||||
const total = ref(0);
|
||||
const queryForm = ref({
|
||||
name: '',
|
||||
content: ''
|
||||
});
|
||||
const dialogVisible = ref(false);
|
||||
const form = ref({
|
||||
name: '',
|
||||
content: ''
|
||||
});
|
||||
|
||||
const rules = ref({
|
||||
name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
|
||||
content: [{ required: true, message: '请输入内容', trigger: 'blur' }]
|
||||
});
|
||||
const loading = ref(false);
|
||||
|
||||
//字典获取数据
|
||||
const getTabsList = async () => {
|
||||
const res = await getDicts('subcontracting_type');
|
||||
if (res.code == 200) {
|
||||
activeTab.value = res.data[0].dictValue;
|
||||
tabList.value = res.data.map((item: any) => {
|
||||
return {
|
||||
label: item.dictLabel,
|
||||
value: item.dictValue
|
||||
};
|
||||
});
|
||||
getList();
|
||||
}
|
||||
};
|
||||
//获取表格数据
|
||||
const getList = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
const params = {
|
||||
projectId: currentProject.value?.id,
|
||||
...queryParams.value,
|
||||
...queryForm.value,
|
||||
dictName: activeTab.value
|
||||
};
|
||||
const res = await getPlanningList(params);
|
||||
if (res.code == 200) {
|
||||
tableData.value = res.rows;
|
||||
total.value = res.total;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
ElMessage({
|
||||
message: '获取数据失败',
|
||||
type: 'error'
|
||||
});
|
||||
>>>>>>> aab67593ebb8d9116738d0d867a6119ba61615c8
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
<<<<<<< HEAD
|
||||
|
||||
// const handleSuccess = (list, res, fileType) => {
|
||||
// console.log(list);
|
||||
@ -374,6 +566,12 @@ const reset = () => {
|
||||
planFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
=======
|
||||
const handleTabChange = (tabs: any) => {
|
||||
activeTab.value = tabs;
|
||||
getList();
|
||||
};
|
||||
>>>>>>> aab67593ebb8d9116738d0d867a6119ba61615c8
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
@ -382,6 +580,7 @@ const handleQuery = () => {
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
<<<<<<< HEAD
|
||||
queryFormRef.value?.resetFields();
|
||||
queryParams.value.projectId = currentProjectId.value;
|
||||
handleQuery();
|
||||
@ -454,10 +653,248 @@ const submitForm = () => {
|
||||
} finally {
|
||||
buttonLoading.value = false;
|
||||
}
|
||||
=======
|
||||
queryForm.value.content = '';
|
||||
queryForm.value.name = '';
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
const openDialog = () => {
|
||||
dialogVisible.value = true;
|
||||
getSheetName();
|
||||
};
|
||||
const closeDialog = () => {
|
||||
dialogVisible.value = false;
|
||||
form.value = {
|
||||
name: '',
|
||||
content: ''
|
||||
};
|
||||
formRef.value?.resetFields();
|
||||
};
|
||||
const treeData = ref<any[]>([]);
|
||||
const treeForm = ref({
|
||||
sheet: ''
|
||||
});
|
||||
const sheets = ref<any[]>([]);
|
||||
const treeTableRef = ref();
|
||||
const isExpandAll = ref(false);
|
||||
const treeLoading = ref(false);
|
||||
const selectionData = ref<any>([]);
|
||||
//获取表名
|
||||
const getSheetName = async () => {
|
||||
try {
|
||||
const params = {
|
||||
projectId: currentProject.value?.id
|
||||
// versions: queryForm.value.versions
|
||||
};
|
||||
const res = await sheetList(params);
|
||||
if (res.code == 200) {
|
||||
sheets.value = res.data;
|
||||
if (res.data.length > 0) {
|
||||
treeForm.value.sheet = res.data[0];
|
||||
} else {
|
||||
treeForm.value.sheet = '';
|
||||
ElMessage({
|
||||
message: '获取表名失败',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
getTreeList();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
ElMessage({
|
||||
message: '获取表名失败',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
};
|
||||
const handleSelection = (selection: any) => {
|
||||
selectionData.value = selection;
|
||||
};
|
||||
const handleNumberChange = (row: any) => {
|
||||
const selectedIds = selectionData.value.map((item) => item.id);
|
||||
nextTick(() => {
|
||||
treeTableRef.value.toggleRowSelection(row, true);
|
||||
});
|
||||
restoreSelections(treeData.value, selectedIds);
|
||||
};
|
||||
|
||||
//寻找节点选择
|
||||
const restoreSelections = (data, selectedIds) => {
|
||||
const traverse = (nodes) => {
|
||||
nodes.forEach((node) => {
|
||||
if (selectedIds.includes(node.id)) {
|
||||
nextTick(() => {
|
||||
treeTableRef.value.toggleRowSelection(node, true);
|
||||
});
|
||||
}
|
||||
if (node.children && node.children.length > 0) {
|
||||
traverse(node.children);
|
||||
}
|
||||
});
|
||||
};
|
||||
traverse(data);
|
||||
};
|
||||
watch(
|
||||
() => selectionData.value,
|
||||
(newVal, oldVal) => {
|
||||
console.log(newVal, 55555555555555555);
|
||||
}
|
||||
);
|
||||
|
||||
//选择表名
|
||||
const changeSheet = () => {
|
||||
getTreeList();
|
||||
};
|
||||
|
||||
const toggleExpandAll = (isExpand: boolean) => {
|
||||
treeData.value.forEach((row) => {
|
||||
treeTableRef.value.toggleRowExpansion(row, isExpand);
|
||||
});
|
||||
isExpandAll.value = isExpand;
|
||||
};
|
||||
//打开获取表数据
|
||||
const getTreeList = async () => {
|
||||
try {
|
||||
treeLoading.value = true;
|
||||
const params = {
|
||||
projectId: currentProject.value?.id,
|
||||
sheet: treeForm.value.sheet
|
||||
};
|
||||
const res = await treeList(params);
|
||||
if (res.code == 200) {
|
||||
res.data.forEach((item: any) => {
|
||||
item.selectNum = '';
|
||||
});
|
||||
treeData.value = res.data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
ElMessage({
|
||||
message: '获取表格失败',
|
||||
type: 'error'
|
||||
});
|
||||
} finally {
|
||||
treeLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const submitForm = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate(async (valid, fields) => {
|
||||
if (valid) {
|
||||
try {
|
||||
if (selectionData.value.length == 0) {
|
||||
ElMessage({
|
||||
message: '请选择项目材料',
|
||||
type: 'warning'
|
||||
});
|
||||
return;
|
||||
}
|
||||
const newSelectionData = selectionData.value.filter((item) => item.quantity != '' && item.quantity != null);
|
||||
if (newSelectionData.some((item) => item.selectNum == '' || item.selectNum == null)) {
|
||||
ElMessage.error('存在未填写数量的工程或费用名称,请检查');
|
||||
return;
|
||||
}
|
||||
const limitListBos = newSelectionData.map((item: any) => {
|
||||
return {
|
||||
limitListId: item.id,
|
||||
num: item.selectNum
|
||||
};
|
||||
});
|
||||
const params = {
|
||||
projectId: currentProject.value?.id,
|
||||
...form.value,
|
||||
dictName: activeTab.value,
|
||||
limitListBos,
|
||||
type: activeTab.value == '2' ? '3' : '2'
|
||||
};
|
||||
return;
|
||||
const res = await segmentedIndicatorPlanning(params);
|
||||
if (res.code == 200) {
|
||||
ElMessage({
|
||||
message: '新增成功',
|
||||
type: 'success'
|
||||
});
|
||||
closeDialog();
|
||||
getList();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
} else {
|
||||
console.log('error submit!', fields);
|
||||
}
|
||||
});
|
||||
};
|
||||
//确定修改
|
||||
const handleSave = (row: any) => {
|
||||
try {
|
||||
if (!row.plannedBiddingTime) {
|
||||
ElMessage({
|
||||
message: '请输入计划招标时间',
|
||||
type: 'warning'
|
||||
});
|
||||
return;
|
||||
}
|
||||
updatePlanning(row).then((res) => {
|
||||
if (res.code == 200) {
|
||||
ElMessage({
|
||||
message: '修改成功',
|
||||
type: 'success'
|
||||
});
|
||||
getList();
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
ElMessage({
|
||||
message: '修改失败',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
};
|
||||
//删除
|
||||
const delHandle = (row: any) => {
|
||||
try {
|
||||
const params = { ids: row.id };
|
||||
delPlanning(params).then((res) => {
|
||||
if (res.code == 200) {
|
||||
ElMessage({
|
||||
message: '删除成功',
|
||||
type: 'success'
|
||||
});
|
||||
getList();
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
ElMessage({
|
||||
message: '删除失败',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
};
|
||||
const detailDialog = ref();
|
||||
const detailData = ref([]);
|
||||
const detailLoading = ref(false);
|
||||
|
||||
//详情
|
||||
const handleDetail = (row: any) => {
|
||||
detailDialog.value = true;
|
||||
getDetails(row);
|
||||
};
|
||||
const getDetails = (row: any) => {
|
||||
getDetailsList({ id: row.id }).then((res) => {
|
||||
if (res.code == 200) {
|
||||
detailData.value = res.data;
|
||||
>>>>>>> aab67593ebb8d9116738d0d867a6119ba61615c8
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
<<<<<<< HEAD
|
||||
/** 删除按钮操作(原代码存在但模板未引用,保留逻辑) */
|
||||
const handleDelete = async (row?: PlanVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
@ -573,19 +1010,31 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb-4 {
|
||||
<<<<<<< HEAD .mb-4 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.el-table .small-padding .cell {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.el-table .fixed-width {
|
||||
width: 120px !important;
|
||||
}
|
||||
|
||||
.el-table-column .el-button--text+.el-button--text {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.upload-container {
|
||||
padding: 10px 0;
|
||||
|
||||
=======.Region {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
>>>>>>>aab67593ebb8d9116738d0d867a6119ba61615c8
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user