feat: dq 页面调整

This commit is contained in:
caoqianming 2025-11-04 15:13:18 +08:00
parent 10e833c6c9
commit e1681c0135
4 changed files with 511 additions and 132 deletions

View File

@ -1,7 +1,20 @@
<template>
<t-layout style="height: 99%;">
<t-content style="background-color: white;">暂未开放</t-content>
<t-content style="background-color: white;">
<div class="bigNav">暂未开放</div>
</t-content>
</t-layout>
</template>
<script setup>
</script>
</script>
<style>
.bigNav {
font-size: 20px;
font-weight: 500;
color: var(--td-brand-color);
height: 180px;
display: flex;
align-items: center;
justify-content: center;
}
</style>

View File

@ -1,127 +1,88 @@
<template>
<t-row style="height: 100%;">
<t-col :flex="2" style="height: 100%;min-height: 700px;">
<t-card style="height: 100%;">
<t-form label-align="left" label-width="0">
<t-form-item style="min-height: 70px;">
<t-upload v-model="file1" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"
tips="企业低碳转型战略与总体规划" />
<t-col :flex="5" style="height: 100%;">
<t-card header-bordered style="height: 100%;">
<template #header>
<t-button @click="handleCal" :loading="calLoading">开始计算</t-button>
</template>
<template #content>
<t-form label-align="left" label-width="280px" style="overflow-y: auto;">
<t-form-item style="min-height: 80px;" label="企业技术说明及改造方案">
<t-upload v-model="file6" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"/>
</t-form-item>
<t-form-item style="min-height: 70px;">
<t-upload v-model="file2" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"
tips="碳排放数据监测、核查与信息披露报告" />
<t-form-item style="min-height: 80px;" label="企业低碳转型战略与总体规划">
<t-upload v-model="file1" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt" />
</t-form-item>
<t-form-item style="min-height: 70px;">
<t-upload v-model="file3" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"
tips="环境、社会与治理ESG尽职调查报告" />
<t-form-item style="min-height: 80px;" label="碳排放数据监测、核查与信息披露报告">
<t-upload v-model="file2" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"/>
</t-form-item>
<t-form-item style="min-height: 70px;">
<t-upload v-model="file4" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"
tips="项目融资与可行性研究方案" />
<t-form-item style="min-height: 80px;" label="数字化与智能控制系统技术方案">
<t-upload v-model="file5" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"/>
</t-form-item>
<t-form-item style="min-height: 70px;">
<t-upload v-model="file5" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"
tips="数字化与智能控制系统技术方案" />
<t-form-item style="min-height: 80px;" label="环境、社会与治理ESG尽职调查报告" >
<t-upload v-model="file3" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"/>
</t-form-item>
<t-form-item style="min-height: 70px;">
<t-upload v-model="file6" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"
tips="企业技术说明及改造方案" />
</t-form-item>
<t-form-item>
<t-button @click="handleCal" :loading="calLoading">开始计算</t-button>
<t-form-item style="min-height: 80px;" label="项目融资与可行性研究方案">
<t-upload v-model="file4" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"/>
</t-form-item>
</t-form>
</template>
</t-card>
</t-col>
<t-col :flex="10" style="height: 100%;">
<t-card style="font-size: 24px;height: 56px;">
<span v-if="score === null">暂无评分数据请上传相关文件后计算</span>
<span v-else>
贵企业的双碳贷前得分为
<span :style="{
color: levelColor,
fontWeight: 'bold',
fontSize: '32px',
}">{{ score }}</span> ;
等级: <span :style="{
color: levelColor,
fontWeight: 'bold',
fontSize: '32px',
}">
{{ level }}
</span>
</span>
</t-card>
<t-card>
<t-table :data="tableData" :columns="columns" row-key="id" :hover="true" size="small"
:rowspan-and-colspan="colSpan">
<template #scoringCriteria="{ row }">
<span v-for="(option, optIndex) in row.scoringCriteria" :key="optIndex"
style="margin-bottom: 4px;">
{{ option.选项 }} ({{ option.得分 }})
<t-col :flex="7" style="height: 100%;">
<t-card header-bordered style="height: 100%;">
<template #header>
<span v-if="score === null">暂无评分数据请上传相关文件后计算</span>
<span v-else>
贵企业的双碳贷前得分为
<span class="score-display">{{ score }}</span> ;
等级: <span class="level-display" :style="levelStyle">
{{ level }}
</span>
</template>
</t-table>
</span>
</template>
<template #content>
<!-- 动画容器 -->
<div class="animation-container" v-show="showAnimation">
<div class="particles-container">
<div class="particle" v-for="n in 30" :key="n" :style="particleStyle(n)"></div>
</div>
<div class="loading-circle">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
<div class="loading-text" :style="{color: loadingTextColor}">{{ loadingText }}</div>
</div>
<!-- 结果展示 -->
<div class="result-container" v-show="showResult">
<div class="score-circle" :style="scoreCircleStyle">
<div class="score-value">{{ score }}</div>
<div class="score-label">总分</div>
</div>
<div class="level-badge" :style="levelStyle">
{{ level }}
</div>
<div class="result-description">
<p>根据您提交的资料我们已完成双碳贷前评估</p>
<p>您的企业评级为 <strong :style="{color: levelColor}">{{ level }}</strong> </p>
</div>
</div>
</template>
</t-card>
</t-col>
</t-row>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
import http from "@/api/request.js";
onMounted(() => {
getStandard();
})
const getStandard = async () => {
tableData.value = await http.get("/standard/");
}
const tableData = ref([]);
const columns = ref([
{
title: '一级指标',
colKey: 'firstLevel',
},
{
title: '二级指标',
colKey: 'secondLevel',
},
{
title: '三级指标',
colKey: 'thirdLevel',
},
{
title: '选项及分值',
colKey: 'scoringCriteria',
width: 300
},
{
title: '结果',
colKey: 'result',
},
{
title: '得分',
colKey: 'score',
}
]);
const colSpan = ({ row, column, rowIndex, columnIndex }) => {
// if (column.colKey === 'firstLevel') {
// return {
// rowspan: getFirstLevelRowspan(rowIndex),
// colspan: 1
// };
// }
// if (column.colKey === 'secondLevel') {
// return {
// rowspan: getSecondLevelRowspan(rowIndex),
// colspan: 1
// };
// }
return {
rowspan: 1,
colspan: 1
};
};
<script setup>
import { ref, onMounted, watch, computed } from 'vue';
import http from "@/api/request.js";
import { MessagePlugin } from "tdesign-vue-next"
onMounted(() => {
//
})
const file1 = ref([]);
const file2 = ref([]);
@ -132,23 +93,72 @@ const file6 = ref([]);
const calLoading = ref(false);
const score = ref(null);
const level = ref("较差");
const levelColor = ref('#000')
const levelColor = ref('#000');
const showAnimation = ref(false);
const showResult = ref(false);
const loadingText = ref("正在计算评分...");
const loadingTextColor = ref("#ff4444");
//
const levelStyle = computed(() => {
return {
color: levelColor.value,
background: `${levelColor.value}15`,
border: `1px solid ${levelColor.value}30`
};
});
//
const scoreCircleStyle = computed(() => {
const percentage = score.value ? (score.value / 100) * 360 : 0;
return {
background: `conic-gradient(${levelColor.value} ${percentage}deg, #f0f0f0 ${percentage}deg 360deg)`
};
});
//
const particleStyle = (n) => {
const size = Math.random() * 8 + 4;
const left = Math.random() * 100;
const animationDelay = Math.random() * 2;
const animationDuration = Math.random() * 3 + 2;
return {
width: `${size}px`,
height: `${size}px`,
left: `${left}%`,
animationDelay: `${animationDelay}s`,
animationDuration: `${animationDuration}s`,
background: levelColor.value
};
};
watch(score, (newScore) => {
if (newScore >= 80) {
level.value = '领先'
levelColor.value = '#4caf50'
} else if (newScore >= 60) {
level.value = '良好'
levelColor.value = '#2196f3'
} else if (newScore >= 30) {
level.value = '一般'
levelColor.value = '#ff9800'
} else {
level.value = '较差'
levelColor.value = '#f44336'
}
}, { immediate: true })
if (newScore >= 80) {
level.value = '领先'
levelColor.value = '#4caf50'
} else if (newScore >= 60) {
level.value = '良好'
levelColor.value = '#2196f3'
} else if (newScore >= 30) {
level.value = '一般'
levelColor.value = '#ff9800'
} else {
level.value = '较差'
levelColor.value = '#f44336'
}
}, { immediate: true });
const handleCal = () => {
//
const files = [file1.value, file2.value, file3.value, file4.value, file5.value, file6.value];
const hasFiles = files.some(fileArray => fileArray && fileArray.length > 0);
if (!hasFiles) {
MessagePlugin.error('请至少上传一个文件后再进行计算');
return;
}
let formData = new FormData();
formData.append('file1', file1.value?.[0]?.raw);
formData.append('file2', file2.value?.[0]?.raw);
@ -156,12 +166,201 @@ const handleCal = () => {
formData.append('file4', file4.value?.[0]?.raw);
formData.append('file5', file5.value?.[0]?.raw);
formData.append('file6', file6.value?.[0]?.raw);
calLoading.value = true;
http.postForm("/cal/", formData).then(res => {
calLoading.value = false;
tableData.value = res.data;
score.value = res.total_score;
}).catch(e=>{calLoading.value = false;})
console.log(formData);
showAnimation.value = true;
showResult.value = false;
//
const loadingTexts = [
"正在分析企业低碳转型战略...",
"正在评估碳排放数据...",
"正在审核ESG尽职调查报告...",
"正在研究项目融资方案...",
"正在分析数字化技术方案...",
"正在评估企业技术说明...",
"正在生成最终评分..."
];
let textIndex = 0;
const textInterval = setInterval(() => {
loadingText.value = loadingTexts[textIndex];
textIndex = (textIndex + 1) % loadingTexts.length;
}, 800);
// API
setTimeout(() => {
http.postForm("/cal/", formData).then(res => {
clearInterval(textInterval);
calLoading.value = false;
score.value = res.total_score;
//
setTimeout(() => {
showAnimation.value = false;
showResult.value = true;
}, 500);
}).catch(e => {
clearInterval(textInterval);
calLoading.value = false;
showAnimation.value = false;
alert('计算失败,请重试');
});
}, 3000); //
}
</script>
</script>
<style scoped>
.animation-container {
margin-top: 80px;
position: relative;
height: 300px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.particles-container {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
}
.particle {
position: absolute;
border-radius: 50%;
opacity: 0.7;
animation: floatUp linear infinite;
}
@keyframes floatUp {
0% {
transform: translateY(100px) scale(0);
opacity: 0;
}
10% {
opacity: 0.7;
}
90% {
opacity: 0.7;
}
100% {
transform: translateY(-100px) scale(1);
opacity: 0;
}
}
.loading-circle {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.circle {
width: 15px;
height: 15px;
border-radius: 50%;
background: #2d8cf0;
animation: pulse 1.5s ease-in-out infinite;
}
.circle:nth-child(2) {
animation-delay: 0.2s;
}
.circle:nth-child(3) {
animation-delay: 0.4s;
}
@keyframes pulse {
0%, 100% {
transform: scale(0.8);
opacity: 0.5;
}
50% {
transform: scale(1.2);
opacity: 1;
}
}
.loading-text {
font-size: 18px;
font-weight: 500;
transition: all 0.3s ease;
}
.result-container {
margin-top: 80px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 300px;
gap: 20px;
}
.score-circle {
width: 150px;
height: 150px;
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}
.score-circle::before {
content: '';
position: absolute;
width: 130px;
height: 130px;
border-radius: 50%;
background: white;
}
.score-value {
font-size: 36px;
font-weight: bold;
z-index: 1;
color: #333;
}
.score-label {
font-size: 14px;
color: #666;
z-index: 1;
}
.level-badge {
padding: 8px 20px;
border-radius: 20px;
font-size: 18px;
font-weight: bold;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.result-description {
text-align: center;
max-width: 80%;
line-height: 1.6;
font-size: 18px;
}
.score-display {
font-weight: bold;
font-size: 32px;
color: #2d8cf0;
}
.level-display {
font-weight: bold;
font-size: 32px;
padding: 4px 12px;
border-radius: 8px;
}
</style>

167
src/pages/cal/dq_old.vue Normal file
View File

@ -0,0 +1,167 @@
<template>
<t-row style="height: 100%;">
<t-col :flex="2" style="height: 100%;min-height: 700px;">
<t-card style="height: 100%;">
<t-form label-align="left" label-width="0">
<t-form-item style="min-height: 70px;">
<t-upload v-model="file1" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"
tips="企业低碳转型战略与总体规划" />
</t-form-item>
<t-form-item style="min-height: 70px;">
<t-upload v-model="file2" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"
tips="碳排放数据监测、核查与信息披露报告" />
</t-form-item>
<t-form-item style="min-height: 70px;">
<t-upload v-model="file3" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"
tips="环境、社会与治理ESG尽职调查报告" />
</t-form-item>
<t-form-item style="min-height: 70px;">
<t-upload v-model="file4" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"
tips="项目融资与可行性研究方案" />
</t-form-item>
<t-form-item style="min-height: 70px;">
<t-upload v-model="file5" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"
tips="数字化与智能控制系统技术方案" />
</t-form-item>
<t-form-item style="min-height: 70px;">
<t-upload v-model="file6" :autoUpload="false" :max="1" accept=".docx,.pdf,.txt"
tips="企业技术说明及改造方案" />
</t-form-item>
<t-form-item>
<t-button @click="handleCal" :loading="calLoading">开始计算</t-button>
</t-form-item>
</t-form>
</t-card>
</t-col>
<t-col :flex="10" style="height: 100%;">
<t-card style="font-size: 24px;height: 56px;">
<span v-if="score === null">暂无评分数据请上传相关文件后计算</span>
<span v-else>
贵企业的双碳贷前得分为
<span :style="{
color: levelColor,
fontWeight: 'bold',
fontSize: '32px',
}">{{ score }}</span> ;
等级: <span :style="{
color: levelColor,
fontWeight: 'bold',
fontSize: '32px',
}">
{{ level }}
</span>
</span>
</t-card>
<t-card>
<t-table :data="tableData" :columns="columns" row-key="id" :hover="true" size="small"
:rowspan-and-colspan="colSpan">
<template #scoringCriteria="{ row }">
<span v-for="(option, optIndex) in row.scoringCriteria" :key="optIndex"
style="margin-bottom: 4px;">
{{ option.选项 }} ({{ option.得分 }})
</span>
</template>
</t-table>
</t-card>
</t-col>
</t-row>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
import http from "@/api/request.js";
onMounted(() => {
getStandard();
})
const getStandard = async () => {
tableData.value = await http.get("/standard/");
}
const tableData = ref([]);
const columns = ref([
{
title: '一级指标',
colKey: 'firstLevel',
},
{
title: '二级指标',
colKey: 'secondLevel',
},
{
title: '三级指标',
colKey: 'thirdLevel',
},
{
title: '选项及分值',
colKey: 'scoringCriteria',
width: 300
},
{
title: '结果',
colKey: 'result',
},
{
title: '得分',
colKey: 'score',
}
]);
const colSpan = ({ row, column, rowIndex, columnIndex }) => {
// if (column.colKey === 'firstLevel') {
// return {
// rowspan: getFirstLevelRowspan(rowIndex),
// colspan: 1
// };
// }
// if (column.colKey === 'secondLevel') {
// return {
// rowspan: getSecondLevelRowspan(rowIndex),
// colspan: 1
// };
// }
return {
rowspan: 1,
colspan: 1
};
};
const file1 = ref([]);
const file2 = ref([]);
const file3 = ref([]);
const file4 = ref([]);
const file5 = ref([]);
const file6 = ref([]);
const calLoading = ref(false);
const score = ref(null);
const level = ref("较差");
const levelColor = ref('#000')
watch(score, (newScore) => {
if (newScore >= 80) {
level.value = '领先'
levelColor.value = '#4caf50'
} else if (newScore >= 60) {
level.value = '良好'
levelColor.value = '#2196f3'
} else if (newScore >= 30) {
level.value = '一般'
levelColor.value = '#ff9800'
} else {
level.value = '较差'
levelColor.value = '#f44336'
}
}, { immediate: true })
const handleCal = () => {
let formData = new FormData();
formData.append('file1', file1.value?.[0]?.raw);
formData.append('file2', file2.value?.[0]?.raw);
formData.append('file3', file3.value?.[0]?.raw);
formData.append('file4', file4.value?.[0]?.raw);
formData.append('file5', file5.value?.[0]?.raw);
formData.append('file6', file6.value?.[0]?.raw);
calLoading.value = true;
http.postForm("/cal/", formData).then(res => {
calLoading.value = false;
tableData.value = res.data;
score.value = res.total_score;
}).catch(e=>{calLoading.value = false;})
console.log(formData);
}
</script>

View File

@ -18,7 +18,7 @@
<t-col :flex="3">
<t-card hoverShadow header-bordered>
<template #header>
<div class="redTitle" @click="goDq">转型金融贷后计算器</div>
<div class="redTitle" @click="goDh">转型金融贷后计算器</div>
</template>
<div class="bigNav">暂未开放</div>
</t-card>