提交 bf04ed1e authored 作者: coderBryanFu's avatar coderBryanFu

update

...@@ -3,63 +3,60 @@ ...@@ -3,63 +3,60 @@
<!-- 导航菜单 --> <!-- 导航菜单 -->
<div class="layout-main"> <div class="layout-main">
<div class="header-main"> <div class="header-main">
<div class="layout-main-header"> <div class="layout-main-header">
<div class="layout-main-header-left-box"> <div class="layout-main-header-left-box">
<div class="left-box-top"> <div class="left-box-top">
<div class="icon">
<img :src="billInfoGlobal.imageUrl || USALogo" alt="" />
</div>
<div class="info">
<div class="info-box1">{{ billInfoGlobal.billName }}</div>
<div class="info-box2">
{{ billInfoGlobal.description }} {{ billInfoGlobal.billNameEn }}
</div>
</div>
</div>
<div class="left-box-bottom">
<div
class="left-box-bottom-item"
:class="{ leftBoxBottomItemActive: activeTitle === item.name }"
v-for="(item, index) in mainHeaderBtnList"
:key="index"
@click="handleClickMainHeaderBtn(item)"
>
<div class="icon"> <div class="icon">
<img v-if="activeTitle === item.name" :src="item.activeIcon" alt="" /> <img :src="billInfoGlobal.imageUrl || USALogo" alt="" />
<img v-else :src="item.icon" alt="" />
</div> </div>
<div class="name" :class="{ nameActive: activeTitle === item.name }"> <div class="info">
{{ item.name }} <div class="info-box1">{{ billInfoGlobal.billName }}</div>
<div class="info-box2">{{ billInfoGlobal.description }} {{ billInfoGlobal.billNameEn }}</div>
</div> </div>
</div> </div>
</div> <div class="left-box-bottom">
</div> <div
<div class="layout-main-header-right-box"> class="left-box-bottom-item"
<div class="right-box-top"> :class="{ leftBoxBottomItemActive: activeTitle === item.name }"
<div class="time">{{ billInfoGlobal.introductionDate }}</div> v-for="(item, index) in mainHeaderBtnList"
<div class="name">{{ billInfoGlobal.tarName }}</div> :key="index"
</div> @click="handleClickMainHeaderBtn(item)"
<div class="right-box-bottom"> >
<div class="btn1" @click="handleSwitchActiveName('法案原文')"> <div class="icon">
<div class="icon"> <img v-if="activeTitle === item.name" :src="item.activeIcon" alt="" />
<img src="./assets/icons/btn-icon1.png" alt="" /> <img v-else :src="item.icon" alt="" />
</div>
<div class="name" :class="{ nameActive: activeTitle === item.name }">
{{ item.name }}
</div>
</div> </div>
<div class="text">{{ "法案原文" }}</div>
</div> </div>
<!-- <div class="btn2"> </div>
<div class="layout-main-header-right-box">
<div class="right-box-top">
<div class="time">{{ billInfoGlobal.introductionDate }}</div>
<div class="name">{{ billInfoGlobal.tarName }}</div>
</div>
<div class="right-box-bottom">
<div class="btn1" @click="handleSwitchActiveName('法案原文')">
<div class="icon">
<img src="./assets/icons/btn-icon1.png" alt="" />
</div>
<div class="text">{{ "法案原文" }}</div>
</div>
<!-- <div class="btn2">
<div class="icon"> <div class="icon">
<img src="./assets/icons/btn-icon2.png" alt="" /> <img src="./assets/icons/btn-icon2.png" alt="" />
</div> </div>
<div class="text">{{ "查看官网" }}</div> <div class="text">{{ "查看官网" }}</div>
</div> --> </div> -->
<div class="btn3"> <div class="btn3" @click="handleAnalysisClick">
<div class="icon"> <div class="icon">
<img src="./assets/icons/btn-icon3.png" alt="" /> <img src="./assets/icons/btn-icon3.png" alt="" />
</div>
<div class="text">{{ "分析报告" }}</div>
</div> </div>
<div class="text">{{ "分析报告" }}</div> <!-- <div class="btn4">
</div>
<!-- <div class="btn4">
<div class="icon"> <div class="icon">
<img src="./assets/icons/btn-icon4.png" alt="" /> <img src="./assets/icons/btn-icon4.png" alt="" />
</div> </div>
...@@ -68,11 +65,11 @@ ...@@ -68,11 +65,11 @@
<img src="./assets/icons/btn-icon5.png" alt="" /> <img src="./assets/icons/btn-icon5.png" alt="" />
</div> </div>
</div> --> </div> -->
</div>
</div> </div>
</div> </div>
</div>
</div> </div>
<div class="layout-main-center"> <div class="layout-main-center">
<router-view /> <router-view />
</div> </div>
...@@ -150,7 +147,6 @@ import icon4 from "./assets/icons/icon4.svg"; ...@@ -150,7 +147,6 @@ import icon4 from "./assets/icons/icon4.svg";
import icon4Active from "./assets/icons/icon4_active.svg"; import icon4Active from "./assets/icons/icon4_active.svg";
import USALogo from "./assets/images/USA-logo.png"; import USALogo from "./assets/images/USA-logo.png";
// 法案原文 // 法案原文
const billFullText = ref(""); const billFullText = ref("");
const getBillFullTextFn = async () => { const getBillFullTextFn = async () => {
...@@ -213,7 +209,7 @@ const mainHeaderBtnList = ref([ ...@@ -213,7 +209,7 @@ const mainHeaderBtnList = ref([
activeIcon: icon2Active, activeIcon: icon2Active,
name: "深度挖掘", name: "深度挖掘",
path: "/billLayout/deepDig" path: "/billLayout/deepDig"
}, }
// { // {
// icon: icon3, // icon: icon3,
// activeIcon: icon3Active, // activeIcon: icon3Active,
...@@ -241,6 +237,16 @@ const handleClickMainHeaderBtn = item => { ...@@ -241,6 +237,16 @@ const handleClickMainHeaderBtn = item => {
}); });
}; };
const handleAnalysisClick = () => {
router.push({
path: "/writtingAsstaint",
query: {
topic: "法案",
fileId: route.query.billId
}
});
};
onMounted(() => { onMounted(() => {
getBillInfoGlobalFn(); getBillInfoGlobalFn();
if (window.sessionStorage.getItem("activeTitle")) { if (window.sessionStorage.getItem("activeTitle")) {
...@@ -375,12 +381,11 @@ onMounted(() => { ...@@ -375,12 +381,11 @@ onMounted(() => {
// margin-right: 150px; // margin-right: 150px;
// margin-top: 19px; // margin-top: 19px;
.right-box-top { .right-box-top {
height: 64px; height: 64px;
display: flex; display: flex;
align-items: right; align-items: right;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
.time { .time {
// height: 24px; // height: 24px;
// line-height: 24px; // line-height: 24px;
......
...@@ -3,23 +3,29 @@ ...@@ -3,23 +3,29 @@
<!-- 导航菜单 --> <!-- 导航菜单 -->
<div class="layout-main"> <div class="layout-main">
<div class="header-main"> <div class="header-main">
<div class="layout-main-header"> <div class="layout-main-header">
<div class="layout-main-header-container"> <div class="layout-main-header-container">
<div class="layout-main-header-left-box"> <div class="layout-main-header-left-box">
<div class="left-box-top"> <div class="left-box-top">
<div class="icon"> <div class="icon">
<img
<img v-if="summaryInfo.imageUrl" :src="summaryInfo.imageUrl" alt="" style="height: 40px;margin-top: 12px;"/> v-if="summaryInfo.imageUrl"
:src="summaryInfo.imageUrl"
alt=""
style="height: 40px; margin-top: 12px"
/>
<img v-else :src="USALogo" alt="" /> <img v-else :src="USALogo" alt="" />
</div> </div>
<div class="info"> <div class="info">
<div class="info-box1">{{ summaryInfo.name }}</div> <div class="info-box1">{{ summaryInfo.name }}</div>
<div class="info-box2"> <div class="info-box2">
<div class="info-box2-item item1" v-if="summaryInfo.order">{{ summaryInfo.order +" | "}}</div> <div class="info-box2-item item1" v-if="summaryInfo.order">
{{ summaryInfo.order + " | " }}
<div class="info-box2-item item2" v-if="summaryInfo.type">{{ summaryInfo.type + " | " }}</div> </div>
<div class="info-box2-item item2" v-if="summaryInfo.type">
{{ summaryInfo.type + " | " }}
</div>
<div class="info-box2-item item3" v-if="summaryInfo.ename">{{ summaryInfo.ename }}</div> <div class="info-box2-item item3" v-if="summaryInfo.ename">{{ summaryInfo.ename }}</div>
</div> </div>
</div> </div>
...@@ -54,7 +60,7 @@ ...@@ -54,7 +60,7 @@
</div> </div>
<div class="text">{{ "政令原文" }}</div> <div class="text">{{ "政令原文" }}</div>
</div> </div>
<div class="btn-active"> <div class="btn-active" @click="handleAnalysisClick">
<div class="icon-active"> <div class="icon-active">
<img src="./assets/icons/edit-icon.png" alt="" /> <img src="./assets/icons/edit-icon.png" alt="" />
</div> </div>
...@@ -265,6 +271,16 @@ const handleShowReport = () => { ...@@ -265,6 +271,16 @@ const handleShowReport = () => {
window.open(curRoute.href, "_blank"); window.open(curRoute.href, "_blank");
}; };
const handleAnalysisClick = () => {
router.push({
path: "/writtingAsstaint",
query: {
topic: "政令",
fileId: route.query.id
}
});
};
onMounted(() => { onMounted(() => {
handleGetSummary(); handleGetSummary();
console.log(route.path); console.log(route.path);
......
<template> <template>
<div class="entity-list"> <div class="entity-list">
<div class="header"> <div class="header">
<div class="header-title"> <div class="header-title">
<img :src="headerTitle.img" alt=""> <img :src="headerTitle.img" alt="" />
<div> <div>
<div class="title"> <div class="title">
{{ headerTitle.title }} {{ headerTitle.title }}
<!-- <span>{{ headerTitle.titleEn }}</span> --> <!-- <span>{{ headerTitle.titleEn }}</span> -->
</div> </div>
<div class="department"> <div class="department">
{{ headerTitle.department }} {{ headerTitle.department }}
</div> </div>
</div> </div>
<div class="btn"> <div class="btn"><img :src="icon01" alt="" />切换</div>
<img :src="icon01" alt="">切换 </div>
</div> <div class="header-nav">
</div> <div
<div class="header-nav"> class="nav-item"
<div v-for="(item, index) in headerNavList"
class="nav-item" :key="index"
v-for="(item, index) in headerNavList" :class="{ active: activeIndex === index }"
:key="index" @click="activeIndex = index"
:class="{ active: activeIndex === index }" >
@click="activeIndex = index" <img :src="activeIndex === index ? item.imgActive : item.img" alt="" />
> <span>{{ item.title }}</span>
<img :src="activeIndex === index ? item.imgActive : item.img" alt=""> <div class="active-line" v-if="activeIndex === index"></div>
<span>{{ item.title }}</span> </div>
<div class="active-line" v-if="activeIndex === index"></div> <div class="original-text-btn" @click="handleClickOriginalText">
</div> <img :src="icon1" alt="" />
<div class="original-text-btn" @click="handleClickOriginalText"> <span>实体清单原文</span>
<img :src="icon1" alt=""> </div>
<span>实体清单原文</span> <div class="btn3" @click="handleAnalysisClick">
</div> <div class="icon">
</div> <img src="./assets/btn-icon3.png" alt="" />
</div> </div>
<div class="main"> <div class="text">{{ "分析报告" }}</div>
<sanctions-overview </div>
v-if="activeIndex === 0" </div>
:data="singleSanctionOverview" </div>
></sanctions-overview> <div class="main">
<data-statistics v-if="activeIndex === 1"></data-statistics> <sanctions-overview v-if="activeIndex === 0" :data="singleSanctionOverview"></sanctions-overview>
<deep-mining v-if="activeIndex === 2"></deep-mining> <data-statistics v-if="activeIndex === 1"></data-statistics>
<impact-analysis v-if="activeIndex === 3"></impact-analysis> <deep-mining v-if="activeIndex === 2"></deep-mining>
</div> <impact-analysis v-if="activeIndex === 3"></impact-analysis>
</div> </div>
</div>
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from 'vue' import { ref, onMounted } from "vue";
import sanctionsOverview from "./components/sanctionsOverview/index.vue" import sanctionsOverview from "./components/sanctionsOverview/index.vue";
import dataStatistics from "./components/dataStatistics/index.vue" import dataStatistics from "./components/dataStatistics/index.vue";
import deepMining from "./components/deepMining/index.vue" import deepMining from "./components/deepMining/index.vue";
import impactAnalysis from "./components/impactAnalysis/index.vue" import impactAnalysis from "./components/impactAnalysis/index.vue";
import title from "./assets/title.png" import title from "./assets/title.png";
import icon01 from "./assets/icon01.png" import icon01 from "./assets/icon01.png";
import icon1 from "../assets/icons/icon1.png"; import icon1 from "../assets/icons/icon1.png";
import icon1Active from "../assets/icons/icon1_active.png"; import icon1Active from "../assets/icons/icon1_active.png";
import icon5 from "../assets/icons/icon5.png"; import icon5 from "../assets/icons/icon5.png";
...@@ -65,249 +66,288 @@ import icon2Active from "../assets/icons/icon2_active.png"; ...@@ -65,249 +66,288 @@ import icon2Active from "../assets/icons/icon2_active.png";
import icon3 from "../assets/icons/icon3.png"; import icon3 from "../assets/icons/icon3.png";
import icon3Active from "../assets/icons/icon3_active.png"; import icon3Active from "../assets/icons/icon3_active.png";
import { getSingleSanctionOverview } from "@/api/exportControlV2.0.js" import { getSingleSanctionOverview } from "@/api/exportControlV2.0.js";
import router from "@/router";
// 处理点击实体清单原文按钮 // 处理点击实体清单原文按钮
const handleClickOriginalText = () => { const handleClickOriginalText = () => {
// 打开新标签页 // 打开新标签页
window.open(`/exportControl/origin?id=${sanRecordId.value}`, "_blank") window.open(`/exportControl/origin?id=${sanRecordId.value}`, "_blank");
} };
// 获取URL参数 // 获取URL参数
const sanRecordId = ref("") const sanRecordId = ref("");
const getUrlParams = () => { const getUrlParams = () => {
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
sanRecordId.value = urlParams.get("id") || "" sanRecordId.value = urlParams.get("id") || "";
} };
// console.log(sanRecordId.value) // console.log(sanRecordId.value)
// 单次制裁-制裁概况-基本信息 // 单次制裁-制裁概况-基本信息
const singleSanctionOverview = ref({}) const singleSanctionOverview = ref({});
const getSingleSanctionOverviewData = async () => { const getSingleSanctionOverviewData = async () => {
if (!sanRecordId.value) return if (!sanRecordId.value) return;
try { try {
const res = await getSingleSanctionOverview({ const res = await getSingleSanctionOverview({
sanRecordId: sanRecordId.value sanRecordId: sanRecordId.value
}) });
if (res.code === 200) { if (res.code === 200) {
singleSanctionOverview.value = res.data || {} singleSanctionOverview.value = res.data || {};
// 格式化日期
let dateStr = "";
if (singleSanctionOverview.value.postDate) {
const date = new Date(singleSanctionOverview.value.postDate);
if (!isNaN(date.getTime())) {
dateStr = `${date.getFullYear()}${date.getMonth() + 1}${date.getDate()}日`;
} else {
dateStr = singleSanctionOverview.value.postDate;
}
}
// 更新头部信息
headerTitle.value = {
...headerTitle.value,
title: `${dateStr}${singleSanctionOverview.value.sanTitleZh || singleSanctionOverview.value.sanTitle}》`,
titleEn: singleSanctionOverview.value.sanTitle || "",
department: singleSanctionOverview.value.fileCode || ""
}
}
} catch (error) {
console.error("获取制裁概况失败:", error)
}
}
// 格式化日期
let dateStr = "";
if (singleSanctionOverview.value.postDate) {
const date = new Date(singleSanctionOverview.value.postDate);
if (!isNaN(date.getTime())) {
dateStr = `${date.getFullYear()}${date.getMonth() + 1}${date.getDate()}日`;
} else {
dateStr = singleSanctionOverview.value.postDate;
}
}
// 更新头部信息
headerTitle.value = {
...headerTitle.value,
title: `${dateStr}${singleSanctionOverview.value.sanTitleZh || singleSanctionOverview.value.sanTitle}》`,
titleEn: singleSanctionOverview.value.sanTitle || "",
department: singleSanctionOverview.value.fileCode || ""
};
}
} catch (error) {
console.error("获取制裁概况失败:", error);
}
};
const headerTitle = ref({ const headerTitle = ref({
img: title, img: title
}) });
const activeIndex = ref(0) const activeIndex = ref(0);
const headerNavList = ref([ const headerNavList = ref([
{ {
img: icon1, img: icon1,
imgActive: icon1Active, imgActive: icon1Active,
title: "制裁概况" title: "制裁概况"
}, },
{ {
img: icon5, img: icon5,
imgActive: icon5Active, imgActive: icon5Active,
title: "数据统计" title: "数据统计"
}, },
{ {
img: icon2, img: icon2,
imgActive: icon2Active, imgActive: icon2Active,
title: "深度挖掘" title: "深度挖掘"
}, },
{ {
img: icon3, img: icon3,
imgActive: icon3Active, imgActive: icon3Active,
title: "影响分析" title: "影响分析"
} }
]) ]);
const handleAnalysisClick = () => {
router.push({
path: "/writtingAsstaint",
query: {
topic: "清单",
fileId: singleSanctionOverview.value.postDate
}
});
};
onMounted(() => { onMounted(() => {
getUrlParams() getUrlParams();
getSingleSanctionOverviewData() getSingleSanctionOverviewData();
}) });
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
*{ * {
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
.entity-list{ .entity-list {
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
.header{ .header {
width: 100%; width: 100%;
height: 148px; height: 148px;
background-color: #fff; background-color: #fff;
padding-top: 16px; padding-top: 16px;
position: sticky; position: sticky;
top: 0; top: 0;
z-index: 1000; z-index: 1000;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.05); box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.05);
.header-title{ .header-title {
width: 1601px; width: 1601px;
height: 72px; height: 72px;
background-color: rgba(246, 250, 255, 1); background-color: rgba(246, 250, 255, 1);
margin: 0 auto; margin: 0 auto;
border-radius: 10px; border-radius: 10px;
border: 2px solid rgba(174, 214, 255, 1); border: 2px solid rgba(174, 214, 255, 1);
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 12px; margin-bottom: 12px;
position: relative; position: relative;
img { img {
width: 54px; width: 54px;
height: 54px; height: 54px;
margin-left: 15px; margin-left: 15px;
margin-right: 11px; margin-right: 11px;
} }
.title { .title {
font-size: 20px; font-size: 20px;
font-weight: 700; font-weight: 700;
font-family: "Microsoft YaHei"; font-family: "Microsoft YaHei";
line-height: 26px; line-height: 26px;
color: rgb(59, 65, 75); color: rgb(59, 65, 75);
span { span {
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
font-family: "Microsoft YaHei"; font-family: "Microsoft YaHei";
line-height: 24px; line-height: 24px;
color: rgb(95, 101, 108); color: rgb(95, 101, 108);
margin-left: 11px; margin-left: 11px;
} }
} }
.department { .department {
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
font-family: "Microsoft YaHei"; font-family: "Microsoft YaHei";
line-height: 24px; line-height: 24px;
color: rgb(95, 101, 108); color: rgb(95, 101, 108);
} }
.btn { .btn {
cursor: pointer; cursor: pointer;
display: flex; display: flex;
align-items: center; align-items: center;
position: absolute; position: absolute;
right: 16px; right: 16px;
top: 25px; top: 25px;
font-size: 18px; font-size: 18px;
font-weight: 700; font-weight: 700;
font-family: "Microsoft YaHei"; font-family: "Microsoft YaHei";
line-height: 24px; line-height: 24px;
color: rgb(5, 95, 194); color: rgb(5, 95, 194);
img { img {
width: 20px; width: 20px;
height: 20px; height: 20px;
margin-right: 7px; margin-right: 7px;
} }
} }
} }
.header-nav { .header-nav {
width: 1601px; width: 1601px;
margin: 0 auto; margin: 0 auto;
height: 48px; height: 48px;
display: flex; display: flex;
align-items: center; align-items: center;
.nav-item { .nav-item {
display: flex; display: flex;
align-items: center; align-items: center;
height: 100%; height: 100%;
margin-right: 32px; margin-right: 32px;
cursor: pointer; cursor: pointer;
position: relative; position: relative;
font-size: 18px; font-size: 18px;
font-weight: 400; font-weight: 400;
font-family: "Microsoft YaHei"; font-family: "Microsoft YaHei";
color: rgb(59, 65, 75); color: rgb(59, 65, 75);
&:last-child { &:last-child {
margin-right: 0; margin-right: 0;
} }
img {
width: 16px;
height: 16px;
margin-right: 4px;
}
&.active {
color: rgb(5, 95, 194);
font-weight: 700;
}
.active-line {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 3px;
background-color: #055fc2;
border-radius: 1.5px;
}
}
img { .original-text-btn {
width: 16px; margin-left: auto;
height: 16px; width: 152px;
margin-right: 4px; height: 36px;
} background: #ffffff;
border-radius: 4px;
border: 1px solid rgba(230, 231, 232, 1);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
&.active { img {
color: rgb(5, 95, 194); width: 16px;
font-weight: 700; height: 16px;
} margin-right: 8px;
}
.active-line { span {
position: absolute; font-size: 16px;
bottom: 0; font-weight: 400;
left: 0; color: rgb(95, 101, 108);
width: 100%; font-family: "Microsoft YaHei";
height: 3px; line-height: 24px;
background-color: #055fc2; }
border-radius: 1.5px; }
}
}
.original-text-btn { .btn3 {
margin-left: auto; cursor: pointer;
width: 152px; width: 120px;
height: 36px; height: 36px;
background: #FFFFFF; border-radius: 6px;
border-radius: 4px; background: rgba(5, 95, 194, 1);
border: 1px solid rgba(230, 231, 232, 1); display: flex;
display: flex; justify-content: center;
align-items: center; align-items: center;
justify-content: center; gap: 8px;
cursor: pointer; margin-left: 8px;
.icon {
img { width: 16px;
width: 16px; height: 16px;
height: 16px; img {
margin-right: 8px; width: 100%;
} height: 100%;
}
span { }
font-size: 16px; .text {
font-weight: 400; height: 24px;
color: rgb(95, 101, 108); color: rgba(255, 255, 255, 1);
font-family: "Microsoft YaHei"; font-family: Microsoft YaHei;
line-height: 24px; font-size: 16px;
} font-weight: 400;
} line-height: 24px;
} letter-spacing: 0px;
} text-align: left;
.main{ }
width: 100%; }
height: auto; }
min-height: calc(100% - 148px); }
background-color: #F7F8F9; .main {
} width: 100%;
height: auto;
min-height: calc(100% - 148px);
background-color: #f7f8f9;
}
} }
</style> </style>
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
</div> </div>
<div class="text">{{ "文档下载" }}</div> <div class="text">{{ "文档下载" }}</div>
</div> </div>
<div class="btn btn1"> <div class="btn btn1" @click="handleAnalysisClick">
<div class="icon"> <div class="icon">
<img src="./images/btn-icon4.png" alt="" /> <img src="./images/btn-icon4.png" alt="" />
</div> </div>
...@@ -79,8 +79,9 @@ import { ref, onMounted } from "vue"; ...@@ -79,8 +79,9 @@ import { ref, onMounted } from "vue";
import ReportAnalysis from "./reportAnalysis/index.vue"; import ReportAnalysis from "./reportAnalysis/index.vue";
import PolicyTracking from "./policyTracking/index.vue"; import PolicyTracking from "./policyTracking/index.vue";
import { getThinkTankReportSummary } from "@/api/thinkTank/overview"; import { getThinkTankReportSummary } from "@/api/thinkTank/overview";
import { useRouter } from "vue-router"; import { useRoute, useRouter } from "vue-router";
const router = useRouter(); const router = useRouter();
const route = useRoute();
const reportUrl = ref(""); const reportUrl = ref("");
const thinkInfo = ref({}); const thinkInfo = ref({});
...@@ -113,6 +114,16 @@ const tabActiveName = ref("报告分析"); ...@@ -113,6 +114,16 @@ const tabActiveName = ref("报告分析");
const switchTab = name => { const switchTab = name => {
tabActiveName.value = name; tabActiveName.value = name;
}; };
const handleAnalysisClick = () => {
router.push({
path: "/writtingAsstaint",
query: {
topic: "智库",
fileId: router.currentRoute._value.params.id
}
});
};
onMounted(async () => { onMounted(async () => {
handleGetThinkTankReportSummary(); handleGetThinkTankReportSummary();
}); });
......
...@@ -31,98 +31,108 @@ ...@@ -31,98 +31,108 @@
</div> </div>
<div class="writting-main"> <div class="writting-main">
<div class="left-box"> <div class="left-box">
<div class="process-box" v-if="isShowProcess"> <div class="left-box-input">
<div class="back" @click="handleBack">{{ "< 返回" }}</div> <div class="process-box" v-if="isShowProcess">
<div class="process-main-box"> <div class="back" @click="handleBack">{{ "< 返回" }}</div>
<div class="steps-box"> <div class="process-main-box">
<div class="steps-header"> <div class="steps-box">
<div class="icon"> <div class="steps-header">
<img src="./assets/images/right-arrow.png" alt="" /> <div class="icon">
<img src="./assets/images/right-arrow.png" alt="" />
</div>
<div class="text">{{ "执行步骤:" }}</div>
</div> </div>
<div class="text">{{ "执行步骤:" }}</div> <div class="steps-content" ref="scrollProcessContainer" v-html="renderedProcess"></div>
</div>
<div class="tool-box">
<div class="tool-header">{{ "工具调用" }}</div>
<div class="tool-main">当前智能体工具:{{ curAgentTool ? curAgentTool : "无" }}</div>
</div> </div>
<div class="steps-content" ref="scrollProcessContainer" v-html="renderedProcess"></div>
</div>
<div class="tool-box">
<div class="tool-header">{{ "工具调用" }}</div>
<div class="tool-main">当前智能体工具:{{ curAgentTool ? curAgentTool : "无" }}</div>
</div> </div>
</div> </div>
</div> <div class="sider" v-else>
<div class="sider" v-else> <div class="sider-box">
<div class="sider-box" v-if="false"> <div class="header">报文主题</div>
<div class="header">报文主题</div> <div class="title-box">
<div class="title-box"> <div class="title">主题名称</div>
<div class="title">主题名称</div> <el-input
<el-input :disabled="true"
:disabled="true" style="width: 476px; height: 32px"
style="width: 476px; height: 32px" class="title-input"
class="title-input" placeholder="输入主题名称,如:大而美法案"
placeholder="输入主题名称,如:大而美法案" v-model="writtingTitle"
v-model="writtingTitle" />
/> </div>
</div> <div class="description-box">
<div class="description-box"> <div class="title">主题描述</div>
<div class="title">主题描述</div> <el-input
<el-input :disabled="true"
:disabled="true" class="description-input"
class="description-input" type="textarea"
type="textarea" style="width: 476px"
style="width: 476px" :rows="8"
:rows="8" placeholder="输入报文主题描述,如:从科技领域方面分析大而美法案通过后对中国可能产生的影响"
placeholder="输入报文主题描述,如:从科技领域方面分析大而美法案通过后对中国可能产生的影响" v-model="descText"
v-model="descText" />
/> </div>
</div> </div>
</div> <div class="sider-box">
<div class="sider-box"> <div class="header">报文模板</div>
<div class="header">报文模板</div> <div class="template-box">
<div class="template-box"> <div
<div class="template"
class="template" :class="{
:class="{ tempActive: tempActiveIndex === index }" tempActive: tempActiveIndex === index,
v-for="(temp, index) in tempList" disableTemplate: tempActiveIndex !== index && Object.keys(route.query).length > 0
:key="index" }"
@click="handleClickTemp(temp, index)" v-for="(temp, index) in tempList"
> :key="index"
<div class="header"> @click="handleClickTemp(temp, index)"
<div class="title">{{ temp.title }}</div> >
<div class="icon"> <div class="header">
<img src="./assets/images/template-icon.png" alt="" /> <div class="title">{{ temp.title }}</div>
<div class="icon">
<img src="./assets/images/template-icon.png" alt="" />
</div>
</div>
<div class="content">{{ temp.desc }}</div>
<div class="active-icon" v-if="tempActiveIndex === index">
<img src="./assets/images/active-icon.png" alt="" />
</div>
<div class="selected-icon" v-if="tempActiveIndex === index">
<img src="./assets/images/selected-icon.png" alt="" />
</div> </div>
</div>
<div class="content">{{ temp.desc }}</div>
<div class="active-icon" v-if="tempActiveIndex === index">
<img src="./assets/images/active-icon.png" alt="" />
</div>
<div class="selected-icon" v-if="tempActiveIndex === index">
<img src="./assets/images/selected-icon.png" alt="" />
</div> </div>
</div> </div>
</div> </div>
</div> <div class="sider-box">
<div class="sider-box"> <div class="header">加载本地文件</div>
<div class="header">加载本地文件</div> <el-upload
<el-upload action=""
action="" :auto-upload="false"
:auto-upload="false" accept=".pdf"
accept=".pdf" limit="1"
limit="1" :on-exceed="handleExceed"
:on-exceed="handleExceed" ref="upload"
ref="upload" :on-change="handleFileChange"
:on-change="handleFileChange" :file-list="uploadFileList"
:file-list="uploadFileList" :disabled="Object.keys(route.query).length !== 0"
> >
<el-button class="sider-upload-btn" type="primary"> <el-button
<el-icon class="sider-upload-btn-text"> class="sider-upload-btn"
<Upload /> type="primary"
</el-icon> :disabled="Object.keys(route.query).length !== 0"
<span class="sider-upload-btn-text">上传文件</span> >
</el-button> <el-icon class="sider-upload-btn-text">
<template #tip> <Upload />
<div class="sider-upload-btn-tip">支持扩展名:.doc .docx .pdf</div> </el-icon>
</template> <span class="sider-upload-btn-text">上传文件</span>
</el-upload> </el-button>
<template #tip>
<div class="sider-upload-btn-tip">支持扩展名:.doc .docx .pdf</div>
</template>
</el-upload>
</div>
</div> </div>
</div> </div>
<div class="submit-area"> <div class="submit-area">
...@@ -182,14 +192,61 @@ import "@kangc/v-md-editor/lib/theme/style/vuepress.css"; ...@@ -182,14 +192,61 @@ import "@kangc/v-md-editor/lib/theme/style/vuepress.css";
import Prism from "prismjs"; import Prism from "prismjs";
import { ElButton, ElIcon, ElInput, ElMessage, ElUpload, genFileId } from "element-plus"; import { ElButton, ElIcon, ElInput, ElMessage, ElUpload, genFileId } from "element-plus";
VMdEditor.use(vuepressTheme, { import { useRoute } from "vue-router";
Prism const route = useRoute();
});
const isGenerating = ref(false); const isGenerating = ref(false);
const isShowProcess = ref(false); const isShowProcess = ref(false);
const uploadFileList = ref([]); const uploadFileList = ref([]);
const upload = ref(); const upload = ref();
// 流程
const scrollProcessContainer = ref(null);
const processContent = ref("");
// 报文
const scrollContainer = ref(null);
const reportContent = ref("");
const curTempTitle = ref("政令");
const abortController = ref(null);
// 当前调用工具
const curAgentTool = ref("");
const writtingTitle = ref("");
const descText = ref("");
const tabList = ref([
{
name: "写报",
active: true
},
{
name: "收藏",
active: false
},
{
name: "问答",
active: false
}
]);
const tempList = ref([
{
title: "政令",
desc: "基于政令内容生成各维度的综合分析报告"
},
{
title: "法案",
desc: "基于政令内容生成各维度的综合分析报告"
},
{
title: "智库",
desc: "基于智库内容生成各维度的综合分析报告"
},
{
title: "清单",
desc: "基于清单内容生成各维度的综合分析报告"
}
]);
const tempActiveIndex = ref(0);
VMdEditor.use(vuepressTheme, {
Prism
});
//新上传文件替换 //新上传文件替换
const handleExceed = files => { const handleExceed = files => {
...@@ -214,7 +271,7 @@ const handleBack = () => { ...@@ -214,7 +271,7 @@ const handleBack = () => {
handleGenerate(); handleGenerate();
}; };
const isEditMode = ref(false); const isEditMode = ref(true);
const handleSwitchMode = () => { const handleSwitchMode = () => {
isEditMode.value = !isEditMode.value; isEditMode.value = !isEditMode.value;
if (!isEditMode.value) { if (!isEditMode.value) {
...@@ -241,20 +298,9 @@ const saveToLocalStorage = text => { ...@@ -241,20 +298,9 @@ const saveToLocalStorage = text => {
localStorage.setItem("markdown-content", text); localStorage.setItem("markdown-content", text);
}; };
const abortController = ref(null);
const { renderedContent, updateContent } = useMarkdownStream(); const { renderedContent, updateContent } = useMarkdownStream();
const { renderedProcess, updateProcess } = useStream(); const { renderedProcess, updateProcess } = useStream();
// 流程
const scrollProcessContainer = ref(null);
const processContent = ref("");
// 报文
const scrollContainer = ref(null);
const reportContent = ref("");
const curTempTitle = ref("法案");
// 停止生成 // 停止生成
const handleGenerate = () => { const handleGenerate = () => {
isShowProcess.value = false; isShowProcess.value = false;
...@@ -262,87 +308,160 @@ const handleGenerate = () => { ...@@ -262,87 +308,160 @@ const handleGenerate = () => {
abortController.value.abort(); abortController.value.abort();
}; };
// 当前调用工具
const curAgentTool = ref("报告整体优化工具");
const getStreamChat = async (search, inputValue) => { const getStreamChat = async (search, inputValue) => {
if (uploadFileList.value.length > 0) { if (Object.keys(route.query).length !== 0) {
const rawFile = uploadFileList.value[0].raw;
if (!rawFile) {
ElMessage.error("文件解析失败,请重新选择");
return;
}
callSseWithPdf(rawFile);
} else {
const params = { const params = {
query: writtingTitle.value, // "输出一篇报文" query: writtingTitle.value, // "输出一篇报文"
desc: descText.value, desc: descText.value,
topic: curTempTitle.value // 政令、智库、法案、清单 topic: curTempTitle.value,
report_id: route.query.fileId // 政令、智库、法案、清单
}; };
callSseWithAi(params); callSseWithAi(params);
} else {
if (curTempTitle.value === "政令") {
if (uploadFileList.value.length === 0) {
ElMessage.error("请上传政令文件");
return;
}
const rawFile = uploadFileList.value[0].raw;
if (!rawFile) {
ElMessage.error("文件解析失败,请重新选择");
return;
}
callSseWithPdf(rawFile);
} else {
const params = {
query: writtingTitle.value, // "输出一篇报文"
desc: descText.value,
topic: curTempTitle.value // 政令、智库、法案、清单
};
callSseWithAi(params);
}
} }
}; };
const getFormattedTime = () => {
const now = new Date();
// 补零函数:确保单个数字补为两位(如 1 → 01,9 → 09)
const pad = n => n.toString().padStart(2, "0");
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(
now.getMinutes()
)}:${pad(now.getSeconds())}`;
};
// 核心SSE调用函数(修复后)
const callSseWithPdf = async selectedFile => { const callSseWithPdf = async selectedFile => {
// 重置中断控制器
if (abortController.value) {
abortController.value.abort();
}
abortController.value = new AbortController(); abortController.value = new AbortController();
// 状态重置
isGenerating.value = false;
isShowProcess.value = false;
try { try {
// 构造FormData(和后端字段名保持一致)
const formData = new FormData(); const formData = new FormData();
formData.append("pdf", selectedFile); formData.append("pdf", selectedFile);
// 调用fetchEventSource(核心:支持POST+FormData+SSE)
await fetchEventSource("/pdfSse/api/v1/order/pdf/extract/report/sse", { await fetchEventSource("/pdfSse/api/v1/order/pdf/extract/report/sse", {
method: "POST", // 关键:设置POST方法 method: "POST",
body: formData, // 关键:传递PDF文件的FormData body: formData,
signal: abortController.value.signal, // 中断信号 signal: abortController.value.signal,
headers: { headers: {
// 禁用默认的SSE协议头(避免和文件上传冲突)
Accept: "text/event-stream", Accept: "text/event-stream",
"Cache-Control": "no-cache", "Cache-Control": "no-cache"
Connection: "keep-alive"
}, },
openWhenHidden: true, openWhenHidden: true,
// 核心:原生onmessage回调(无需手动分割/解析) retryDelay: 1000,
async onopen(res) { maxRetries: 3,
console.log("流式回答开始", res); // 连接打开回调
isGenerating.value = true; async onopen(response) {
isShowProcess.value = true; console.log("流式回答开始", response);
// 校验响应状态
if (response.ok && response.headers.get("content-type")?.includes("text/event-stream")) {
isGenerating.value = true;
isShowProcess.value = true;
} else {
ElMessage.warning("SSE连接格式异常,即将断开");
abortController.value.abort();
}
}, },
async onmessage(res) { // 核心修复:消息处理回调
const { data, event } = res; async onmessage(event) {
const jsonData = JSON.parse(data); // 1. 严格过滤空消息(解决失焦时空消息问题)
switch (event) { if (!event || !event.data || event.data.trim() === "") {
console.debug("收到空SSE消息,忽略", event);
return;
}
let jsonData = null;
try {
// 2. 容错处理:防止非JSON格式的消息导致解析报错
jsonData = JSON.parse(event.data.trim());
} catch (parseError) {
console.warn("SSE消息JSON解析失败", parseError, event.data);
return;
}
// 3. 按事件类型处理业务逻辑
switch (event.event) {
case "progress": case "progress":
processContent.value += `${getFormattedTime()}:${jsonData.message}\r\n`; // 校验数据完整性
updateProcess(processContent.value, scrollProcessContainer.value); if (jsonData.message) {
processContent.value += `${getFormattedTime()}:${jsonData.message}\r\n`;
updateProcess(processContent.value, scrollProcessContainer.value);
}
break; break;
case "result": case "result":
callSseWithAi({ // 确保result数据有效
query: writtingTitle.value, // "输出一篇报文" if (jsonData && Object.keys(jsonData).length) {
desc: descText.value, await callSseWithAi({
topic: "政令", query: writtingTitle.value,
result: data // 政令、智库、法案、清单 desc: descText.value,
}); topic: curTempTitle.value,
result: jsonData // 传递解析后的对象而非原始字符串
});
}
break;
default: default:
console.debug("未处理的SSE事件类型", event.event);
break; break;
} }
}, },
// 错误处理优化
onerror(error) { onerror(error) {
ElMessage({ console.error("SSE连接错误", error);
message: "写报生成报错!", ElMessage.warning("写报生成报错!");
type: "warning" // 只在非主动中断时重连/终止
}); if (error.name !== "AbortError") {
// 触发库的自动重连机制(返回true)
return true;
}
// 主动中断时清理控制器
abortController.value.abort(); abortController.value.abort();
abortController.value = new AbortController(); abortController.value = new AbortController();
throw new Error(error); },
// 连接关闭回调
onclose() {
console.log("SSE连接正常关闭");
isGenerating.value = false;
} }
}); });
} catch (error) { } catch (error) {
// 全局异常捕获
if (error.name !== "AbortError") { if (error.name !== "AbortError") {
ElMessage.error(`请求失败:${error.message}`); ElMessage.error(`请求失败:${error.message}`);
isLoading.value = false; console.error("SSE请求异常", error);
} }
// 重置状态
isGenerating.value = false;
isShowProcess.value = false;
// 清理控制器
abortController.value.abort();
abortController.value = new AbortController();
} }
}; };
...@@ -412,54 +531,8 @@ const callSseWithAi = async params => { ...@@ -412,54 +531,8 @@ const callSseWithAi = async params => {
}); });
}; };
const getFormattedTime = () => {
const now = new Date();
// 补零函数:确保单个数字补为两位(如 1 → 01,9 → 09)
const pad = n => n.toString().padStart(2, "0");
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(
now.getMinutes()
)}:${pad(now.getSeconds())}`;
};
const writtingTitle = ref("");
const descText = ref("");
const tabList = ref([
{
name: "写报",
active: true
},
{
name: "收藏",
active: false
},
{
name: "问答",
active: false
}
]);
const tempList = ref([
{
title: "法案1",
desc: "基于法案内容生成各维度的综合分析报告"
},
{
title: "智库",
desc: "基于智库内容生成各维度的综合分析报告"
},
{
title: "政令",
desc: "基于政令内容生成各维度的综合分析报告"
},
{
title: "清单",
desc: "基于清单内容生成各维度的综合分析报告"
}
]);
const tempActiveIndex = ref(0);
const handleClickTemp = (item, index) => { const handleClickTemp = (item, index) => {
if (Object.keys(route.query).length !== 0) return;
tempActiveIndex.value = index; tempActiveIndex.value = index;
curTempTitle.value = item.title; curTempTitle.value = item.title;
}; };
...@@ -475,7 +548,16 @@ const exportContent = () => { ...@@ -475,7 +548,16 @@ const exportContent = () => {
URL.revokeObjectURL(url); URL.revokeObjectURL(url);
}; };
onMounted(() => {}); onMounted(() => {
if (route && Object.keys(route.query).length !== 0) {
const { topic, fileId } = route.query;
if (!topic || !fileId) return;
curTempTitle.value = topic;
tempActiveIndex.value = tempList.value.findIndex((item, index) => {
return item.title === topic;
});
}
});
onUnmounted(() => { onUnmounted(() => {
if (abortController.value) { if (abortController.value) {
...@@ -584,321 +666,413 @@ onUnmounted(() => { ...@@ -584,321 +666,413 @@ onUnmounted(() => {
.left-box { .left-box {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 520px; width: 525px;
padding: 21px 21px 29px 22px; padding-top: 22px;
padding-bottom: 29px;
box-sizing: border-box; box-sizing: border-box;
border-right: 1px solid rgba(234, 236, 238, 1); border-right: 1px solid rgba(234, 236, 238, 1);
border-top: 1px solid rgba(234, 236, 238, 1); border-top: 1px solid rgba(234, 236, 238, 1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
.process-box { .left-box-input {
display: flex; overflow-y: scroll;
flex-direction: column; overflow-x: hidden;
gap: 20px; scrollbar-width: none;
padding-inline: 22px;
.back { .process-box {
height: 24px; display: flex;
line-height: 24px; flex-direction: column;
color: var(--color-main-active); gap: 20px;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
cursor: pointer;
}
.process-main-box { .back {
width: 476px; height: 24px;
line-height: 24px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
cursor: pointer;
}
.analysis-box { .process-main-box {
.analysis-header { width: 476px;
display: flex;
.analysis-box {
.analysis-header {
display: flex;
.icon { .icon {
margin-top: 5px; margin-top: 5px;
width: 20px; width: 20px;
height: 20px; height: 20px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
}
}
.text {
height: 30px;
line-height: 30px;
font-family: Microsoft YaHei;
color: #333;
font-size: 20px;
font-weight: 700;
margin-left: 5px;
} }
} }
.text { .analysis-content {
height: 30px; height: 90px;
line-height: 30px; line-height: 30px;
color: #555;
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
color: #333; font-size: 16px;
font-size: 20px; font-weight: 400;
font-weight: 700; text-indent: 32px;
margin-left: 5px;
} }
} }
.analysis-content { .steps-box {
height: 90px; .steps-header {
line-height: 30px; display: flex;
color: #555;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
text-indent: 32px;
}
}
.steps-box { .icon {
.steps-header { margin-top: 5px;
display: flex; width: 20px;
height: 20px;
.icon { img {
margin-top: 5px; width: 100%;
width: 20px; height: 100%;
height: 20px; }
}
img { .text {
width: 100%; height: 30px;
height: 100%; line-height: 30px;
font-family: Microsoft YaHei;
color: #333;
font-size: 20px;
font-weight: 700;
margin-left: 5px;
} }
} }
.text { .steps-content {
height: 30px; width: 100%;
line-height: 30px; min-height: 20px;
font-family: Microsoft YaHei; max-height: 480px;
color: #333; overflow-x: hidden;
font-size: 20px; overflow-y: auto;
font-weight: 700;
margin-left: 5px;
} }
} }
.steps-content { .doing-box {
width: 100%; height: 40px;
min-height: 20px; line-height: 40px;
max-height: 480px; color: #555;
overflow-x: hidden; font-family: Microsoft YaHei;
overflow-y: auto; font-size: 16px;
font-weight: 400;
margin-left: 20px;
} }
}
.doing-box { .tool-box {
height: 40px; width: 440px;
line-height: 40px; height: 160px;
color: #555; margin: 10px auto;
font-family: Microsoft YaHei; background: #f6f9fe;
font-size: 16px; border-radius: 10px;
font-weight: 400;
margin-left: 20px;
}
.tool-box { .tool-header {
width: 440px; height: 30px;
height: 160px; line-height: 30px;
margin: 10px auto; margin-left: 20px;
background: #f6f9fe; color: var(--color-main-active);
border-radius: 10px; }
.tool-header { .tool-main {
height: 30px; height: 110px;
line-height: 30px; width: 400px;
margin-left: 20px; margin: 0 auto;
color: var(--color-main-active); background: #fff;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 40px;
}
} }
}
}
.tool-main { .sider {
height: 110px; box-sizing: border-box;
width: 400px; display: flex;
margin: 0 auto; flex-direction: column;
background: #fff; gap: 23px;
color: rgba(95, 101, 108, 1);
.sider-box {
.header {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 700;
line-height: 40px; line-height: 24px;
} }
}
}
}
.sider { .template-box {
box-sizing: border-box; margin-top: 19px;
display: flex; height: 260px;
flex-direction: column; display: flex;
gap: 23px; flex-wrap: wrap;
gap: 16px;
.template {
width: 230px;
height: 120px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 4px;
position: relative;
cursor: pointer;
.active-icon {
width: 24px;
height: 24px;
position: absolute;
top: 0;
right: 0;
z-index: 99;
.sider-box { img {
.header { width: 100%;
color: rgba(59, 65, 75, 1); height: 100%;
font-family: Microsoft YaHei; }
font-size: 16px; }
font-weight: 700;
line-height: 24px;
}
.template-box { .selected-icon {
margin-top: 19px; width: 8px;
height: 260px; height: 6px;
display: flex; position: absolute;
flex-wrap: wrap; top: -4px;
gap: 16px; right: 3px;
z-index: 100;
.template { img {
width: 230px; width: 8px;
height: 120px; height: 6px;
box-sizing: border-box; }
border: 1px solid rgba(234, 236, 238, 1); }
border-radius: 4px;
position: relative;
cursor: pointer;
.active-icon { .header {
width: 24px; display: flex;
height: 24px; justify-content: space-between;
position: absolute; height: 50px;
top: 0;
right: 0; .title {
z-index: 99; height: 24px;
// color: rgba(59, 65, 75, 1);
img { color: #333;
width: 100%; font-family: Microsoft YaHei;
height: 100%; font-size: 16px;
font-weight: 700;
line-height: 24px;
margin-left: 15px;
margin-top: 16px;
}
.icon {
margin-top: 15px;
margin-right: 16px;
width: 30px;
height: 30px;
border-radius: 15px;
background: rgba(231, 243, 255, 1);
img {
width: 17px;
height: 14px;
margin-top: 8px;
margin-left: 7px;
}
}
}
.content {
margin: 0 auto;
width: 200px;
height: 48px;
margin-top: 10px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
} }
} }
.selected-icon { .disableTemplate {
width: 8px; width: 230px;
height: 6px; height: 120px;
position: absolute; box-sizing: border-box;
top: -4px; border: 1px solid #e4e7ed;
right: 3px; border-radius: 4px;
z-index: 100; position: relative;
cursor: not-allowed;
background-color: #f5f7fa;
.active-icon {
width: 24px;
height: 24px;
position: absolute;
top: 0;
right: 0;
z-index: 99;
img { img {
width: 100%;
height: 100%;
}
}
.selected-icon {
width: 8px; width: 8px;
height: 6px; height: 6px;
position: absolute;
top: -4px;
right: 3px;
z-index: 100;
img {
width: 8px;
height: 6px;
}
} }
}
.header { .header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
height: 50px; height: 50px;
.title {
height: 24px;
color: #c0c4cc;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 24px;
margin-left: 15px;
margin-top: 16px;
}
.title { .icon {
height: 24px; margin-top: 15px;
// color: rgba(59, 65, 75, 1); margin-right: 16px;
color: #333; width: 30px;
height: 30px;
border-radius: 15px;
background: #f0f2f5;
img {
width: 17px;
height: 14px;
margin-top: 8px;
margin-left: 7px;
opacity: 0.5;
}
}
}
.content {
margin: 0 auto;
width: 200px;
height: 48px;
margin-top: 10px;
color: #dcdfe6;
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px; font-size: 16px;
font-weight: 700; font-weight: 400;
line-height: 24px; line-height: 24px;
margin-left: 15px;
margin-top: 16px;
} }
}
.icon { .tempActive {
margin-top: 15px; border: 1px solid rgba(5, 95, 194, 1);
margin-right: 16px; background: rgba(246, 250, 255, 1);
width: 30px;
height: 30px;
border-radius: 15px;
background: rgba(231, 243, 255, 1);
img {
width: 17px;
height: 14px;
margin-top: 8px;
margin-left: 7px;
}
}
} }
}
.content { .title-box {
margin: 0 auto; margin-top: 15px;
width: 200px;
height: 48px; .title {
margin-top: 10px; color: rgba(95, 101, 108, 1);
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 24px; line-height: 24px;
} }
}
.tempActive { .title-input {
border: 1px solid rgba(5, 95, 194, 1); margin-top: 15px;
background: rgba(246, 250, 255, 1); }
} }
}
.title-box { .description-box {
margin-top: 15px; margin-top: 24px;
.title { .title {
color: rgba(95, 101, 108, 1); height: 24px;
font-family: Microsoft YaHei; color: rgba(95, 101, 108, 1);
font-size: 16px; font-family: Microsoft YaHei;
font-weight: 400; font-size: 16px;
line-height: 24px; font-weight: 400;
} line-height: 24px;
}
.title-input { .description-input {
margin-top: 15px; margin-top: 12px;
height: 200px;
}
} }
}
.description-box { .sider-upload-btn {
margin-top: 24px; width: 476px;
height: 36px;
box-sizing: border-box;
border: 1px dashed rgba(234, 236, 238, 1);
border-radius: 6px;
background: rgba(247, 248, 249, 1);
margin-top: 19px;
}
.title { .sider-upload-btn-text {
height: 24px; color: rgba(59, 65, 75, 1);
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px; font-style: Regular;
font-size: 14px;
font-weight: 400; font-weight: 400;
line-height: 24px; line-height: 22px;
letter-spacing: 0px;
text-align: left;
} }
.description-input { .sider-upload-btn-tip {
margin-top: 12px; color: rgba(95, 101, 108, 1);
height: 200px; font-family: Microsoft YaHei;
font-style: Regular;
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
margin-top: 8px;
} }
} }
.sider-upload-btn {
width: 476px;
height: 36px;
box-sizing: border-box;
border: 1px dashed rgba(234, 236, 238, 1);
border-radius: 6px;
background: rgba(247, 248, 249, 1);
margin-top: 19px;
}
.sider-upload-btn-text {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-style: Regular;
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
}
.sider-upload-btn-tip {
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-style: Regular;
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
margin-top: 8px;
}
} }
} }
...@@ -906,6 +1080,7 @@ onUnmounted(() => { ...@@ -906,6 +1080,7 @@ onUnmounted(() => {
margin-top: auto; margin-top: auto;
width: 100%; width: 100%;
min-height: 74px; min-height: 74px;
padding-inline: 22px;
.tips { .tips {
height: 22px; height: 22px;
...@@ -1026,7 +1201,7 @@ onUnmounted(() => { ...@@ -1026,7 +1201,7 @@ onUnmounted(() => {
background: #f7f8f9; background: #f7f8f9;
.edit-panel { .edit-panel {
width: calc(100% - 100px); width: calc(100% - 170px);
height: calc(100% - 40px); height: calc(100% - 40px);
margin: 20px 50px; margin: 20px 50px;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论