From 7954d34524efdc0f1caec8fd76931c3cb60d2551 Mon Sep 17 00:00:00 2001 From: JayChou <xxx@gmail.com> Date: Wed, 19 Mar 2025 15:37:56 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=AB=AF=E7=A8=8B=E5=BA=8F=E7=BC=96=E5=86=99=20=E5=B0=81?= =?UTF-8?q?=E8=A3=85=E5=AE=9E=E9=AA=8C=E6=AD=A5=E9=AA=A4=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 + pnpm-lock.yaml | 23 ++ src/api/index.ts | 46 ++- src/assets/images/idea.png | Bin 0 -> 44976 bytes src/main.ts | 7 + src/permissions.ts | 13 +- src/router/index.ts | 7 +- src/store/modules/setting.ts | 43 ++- src/store/modules/user.ts | 23 +- src/utils/index.ts | 12 + src/utils/setStep.ts | 16 + src/views/compiler/index.vue | 77 +++++ src/views/designRoute/components/wenBenYu.vue | 35 ++- .../designRoute/components/wenBenYu2.vue | 10 +- src/views/designRoute/index.vue | 105 ++++--- src/views/program/components/yibiao.vue | 8 +- src/views/program/index.vue | 281 ++++++++++++++---- 17 files changed, 579 insertions(+), 129 deletions(-) create mode 100644 src/assets/images/idea.png create mode 100644 src/utils/index.ts create mode 100644 src/utils/setStep.ts create mode 100644 src/views/compiler/index.vue diff --git a/package.json b/package.json index c7275f2..e0d6e59 100644 --- a/package.json +++ b/package.json @@ -19,10 +19,12 @@ "@antv/x6-plugin-transform": "^2.1.8", "@antv/x6-vue-shape": "^2.1.2", "@element-plus/icons-vue": "^2.3.1", + "@highlightjs/vue-plugin": "^2.1.0", "@kjgl77/datav-vue3": "^1.7.3", "axios": "^1.7.2", "echarts": "^5.6.0", "element-plus": "^2.9.5", + "highlight.js": "^11.11.1", "insert-css": "^2.0.0", "lib-flexible": "^0.3.2", "pinia": "^2.1.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11ad3e4..d641ff1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,9 @@ importers: '@element-plus/icons-vue': specifier: ^2.3.1 version: 2.3.1(vue@3.4.29(typescript@5.2.2)) + '@highlightjs/vue-plugin': + specifier: ^2.1.0 + version: 2.1.0(highlight.js@11.11.1)(vue@3.4.29(typescript@5.2.2)) '@kjgl77/datav-vue3': specifier: ^1.7.3 version: 1.7.3(vue@3.4.29(typescript@5.2.2)) @@ -50,6 +53,9 @@ importers: element-plus: specifier: ^2.9.5 version: 2.9.5(vue@3.4.29(typescript@5.2.2)) + highlight.js: + specifier: ^11.11.1 + version: 11.11.1 insert-css: specifier: ^2.0.0 version: 2.0.0 @@ -344,6 +350,12 @@ packages: '@floating-ui/utils@0.2.9': resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + '@highlightjs/vue-plugin@2.1.0': + resolution: {integrity: sha512-E+bmk4ncca+hBEYRV2a+1aIzIV0VSY/e5ArjpuSN9IO7wBJrzUE2u4ESCwrbQD7sAy+jWQjkV5qCCWgc+pu7CQ==} + peerDependencies: + highlight.js: ^11.0.1 + vue: ^3 + '@jiaminghi/bezier-curve@0.0.9': resolution: {integrity: sha512-u9xJPOEl6Dri2E9FfmJoGxYQY7vYJkURNX04Vj64tdi535tPrpkuf9Sm0lNr3QTKdHQh0DdNRsaa62FLQNQEEw==} @@ -772,6 +784,10 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + highlight.js@11.11.1: + resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} + engines: {node: '>=12.0.0'} + htmlparser2@8.0.2: resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} @@ -1362,6 +1378,11 @@ snapshots: '@floating-ui/utils@0.2.9': {} + '@highlightjs/vue-plugin@2.1.0(highlight.js@11.11.1)(vue@3.4.29(typescript@5.2.2))': + dependencies: + highlight.js: 11.11.1 + vue: 3.4.29(typescript@5.2.2) + '@jiaminghi/bezier-curve@0.0.9': dependencies: '@babel/runtime': 7.24.7 @@ -1847,6 +1868,8 @@ snapshots: he@1.2.0: {} + highlight.js@11.11.1: {} + htmlparser2@8.0.2: dependencies: domelementtype: 2.3.0 diff --git a/src/api/index.ts b/src/api/index.ts index 3879b01..9b23e72 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,14 +1,38 @@ -import request from '@/utils/request' +import request from "@/utils/request"; export const login = (data: any) => { - return request({ - url: '/sys/login', - method: 'post', - data - }) -} + return request({ + url: "/sys/login", + method: "post", + data, + }); +}; export const getCode = (time: any) => { - return request({ - url: '/sys/randomImage/' + time, - }) - } \ No newline at end of file + return request({ + url: "/sys/randomImage/" + time, + }); +}; +// 获取用户信息 +export const getUserInfo = () => { + return request({ + url: "/sys/user/getUserInfo", + method: "get", + }); +}; + +// 实验步骤 +export const setStep = (params: any) => { + return request({ + url: "/experimentrecords/xnExperimentRecords/check", + method: "get", + params + }) +} +// 获取步骤id +export const getStepId = () => { + return request({ + url: "/experimentrecords/xnExperimentRecords/getProcedureList", + method: "get", + + }) +} \ No newline at end of file diff --git a/src/assets/images/idea.png b/src/assets/images/idea.png new file mode 100644 index 0000000000000000000000000000000000000000..c6b88c606a619fa4299f8233be3c03099ea9f295 GIT binary patch literal 44976 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 literal 0 HcmV?d00001 diff --git a/src/main.ts b/src/main.ts index e979875..21fcf3a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -7,7 +7,14 @@ import 'element-plus/dist/index.css'; // 引入 Element Plus 的样式文件 import '@/utils/rem.js' import DataVVue3 from '@kjgl77/datav-vue3' import pinia from '@/store/index' +//引入依赖和语言 +import 'highlight.js/styles/stackoverflow-light.css' +// import hljs from "highlight.js/lib/core"; +// import hljsVuePlugin from "@highlightjs/vue-plugin"; +// import java from "highlight.js/lib/languages/java"; const app = createApp(App) +// hljs.registerLanguage("java", java); +// app.use(hljsVuePlugin); app.use(ElementPlus) app.use(pinia) app.use(DataVVue3) diff --git a/src/permissions.ts b/src/permissions.ts index 3bc2aa0..fa9a430 100644 --- a/src/permissions.ts +++ b/src/permissions.ts @@ -14,10 +14,19 @@ router.beforeEach((to: any, from: any, next: any) => { } else { const token = getToken(); if (token) { - next(); + console.log(store.userInfo); + + if (store.userInfo) { + next(); + } else { + store.getUserInfo().then(() => { + next(); + }); + } + // next(); } else { next("/login"); } } }); -export default router; \ No newline at end of file +export default router; diff --git a/src/router/index.ts b/src/router/index.ts index 8d73740..73e7f74 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -19,7 +19,12 @@ const routerList: any = [ path: "program", name: "Program", component: () => import("@/views/program/index.vue"), - } + }, + { + path: "compiler", + name: "Compiler", + component: () => import("@/views/compiler/index.vue"), + }, ], }, { diff --git a/src/store/modules/setting.ts b/src/store/modules/setting.ts index f86ce30..74494ec 100644 --- a/src/store/modules/setting.ts +++ b/src/store/modules/setting.ts @@ -16,6 +16,11 @@ const settingStore = defineStore("settingStore", { sdsz: 0, // 湿度数值 falg: false, timer: null, + experimentPreservation: false, // 是否设计好实验 + saveRoute: false, // 是否保存路由 + stepIds: null, + wenduCode: null, + shiduCode:null }; }, actions: { @@ -27,7 +32,7 @@ const settingStore = defineStore("settingStore", { this.qw = value; }, - setValue(value: number, name: string) { + setValue(value: number | boolean, name: string) { this[name] = value; }, openHeating() { @@ -46,7 +51,7 @@ const settingStore = defineStore("settingStore", { } }, calculateTemperature() { - this.qw <= 0 ? this.qw=1 : this.qw; + this.qw <= 0 ? (this.qw = 1) : this.qw; const a = (100000 * this.zl * this.srmj) / this.jrgl; let time = 0; let currentTemp = this.qw; @@ -61,6 +66,40 @@ const settingStore = defineStore("settingStore", { clearInterval(interval); } + time += 1; // 每秒增加 1s + }, 1000); + }, + simulateHeatingAndHumidifying() { + // 计算时间常数 + const a = (100000 * this.zl * this.srmj) / this.jrgl; + const b = (10000 * this.jsmj) / this.jsgl; + + let time = 0; + let currentTemp = this.qw; + let currentHumidity = this.cssd; + + const interval = setInterval(() => { + // 计算温度 + currentTemp = (1 - Math.exp(-time / a)) * 100 + this.qw; + if (currentTemp > 100) currentTemp = 100; + + // 计算湿度 + currentHumidity = (1 - Math.exp(-time / b)) * 100 + this.cssd; + if (currentHumidity > 100) currentHumidity = 100; + + console.log( + `时间: ${time}s, 温度: ${currentTemp.toFixed( + 2 + )}°C, 湿度: ${currentHumidity}%RH` + ); + this.qw = currentTemp >= 100 ? 100 : currentTemp; + this.cssd = currentHumidity >= 100 ? 100 : Number(currentHumidity.toFixed(2)); + // 停止加热 & 加湿 + if (currentTemp >= 100 && currentHumidity >= 100) { + console.log("温度和湿度均达到上限,停止模拟!"); + clearInterval(interval); + } + time += 1; // 每秒增加 1s }, 1000); }, diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index a2c0c45..6b37de5 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -1,30 +1,37 @@ import { defineStore } from "pinia"; -import { getToken,setToken } from "@/utils/auth"; -import { login } from "@/api"; +import { getToken, setToken } from "@/utils/auth"; +import { login, getUserInfo } from "@/api"; import { ElMessage } from "element-plus"; const userStore = defineStore("userStore", { state: () => ({ token: getToken(), - userInfo: {}, + userInfo: null, }), actions: { async logIn(form: any) { console.log(form); const res: any = await login(form); // if(res.code === 500) return ElMessage.error(res.msg) - if(res.code !== 200) { - ElMessage.error(res.msg) - return false + if (res.code !== 200) { + ElMessage.error(res.msg); + return false; } this.token = res.result.token; this.userInfo = res.result.userInfo; setToken(this.token); console.log(res); - return true + return true; }, clearStatus() { this.token = ""; - this.userInfo = {}; + this.userInfo = null; + }, + async getUserInfo() { + const res:any = await getUserInfo(); + this.userInfo = res.result.userInfo; + console.log(res); + + // this.userInfo = res.result; }, }, }); diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..8c8eebe --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,12 @@ +// 格式化时间 年月日时分秒 +export function formatDate(date: any) { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const day = String(date.getDate()).padStart(2, "0"); + const hours = String(date.getHours()).padStart(2, "0"); + const minutes = String(date.getMinutes()).padStart(2, "0"); + const seconds = String(date.getSeconds()).padStart(2, "0"); + console.log(`${year}-${month}-${day} ${hours}:${minutes}:${seconds}`); + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; +} \ No newline at end of file diff --git a/src/utils/setStep.ts b/src/utils/setStep.ts new file mode 100644 index 0000000..14b1391 --- /dev/null +++ b/src/utils/setStep.ts @@ -0,0 +1,16 @@ +import { setStep, getStepId } from "../api/index"; +import settingStore from "../store/modules/setting"; +import pinia from "@/store"; +const useStore = settingStore(pinia); +export const setStepEvent = async (step: number, controlsSt: string) => { + let id: any = null; + if (!useStore.stepIds) { + const data: any = await getStepId(); + useStore.stepIds = data.result.map((item: any) => item.id); + id = useStore.stepIds[step - 1]; + // return id; + await setStep({ id, controlsSt }); + } else { + await setStep({ id: useStore.stepIds[step - 1], controlsSt }); + } +}; diff --git a/src/views/compiler/index.vue b/src/views/compiler/index.vue new file mode 100644 index 0000000..d88adbf --- /dev/null +++ b/src/views/compiler/index.vue @@ -0,0 +1,77 @@ +<template> + <div class="container"> + <div class="main"> + <!-- <pre><code ref="editor" class="edit-text html" contenteditable="true" @input="highlightCode">console.log('Hello, World!');</code></pre> --> + <div class="edit-text" contenteditable="true" spellcheck="false"> + <!-- <highlightjs ref="editor" :language="language" :code="code" v-model="code" contenteditable="true" @input="highlightCode"></highlightjs> --> + oisafkahsdkjfhasdf sdfhkjsahfdlkjas \n /n sldhfkajshfd salkdhflkasf asfasdf + </div> + </div> + <div class="setting"> + <el-button>保存</el-button> + </div> + </div> +</template> + +<script setup> +import { onMounted, ref } from "vue"; + +import hljs from "highlight.js/lib/core"; + +const editor = ref(null); +const code = ref('console.log("Hello, World!");'); +const highlightCode = () => { + const codeBlock = editor.value; + console.log(codeBlock); + + if (codeBlock) { + hljs.highlightElement(code); + } +}; + +onMounted(() => { + // highlightCode(); +}); +</script> + +<style scoped> +.container { + width: 100%; + height: 100vh; + display: flex; + justify-content: center; + margin-top: 100px; + /* position: relative; */ +} + +.main { + width: 1442px; + height: 753px; + background-color: pink; + background: url("../../assets/images/idea.png") no-repeat; + background-size: contain; + background-position: center center; + position: relative; +} + +.edit-text { + position: absolute; + left: 410px; + top: 60px; + width: 700px; + height: 670px; + background-color: #1e1e1e; + color: #fff; + font-family: "Courier New", monospace; + padding: 10px; + border-radius: 5px; + overflow: auto; + outline: none; + line-height: 30px; +} +.setting{ + position: absolute; + top: 20px; + right: 100px; +} +</style> diff --git a/src/views/designRoute/components/wenBenYu.vue b/src/views/designRoute/components/wenBenYu.vue index 59dde09..80d423b 100644 --- a/src/views/designRoute/components/wenBenYu.vue +++ b/src/views/designRoute/components/wenBenYu.vue @@ -6,12 +6,31 @@ <div class="W">W</div> <div class="t">t</div> <div class="T">T</div> - <textarea type="textarea" style="width: 100%;height: 100%;border: none;font-size: 14px;line-height: 30px;" /> + <textarea + type="textarea" + @change="wenduCodeChange" + style=" + width: 100%; + height: 100%; + border: none; + font-size: 14px; + line-height: 30px; + " + /> </div> </template> <script setup> -import { ref, computed, nextTick, watch, onMounted } from "vue"; +import { ref } from "vue"; +import settingStore from "@/store/modules/setting"; +const useSettingStore = settingStore(); +const value = ref(""); +let code = "float a;a=1000000*M*S/W;T+(1-exp(-t/a))*100+T0;if(T>=100){T=100;}"; +const wenduCodeChange = (e) => { + // 将文本去除换行转为字符串 + useSettingStore.wenduCode = e.target.value.replace(/\n/g, ""); + // console.log(e.target.value.replace(/\n/g, '') === code); +}; </script> <style scoped> @@ -27,7 +46,6 @@ import { ref, computed, nextTick, watch, onMounted } from "vue"; left: -25px; border: 1px solid #ccc; color: #fff; - } .M { position: absolute; @@ -35,7 +53,6 @@ import { ref, computed, nextTick, watch, onMounted } from "vue"; left: -25px; border: 1px solid #ccc; color: #fff; - } .S { position: absolute; @@ -43,30 +60,26 @@ import { ref, computed, nextTick, watch, onMounted } from "vue"; left: -17px; border: 1px solid #ccc; color: #fff; - } -.W{ +.W { position: absolute; top: 180px; left: -17px; border: 1px solid #ccc; color: #fff; - } -.t{ +.t { position: absolute; top: 240px; left: -17px; border: 1px solid #ccc; color: #fff; - } -.T{ +.T { position: absolute; top: 50%; right: -17px; border: 1px solid #ccc; color: #fff; - } </style> diff --git a/src/views/designRoute/components/wenBenYu2.vue b/src/views/designRoute/components/wenBenYu2.vue index 8797e8f..caa5d0f 100644 --- a/src/views/designRoute/components/wenBenYu2.vue +++ b/src/views/designRoute/components/wenBenYu2.vue @@ -6,12 +6,18 @@ <!-- <div class="W">W</div> --> <div class="t">t1</div> <div class="T">R</div> - <textarea type="textarea" style="width: 100%;height: 100%;border: none;font-size: 14px;line-height: 30px;" /> + <textarea type="textarea" @change="wenduCodeChange" style="width: 100%;height: 100%;border: none;font-size: 14px;line-height: 30px;" /> </div> </template> <script setup> -import { ref, computed, nextTick, watch, onMounted } from "vue"; +import { ref } from "vue"; +import settingStore from "@/store/modules/setting"; +const useSettingStore = settingStore(); +const value = ref(""); +const wenduCodeChange = (e) => { + useSettingStore.shiduCode = e.target.value.replace(/\n/g, ""); +} </script> <style scoped> diff --git a/src/views/designRoute/index.vue b/src/views/designRoute/index.vue index 2e67c55..2005abb 100644 --- a/src/views/designRoute/index.vue +++ b/src/views/designRoute/index.vue @@ -69,8 +69,13 @@ import shiduValueSetting from "./components/shiduValueSetting.vue"; import setzijie from "./components/setzijie.vue"; import { ElMessage } from "element-plus"; import tipView from "@/assets/images/guanxitu.png"; +import { useRouter } from "vue-router"; +import useSettingStore from "@/store/modules/setting"; +import { setStepEvent } from "@/utils/setStep"; +import { formatDate } from "@/utils"; let graph = null; - +const router = useRouter(); +const settingStore = useSettingStore(); // 定义通用的端口配置,避免重复 const portConfig = { top: { @@ -165,12 +170,12 @@ onMounted(() => { }); }, validateConnection({ sourceCell, targetCell }) { - // 禁止连接到自身 - if (sourceCell && targetCell && sourceCell.id === targetCell.id) { - return false; - } - return true; + // 禁止连接到自身 + if (sourceCell && targetCell && sourceCell.id === targetCell.id) { + return false; } + return true; + }, }, highlighting: { magnetAdsorbed: { @@ -326,7 +331,7 @@ onMounted(() => { // 添加代码控件1节点 graph.addNode({ shape: "custom-vue-node-wenBenYu", - id:'32', + id: "32", width: 210, height: 300, x: 320, @@ -366,7 +371,7 @@ onMounted(() => { // 添加代码控件2节点 graph.addNode({ shape: "custom-vue-node-wenBenYu2", - id:'33', + id: "33", width: 210, height: 300, x: 400, @@ -795,11 +800,11 @@ onMounted(() => { }); graph.on("edge:connected", ({ edge }) => { const data = { - type: "add", - edge: edge.toJSON(), // toJSON 会自动包含正确的 port 数据 + type: "add", + edge: edge.toJSON(), // toJSON 会自动包含正确的 port 数据 }; saveToLocalStorage(data); -}) + }); // 记录删除连线 graph.on("edge:removed", ({ edge }) => { @@ -810,11 +815,11 @@ onMounted(() => { saveToLocalStorage(data); }); setTimeout(() => { - restoreGraph() + restoreGraph(); }, 1000); - graph.on('edge:added', ({ edge }) => { - console.log('新增连线数据:', edge.toJSON()); -}) + graph.on("edge:added", ({ edge }) => { + console.log("新增连线数据:", edge.toJSON()); + }); // const nodes = graph.getNodes(); // console.log(nodes); // const data = graph.toJSON(); @@ -830,16 +835,44 @@ const onUndo = () => { const onRedo = () => { graph.redo(); }; +const wenduCode = "float a;a=1000000*M*S/W;T+(1-exp(-t/a))*100+T0;if(T>=100){T=100;}"; +const shiduCode = "float b;a=10000*S0/W1;R+(1-exp(-t1/b))*100+R0;if(R>=100){R=100;}"; const onSave = () => { - if (standardData.length !== formatEdges().length) + setStepEvent(3, formatDate(new Date())); + // console.log(removeDuplicateEdges(formatEdges()), standardData); + // return + if (standardData.length !== removeDuplicateEdges(formatEdges()).length) return ElMessage.error("请完善数据"); validateRelationships(standardData, formatEdges()); + if(settingStore.wenduCode != wenduCode){ + return ElMessage.error("温度代码编写错误"); + } + if(settingStore.shiduCode != shiduCode){ + return ElMessage.error("湿度代码编写错误"); + } ElMessage.success("保存成功"); + settingStore.setValue( true,'saveRoute'); + router.push('/program') // const data = graph.toJSON(); // console.log(data); // const edges = graph.getEdges(); // console.log(formatEdges()); }; +function removeDuplicateEdges(edges) { + const seen = new Set(); + return edges.filter(edge => { + // 生成唯一键,无视 source 和 target 的顺序 + const key = edge.source < edge.target + ? `${edge.source}-${edge.target}` + : `${edge.target}-${edge.source}`; + + if (seen.has(key)) { + return false; + } + seen.add(key); + return true; + }); +} const formatEdges = () => { const edges = graph.getEdges(); // console.log(edges); @@ -1081,38 +1114,38 @@ const onTip = () => { function restoreGraph() { const operations = loadFromLocalStorage(); - // 先恢复节点 - operations - .filter(op => op.type === 'add' && op.node) - .forEach(op => graph.addNode(op.node)); + // 先恢复节点 + operations + .filter((op) => op.type === "add" && op.node) + .forEach((op) => graph.addNode(op.node)); - // 再恢复连线 - operations - .filter(op => op.type === 'add' && op.edge) - .forEach(op => { - const edgeData = op.edge; + // 再恢复连线 + operations + .filter((op) => op.type === "add" && op.edge) + .forEach((op) => { + const edgeData = op.edge; - // 若发现 port 数据缺失,补上默认 port ID - if (!edgeData.source.port) edgeData.source.port = "70"; - if (!edgeData.target.port) edgeData.target.port = "70"; + // 若发现 port 数据缺失,补上默认 port ID + if (!edgeData.source.port) edgeData.source.port = "70"; + if (!edgeData.target.port) edgeData.target.port = "70"; - graph.addEdge(edgeData); - }); + graph.addEdge(edgeData); + }); } -const SESSION_KEY = 'graph_operations1'; +const SESSION_KEY = "graph_operations1"; function saveToLocalStorage(data) { - const operations = JSON.parse(localStorage.getItem(SESSION_KEY)) || []; - operations.push(data); - localStorage.setItem(SESSION_KEY, JSON.stringify(operations)); + const operations = JSON.parse(localStorage.getItem(SESSION_KEY)) || []; + operations.push(data); + localStorage.setItem(SESSION_KEY, JSON.stringify(operations)); } function loadFromLocalStorage() { - return JSON.parse(localStorage.getItem(SESSION_KEY)) || []; + return JSON.parse(localStorage.getItem(SESSION_KEY)) || []; } function clearLocalStorage() { - localStorage.removeItem(SESSION_KEY); + localStorage.removeItem(SESSION_KEY); } </script> diff --git a/src/views/program/components/yibiao.vue b/src/views/program/components/yibiao.vue index 76b8700..03a5e32 100644 --- a/src/views/program/components/yibiao.vue +++ b/src/views/program/components/yibiao.vue @@ -9,7 +9,7 @@ import { onMounted, watch } from "vue"; import * as echarts from "echarts"; import settingStore from "@/store/modules/setting"; const useSettingStore = settingStore(); -var value = useSettingStore.cssd * 100; +var value = useSettingStore.cssd; var myChart = null; const initChart = () => { const option = { @@ -187,7 +187,7 @@ const initChart = () => { fontSize: 20, distance: -70, formatter: function (params) { - var value = params.toFixed(0); + var value = params; if (value == 0.0) { return "0"; @@ -235,7 +235,7 @@ const initChart = () => { }, detail: { formatter: function (params) { - return params / 100; + return params ; }, fontSize: 30, color: "#fff", @@ -261,7 +261,7 @@ onMounted(() => { watch( () => useSettingStore.cssd, (newValue) => { - value=newValue * 100 + value=newValue setTimeout(() => { initChart(); }, 100); diff --git a/src/views/program/index.vue b/src/views/program/index.vue index 1f227fa..d8a1767 100644 --- a/src/views/program/index.vue +++ b/src/views/program/index.vue @@ -43,7 +43,9 @@ <el-button @click="onUndo">撤回</el-button> <el-button @click="onRedo">恢复</el-button> <el-button @click="clearLocalStorage">清除缓存</el-button> - <el-button @click="onSave">运行</el-button> + <el-button @click="onSave">{{ + useSettingStore.experimentPreservation ? "运行" : "保存" + }}</el-button> <el-button @click="onTip">提示</el-button> </div> <div class="tip-view"> @@ -80,8 +82,11 @@ import settingStore from "@/store/modules/setting"; import Yibiao from "./components/yibiao.vue"; import { ElMessage } from "element-plus"; import tipView from "@/assets/images/chengxv.png"; - +import { useRouter } from "vue-router"; +import { setStepEvent } from "@/utils/setStep"; +import { formatDate } from "@/utils"; const useSettingStore = settingStore(); +const router = useRouter(); // console.log(useSettingStore.qw); // 为了协助代码演示 @@ -189,14 +194,20 @@ onMounted(() => { // 点击节点时显示编辑框 graph.on("node:click", ({ cell }: any) => { // console.log(cell.store.previous.name); - // console.log(cell); - + console.log(cell); + if (!useSettingStore.saveRoute) { + ElMessage({ + message: "请先完成配置", + type: "warning", + }); + return; + } if ( cell.shape === "deom" || cell.shape === "yibiao" || cell.shape === "rect" || - cell.store.previous.name === "wdsz" || - cell.store.previous.name === "sdsz" + cell.shape === "custom-text-wdsz" || + cell.shape === "custom-text-sdsz" ) return; // if (cell.store.previous.name === "qw") { @@ -220,7 +231,7 @@ onMounted(() => { // ]); }); - graph.on("node:added", ({ node }:any) => { + graph.on("node:added", ({ node }: any) => { const data = { type: "add", node: node.toJSON(), @@ -229,7 +240,7 @@ onMounted(() => { saveToLocalStorage(data); }); - graph.on("node:removed", ({ node }:any) => { + graph.on("node:removed", ({ node }: any) => { const data = { type: "remove", id: node.id, @@ -1057,7 +1068,40 @@ const saveNodeData = () => { if (falg.value) { const value = Number(selectedNodeData.value.label); // useSettingStore.setqw(value); - useSettingStore.setValue(value, selectedNodeData.value.name); + console.log(value, selectedNodeData.value.name); + switch (node.shape) { + case "custom-text": + useSettingStore.setValue(parseInt(node.label), "qw"); //初始温度 + break; + case "custom-text-zl": + useSettingStore.setValue(parseInt(node.label), "zl"); // 质量 + break; + case "custom-text-srmj": + useSettingStore.setValue(parseInt(node.label), "srmj"); // 散热面积 + break; + case "custom-text-jrgl": + useSettingStore.setValue(parseInt(node.label), "jrgl"); // 加热功率 + break; + case "custom-text-jrmj": + useSettingStore.setValue(parseInt(node.label), "jrmj"); // 加热面积 + break; + case "custom-text-prot": + useSettingStore.setValue(node.label, "port"); // 端口 + break; + case "custom-text-IP": + useSettingStore.setValue(node.label, "ip"); // IP + break; + case "custom-text-cssd": + useSettingStore.setValue(parseInt(node.label), "cssd"); // 初始湿度 + break; + case "custom-text-jsgl": + useSettingStore.setValue(parseInt(node.label), "jsgl"); // 加湿功率 + break; + case "custom-text-jsmj": + useSettingStore.setValue(parseInt(node.label), "jsmj"); // 加湿面积 + break; + } + // useSettingStore.setValue(value, selectedNodeData.value.name); graph.getNodes().forEach((node: any) => { // console.log(node.label); @@ -1140,42 +1184,6 @@ const onRedo = () => { }; const sdsz = ref<any>(null); const onSave = () => { - // console.log(graph.toJSON()); - graph.toJSON().cells.forEach((item: any) => { - console.log(item); - - switch (item.shape) { - case "custom-text": - useSettingStore.setValue(parseInt(item.attrs.text.text),item.name, ); - break; - case "custom-text-zl": - useSettingStore.setValue(parseInt(item.attrs.text.text),item.name, ); - break; - case "custom-text-srmj": - useSettingStore.setValue(parseInt(item.attrs.text.text),item.name, ); - break; - case "custom-text-jrgl": - useSettingStore.setValue(parseInt(item.attrs.text.text),item.name, ); - break; - case "custom-text-prot": - useSettingStore.setValue(parseInt(item.attrs.text.text),item.name, ); - break; - case "custom-text-cssd": - useSettingStore.setValue(parseInt(item.attrs.text.text),item.name, ); - break; - } - }); - // return; - clearLocalStorage(); - const data = graph.toJSON().cells.map((item: any) => { - return { - node: item, - type: "add", - }; - }); - console.log(data); - - localStorage.setItem(SESSION_KEY, JSON.stringify(data)); if ( !hasExactNames(graph.getNodes(), [ "custom-text", @@ -1196,6 +1204,156 @@ const onSave = () => { message: "请填写完整信息", }); } + if (!useSettingStore.experimentPreservation) { + useSettingStore.setValue(true, "experimentPreservation"); + router.push("/designRoute"); + return; + } + graph.toJSON().cells.forEach((item: any) => { + switch (item.shape) { + case "custom-text": + // console.log(parseInt(item.attrs.text.text)); + if (!parseInt(item.attrs.text.text)) { + ElMessage({ + type: "warning", + message: "请请填写初始温度信息", + }); + return; + } + useSettingStore.setValue(parseInt(item.attrs.text.text), item.name); + break; + case "custom-text-zl": + // console.log(parseInt(item.attrs.text.text)); + if (!parseInt(item.attrs.text.text)) { + ElMessage({ + type: "warning", + message: "请请填写质量信息", + }); + return; + } + useSettingStore.setValue(parseInt(item.attrs.text.text), item.name); + break; + case "custom-text-srmj": + // console.log(parseInt(item.attrs.text.text)); + if (!parseInt(item.attrs.text.text)) { + ElMessage({ + type: "warning", + message: "请请填写散热面积信息", + }); + return; + } + useSettingStore.setValue(parseInt(item.attrs.text.text), item.name); + break; + case "custom-text-jrgl": + if (!parseInt(item.attrs.text.text)) { + ElMessage({ + type: "warning", + message: "请请填写加热功率信息", + }); + return; + } + useSettingStore.setValue(parseInt(item.attrs.text.text), item.name); + break; + // case "custom-text-prot": + // useSettingStore.setValue(parseInt(item.attrs.text.text), item.name); + // break; + case "custom-text-cssd": + // console.log(parseInt(item.attrs.text.text)); + if (!parseInt(item.attrs.text.text)) { + ElMessage({ + type: "warning", + message: "请请填写初始湿度信息", + }); + return; + } + useSettingStore.setValue(parseInt(item.attrs.text.text), item.name); + break; + case "custom-text-jsgl": + // console.log(parseInt(item.attrs.text.text)); + if (!parseInt(item.attrs.text.text)) { + ElMessage({ + type: "warning", + message: "请请填写加湿功率信息", + }); + return; + } + useSettingStore.setValue(parseInt(item.attrs.text.text), item.name); + break; + case "custom-text-jsmj": + // console.log(parseInt(item.attrs.text.text)); + if (!parseInt(item.attrs.text.text)) { + ElMessage({ + type: "warning", + message: "请请填写加湿面积信息", + }); + return; + } + useSettingStore.setValue(parseInt(item.attrs.text.text), item.name); + break; + case "custom-text-IP": + // console.log(parseInt(item.attrs.text.text)); + if (!parseInt(item.attrs.text.text)) { + ElMessage({ + type: "warning", + message: "请请填写ip设置信息", + }); + return; + } + useSettingStore.setValue(parseInt(item.attrs.text.text), item.name); + break; + case "custom-text-prot": + // console.log(parseInt(item.attrs.text.text)); + if (!parseInt(item.attrs.text.text)) { + ElMessage({ + type: "warning", + message: "请请填写设定温度信息", + }); + return; + } + useSettingStore.setValue(parseInt(item.attrs.text.text), item.name); + break; + } + }); + + if (useSettingStore.experimentPreservation) { + const arr = [ + useSettingStore.qw, + useSettingStore.zl, + useSettingStore.srmj, + useSettingStore.jrgl, + useSettingStore.port, + useSettingStore.cssd, + useSettingStore.jsmj, + useSettingStore.jsgl, + useSettingStore.ip, + ]; + console.log( + arr, + arr.every((item) => item !== 0 && item !== "") + ); + + // 判断全部不能为空 + if (!arr.every((item) => item !== 0 && item !== "")) { + return ElMessage({ + type: "warning", + message: "请完善配置信息", + }); + } + + // console.log(graph.toJSON()); + + // return; + clearLocalStorage(); + const data = graph.toJSON().cells.map((item: any) => { + return { + node: item, + type: "add", + }; + }); + console.log(data); + + localStorage.setItem(SESSION_KEY, JSON.stringify(data)); + } csedNode.value = graph .getNodes() .find((node: any) => node.shape === "custom-text-wdsz"); @@ -1205,7 +1363,10 @@ const onSave = () => { console.log(csedNode.value); sdsz.value.label = useSettingStore.cssd; // useSettingStore.openHeating(); - useSettingStore.calculateTemperature(); + // useSettingStore.calculateTemperature(); + useSettingStore.simulateHeatingAndHumidifying(); + setStepEvent(4, formatDate(new Date())); + // const data = graph.toJSON(); // console.log(data); // const edges = graph.getEdges(); @@ -1213,15 +1374,19 @@ const onSave = () => { }; function hasExactNames(arr: any, names: any) { // 提取数组中所有的 name 值 - const nameList = arr.map((obj:any) => obj.shape); + const nameList = arr.map((obj: any) => obj.shape); console.log( nameList, names, - names.every((name:any) => nameList.filter((n:any) => n === name).length === 1) + names.every( + (name: any) => nameList.filter((n: any) => n === name).length === 1 + ) ); // 检查 names 里的所有元素是否都在 nameList 中,且仅出现一次 - return names.every((name:any) => nameList.filter((n:any) => n === name).length === 1); + return names.every( + (name: any) => nameList.filter((n: any) => n === name).length === 1 + ); } watch( () => useSettingStore.qw, @@ -1234,10 +1399,22 @@ watch( } } ); +watch( + () => useSettingStore.cssd, + (newValue: number) => { + console.log(newValue, "newValue"); + console.log(sdsz.value, "sdsz.value"); + + if (sdsz.value) { + sdsz.value.label = newValue; + } + } +); const SESSION_KEY = "graph_operations"; -function saveToLocalStorage(data:any) { - const operations = JSON.parse(localStorage.getItem(SESSION_KEY) as string) || []; +function saveToLocalStorage(data: any) { + const operations = + JSON.parse(localStorage.getItem(SESSION_KEY) as string) || []; operations.push(data); localStorage.setItem(SESSION_KEY, JSON.stringify(operations)); } @@ -1253,7 +1430,7 @@ function clearLocalStorage() { function restoreGraph() { const operations = loadFromLocalStorage(); - operations.forEach((op:any) => { + operations.forEach((op: any) => { if (op.type === "add") { graph.addNode(op.node); } else if (op.type === "remove") { From 59642372c6bb81a2405020efdfb6cd9edffc6ea8 Mon Sep 17 00:00:00 2001 From: JayChou <xxx@gmail.com> Date: Wed, 19 Mar 2025 15:39:31 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E6=8E=92=E9=99=A4package-lock.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4be8bcd..cfece66 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ lerna-debug.log* pnpm-lock.yaml node_modules dist +package-lock.json dist-ssr *.local From 4d9d68d8acbe79367dec5d8312335c02b365cc9a Mon Sep 17 00:00:00 2001 From: Ly <503441659@qq.com> Date: Wed, 19 Mar 2025 15:45:53 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=AE=9E=E9=AA=8C=E5=AE=89=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/index.ts | 17 +- src/assets/images/bg13.png | Bin 0 -> 2463 bytes src/assets/images/bg14.png | Bin 0 -> 5153 bytes src/views/largeDataScreen/home.vue | 420 +++++++++++++++++++++++++++-- src/views/subjectTest/index.vue | 138 +++++----- 5 files changed, 479 insertions(+), 96 deletions(-) create mode 100644 src/assets/images/bg13.png create mode 100644 src/assets/images/bg14.png diff --git a/src/api/index.ts b/src/api/index.ts index 3879b01..26be9c7 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -11,4 +11,19 @@ export const getCode = (time: any) => { return request({ url: '/sys/randomImage/' + time, }) - } \ No newline at end of file + } + //试题表 + export const subTestapi = () => { + return request({ + url: '/questions/xnQuestions/api/list', + method: 'get', + }) +} +//试题回答检查 +export const checkapi = (params:any)=> { + return request({ + url: '/questionrecords/xnQuestionRecords/check', + method: 'get', + params + }) +} \ No newline at end of file diff --git a/src/assets/images/bg13.png b/src/assets/images/bg13.png new file mode 100644 index 0000000000000000000000000000000000000000..4b1b03adae3a1e94462e833c1f299fc11e04e5e6 GIT binary patch literal 2463 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 literal 0 HcmV?d00001 diff --git a/src/assets/images/bg14.png b/src/assets/images/bg14.png new file mode 100644 index 0000000000000000000000000000000000000000..af40c9c9e90d16195731ab13cb008e86ec735a21 GIT binary patch literal 5153 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 P00000NkvXXu0mjfV59yd literal 0 HcmV?d00001 diff --git a/src/views/largeDataScreen/home.vue b/src/views/largeDataScreen/home.vue index 4e7b75f..c69390b 100644 --- a/src/views/largeDataScreen/home.vue +++ b/src/views/largeDataScreen/home.vue @@ -131,6 +131,71 @@ </div> </div> </el-popover> + <el-popover + placement="right" + :width="260" + trigger="contextmenu" + v-if="product" + ref="popover2" + > + <template #reference> + <div class="item"> + <div class="icon"> + <img + style="width: 100%" + src="@/assets/images/bg14.png" + alt="" + srcset="" + /> + </div> + <div class="file-name">LabVIEW2014</div> + </div> + </template> + <div class="setting-list"> + <div class="item" @click="openSrttingDialog"> + <div class="icon"> + <!-- <img src="@/assets/images/home.png" alt="" /> --> + </div> + <div class="name" style="font-weight: 700">打开</div> + </div> + <div class="item"> + <div class="icon"> + <img src="@/assets/images/home.png" alt="" /> + </div> + <div class="name">管理员身份运行</div> + </div> + <div class="item"> + <div class="icon"> + <img src="@/assets/images/home.png" alt="" /> + </div> + <div class="name">解压到当前文件夹</div> + </div> + <div class="item"> + <div class="icon"> + <img src="@/assets/images/home.png" alt="" /> + </div> + <div class="name">解压到...</div> + </div> + <div class="item"> + <div class="icon"> + <img src="@/assets/images/home.png" alt="" /> + </div> + <div class="name">解压到"LabVIEW2024 (64位)\"</div> + </div> + <div class="item"> + <div class="icon"> + <img src="@/assets/images/home.png" alt="" /> + </div> + <div class="name">其他压缩命令</div> + </div> + <div class="item"> + <div class="icon"> + <img src="@/assets/images/home.png" alt="" /> + </div> + <div class="name">Edit width Notepad++</div> + </div> + </div> + </el-popover> </div> <div class="openFilesGroupDialg"> <div class="step1" v-show="step === 1"> @@ -248,19 +313,115 @@ <div class="title">用户信息</div> <div class="tip">请输入以下信息</div> <div class="name"> - <span>全名:</span><el-input style="width: 280px;margin-left: 30px;"></el-input> + <span>全名:</span><el-input style="width: 280px;margin-left: 30px;"placeholder="软件安全管家"></el-input> </div> <div class="unit"> - <span>单位:</span><el-input style="width: 280px;margin-left: 30px;"></el-input> + <span>单位:</span><el-input style="width: 280px;margin-left: 30px;"placeholder="中国大陆"></el-input> + </div> + </div> + <div class="step3" v-show="installationStep === 3"> + <div class="title">序列号</div> + <div class="tip">请输入以下产品序列号</div> + <div class="serial"> + <div class="name" >序列号:</div> + <el-form label-width="400px" style="max-width: 720" > + <el-form-item label="LabVIEW 2014(基本版 / 完整版 / 专业版):"label-width="307px"> + <el-input style="width: 300px;margin-left: 95px;" /> + </el-form-item> + <el-form-item label="应用程序生成器 - 用于 LabVIEW 2014,如激活 LabVIEW 专业版则保留空白:"> + <el-input style="width: 300px"/> + </el-form-item> + <el-form-item label="Report Generation 工具包 - 用于 LabVIEW 2014,如激活 LabVIEW 专业版则保留空白:"> + <el-input style="width: 300px"/> + </el-form-item> + <el-form-item label="atabase 工具包 - 用于 LabVIEW 2014,如激活 LabVIEW 专业版则保留空白):"> + <el-input style="width: 300px"/> + </el-form-item> + </el-form> </div> </div> + <div class="step4" v-show="installationStep === 4"> + <div class="title">目标目录</div> + <div class="tip">选择主安装目录</div> + <div class="item">选择 NI 软件的安装文件夹</div> + <el-select disabled placeholder="C:\Users\LabVIEW Chinese\2014" style="width: 300px;margin-top: 10px;"/> + <el-button disabled style="margin-left: 5px;margin-top: 10px;">浏览</el-button> + <div class="item">选择NI LabVIEW 2014的安装文件夹</div> + <el-select disabled placeholder="C:\Users\LabVIEW Chinese\2014" style="width: 300px;margin-top: 10px;"/> + <el-button disabled style="margin-left: 5px;margin-top: 10px;">浏览</el-button> + </div> + <div class="step5" v-show="installationStep === 5"> + <div class="title">组件</div> + <div class="tip">选择需要安装的组件</div> + <div class="headers"> + <div class="header"> + <div class="item">NI LabVIEW 2014</div> + <div class="item">Database Connectivity工具包</div> + <div class="item">Report Generation工具包</div> + <div class="item">V Package Manager 2014</div> + <div class="item">附加组件</div> + <div class="item">HI Measurement & Automation Explorer</div> + <div class="item">设备驱动程序</div> + </div> + <div class="image-container"> + <p style="margin-bottom: 20px;">测量和仪器的图形化编程</p> + <img src="@/assets/images/bg13.png" alt=""> + <p style="margin-top: 20px;">该组件将安装至本地硬盘</p> + </div> + </div> + <div class="name">选择NI LabVIEW 2014的安装文件夹</div> + <el-select disabled placeholder="C:\Users\LabVIEW Chinese\2014" style="width: 300px;margin-top: 10px;"/> + <el-button disabled style="margin-left: 5px;margin-top: 10px;">浏览</el-button> + </div> + <div class="step6" v-show="installationStep === 6"> + <div class="title">产品通知</div> + <div class="tip">请查看所选配置的相关信息。</div> + <div class="item"> + 警告:可能已启用Windows防火墙默认状态下,Windows操作系统启用防火墙。首次打开LabVIEW时,可能会弹出一个对话框,要求您选择是否从网络接收信息。建议选择“解除阻止”,以使用LabVIEW的所有网络功能。详细信息请访问ni.com/info,并输入信息代码expm69查询。 + <br>产品注意事项 + <br>安装该产品之前,必须安装Microsoft Office XP或更高版本。“Report Generation工具包-用于Microsoft Office”提供的一组VI可用于创建和编辑Microsoft Word和Microsoft Excel格式的报表。通过报表生成工具,用户可使用Word、Excel或自定义模板创建风格一致的专业报表;减少报表显示、打印或保存前编程的工作量。还可以在*.rd文档和Excel工作表中执行Visual Basic宏,实现自定义的功能。更多关于Report Generation工具包的信息,请访问ni.com/info并输入信息代码report。 + <br>正在安装自等社过猪保要票影的前我地,是器得品和更新。如执行搜索,则gational Instruments将在遵循保密协议的前提下,使用您的搜索查询来改进搜索结果和相关性。 + </div> + </div> + <div class="step7" v-show="installationStep === 7"> + <p class="name">总进度</p> + <el-progress :text-inside="true" :stroke-width="20" :percentage="80" style="margin-bottom: 25px"/> + <p class="name">复制新文件</p> + <el-progress :percentage="100" status="success" :stroke-width="20" /> + </div> + <div class="step7" v-show="installationStep === 8"> + <p class="name">总进度</p> + <el-progress :text-inside="true" :stroke-width="20" :percentage="80" style="margin-bottom: 25px"/> + <p class="name">复制新文件</p> + <el-progress :percentage="100" status="success" :stroke-width="20" /> + </div> + + </div> <template #footer> <div class="dialog-footer"> <el-button + v-show="installationStep === 5" + @click="Installation = false" + style="background-color: #f3f3f3; color: #000000; border-color: #ccc" + >恢复默认设置</el-button + > + <el-button + v-show="installationStep === 5" + @click="Installation = false" + style="background-color: #f3f3f3; color: #000000; border-color: #ccc" + >磁盘占用</el-button + > + <el-button + v-show="installationStep === 6" @click="Installation = false" - style="background-color: #f3f3f3; color: #fff; border-color: #ccc" + style="background-color: #f3f3f3; color: #000000; border-color: #ccc" + >保存文件</el-button + > + <el-button + @click="Installation = false" + style="background-color: #f3f3f3; color: #000000; border-color: #ccc" >上一步</el-button > <el-button @@ -273,13 +434,80 @@ <el-button type="primary" @click="Installation = false" - style="background-color: #f3f3f3; color: #fff; border-color: #ccc" + style="background-color: #f3f3f3; color: #000000; border-color: #ccc" > 取消 </el-button> </div> </template> </el-dialog> + <el-dialog + v-model="Popup" + width="650px" + height="500px" + top="10%" + style="left: 5%;padding: 0;" + > + <template #header> + <div class="dialog-header" >安装LabVIEW硬件支持</div> + </template> + <div class="installation-box"> + <div v-show="installationStep === 8"> + <div style="margin-top: 8px; margin-bottom: 80px;font-size: 16px;line-height: 1.6;letter-spacing: 0.5px;font-weight: bold">如需使LabVIEW支持硬件设备,必须安装相应的设备驱动程序即便以前版本的LabVIEW已经安装相应设备驱动程序,仍需。需为当前版本的LabVIEW重新安装。</div> + <div class="item">如所需文件处于其他位置,请在下面输入相应路径。</div> + <el-select disabled placeholder="C:\Users\LabVIEW Chinese\2014" style="width: 300px;margin-top: 10px;margin-left: 15px;"/> + <el-button disabled style="margin-left: 5px;margin-top: 10px;">浏览</el-button> + </div> + <div class="step9" v-show="installationStep === 9"style="height: 250px;font-weight: bold;font-size: 16px;"> + 安装完成! + </div> + </div> + <template #footer> + <div class="dialog-footer"> + <el-button + v-show="installationStep === 8" + size="large" + @click="Installation = false" + style="background-color: #f3f3f3; color: #000000; border-color: #ccc" + >安装支持</el-button + > + <el-button + v-show="installationStep === 8" + type="primary" + size="large" + @click="setInstallationStep" + style="background-color: #0052d9; color: #fff; border: 0" + > + 不需要支持 + </el-button> + <el-button + v-show="installationStep === 9" + size="large" + @click="Installation = false" + style="background-color: #f3f3f3; color: #000000; border-color: #ccc" + >上一步</el-button + > + <el-button + v-show="installationStep === 9" + type="primary" + size="large" + @click="Installation = false" + style="background-color: #f3f3f3; color: #000000; border-color: #ccc" + + > + 下一步 + </el-button> + <el-button + v-show="installationStep === 9" + size="large" + @click="Completed" + style="background-color: #0052d9; color: #fff; border: 0" + >完成</el-button + > + </div> + </template> + + </el-dialog> </template> <script setup lang="ts"> @@ -287,11 +515,13 @@ import { ref } from "vue"; type Falg = boolean; type Step = number; const falg = ref<Falg>(false); +const product = ref<Falg>(false); const step = ref<Step>(0); const popover1 = ref<any>(null); const popover2 = ref<any>(null); const dialogVisible = ref<Falg>(false); const Installation = ref<Falg>(false); +const Popup = ref<Falg>(false); const installationStep = ref<Step>(1); const checkList = ref<Step[]>([1, 2]); const unpack = (): void => { @@ -316,7 +546,18 @@ const openSrttingDialog = (): void => { }; const setInstallationStep = (): void => { installationStep.value++; + if(installationStep.value == 8){ + Popup.value = true + } + if(installationStep.value == 9){ + Installation.value = false + Popup.value = true + } }; +const Completed = ():void => { + Popup.value = false + product.value = true; +} </script> <style scoped lang="scss"> @@ -332,8 +573,8 @@ const setInstallationStep = (): void => { height: 753px; // background-color: pink; .app-list { - width: 100%; - height: 100%; + width: 500px; + height: 500px; display: flex; flex-direction: column; flex-wrap: wrap; @@ -345,7 +586,7 @@ const setInstallationStep = (): void => { display: flex; flex-direction: column; align-items: center; - justify-content: center; + // justify-content: center; cursor: pointer; &:hover { border: 1px solid #41d3ff; @@ -537,28 +778,155 @@ const setInstallationStep = (): void => { } } .step2 { - min-height: 230px; - .title { - font-size: 24px; - color: #585858; - font-weight: 700; - margin-top: 10px; - } - .tip { - font-size: 16px; - line-height: 30px; - color: #585858; - - margin-top: 10px; - } - .name, - .unit { - padding-left: 37px; - margin-top: 25px; + min-height: 230px; + .title { + font-size: 24px; + color: #585858; + font-weight: 700; + margin-top: 10px; + } + .tip { + font-size: 16px; + line-height: 30px; + color: #585858; - } + margin-top: 10px; + } + .name, + .unit { + padding-left: 37px; + margin-top: 25px; + } } + .step3{ + // width: 540px; + // height: 500px; + // border-radius: 5px; + // background-color: #fff; + .title { + font-size: 25px; + font-weight: bold; /* 设置文字加粗 */ + } + .tip{ + margin-top: 20px; + font-size: 15px; + font-weight: bold; /* 设置文字加粗 */ + } + .serial{ + margin-top: 40px; + .name{ + font-size: 15px; + font-weight: bold; /* 设置文字加粗 */ + margin-left: 400px; + margin-bottom: 15px; + } + :deep(.el-form-item__label ){ + text-align: left; /* 设置label左对齐 */ + line-height: 20px; + } + } + } + .step4{ + .title { + font-size: 25px; + font-weight: bold; /* 设置文字加粗 */ + } + .tip { + margin-top: 20px; + font-size: 15px; + font-weight: bold; /* 设置文字加粗 */ + } + .item{ + margin-top: 50px; + } + .item:before { + content: "• "; /* 在内容前添加一个小点和空格 */ + color: rgb(0, 0, 0); /* 设置小点的颜色 */ + font-size: 15px; /* 设置小点的大小 */ + margin-right: 5px; /* 设置小点和文本之间的间距 */ + } + } + .step5{ + .title { + font-size: 25px; + font-weight: bold; /* 设置文字加粗 */ + } + .tip { + margin-top: 20px; + font-size: 15px; + font-weight: bold; /* 设置文字加粗 */ + } + .headers{ + display: flex; /* 使用Flexbox布局 */ + justify-content: space-between; /* 让子元素在容器中左右对齐 */ + } + .header{ + display: flex; /* 使用Flexbox布局 */ + flex-direction: column; /* 设置子元素竖向排列 */ + align-items: flex-start; /* 对齐方式,让子元素的起始位置对齐 */ + width: auto; + } + .item{ + margin-top: 20px; + margin-left: 30px; + font-size: 13px; + + } + .item:before { + content: '▸ '; /* 在内容前添加一个小点和空格 */ + color: rgb(0, 0, 0); /* 设置小点的颜色 */ + font-size: 13px; /* 设置小点的大小 */ + margin-right: 5px; /* 设置小点和文本之间的间距 */ + } + .image-container { + background-color: #ebebeb; + width: 300px; /* 或者根据需要调整宽度 */ + margin-left: auto; /* 推动到右侧 */ + padding: 10px; + display: flex; /* 启用Flexbox布局 */ + flex-direction: column; /* 设置子元素竖向排列 */ + justify-content: center; /* 垂直居中 */ + align-items: center; /* 水平居中 */ + } + .name{ + margin-top: 40px; + } + .name:before { + content: "• "; /* 在内容前添加一个小点和空格 */ + color: rgb(0, 0, 0); /* 设置小点的颜色 */ + font-size: 15px; /* 设置小点的大小 */ + margin-right: 5px; /* 设置小点和文本之间的间距 */ + } + } + .step6{ + .title { + font-size: 15px; + font-weight: bold; /* 设置文字加粗 */ + color: #f2994a; + margin-bottom: 10px; + } + .item{ + margin-top: 40px; + line-height: 1.6; /* 设置行高 */ + letter-spacing: 0.5px; /* 设置字母间距 */ + } + } + .step7{ + padding: 50px; + // width: 600px; + .name{ + margin-bottom: 8px; + font-size: 15px; + font-weight: bold; /* 设置文字加粗 */ + } + .item:before { + content: "• "; /* 在内容前添加一个小点和空格 */ + color: rgb(0, 0, 0); /* 设置小点的颜色 */ + font-size: 15px; /* 设置小点的大小 */ + margin-right: 5px; /* 设置小点和文本之间的间距 */ + } + } } .dialog-header { padding: 20px; diff --git a/src/views/subjectTest/index.vue b/src/views/subjectTest/index.vue index dd07fb7..e85d5b1 100644 --- a/src/views/subjectTest/index.vue +++ b/src/views/subjectTest/index.vue @@ -15,19 +15,19 @@ <p class="questions">共<span class="questions-count">10</span>题</p> <!-- 遍历题目 --> <div v-if="currentQuestionIndex < questions.length" class="txt"> - <span>{{ currentQuestion.question }}</span> + <span>{{ currentQuestion }}</span> </div> <!-- 遍历选项 --> <div class="options"> <button - v-for="option in currentQuestion.options" - :key="option.option" - :class="{ option: true, selected: selectedOption[currentQuestionIndex] === option.option }" - @click="selectOption(option.option)" + v-for="option in xnOptionsList" + :key="option.id" + :class="['option', { 'selected': selectedOption[currentQuestionIndex] && selectedOption[currentQuestionIndex].oid == option.id }]" + @click="selectOption(option.id)" class="option" > - <span class="option-letter">{{ option.option }}</span> - {{ option.content }} + <span class="option-letter">{{ option.optionName }}</span> + {{ option.optionText }} </button> </div> @@ -46,6 +46,7 @@ <script lang="ts" setup> import resultsAnnounced from '@/views/resultsAnnounced/index.vue' import settingStore from "@/store/modules/setting"; +import {subTestapi,checkapi} from '@/api/index.ts' import { ref,computed,onMounted, onUnmounted} from "vue" import { ElMessage } from 'element-plus' const setting = settingStore(); @@ -59,13 +60,15 @@ import { ElMessage } from 'element-plus' } } //右箭头 - const SubRight =()=>{ + const SubRight = async()=>{ + const res:any = await checkapi(selectedOption.value[currentQuestionIndex.value]); + // answer.value = res.result; + console.log(selectedOption.value); + console.log(res,'res') // 如果答对了,进入下一题 - if (selectedOption.value[currentQuestionIndex.value] === currentQuestion.value.correctAnswer) { - if(currentSum.value < questions.length){ - setTimeout(() => { - currentQuestionIndex.value++; // 更新到下一题 - }, 200); // 延迟0.2秒进入下一题 + if (res.result == "success") { + if(currentSum.value < questions.value.length){ + currentQuestionIndex.value++; // 更新到下一题 } else{ ElMessage.success('答题已完成,请提交') @@ -79,82 +82,79 @@ import { ElMessage } from 'element-plus' } } } - const questions = [ - { - //题目 - question: "根据基尔霍夫电压定律(KVL),下列说法正确的是:", - //选项 - options: [ - { option: "A", content: "在任一瞬时,沿任一闭合回路各段电压的代数和为零。" }, - { option: "B", content: "在任一瞬时,沿任一闭合回路各段电压的代数和不为零。" }, - { option: "C", content: "在任一瞬时,沿任一闭合回路各段电压的代数和为正。" }, - { option: "D", content: "在任一瞬时,沿任一闭合回路各段电压的代数和为负。" } - ], - correctAnswer: "A" // 正确答案 - }, - { - question: "根据欧姆定律,下列说法正确的是:", - options: [ - { option: "A", content: "电流与电压成反比,与电阻成正比。" }, - { option: "B", content: "电流与电压成正比,与电阻成反比。" }, - { option: "C", content: "电流与电压和电阻无关。" }, - { option: "D", content: "电流与电压成正比,与电阻成正比。" } - ], - correctAnswer: "B" // 正确答案 - }, - { - question: "在电路分析中,欧姆定律是一个基本而重要的原理,它描述了电流、电压和电阻之间的关系。根据欧姆定律,通过导体的电流与导体两端的电压成正比,与导体的电阻成反比。请根据这一定律,选择下列哪个选项最准确地描述了这一关系?此外,考虑到实际应用中,导体的电阻可能会受到温度、材料和几何尺寸等因素的影响,这些因素如何改变电流与电压和电阻之间的关系?", - options: [ - { option: "A", content: "电流与电压成正比,与电阻成正比。" }, - { option: "B", content: "电流与电压成正比,与电阻成反比。" }, - { option: "C", content: "电流与电压成反比,与电阻无关。" }, - { option: "D", content: "电流与电压和电阻均无关,仅受外部磁场影响。" } - ], - correctAnswer: "C" // 正确答案 - } - ]; + const questions = ref<any[]>([]); + const currentList = async ()=>{ + const res:any = await subTestapi(); + questions.value = res.result + console.log(res.result) + // console.log(questions.value[0].xnOptionsList[0].id) + // console.log(questions.value,'questions1.value') + } // 当前题目的索引 const currentQuestionIndex = ref(0); //计算当前题目的序号(从1开始) const currentSum = computed(() => currentQuestionIndex.value + 1); // 当前题目 - const currentQuestion = computed(() => questions[currentQuestionIndex.value]); + const currentQuestion = computed(() => { + // 确保 questions.value 至少有一个元素 + if (questions.value.length > 0) { + return questions.value[currentQuestionIndex.value].questionText; + } + return ''; + }); + const xnOptionsList =computed(() =>{ + if (questions.value.length > 0) { + return questions.value[currentQuestionIndex.value].xnOptionsList + } + console.log(selectedOption.value) + return []; + }) // 当前选中的按钮索引 - const selectedOption = ref<string[]>(Array(questions.length).fill(null)); // 初始化数组,默认值为 null + // 初始化为一个数组,数组长度与 questions.value 的长度一致,每个元素初始值为 null + const selectedOption = ref<{ oid: any; qid: string }[]>(Array(questions.value.length).fill(null)); + //选中逻辑 - const selectOption = (option: string) => { - selectedOption.value[currentQuestionIndex.value] = option; // 更新当前题目的选中选项 - console.log(selectedOption.value); - }; - + const selectOption = (option:any) => { + + if (questions.value.length > 0) { + + const currentQuestion = questions.value[currentQuestionIndex.value]; + selectedOption.value[currentQuestionIndex.value]= { + oid: option, + qid: currentQuestion.id + }; + console.log(selectedOption.value[currentQuestionIndex.value].oid,option); + } + } const score = ref(0); // 初始化分数为0 const isVisible = ref (false) //成绩公布页的显示与否 // 提交成绩按钮 - const submitAnswers = () => { + const submitAnswers = async() => { console.log(selectedOption.value[currentQuestionIndex.value]) //答完全部题才能提交成绩 - if(selectedOption.value[questions.length - 1] == null){ + if(selectedOption.value[questions.value.length - 1] == null){ ElMessage.warning('请先完成答题') }else{ - if (selectedOption.value[currentQuestionIndex.value] !== currentQuestion.value.correctAnswer){ + const res:any = await checkapi(selectedOption.value[currentQuestionIndex.value]); + if (res.result !== "success"){ ElMessage.error('回答错误') }else{ stopTimer(); // 停止计时 - score.value = 0; // 重置分数 + score.value = 100; // 重置分数 isVisible.value = true; - for (let i = 0; i < questions.length; i++) { - // 如果当前题目的选中选项与正确答案一致,则加10分 - if (selectedOption.value[i] === questions[i].correctAnswer) { - score.value += 10; - } - } + // for (let i = 0; i < questions.value.length; i++) { + // // 如果当前题目的选中选项与正确答案一致,则加10分 + // if (res.result == "success") { + // // score.value += 10; + // score.value == 100 + // } + // } } } }; // 退出答题 const resetAnswers = () => { - isVisible.value = false; }; // 计时器相关变量 const timer = ref<number | null>(null); // 用于存储 setInterval 的返回值 @@ -182,7 +182,7 @@ import { ElMessage } from 'element-plus' } }; // 页面加载时开始计时 - onMounted(() => {startTimer();}); + onMounted(() => {startTimer();currentList();}); // 页面卸载时停止计时(防止内存泄漏) onUnmounted(() => {stopTimer();}); @@ -191,7 +191,7 @@ import { ElMessage } from 'element-plus' const handleRecreate = () => { console.log(timer.value,"子组件触发了重做事件"); isVisible.value = false; // 隐藏子组件 - selectedOption.value = Array(questions.length).fill(null); // 重置所有选中结果 + selectedOption.value = Array(questions.value.length).fill(null); // 重置所有选中结果 currentQuestionIndex.value = 0; // 重置到第一题 stopTimer()//计时器清零 elapsedTime.value = 0 @@ -277,8 +277,8 @@ import { ElMessage } from 'element-plus' letter-spacing: 3px; /* 字符间距 */ text-align: right; position: absolute; /* 使用绝对定位 */ - top: 24.5%; /* 距离顶部 50% */ - left: 71%; /* 距离左侧 50% */ + top: 24.5%; /* 距离顶部 */ + left: 71.4%; /* 距离左侧 */ } .questions{ font-size: 23px; /* 字体大小 */ From 931ce7446b4053f4700ea78e654e27668566ba92 Mon Sep 17 00:00:00 2001 From: Ly <503441659@qq.com> Date: Thu, 20 Mar 2025 16:03:42 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=AE=89=E8=A3=85=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/largeDataScreen/home.vue | 111 ++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 19 deletions(-) diff --git a/src/views/largeDataScreen/home.vue b/src/views/largeDataScreen/home.vue index c69390b..d972853 100644 --- a/src/views/largeDataScreen/home.vue +++ b/src/views/largeDataScreen/home.vue @@ -383,24 +383,59 @@ <br>正在安装自等社过猪保要票影的前我地,是器得品和更新。如执行搜索,则gational Instruments将在遵循保密协议的前提下,使用您的搜索查询来改进搜索结果和相关性。 </div> </div> - <div class="step7" v-show="installationStep === 7"> + <div class="step6" v-show="installationStep === 7"> + <div class="title">产品通知</div> + <div class="tip">请查看所选配置的相关信息。</div> + <div class="item"> + 安装须知:本协议具合同效力。在你方下载软件和/或完成软件安装过程之前,请仔细阅读本协议。一旦你方下载和/或点击相应的按钮,从而完成软件安装过程,即表示你方同意本协议条款并愿意受本协议的约束。若你方不愿意成为本协议的当事方,并不接受本协议所有条款和条件的约束,请点击相应的按钮取消安装过程,即不要安装或使用软件,并在收到软件之日起三十(30)日内将软件(及所有随附书面材料及其包装)退还至获取该软件的地点,所有退还事宜都应遵守退还发生时适用的NI退还政策。.com/info,并输入信息代码expm69查询。 + <br>定义 在本协议中,下列术语的含义如下本National Instruments许可适用于软件LabVIEW 204 + </div> + <div class="radio-container"> + <el-radio-group v-model="radio1"> + <el-radio value="接受" size="large">我接受上述2条许可协议。</el-radio> + <el-radio value="不接受" size="large">我不接受某些许可协议。</el-radio> + </el-radio-group> + </div> + </div> + <div class="step8" v-show="installationStep === 8"> <p class="name">总进度</p> <el-progress :text-inside="true" :stroke-width="20" :percentage="80" style="margin-bottom: 25px"/> <p class="name">复制新文件</p> <el-progress :percentage="100" status="success" :stroke-width="20" /> </div> - <div class="step7" v-show="installationStep === 8"> + <div class="step8" v-show="installationStep === 9"> <p class="name">总进度</p> <el-progress :text-inside="true" :stroke-width="20" :percentage="80" style="margin-bottom: 25px"/> <p class="name">复制新文件</p> <el-progress :percentage="100" status="success" :stroke-width="20" /> </div> - - + <div class="step11" v-show="installationStep === 11"> + <div class="item">必须重新启动计算机才能完成当前操作。<br>如需马上安装硬件,请关闭计算机。如需稍后重启计算机,在重启之前请不要运行该软件。</div> + </div> </div> <template #footer> <div class="dialog-footer"> + <el-button + v-show="installationStep === 11" + @click="Installation = false" + style="background-color: #f3f3f3; color: #000000; border-color: #ccc" + >稍后重启(A)</el-button + > + <el-button + v-show="installationStep === 11" + type="primary" + @click="Completed" + style="background-color: #0052d9; color: #fff; border: 0" + > + 关闭计算机(S) + </el-button> + <el-button + v-show="installationStep === 11" + @click="Installation = false" + style="background-color: #f3f3f3; color: #000000; border-color: #ccc" + >重新启动(R)</el-button + > <el-button v-show="installationStep === 5" @click="Installation = false" @@ -414,17 +449,19 @@ >磁盘占用</el-button > <el-button - v-show="installationStep === 6" + v-show="installationStep === 6||installationStep === 7||installationStep === 8||installationStep === 9" @click="Installation = false" style="background-color: #f3f3f3; color: #000000; border-color: #ccc" >保存文件</el-button > <el-button + v-if="installationStep === 11 ==false" @click="Installation = false" style="background-color: #f3f3f3; color: #000000; border-color: #ccc" >上一步</el-button > <el-button + v-if="installationStep === 11 ==false" type="primary" @click="setInstallationStep" style="background-color: #0052d9; color: #fff; border: 0" @@ -432,6 +469,7 @@ 下一步 </el-button> <el-button + v-if="installationStep === 11 ==false" type="primary" @click="Installation = false" style="background-color: #f3f3f3; color: #000000; border-color: #ccc" @@ -452,27 +490,27 @@ <div class="dialog-header" >安装LabVIEW硬件支持</div> </template> <div class="installation-box"> - <div v-show="installationStep === 8"> + <div class="step9" v-show="installationStep === 9"> <div style="margin-top: 8px; margin-bottom: 80px;font-size: 16px;line-height: 1.6;letter-spacing: 0.5px;font-weight: bold">如需使LabVIEW支持硬件设备,必须安装相应的设备驱动程序即便以前版本的LabVIEW已经安装相应设备驱动程序,仍需。需为当前版本的LabVIEW重新安装。</div> <div class="item">如所需文件处于其他位置,请在下面输入相应路径。</div> <el-select disabled placeholder="C:\Users\LabVIEW Chinese\2014" style="width: 300px;margin-top: 10px;margin-left: 15px;"/> <el-button disabled style="margin-left: 5px;margin-top: 10px;">浏览</el-button> </div> - <div class="step9" v-show="installationStep === 9"style="height: 250px;font-weight: bold;font-size: 16px;"> + <div class="step10" v-show="installationStep === 10"style="height: 250px;font-weight: bold;font-size: 16px;"> 安装完成! </div> </div> <template #footer> <div class="dialog-footer"> <el-button - v-show="installationStep === 8" + v-show="installationStep === 9" size="large" @click="Installation = false" style="background-color: #f3f3f3; color: #000000; border-color: #ccc" >安装支持</el-button > <el-button - v-show="installationStep === 8" + v-show="installationStep === 9" type="primary" size="large" @click="setInstallationStep" @@ -481,27 +519,28 @@ 不需要支持 </el-button> <el-button - v-show="installationStep === 9" + v-show="installationStep === 10" size="large" @click="Installation = false" style="background-color: #f3f3f3; color: #000000; border-color: #ccc" >上一步</el-button > <el-button - v-show="installationStep === 9" + v-show="installationStep === 10" type="primary" size="large" - @click="Installation = false" - style="background-color: #f3f3f3; color: #000000; border-color: #ccc" + @click="setInstallationStep" + style="background-color: #0052d9; color: #fff; border: 0" > 下一步 </el-button> <el-button - v-show="installationStep === 9" + v-show="installationStep === 10" size="large" - @click="Completed" - style="background-color: #0052d9; color: #fff; border: 0" + + @click="Installation = false" + style="background-color: #f3f3f3; color: #000000; border-color: #ccc" >完成</el-button > </div> @@ -515,6 +554,7 @@ import { ref } from "vue"; type Falg = boolean; type Step = number; const falg = ref<Falg>(false); +const radio1 = ref('接受') const product = ref<Falg>(false); const step = ref<Step>(0); const popover1 = ref<any>(null); @@ -546,15 +586,20 @@ const openSrttingDialog = (): void => { }; const setInstallationStep = (): void => { installationStep.value++; - if(installationStep.value == 8){ + if(installationStep.value == 9){ Popup.value = true } - if(installationStep.value == 9){ + if(installationStep.value == 10){ Installation.value = false Popup.value = true } + if(installationStep.value == 11){ + Installation.value = true + Popup.value = false + } }; const Completed = ():void => { + Installation.value = false Popup.value = false product.value = true; } @@ -900,6 +945,7 @@ const Completed = ():void => { } } .step6{ + position: relative; .title { font-size: 15px; font-weight: bold; /* 设置文字加粗 */ @@ -908,11 +954,26 @@ const Completed = ():void => { } .item{ margin-top: 40px; + margin-bottom: 40px; line-height: 1.6; /* 设置行高 */ letter-spacing: 0.5px; /* 设置字母间距 */ } + .radio-container{ + position: absolute; + bottom: -65px; + right: -10px; + } + + .radio-container .el-radio-group { + display: flex; + flex-direction: column; /* 设置为列方向 */ + align-items: flex-start; /* 左对齐 */ + } + .radio-container .el-radio { + margin-bottom: -10px; /* 单选按钮之间的间距 */ + } } - .step7{ + .step8{ padding: 50px; // width: 600px; .name{ @@ -920,6 +981,9 @@ const Completed = ():void => { font-size: 15px; font-weight: bold; /* 设置文字加粗 */ } + + } + .step9{ .item:before { content: "• "; /* 在内容前添加一个小点和空格 */ color: rgb(0, 0, 0); /* 设置小点的颜色 */ @@ -927,6 +991,15 @@ const Completed = ():void => { margin-right: 5px; /* 设置小点和文本之间的间距 */ } } + .step11{ + .item{ + margin-bottom: 50px; + font-size: 15px; + font-weight: bold; /* 设置文字加粗 */ + line-height: 1.5; /* 设置行高 */ + letter-spacing: 0.5px; /* 设置字母间距 */ + } + } } .dialog-header { padding: 20px; From 1c6e09b74ebf9cc787f9ba702ecbcecae9a8b4ba Mon Sep 17 00:00:00 2001 From: Ly <503441659@qq.com> Date: Fri, 21 Mar 2025 09:09:11 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E5=AE=9E=E9=AA=8C=E6=8A=A5=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/index.ts | 7 ++ src/router/index.ts | 5 ++ src/views/target/index.vue | 167 +++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 src/views/target/index.vue diff --git a/src/api/index.ts b/src/api/index.ts index 766ccd0..2fc361f 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -50,4 +50,11 @@ export const checkapi = (params:any)=> { method: 'get', params }) +} +//获取实验目标 +export const getExperiment = ()=>{ + return request({ + url:'/experimental/xnExperimental/selectExperimental', + method:'get', + }) } \ No newline at end of file diff --git a/src/router/index.ts b/src/router/index.ts index 75b9269..b316d13 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -32,6 +32,11 @@ const routerList: any = [ name: 'SubjectTest', component: () => import('@/views/subjectTest/index.vue'), }, + { + path: '/target', // 实验目标(简介) + name: 'Target', + component: () => import('@/views/target/index.vue'), + }, { path: '/login', name: 'Login', diff --git a/src/views/target/index.vue b/src/views/target/index.vue new file mode 100644 index 0000000..2ee015d --- /dev/null +++ b/src/views/target/index.vue @@ -0,0 +1,167 @@ +<template> + <div class="container-bgc"> + <div class="top"> + <div class="title">{{ setting.title }}</div> + </div> + <!-- 右边箭头 --> + <button class="submit-right" @click="SubRight"></button> + <!-- 左边按钮 --> + <button class="submit-left" @click="SubLeft"></button> + <div class="question-body"> + <div class="question" >实验目标</div> + <el-scrollbar height="330px"> <div class="txt" v-html="Text"></div> </el-scrollbar> + </div> + <div class="submit-buttons"> + <!-- <button class="submit-btn" @click="reset">退出</button> --> + <!-- <button class="submit-btn" @click="enter">进入仿真实验</button> --> + <router-link class="submit-btn" to="">退出</router-link> + <router-link class="submit-btn" to="/program">进入仿真实验</router-link> + </div> + + </div> +</template> + +<script lang="ts" setup> +import settingStore from "@/store/modules/setting"; +import {getExperiment} from '@/api/index' +import { ref,computed,onMounted, onUnmounted} from "vue" +import { useRouter } from 'vue-router'; + const setting = settingStore(); + //左箭头 + const SubLeft =()=>{ + + } + //右箭头 + const SubRight =()=>{ + + } + + const Text = ref() + const getContent = async()=>{ + const res:any = await getExperiment(); + // console.log(res.result.purposeRequirements,'res') + Text.value = res.result.purposeRequirements + console.log(Text.value); + + } + + onMounted(() => {getContent()}); + +</script> + +<style lang="scss" scoped> +.container-bgc { + position: relative; + width: 100%; + // height: 1000px; + min-height: 100vh; + // background-color: #091d22; + background: url("@/assets/images/bg3.png") no-repeat; + background-size: cover; + + .submit-right{ + background: url("@/assets/images/right.png") no-repeat; + background-size: contain; + width: 60px; /* 按钮宽度 */ + height: 60px; /* 按钮高度 */ + border: none; + cursor: pointer; + position: absolute; + right: 0; /* 紧靠右部 */ + top: 40%; /* 垂直居中*/ + } + .submit-left{ + background: url("@/assets/images/left.png") no-repeat; + background-size: contain; + width: 60px; /* 按钮宽度 */ + height: 60px; /* 按钮高度 */ + border: none; + cursor: pointer; + position: absolute; + left: 0; /* 紧靠左部 */ + top: 40%; /* 垂直居中*/ + } + + .top { + width: 100%; + height: 75px; + text-align: center; + font-size: 42px; + line-height: 75px; + font-style: italic; + background: url("@/assets/images/topbgc.png") no-repeat; + background-size: cover; + + .title { + color: #fff; + } + } + + .question-body { + background: url("@/assets/images/FakeAnimateForPrototype.png") no-repeat center center; /* 添加 background-position */ + background-size: contain; /* 确保背景图片覆盖整个元素 */ + width: 1100px; /* 100% 宽度以确保背景图片完全显示 */ + height: 500px; /* 固定高度 */ + margin-top: 100px; + margin-left: auto; + margin-right: auto; + padding-left: 50px; + padding-right: 50px; + padding-top: 30px; + + .question{ + font-size: 42px; /* 字体大小 */ + text-align: center; /* 水平居中 */ + letter-spacing: 3px; /* 字符间距,单位可以是 px、em 等 */ + margin-bottom: 30px; + color: #fff; + } + .scrollbar-demo-item { + display: flex; + align-items: center; + justify-content: center; + height: 50px; + margin: 10px; + text-align: center; + border-radius: 4px; + background: var(--el-color-primary-light-9); + color: var(--el-color-primary); + } + .txt { + margin-top: 18px; + margin-left: 20px; + margin-right: 20px; + font-size: 18px; /* 字体大小 */ + font-family: Consolas, sans-serif; /* 字体样式 */ + letter-spacing: 1.5px; /* 字符间距,单位可以是 px、em 等 */ + line-height: 1.5; /* 行间距,1.5 表示字体大小的 1.5 倍 */ + color: #9b9a9a; + } + } + .submit-buttons { + display: flex; /* 使用 Flexbox 布局 */ + flex-direction: row; /* 水平排列按钮 */ + justify-content: center; /* 水平居中 */ + gap: 450px; /* 按钮之间的间距 */ + margin-top: 50px; + } + + .submit-btn { + background: url("@/assets/images/Button.png") center; + background-size: contain; /* 确保背景图片覆盖整个元素 */ + background-color: transparent; /* 背景颜色设置为透明 */ + border: none; /* 移除边框 */ + cursor: pointer; /* 鼠标悬停时显示手型 */ + width: 300px; + height: 41px; + font-size: 17px; + font-weight: bold; /* 文字加粗 */ + color: #fff; + display: flex; + align-items: center; /* 垂直居中 */ + justify-content: center; /* 水平居中 */ + text-decoration: none + } + +} +</style>