xy 2 weeks ago
commit 7dda839937
  1. 1
      .gitignore
  2. 4
      package.json
  3. 23
      pnpm-lock.yaml
  4. 58
      src/api/index.ts
  5. BIN
      src/assets/images/bg13.png
  6. BIN
      src/assets/images/bg14.png
  7. BIN
      src/assets/images/idea.png
  8. 7
      src/main.ts
  9. 9
      src/permissions.ts
  10. 12
      src/router/index.ts
  11. 43
      src/store/modules/setting.ts
  12. 19
      src/store/modules/user.ts
  13. 12
      src/utils/index.ts
  14. 16
      src/utils/setStep.ts
  15. 77
      src/views/compiler/index.vue
  16. 29
      src/views/designRoute/components/wenBenYu.vue
  17. 10
      src/views/designRoute/components/wenBenYu2.vue
  18. 63
      src/views/designRoute/index.vue
  19. 455
      src/views/largeDataScreen/home.vue
  20. 8
      src/views/program/components/yibiao.vue
  21. 259
      src/views/program/index.vue
  22. 134
      src/views/subjectTest/index.vue
  23. 167
      src/views/target/index.vue

1
.gitignore vendored

@ -9,6 +9,7 @@ lerna-debug.log*
pnpm-lock.yaml pnpm-lock.yaml
node_modules node_modules
dist dist
package-lock.json
dist-ssr dist-ssr
*.local *.local

@ -19,10 +19,12 @@
"@antv/x6-plugin-transform": "^2.1.8", "@antv/x6-plugin-transform": "^2.1.8",
"@antv/x6-vue-shape": "^2.1.2", "@antv/x6-vue-shape": "^2.1.2",
"@element-plus/icons-vue": "^2.3.1", "@element-plus/icons-vue": "^2.3.1",
"@highlightjs/vue-plugin": "^2.1.0",
"@kjgl77/datav-vue3": "^1.7.3", "@kjgl77/datav-vue3": "^1.7.3",
"axios": "^1.7.2", "axios": "^1.7.2",
"echarts": "^5.6.0", "echarts": "^5.6.0",
"element-plus": "^2.9.6", "element-plus": "^2.9.5",
"highlight.js": "^11.11.1",
"insert-css": "^2.0.0", "insert-css": "^2.0.0",
"lib-flexible": "^0.3.2", "lib-flexible": "^0.3.2",
"pinia": "^2.1.7", "pinia": "^2.1.7",

@ -38,6 +38,9 @@ importers:
'@element-plus/icons-vue': '@element-plus/icons-vue':
specifier: ^2.3.1 specifier: ^2.3.1
version: 2.3.1(vue@3.4.29(typescript@5.2.2)) 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': '@kjgl77/datav-vue3':
specifier: ^1.7.3 specifier: ^1.7.3
version: 1.7.3(vue@3.4.29(typescript@5.2.2)) version: 1.7.3(vue@3.4.29(typescript@5.2.2))
@ -50,6 +53,9 @@ importers:
element-plus: element-plus:
specifier: ^2.9.5 specifier: ^2.9.5
version: 2.9.5(vue@3.4.29(typescript@5.2.2)) version: 2.9.5(vue@3.4.29(typescript@5.2.2))
highlight.js:
specifier: ^11.11.1
version: 11.11.1
insert-css: insert-css:
specifier: ^2.0.0 specifier: ^2.0.0
version: 2.0.0 version: 2.0.0
@ -344,6 +350,12 @@ packages:
'@floating-ui/utils@0.2.9': '@floating-ui/utils@0.2.9':
resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} 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': '@jiaminghi/bezier-curve@0.0.9':
resolution: {integrity: sha512-u9xJPOEl6Dri2E9FfmJoGxYQY7vYJkURNX04Vj64tdi535tPrpkuf9Sm0lNr3QTKdHQh0DdNRsaa62FLQNQEEw==} resolution: {integrity: sha512-u9xJPOEl6Dri2E9FfmJoGxYQY7vYJkURNX04Vj64tdi535tPrpkuf9Sm0lNr3QTKdHQh0DdNRsaa62FLQNQEEw==}
@ -772,6 +784,10 @@ packages:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true 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: htmlparser2@8.0.2:
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
@ -1362,6 +1378,11 @@ snapshots:
'@floating-ui/utils@0.2.9': {} '@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': '@jiaminghi/bezier-curve@0.0.9':
dependencies: dependencies:
'@babel/runtime': 7.24.7 '@babel/runtime': 7.24.7
@ -1847,6 +1868,8 @@ snapshots:
he@1.2.0: {} he@1.2.0: {}
highlight.js@11.11.1: {}
htmlparser2@8.0.2: htmlparser2@8.0.2:
dependencies: dependencies:
domelementtype: 2.3.0 domelementtype: 2.3.0

@ -1,14 +1,60 @@
import request from '@/utils/request' import request from "@/utils/request";
export const login = (data: any) => { export const login = (data: any) => {
return request({ return request({
url: '/sys/login', url: "/sys/login",
method: 'post', method: "post",
data data,
});
};
export const getCode = (time: any) => {
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
}) })
} }
export const getCode = (time: any) => { // 获取步骤id
export const getStepId = () => {
return request({
url: "/experimentrecords/xnExperimentRecords/getProcedureList",
method: "get",
})
}
//试题表
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
})
}
//获取实验目标
export const getExperiment = ()=>{
return request({ return request({
url: '/sys/randomImage/' + time, url:'/experimental/xnExperimental/selectExperimental',
method:'get',
}) })
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

@ -7,7 +7,14 @@ import 'element-plus/dist/index.css'; // 引入 Element Plus 的样式文件
import '@/utils/rem.js' import '@/utils/rem.js'
import DataVVue3 from '@kjgl77/datav-vue3' import DataVVue3 from '@kjgl77/datav-vue3'
import pinia from '@/store/index' 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) const app = createApp(App)
// hljs.registerLanguage("java", java);
// app.use(hljsVuePlugin);
app.use(ElementPlus) app.use(ElementPlus)
app.use(pinia) app.use(pinia)
app.use(DataVVue3) app.use(DataVVue3)

@ -14,7 +14,16 @@ router.beforeEach((to: any, from: any, next: any) => {
} else { } else {
const token = getToken(); const token = getToken();
if (token) { if (token) {
console.log(store.userInfo);
if (store.userInfo) {
next(); next();
} else {
store.getUserInfo().then(() => {
next();
});
}
// next();
} else { } else {
next("/login"); next("/login");
} }

@ -19,7 +19,12 @@ const routerList: any = [
path: "program", path: "program",
name: "Program", name: "Program",
component: () => import("@/views/program/index.vue"), component: () => import("@/views/program/index.vue"),
} },
{
path: "compiler",
name: "Compiler",
component: () => import("@/views/compiler/index.vue"),
},
], ],
}, },
{ {
@ -27,6 +32,11 @@ const routerList: any = [
name: 'SubjectTest', name: 'SubjectTest',
component: () => import('@/views/subjectTest/index.vue'), component: () => import('@/views/subjectTest/index.vue'),
}, },
{
path: '/target', // 实验目标(简介)
name: 'Target',
component: () => import('@/views/target/index.vue'),
},
{ {
path: '/login', path: '/login',
name: 'Login', name: 'Login',

@ -16,6 +16,11 @@ const settingStore = defineStore("settingStore", {
sdsz: 0, // 湿度数值 sdsz: 0, // 湿度数值
falg: false, falg: false,
timer: null, timer: null,
experimentPreservation: false, // 是否设计好实验
saveRoute: false, // 是否保存路由
stepIds: null,
wenduCode: null,
shiduCode:null
}; };
}, },
actions: { actions: {
@ -27,7 +32,7 @@ const settingStore = defineStore("settingStore", {
this.qw = value; this.qw = value;
}, },
setValue(value: number, name: string) { setValue(value: number | boolean, name: string) {
this[name] = value; this[name] = value;
}, },
openHeating() { openHeating() {
@ -46,7 +51,7 @@ const settingStore = defineStore("settingStore", {
} }
}, },
calculateTemperature() { 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; const a = (100000 * this.zl * this.srmj) / this.jrgl;
let time = 0; let time = 0;
let currentTemp = this.qw; let currentTemp = this.qw;
@ -61,6 +66,40 @@ const settingStore = defineStore("settingStore", {
clearInterval(interval); 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 time += 1; // 每秒增加 1s
}, 1000); }, 1000);
}, },

@ -1,11 +1,11 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { getToken, setToken } from "@/utils/auth"; import { getToken, setToken } from "@/utils/auth";
import { login } from "@/api"; import { login, getUserInfo } from "@/api";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
const userStore = defineStore("userStore", { const userStore = defineStore("userStore", {
state: () => ({ state: () => ({
token: getToken(), token: getToken(),
userInfo: {}, userInfo: null,
}), }),
actions: { actions: {
async logIn(form: any) { async logIn(form: any) {
@ -13,18 +13,25 @@ const userStore = defineStore("userStore", {
const res: any = await login(form); const res: any = await login(form);
// if(res.code === 500) return ElMessage.error(res.msg) // if(res.code === 500) return ElMessage.error(res.msg)
if (res.code !== 200) { if (res.code !== 200) {
ElMessage.error(res.msg) ElMessage.error(res.msg);
return false return false;
} }
this.token = res.result.token; this.token = res.result.token;
this.userInfo = res.result.userInfo; this.userInfo = res.result.userInfo;
setToken(this.token); setToken(this.token);
console.log(res); console.log(res);
return true return true;
}, },
clearStatus() { clearStatus() {
this.token = ""; 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;
}, },
}, },
}); });

@ -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}`;
}

@ -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 });
}
};

@ -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>

@ -6,12 +6,31 @@
<div class="W">W</div> <div class="W">W</div>
<div class="t">t</div> <div class="t">t</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> </div>
</template> </template>
<script setup> <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> </script>
<style scoped> <style scoped>
@ -27,7 +46,6 @@ import { ref, computed, nextTick, watch, onMounted } from "vue";
left: -25px; left: -25px;
border: 1px solid #ccc; border: 1px solid #ccc;
color: #fff; color: #fff;
} }
.M { .M {
position: absolute; position: absolute;
@ -35,7 +53,6 @@ import { ref, computed, nextTick, watch, onMounted } from "vue";
left: -25px; left: -25px;
border: 1px solid #ccc; border: 1px solid #ccc;
color: #fff; color: #fff;
} }
.S { .S {
position: absolute; position: absolute;
@ -43,7 +60,6 @@ import { ref, computed, nextTick, watch, onMounted } from "vue";
left: -17px; left: -17px;
border: 1px solid #ccc; border: 1px solid #ccc;
color: #fff; color: #fff;
} }
.W { .W {
position: absolute; position: absolute;
@ -51,7 +67,6 @@ import { ref, computed, nextTick, watch, onMounted } from "vue";
left: -17px; left: -17px;
border: 1px solid #ccc; border: 1px solid #ccc;
color: #fff; color: #fff;
} }
.t { .t {
position: absolute; position: absolute;
@ -59,7 +74,6 @@ import { ref, computed, nextTick, watch, onMounted } from "vue";
left: -17px; left: -17px;
border: 1px solid #ccc; border: 1px solid #ccc;
color: #fff; color: #fff;
} }
.T { .T {
position: absolute; position: absolute;
@ -67,6 +81,5 @@ import { ref, computed, nextTick, watch, onMounted } from "vue";
right: -17px; right: -17px;
border: 1px solid #ccc; border: 1px solid #ccc;
color: #fff; color: #fff;
} }
</style> </style>

@ -6,12 +6,18 @@
<!-- <div class="W">W</div> --> <!-- <div class="W">W</div> -->
<div class="t">t1</div> <div class="t">t1</div>
<div class="T">R</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> </div>
</template> </template>
<script setup> <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> </script>
<style scoped> <style scoped>

@ -69,8 +69,13 @@ import shiduValueSetting from "./components/shiduValueSetting.vue";
import setzijie from "./components/setzijie.vue"; import setzijie from "./components/setzijie.vue";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import tipView from "@/assets/images/guanxitu.png"; 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; let graph = null;
const router = useRouter();
const settingStore = useSettingStore();
// //
const portConfig = { const portConfig = {
top: { top: {
@ -170,7 +175,7 @@ onMounted(() => {
return false; return false;
} }
return true; return true;
} },
}, },
highlighting: { highlighting: {
magnetAdsorbed: { magnetAdsorbed: {
@ -326,7 +331,7 @@ onMounted(() => {
// 1 // 1
graph.addNode({ graph.addNode({
shape: "custom-vue-node-wenBenYu", shape: "custom-vue-node-wenBenYu",
id:'32', id: "32",
width: 210, width: 210,
height: 300, height: 300,
x: 320, x: 320,
@ -366,7 +371,7 @@ onMounted(() => {
// 2 // 2
graph.addNode({ graph.addNode({
shape: "custom-vue-node-wenBenYu2", shape: "custom-vue-node-wenBenYu2",
id:'33', id: "33",
width: 210, width: 210,
height: 300, height: 300,
x: 400, x: 400,
@ -799,7 +804,7 @@ onMounted(() => {
edge: edge.toJSON(), // toJSON port edge: edge.toJSON(), // toJSON port
}; };
saveToLocalStorage(data); saveToLocalStorage(data);
}) });
// 线 // 线
graph.on("edge:removed", ({ edge }) => { graph.on("edge:removed", ({ edge }) => {
@ -810,11 +815,11 @@ onMounted(() => {
saveToLocalStorage(data); saveToLocalStorage(data);
}); });
setTimeout(() => { setTimeout(() => {
restoreGraph() restoreGraph();
}, 1000); }, 1000);
graph.on('edge:added', ({ edge }) => { graph.on("edge:added", ({ edge }) => {
console.log('新增连线数据:', edge.toJSON()); console.log("新增连线数据:", edge.toJSON());
}) });
// const nodes = graph.getNodes(); // const nodes = graph.getNodes();
// console.log(nodes); // console.log(nodes);
// const data = graph.toJSON(); // const data = graph.toJSON();
@ -830,16 +835,44 @@ const onUndo = () => {
const onRedo = () => { const onRedo = () => {
graph.redo(); 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 = () => { 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("请完善数据"); return ElMessage.error("请完善数据");
validateRelationships(standardData, formatEdges()); validateRelationships(standardData, formatEdges());
if(settingStore.wenduCode != wenduCode){
return ElMessage.error("温度代码编写错误");
}
if(settingStore.shiduCode != shiduCode){
return ElMessage.error("湿度代码编写错误");
}
ElMessage.success("保存成功"); ElMessage.success("保存成功");
settingStore.setValue( true,'saveRoute');
router.push('/program')
// const data = graph.toJSON(); // const data = graph.toJSON();
// console.log(data); // console.log(data);
// const edges = graph.getEdges(); // const edges = graph.getEdges();
// console.log(formatEdges()); // 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 formatEdges = () => {
const edges = graph.getEdges(); const edges = graph.getEdges();
// console.log(edges); // console.log(edges);
@ -1083,13 +1116,13 @@ function restoreGraph() {
// //
operations operations
.filter(op => op.type === 'add' && op.node) .filter((op) => op.type === "add" && op.node)
.forEach(op => graph.addNode(op.node)); .forEach((op) => graph.addNode(op.node));
// 线 // 线
operations operations
.filter(op => op.type === 'add' && op.edge) .filter((op) => op.type === "add" && op.edge)
.forEach(op => { .forEach((op) => {
const edgeData = op.edge; const edgeData = op.edge;
// port port ID // port port ID
@ -1099,7 +1132,7 @@ function restoreGraph() {
graph.addEdge(edgeData); graph.addEdge(edgeData);
}); });
} }
const SESSION_KEY = 'graph_operations1'; const SESSION_KEY = "graph_operations1";
function saveToLocalStorage(data) { function saveToLocalStorage(data) {
const operations = JSON.parse(localStorage.getItem(SESSION_KEY)) || []; const operations = JSON.parse(localStorage.getItem(SESSION_KEY)) || [];

@ -131,6 +131,71 @@
</div> </div>
</div> </div>
</el-popover> </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>
<div class="openFilesGroupDialg"> <div class="openFilesGroupDialg">
<div class="step1" v-show="step === 1"> <div class="step1" v-show="step === 1">
@ -248,22 +313,155 @@
<div class="title">用户信息</div> <div class="title">用户信息</div>
<div class="tip">请输入以下信息</div> <div class="tip">请输入以下信息</div>
<div class="name"> <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>
<div class="unit"> <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格式的报表通过报表生成工具用户可使用WordExcel或自定义模板创建风格一致的专业报表减少报表显示打印或保存前编程的工作量还可以在*.rd文档和Excel工作表中执行Visual Basic宏实现自定义的功能更多关于Report Generation工具包的信息请访问ni.com/info并输入信息代码report
<br>正在安装自等社过猪保要票影的前我地,是器得品和更新如执行搜索则gational Instruments将在遵循保密协议的前提下使用您的搜索查询来改进搜索结果和相关性
</div>
</div>
<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>
<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="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>
</div> </div>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button <el-button
v-show="installationStep === 11"
@click="Installation = false" @click="Installation = false"
style="background-color: #f3f3f3; color: #fff; border-color: #ccc" 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"
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||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
> >
<el-button <el-button
v-if="installationStep === 11 ==false"
type="primary" type="primary"
@click="setInstallationStep" @click="setInstallationStep"
style="background-color: #0052d9; color: #fff; border: 0" style="background-color: #0052d9; color: #fff; border: 0"
@ -271,15 +469,84 @@
下一步 下一步
</el-button> </el-button>
<el-button <el-button
v-if="installationStep === 11 ==false"
type="primary" type="primary"
@click="Installation = false" @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>
</div> </div>
</template> </template>
</el-dialog> </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 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="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 === 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="setInstallationStep"
style="background-color: #0052d9; color: #fff; border: 0"
>
不需要支持
</el-button>
<el-button
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 === 10"
type="primary"
size="large"
@click="setInstallationStep"
style="background-color: #0052d9; color: #fff; border: 0"
>
下一步
</el-button>
<el-button
v-show="installationStep === 10"
size="large"
@click="Installation = false"
style="background-color: #f3f3f3; color: #000000; border-color: #ccc"
>完成</el-button
>
</div>
</template>
</el-dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -287,11 +554,14 @@ import { ref } from "vue";
type Falg = boolean; type Falg = boolean;
type Step = number; type Step = number;
const falg = ref<Falg>(false); const falg = ref<Falg>(false);
const radio1 = ref('接受')
const product = ref<Falg>(false);
const step = ref<Step>(0); const step = ref<Step>(0);
const popover1 = ref<any>(null); const popover1 = ref<any>(null);
const popover2 = ref<any>(null); const popover2 = ref<any>(null);
const dialogVisible = ref<Falg>(false); const dialogVisible = ref<Falg>(false);
const Installation = ref<Falg>(false); const Installation = ref<Falg>(false);
const Popup = ref<Falg>(false);
const installationStep = ref<Step>(1); const installationStep = ref<Step>(1);
const checkList = ref<Step[]>([1, 2]); const checkList = ref<Step[]>([1, 2]);
const unpack = (): void => { const unpack = (): void => {
@ -316,7 +586,23 @@ const openSrttingDialog = (): void => {
}; };
const setInstallationStep = (): void => { const setInstallationStep = (): void => {
installationStep.value++; installationStep.value++;
if(installationStep.value == 9){
Popup.value = true
}
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;
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@ -332,8 +618,8 @@ const setInstallationStep = (): void => {
height: 753px; height: 753px;
// background-color: pink; // background-color: pink;
.app-list { .app-list {
width: 100%; width: 500px;
height: 100%; height: 500px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex-wrap: wrap; flex-wrap: wrap;
@ -345,7 +631,7 @@ const setInstallationStep = (): void => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; // justify-content: center;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
border: 1px solid #41d3ff; border: 1px solid #41d3ff;
@ -557,7 +843,162 @@ const setInstallationStep = (): void => {
margin-top: 25px; 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{
position: relative;
.title {
font-size: 15px;
font-weight: bold; /* 设置文字加粗 */
color: #f2994a;
margin-bottom: 10px;
}
.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; /* 单选按钮之间的间距 */
}
}
.step8{
padding: 50px;
// width: 600px;
.name{
margin-bottom: 8px;
font-size: 15px;
font-weight: bold; /* 设置文字加粗 */
}
}
.step9{
.item:before {
content: "• "; /* 在内容前添加一个小点和空格 */
color: rgb(0, 0, 0); /* 设置小点的颜色 */
font-size: 15px; /* 设置小点的大小 */
margin-right: 5px; /* 设置小点和文本之间的间距 */
}
}
.step11{
.item{
margin-bottom: 50px;
font-size: 15px;
font-weight: bold; /* 设置文字加粗 */
line-height: 1.5; /* 设置行高 */
letter-spacing: 0.5px; /* 设置字母间距 */
}
} }
} }
.dialog-header { .dialog-header {

@ -9,7 +9,7 @@ import { onMounted, watch } from "vue";
import * as echarts from "echarts"; import * as echarts from "echarts";
import settingStore from "@/store/modules/setting"; import settingStore from "@/store/modules/setting";
const useSettingStore = settingStore(); const useSettingStore = settingStore();
var value = useSettingStore.cssd * 100; var value = useSettingStore.cssd;
var myChart = null; var myChart = null;
const initChart = () => { const initChart = () => {
const option = { const option = {
@ -187,7 +187,7 @@ const initChart = () => {
fontSize: 20, fontSize: 20,
distance: -70, distance: -70,
formatter: function (params) { formatter: function (params) {
var value = params.toFixed(0); var value = params;
if (value == 0.0) { if (value == 0.0) {
return "0"; return "0";
@ -235,7 +235,7 @@ const initChart = () => {
}, },
detail: { detail: {
formatter: function (params) { formatter: function (params) {
return params / 100; return params ;
}, },
fontSize: 30, fontSize: 30,
color: "#fff", color: "#fff",
@ -261,7 +261,7 @@ onMounted(() => {
watch( watch(
() => useSettingStore.cssd, () => useSettingStore.cssd,
(newValue) => { (newValue) => {
value=newValue * 100 value=newValue
setTimeout(() => { setTimeout(() => {
initChart(); initChart();
}, 100); }, 100);

@ -43,7 +43,9 @@
<el-button @click="onUndo">撤回</el-button> <el-button @click="onUndo">撤回</el-button>
<el-button @click="onRedo">恢复</el-button> <el-button @click="onRedo">恢复</el-button>
<el-button @click="clearLocalStorage">清除缓存</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> <el-button @click="onTip">提示</el-button>
</div> </div>
<div class="tip-view"> <div class="tip-view">
@ -80,8 +82,11 @@ import settingStore from "@/store/modules/setting";
import Yibiao from "./components/yibiao.vue"; import Yibiao from "./components/yibiao.vue";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import tipView from "@/assets/images/chengxv.png"; 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 useSettingStore = settingStore();
const router = useRouter();
// console.log(useSettingStore.qw); // console.log(useSettingStore.qw);
// //
@ -189,14 +194,20 @@ onMounted(() => {
// //
graph.on("node:click", ({ cell }: any) => { graph.on("node:click", ({ cell }: any) => {
// console.log(cell.store.previous.name); // console.log(cell.store.previous.name);
// console.log(cell); console.log(cell);
if (!useSettingStore.saveRoute) {
ElMessage({
message: "请先完成配置",
type: "warning",
});
return;
}
if ( if (
cell.shape === "deom" || cell.shape === "deom" ||
cell.shape === "yibiao" || cell.shape === "yibiao" ||
cell.shape === "rect" || cell.shape === "rect" ||
cell.store.previous.name === "wdsz" || cell.shape === "custom-text-wdsz" ||
cell.store.previous.name === "sdsz" cell.shape === "custom-text-sdsz"
) )
return; return;
// if (cell.store.previous.name === "qw") { // if (cell.store.previous.name === "qw") {
@ -1057,7 +1068,40 @@ const saveNodeData = () => {
if (falg.value) { if (falg.value) {
const value = Number(selectedNodeData.value.label); const value = Number(selectedNodeData.value.label);
// useSettingStore.setqw(value); // 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) => { graph.getNodes().forEach((node: any) => {
// console.log(node.label); // console.log(node.label);
@ -1140,31 +1184,164 @@ const onRedo = () => {
}; };
const sdsz = ref<any>(null); const sdsz = ref<any>(null);
const onSave = () => { const onSave = () => {
// console.log(graph.toJSON()); if (
!hasExactNames(graph.getNodes(), [
"custom-text",
"custom-text-zl",
"custom-text-srmj",
"custom-text-jrgl",
"custom-text-wdsz",
"custom-text-IP",
"custom-text-prot",
"custom-text-cssd",
"custom-text-jsgl",
"custom-text-jsmj",
"custom-text-sdsz",
])
) {
return ElMessage({
type: "warning",
message: "请填写完整信息",
});
}
if (!useSettingStore.experimentPreservation) {
useSettingStore.setValue(true, "experimentPreservation");
router.push("/designRoute");
return;
}
graph.toJSON().cells.forEach((item: any) => { graph.toJSON().cells.forEach((item: any) => {
console.log(item);
switch (item.shape) { switch (item.shape) {
case "custom-text": case "custom-text":
useSettingStore.setValue(parseInt(item.attrs.text.text),item.name, ); // 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; break;
case "custom-text-zl": case "custom-text-zl":
useSettingStore.setValue(parseInt(item.attrs.text.text),item.name, ); // 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; break;
case "custom-text-srmj": case "custom-text-srmj":
useSettingStore.setValue(parseInt(item.attrs.text.text),item.name, ); // 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; break;
case "custom-text-jrgl": case "custom-text-jrgl":
useSettingStore.setValue(parseInt(item.attrs.text.text),item.name, ); if (!parseInt(item.attrs.text.text)) {
break; ElMessage({
case "custom-text-prot": type: "warning",
useSettingStore.setValue(parseInt(item.attrs.text.text),item.name, ); message: "请请填写加热功率信息",
});
return;
}
useSettingStore.setValue(parseInt(item.attrs.text.text), item.name);
break; break;
// case "custom-text-prot":
// useSettingStore.setValue(parseInt(item.attrs.text.text), item.name);
// break;
case "custom-text-cssd": case "custom-text-cssd":
useSettingStore.setValue(parseInt(item.attrs.text.text),item.name, ); // 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; 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; // return;
clearLocalStorage(); clearLocalStorage();
const data = graph.toJSON().cells.map((item: any) => { const data = graph.toJSON().cells.map((item: any) => {
@ -1176,25 +1353,6 @@ const onSave = () => {
console.log(data); console.log(data);
localStorage.setItem(SESSION_KEY, JSON.stringify(data)); localStorage.setItem(SESSION_KEY, JSON.stringify(data));
if (
!hasExactNames(graph.getNodes(), [
"custom-text",
"custom-text-zl",
"custom-text-srmj",
"custom-text-jrgl",
"custom-text-wdsz",
"custom-text-IP",
"custom-text-prot",
"custom-text-cssd",
"custom-text-jsgl",
"custom-text-jsmj",
"custom-text-sdsz",
])
) {
return ElMessage({
type: "warning",
message: "请填写完整信息",
});
} }
csedNode.value = graph csedNode.value = graph
.getNodes() .getNodes()
@ -1205,7 +1363,10 @@ const onSave = () => {
console.log(csedNode.value); console.log(csedNode.value);
sdsz.value.label = useSettingStore.cssd; sdsz.value.label = useSettingStore.cssd;
// useSettingStore.openHeating(); // useSettingStore.openHeating();
useSettingStore.calculateTemperature(); // useSettingStore.calculateTemperature();
useSettingStore.simulateHeatingAndHumidifying();
setStepEvent(4, formatDate(new Date()));
// const data = graph.toJSON(); // const data = graph.toJSON();
// console.log(data); // console.log(data);
// const edges = graph.getEdges(); // const edges = graph.getEdges();
@ -1217,11 +1378,15 @@ function hasExactNames(arr: any, names: any) {
console.log( console.log(
nameList, nameList,
names, 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 // 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( watch(
() => useSettingStore.qw, () => 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"; const SESSION_KEY = "graph_operations";
function saveToLocalStorage(data: any) { function saveToLocalStorage(data: any) {
const operations = JSON.parse(localStorage.getItem(SESSION_KEY) as string) || []; const operations =
JSON.parse(localStorage.getItem(SESSION_KEY) as string) || [];
operations.push(data); operations.push(data);
localStorage.setItem(SESSION_KEY, JSON.stringify(operations)); localStorage.setItem(SESSION_KEY, JSON.stringify(operations));
} }

@ -15,19 +15,19 @@
<p class="questions"><span class="questions-count">10</span></p> <p class="questions"><span class="questions-count">10</span></p>
<!-- 遍历题目 --> <!-- 遍历题目 -->
<div v-if="currentQuestionIndex < questions.length" class="txt"> <div v-if="currentQuestionIndex < questions.length" class="txt">
<span>{{ currentQuestion.question }}</span> <span>{{ currentQuestion }}</span>
</div> </div>
<!-- 遍历选项 --> <!-- 遍历选项 -->
<div class="options"> <div class="options">
<button <button
v-for="option in currentQuestion.options" v-for="option in xnOptionsList"
:key="option.option" :key="option.id"
:class="{ option: true, selected: selectedOption[currentQuestionIndex] === option.option }" :class="['option', { 'selected': selectedOption[currentQuestionIndex] && selectedOption[currentQuestionIndex].oid == option.id }]"
@click="selectOption(option.option)" @click="selectOption(option.id)"
class="option" class="option"
> >
<span class="option-letter">{{ option.option }}</span> <span class="option-letter">{{ option.optionName }}</span>
{{ option.content }} {{ option.optionText }}
</button> </button>
</div> </div>
@ -46,6 +46,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import resultsAnnounced from '@/views/resultsAnnounced/index.vue' import resultsAnnounced from '@/views/resultsAnnounced/index.vue'
import settingStore from "@/store/modules/setting"; import settingStore from "@/store/modules/setting";
import {subTestapi,checkapi} from '@/api/index.ts'
import { ref,computed,onMounted, onUnmounted} from "vue" import { ref,computed,onMounted, onUnmounted} from "vue"
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
const setting = settingStore(); 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 (res.result == "success") {
if(currentSum.value < questions.length){ if(currentSum.value < questions.value.length){
setTimeout(() => {
currentQuestionIndex.value++; // currentQuestionIndex.value++; //
}, 200); // 0.2
} }
else{ else{
ElMessage.success('答题已完成,请提交') ElMessage.success('答题已完成,请提交')
@ -79,82 +82,79 @@ import { ElMessage } from 'element-plus'
} }
} }
} }
const questions = [ const questions = ref<any[]>([]);
{ const currentList = async ()=>{
// const res:any = await subTestapi();
question: "根据基尔霍夫电压定律(KVL),下列说法正确的是:", questions.value = res.result
// console.log(res.result)
options: [ // console.log(questions.value[0].xnOptionsList[0].id)
{ option: "A", content: "在任一瞬时,沿任一闭合回路各段电压的代数和为零。" }, // console.log(questions.value,'questions1.value')
{ 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 currentQuestionIndex = ref(0); const currentQuestionIndex = ref(0);
//1 //1
const currentSum = computed(() => currentQuestionIndex.value + 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) => { const selectOption = (option:any) => {
selectedOption.value[currentQuestionIndex.value] = option; //
console.log(selectedOption.value); 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 score = ref(0); // 0
const isVisible = ref (false) // const isVisible = ref (false) //
// //
const submitAnswers = () => { const submitAnswers = async() => {
console.log(selectedOption.value[currentQuestionIndex.value]) console.log(selectedOption.value[currentQuestionIndex.value])
// //
if(selectedOption.value[questions.length - 1] == null){ if(selectedOption.value[questions.value.length - 1] == null){
ElMessage.warning('请先完成答题') ElMessage.warning('请先完成答题')
}else{ }else{
if (selectedOption.value[currentQuestionIndex.value] !== currentQuestion.value.correctAnswer){ const res:any = await checkapi(selectedOption.value[currentQuestionIndex.value]);
if (res.result !== "success"){
ElMessage.error('回答错误') ElMessage.error('回答错误')
}else{ }else{
stopTimer(); // stopTimer(); //
score.value = 0; // score.value = 100; //
isVisible.value = true; isVisible.value = true;
for (let i = 0; i < questions.length; i++) { // for (let i = 0; i < questions.value.length; i++) {
// 10 // // 10
if (selectedOption.value[i] === questions[i].correctAnswer) { // if (res.result == "success") {
score.value += 10; // // score.value += 10;
} // score.value == 100
} // }
// }
} }
} }
}; };
// 退 // 退
const resetAnswers = () => { const resetAnswers = () => {
isVisible.value = false;
}; };
// //
const timer = ref<number | null>(null); // setInterval const timer = ref<number | null>(null); // setInterval
@ -182,7 +182,7 @@ import { ElMessage } from 'element-plus'
} }
}; };
// //
onMounted(() => {startTimer();}); onMounted(() => {startTimer();currentList();});
// //
onUnmounted(() => {stopTimer();}); onUnmounted(() => {stopTimer();});
@ -191,7 +191,7 @@ import { ElMessage } from 'element-plus'
const handleRecreate = () => { const handleRecreate = () => {
console.log(timer.value,"子组件触发了重做事件"); console.log(timer.value,"子组件触发了重做事件");
isVisible.value = false; // isVisible.value = false; //
selectedOption.value = Array(questions.length).fill(null); // selectedOption.value = Array(questions.value.length).fill(null); //
currentQuestionIndex.value = 0; // currentQuestionIndex.value = 0; //
stopTimer()// stopTimer()//
elapsedTime.value = 0 elapsedTime.value = 0
@ -277,8 +277,8 @@ import { ElMessage } from 'element-plus'
letter-spacing: 3px; /* 字符间距 */ letter-spacing: 3px; /* 字符间距 */
text-align: right; text-align: right;
position: absolute; /* 使用绝对定位 */ position: absolute; /* 使用绝对定位 */
top: 24.5%; /* 距离顶部 50% */ top: 24.5%; /* 距离顶部 */
left: 71%; /* 距离左侧 50% */ left: 71.4%; /* 距离左侧 */
} }
.questions{ .questions{
font-size: 23px; /* 字体大小 */ font-size: 23px; /* 字体大小 */

@ -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>
Loading…
Cancel
Save