登录页添加文字提示,物料PU占比修改校验规则,拓扑图添加物料修改文字颜色

This commit is contained in:
limengnan 2026-06-22 08:48:15 +08:00
parent f11e40b3e8
commit e900e43825
5 changed files with 246 additions and 114 deletions

View File

@ -13,7 +13,7 @@ import {
Stencil, Stencil,
Transform Transform
} from '@antv/x6' } from '@antv/x6'
import { searchMaterialsPage } from "@/api/business/database/material";
// @ts-ignore // @ts-ignore
import insertCss from 'insert-css' import insertCss from 'insert-css'
import { updateProjects} from "@/api/business/project"; import { updateProjects} from "@/api/business/project";
@ -43,6 +43,19 @@ const props = defineProps({
default: {} default: {}
}, },
}) })
const materialList:any = ref([]) //
function gettableData() { //
let params = {
pageNum: 1,
pageSize: 99,
};
searchMaterialsPage(params).then((result:any) => {
materialList.value = result.records;
}).catch((err) => {
});
}
// //
const sizeSchemaInfo:any = ref({}); const sizeSchemaInfo:any = ref({});
@ -62,12 +75,13 @@ const projectInfo:any = ref(props.projectInfo) // 项目信息
const isScenario = ref(false) // const isScenario = ref(false) //
const isDisplay = ref(true) // const isDisplay = ref(true) //
const isExpansionandcontraction = ref(false) // const isExpansionandcontraction = ref(false) //
const isExplanation = ref(false) //
// //
let graph: Graph let graph: Graph
onMounted(() => { onMounted(() => {
preWork() preWork()
getSizeSchemaList() getSizeSchemaList()
gettableData()
// #region // #region
graph = new Graph({ graph = new Graph({
container: document.getElementById('graph-container') as HTMLElement, container: document.getElementById('graph-container') as HTMLElement,
@ -1272,8 +1286,16 @@ function closeEditdevice(e:any){ // 关闭编辑设备弹窗
selectedDevice.value = e selectedDevice.value = e
let retrievedNode:any = graph.getCellById(nodeId.value) let retrievedNode:any = graph.getCellById(nodeId.value)
retrievedNode.store.data.deviceInfo = e retrievedNode.store.data.deviceInfo = e
if(retrievedNode.store.data.materialInfo != null && retrievedNode.store.data.materialInfo.name != null){
retrievedNode.attr('text/text',e.name +'('+ retrievedNode.store.data.materialInfo.name + ')')
retrievedNode.attr('label/text', e.name +'('+ retrievedNode.store.data.materialInfo.name + ')')
}else{
retrievedNode.attr('text/text', e.name) retrievedNode.attr('text/text', e.name)
retrievedNode.attr('label/text', e.name) retrievedNode.attr('label/text', e.name)
}
isEditdevice.value = false; isEditdevice.value = false;
let json = graph.toJSON() let json = graph.toJSON()
tabDeviceNum.value = 0 tabDeviceNum.value = 0
@ -1317,7 +1339,23 @@ function closeMaterialModel(e:any){ // 关闭物料信息弹窗
selectedMaterial.value = e selectedMaterial.value = e
let retrievedNode:any = graph.getCellById(nodeId.value) let retrievedNode:any = graph.getCellById(nodeId.value)
// copyNodeInfo.value.store.data.attrs.label = copyDeviceInfo.value.name
retrievedNode.store.data.materialInfo = e retrievedNode.store.data.materialInfo = e
retrievedNode.attr('text/text',retrievedNode.store.data.deviceInfo.name +'('+ e.name + ')')
retrievedNode.attr('label/text', retrievedNode.store.data.deviceInfo.name +'('+ e.name + ')')
retrievedNode.attr('text/fill', e.iconBase64); //
retrievedNode.attr('text/stroke', e.iconBase64); //
// label
// retrievedNode.attr('label/text/fill', '#d25b5b');
// retrievedNode.attr('label/text', retrievedNode.store.data.attrs.label.text);
// retrievedNode.setAttrs({
// 'label/text/fill': '#d25b5b',
// 'label/text/stroke': '#d25b5b',
// 'rect/fill': e.iconBase64 //
// });
saveDesign(false) saveDesign(false)
let json = graph.toJSON() let json = graph.toJSON()
tabDeviceNum.value = 0 tabDeviceNum.value = 0
@ -1945,10 +1983,35 @@ function getName(code:any) {
<img src="@/assets/x6/del.png" alt="图标" title="删除" style="cursor: pointer;" <img src="@/assets/x6/del.png" alt="图标" title="删除" style="cursor: pointer;"
@click="deleteNode"> @click="deleteNode">
</div> </div>
<div class="line-style-left-box">
<div class="explanation-box" v-if="isExplanation == false" @click="isExplanation = true">
<img src="@/assets/x6/expansionandcontraction-right.png">
</div>
<div v-if="isExplanation == true" style="display: flex;align-items: center;">
<div class="style-content-explanation-box">
<div class="style-content-box-title">物料信息</div>
<div style="display: flex;text-align: center;margin-bottom: 10px;margin-top: 10px;">
<div style="width: 50%;">物料</div>
<div style="width: 50%;">颜色</div>
</div>
<div v-for="(item, index) in materialList" :key="index" style="display: flex;text-align: center;margin-bottom: 20px;">
<div style="width: 50%;">{{ item.name }}</div>
<div style="width: 50%;display: flex;justify-content: center;">
<div style="width: 70px;height: 20px;" :style="{backgroundColor: item.iconBase64}"></div>
</div>
</div>
</div>
<div class="explanation-box" @click="isExplanation = false">
<img src="@/assets/x6/expansionandcontraction-right.png">
</div>
</div>
</div>
<div class="line-style-box"> <div class="line-style-box">
<!-- <div class="DisplaySettingsButton">显示设置</div> --> <!-- <div class="DisplaySettingsButton">显示设置</div> -->
<div class="expansionandcontraction-box" v-if="isExpansionandcontraction == false" @click="isExpansionandcontraction = true"> <div class="expansionandcontraction-box" v-if="isExpansionandcontraction == false" @click="isExpansionandcontraction = true">
<img src="@/assets/x6/expansionandcontraction-left.png"> <img src="@/assets/x6/expansionandcontraction-left.png">
</div> </div>
<div v-if="isExpansionandcontraction == true" style="display: flex;align-items: center;"> <div v-if="isExpansionandcontraction == true" style="display: flex;align-items: center;">
@ -2317,6 +2380,17 @@ function getName(code:any) {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.line-style-left-box{
position: absolute;
left: 300px;
height: 100%;
/* width: 100px; */
/* background-color: #d9d9d9; */
z-index: 10;
display: flex;
align-items: center;
}
.expansionandcontraction-box{ .expansionandcontraction-box{
width:15px; width:15px;
height: 64px; height: 64px;
@ -2329,6 +2403,25 @@ function getName(code:any) {
justify-content: center; justify-content: center;
cursor: pointer; cursor: pointer;
} }
.explanation-box{
width: 15px;
height: 64px;
background-color: #ffffff;
border: 1px solid #cfcfcf;
border-radius:0 10px 10px 0;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.style-content-explanation-box{
width: 200px;
height: calc(100vh - 60px);
border: 1px solid #cfcfcf;
border-top: none;
border-left: none;
background: #fff;
}
.style-content-box{ .style-content-box{
width: 300px; width: 300px;
height: calc(100vh - 60px); height: calc(100vh - 60px);

View File

@ -66,13 +66,9 @@ function confirmClick(formEl: any) {
organicRatio: info.value.organicRatio, organicRatio: info.value.organicRatio,
moistureContent: info.value.moistureContent, moistureContent: info.value.moistureContent,
customAttrs: JSON.stringify(customAttrsData.value), customAttrs: JSON.stringify(customAttrsData.value),
iconBase64: info.value.iconBase64,
} }
let data = { saveOrUpdate(params).then((res:any) => {
...params,
iconBase64: iconBase64.value,
}
saveOrUpdate(data).then((res:any) => {
if(res == true){ if(res == true){
emit('closeMaterialModel', params) emit('closeMaterialModel', params)
} }
@ -140,12 +136,48 @@ const validator2 = (rule: any, value: any, callback: any) => {
callback(); callback();
return; return;
} }
if (!/^\d+(\.\d+)?$/.test(value)) {
callback(new Error('请输入有效的数字或小数'));
} else if (parseFloat(value) <= 0) {
callback(new Error('必须大于 0'));
}else if (parseFloat(value) > 1) {
callback(new Error('必须小于等于 1'));
} else {
callback();
}
}
const validator3 = (rule: any, value: any, callback: any) => {
if (!value || value === '') {
callback();
return;
}
let ePu238 = 0;
let ePu239 = 0;
let ePu240 = 0;
let ePu241 = 0;
let ePu242 = 0;
if(info.value.ePu238 != null && info.value.ePu238 != ""){
ePu238 = parseFloat(info.value.ePu238);
}
if(info.value.ePu239 != null && info.value.ePu239 != ""){
ePu239 = parseFloat(info.value.ePu239);
}
if(info.value.ePu240 != null && info.value.ePu240 != ""){
ePu240 = parseFloat(info.value.ePu240);
}
if(info.value.ePu241 != null && info.value.ePu241 != ""){
ePu241 = parseFloat(info.value.ePu241);
}
if(info.value.ePu242 != null && info.value.ePu242 != ""){
ePu242 = parseFloat(info.value.ePu242);
}
if (!/^\d+(\.\d+)?$/.test(value)) { if (!/^\d+(\.\d+)?$/.test(value)) {
callback(new Error('请输入有效的数字或小数')); callback(new Error('请输入有效的数字或小数'));
} else if (parseFloat(value) <= 0) { } else if (parseFloat(value) <= 0) {
callback(new Error('请输入小数')); callback(new Error('请输入小数'));
}else if (parseFloat(value) >= 1) { }else if (ePu238 + ePu239 + ePu240 + ePu241 + ePu242 > 1.005 || ePu238 + ePu239 + ePu240 + ePu241 + ePu242 <0.995) {
callback(new Error('请输入小数')); callback(new Error(' PU占比相加必须等于1'));
} else { } else {
callback(); callback();
} }
@ -183,31 +215,31 @@ const rules = ref({
], ],
ePu238: [ ePu238: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],
ePu239: [ ePu239: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],
ePu240: [ ePu240: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],
ePu241: [ ePu241: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],
ePu242: [ ePu242: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],
@ -312,7 +344,7 @@ function gettableData() { // 获取物料列表
}).catch((err) => { }).catch((err) => {
}); });
} }
const iconBase64:any = ref("") // const iconBase64:any = ref("") //
function handleClick(item:any, index:any){ function handleClick(item:any, index:any){
iconBase64.value = item.iconBase64 iconBase64.value = item.iconBase64
ingredientData.value = [] ingredientData.value = []
@ -509,30 +541,9 @@ function delIconBase(){
<el-input v-model="info.moistureContent" style="width: 100%" placeholder="" @input="handleNumberInput('moistureContent')"></el-input> <el-input v-model="info.moistureContent" style="width: 100%" placeholder="" @input="handleNumberInput('moistureContent')"></el-input>
</el-form-item> </el-form-item>
</div> </div>
<el-form-item label="物料图片"> <el-form-item label="物料颜色">
<el-upload <el-color-picker-panel v-model="info.iconBase64" />
style="margin-left: 10px;" <div style="width: 240px;height: 100px;margin-left: 20px;" :style="{backgroundColor: info.iconBase64}"></div>
class="avatar-uploader"
accept=".png, .jpg, .jpeg"
action=""
:headers="{ token: getToken() }"
:show-file-list="false"
:auto-upload="false"
@change="uploadIconBaseChange"
>
<div style="width: 100px;height: 100px;position: relative;" v-if="info.iconBase64 != ''
&& info.iconBase64 != null && info.iconBase64 != ' '">
<img :src="info.iconBase64" class="avatar" />
<div style="position: absolute;top: 0px;left: 0px;z-index: 1;width: 100px;height: 100px;background: rgba(0,0,0,0.3);color: cornflowerblue;">
<el-icon style="position: absolute;top: 40px;left: 40px;z-index: 1;font-size: 20px;"
@click.stop="delIconBase"><Delete /></el-icon>
</div>
</div>
<div v-else>
<el-icon class="newavatar-uploader-icon"><Plus /></el-icon>
<div class="newavatar-uploader-text">物料图片</div>
</div>
</el-upload>
</el-form-item> </el-form-item>
<div class="custom_attrs_box"> <div class="custom_attrs_box">
@ -604,24 +615,9 @@ function delIconBase(){
</div> </div>
</div> </div>
<div class="custom_attrs_header" style="height: 90px;" v-if="ingredientData.length>0"> <div class="custom_attrs_header" style="height: 90px;" v-if="ingredientData.length>0">
<div class="custom_attrs_content1" style="width: 60%;height: 90px;display: flex;align-items: center;justify-content: center;">图片</div> <div class="custom_attrs_content1" style="width: 60%;height: 90px;display: flex;align-items: center;justify-content: center;">颜色</div>
<div class="custom_attrs_content2" style="width: 40%;height: 90px;display: flex;align-items: center;justify-content: center;" > <div class="custom_attrs_content2" style="width: 40%;height: 90px;display: flex;align-items: center;justify-content: center;" >
<el-image <div style="width: 240px;height: 40px;" :style="{backgroundColor: iconBase64}"></div>
v-if="iconBase64 != '' && iconBase64 != null && iconBase64 != ' '"
style="
max-width: 200px;
max-height: 80px;"
class="materialmodel-iconBase64"
:src="iconBase64"
:zoom-rate="1.2"
:max-scale="7"
:min-scale="0.2"
:preview-src-list="[iconBase64]"
show-progress
:initial-index="4"
fit="contain"
/>
</div> </div>
</div> </div>

View File

@ -124,21 +124,56 @@ const validator1 = (rule: any, value: any, callback: any) => { // 校验数字
} }
} }
const validator2 = (rule: any, value: any, callback: any) => { const validator2 = (rule: any, value: any, callback: any) => {
if (value == null || value === '') { if (!value || value === '') {
callback(); callback();
return; return;
} }
if (!/^\d+(\.\d+)?$/.test(value)) { if (!/^\d+(\.\d+)?$/.test(value)) {
callback(new Error('请输入有效的数字或小数')); callback(new Error('请输入有效的数字或小数'));
} else if (parseFloat(value) <= 0) { } else if (parseFloat(value) <= 0) {
callback(new Error('请输入小数')); callback(new Error('必须大于 0'));
}else if (parseFloat(value) >= 1) { }else if (parseFloat(value) > 1) {
callback(new Error('请输入小数')); callback(new Error('必须小于等于 1'));
} else { } else {
callback(); callback();
} }
} }
const validator3 = (rule: any, value: any, callback: any) => {
if (!value || value === '') {
callback();
return;
}
let ePu238 = 0;
let ePu239 = 0;
let ePu240 = 0;
let ePu241 = 0;
let ePu242 = 0;
if(info.value.ePu238 != null && info.value.ePu238 != ""){
ePu238 = parseFloat(info.value.ePu238);
}
if(info.value.ePu239 != null && info.value.ePu239 != ""){
ePu239 = parseFloat(info.value.ePu239);
}
if(info.value.ePu240 != null && info.value.ePu240 != ""){
ePu240 = parseFloat(info.value.ePu240);
}
if(info.value.ePu241 != null && info.value.ePu241 != ""){
ePu241 = parseFloat(info.value.ePu241);
}
if(info.value.ePu242 != null && info.value.ePu242 != ""){
ePu242 = parseFloat(info.value.ePu242);
}
if (!/^\d+(\.\d+)?$/.test(value)) {
callback(new Error('请输入有效的数字或小数'));
} else if (parseFloat(value) <= 0) {
callback(new Error('请输入小数'));
}else if (ePu238 + ePu239 + ePu240 + ePu241 + ePu242 > 1.005 || ePu238 + ePu239 + ePu240 + ePu241 + ePu242 <0.995) {
callback(new Error(' PU占比相加必须等于1'));
} else {
callback();
}
}
const rulesSize = ref({ const rulesSize = ref({
uConcentration: [ uConcentration: [
{ {
@ -160,31 +195,31 @@ const rulesSize = ref({
], ],
ePu238: [ ePu238: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],
ePu239: [ ePu239: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],
ePu240: [ ePu240: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],
ePu241: [ ePu241: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],
ePu242: [ ePu242: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],

View File

@ -94,7 +94,7 @@ const info: any = ref({
h2c2o4Concentration: "", h2c2o4Concentration: "",
organicRatio: "", organicRatio: "",
moistureContent: "", moistureContent: "",
iconBase64: "" iconBase64: "#409EFF"
}); });
const dialogVisible = ref(false); const dialogVisible = ref(false);
@ -117,7 +117,7 @@ function addClick() {
h2c2o4Concentration: "", h2c2o4Concentration: "",
organicRatio: "", organicRatio: "",
moistureContent: "", moistureContent: "",
iconBase64: "" iconBase64: "#409EFF"
}; };
customAttrsData.value = [] customAttrsData.value = []
dialogVisible.value = true; dialogVisible.value = true;
@ -178,12 +178,48 @@ const validator2 = (rule: any, value: any, callback: any) => {
callback(); callback();
return; return;
} }
if (!/^\d+(\.\d+)?$/.test(value)) {
callback(new Error('请输入有效的数字或小数'));
} else if (parseFloat(value) <= 0) {
callback(new Error('必须大于 0'));
}else if (parseFloat(value) > 1) {
callback(new Error('必须小于等于 1'));
} else {
callback();
}
}
const validator3 = (rule: any, value: any, callback: any) => {
if (!value || value === '') {
callback();
return;
}
let ePu238 = 0;
let ePu239 = 0;
let ePu240 = 0;
let ePu241 = 0;
let ePu242 = 0;
if(info.value.ePu238 != null && info.value.ePu238 != ""){
ePu238 = parseFloat(info.value.ePu238);
}
if(info.value.ePu239 != null && info.value.ePu239 != ""){
ePu239 = parseFloat(info.value.ePu239);
}
if(info.value.ePu240 != null && info.value.ePu240 != ""){
ePu240 = parseFloat(info.value.ePu240);
}
if(info.value.ePu241 != null && info.value.ePu241 != ""){
ePu241 = parseFloat(info.value.ePu241);
}
if(info.value.ePu242 != null && info.value.ePu242 != ""){
ePu242 = parseFloat(info.value.ePu242);
}
if (!/^\d+(\.\d+)?$/.test(value)) { if (!/^\d+(\.\d+)?$/.test(value)) {
callback(new Error('请输入有效的数字或小数')); callback(new Error('请输入有效的数字或小数'));
} else if (parseFloat(value) <= 0) { } else if (parseFloat(value) <= 0) {
callback(new Error('请输入小数')); callback(new Error('请输入小数'));
}else if (parseFloat(value) >= 1) { }else if (ePu238 + ePu239 + ePu240 + ePu241 + ePu242 > 1.005 || ePu238 + ePu239 + ePu240 + ePu241 + ePu242 <0.995) {
callback(new Error('请输入小数')); callback(new Error(' PU占比相加必须等于1'));
} else { } else {
callback(); callback();
} }
@ -221,31 +257,31 @@ const rules = ref({
], ],
ePu238: [ ePu238: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],
ePu239: [ ePu239: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],
ePu240: [ ePu240: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],
ePu241: [ ePu241: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],
ePu242: [ ePu242: [
{ {
validator: validator2, validator: validator3,
trigger: 'blur' trigger: 'blur'
} }
], ],
@ -412,21 +448,6 @@ function downloadFile(obj :any, name :any, suffix :any) {
document.body.removeChild(link) document.body.removeChild(link)
} }
function uploadIconBaseChange(file:any){
var reader = new FileReader();
reader.readAsDataURL(file.raw);
reader.onload = () => {
info.value.iconBase64 =reader.result
};
reader.onerror = function(error) {
console.log("Error: ", error);
};
}
function delIconBase(){
info.value.iconBase64 = " "
}
</script> </script>
<template> <template>
@ -579,29 +600,8 @@ function delIconBase(){
<el-input v-model="info.moistureContent" style="width: 100%" placeholder="" @input="handleNumberInput('moistureContent')"></el-input> <el-input v-model="info.moistureContent" style="width: 100%" placeholder="" @input="handleNumberInput('moistureContent')"></el-input>
</el-form-item> </el-form-item>
</div> </div>
<el-form-item label="物料图片"> <el-form-item label="物料颜色">
<el-upload <el-color-picker-panel v-model="info.iconBase64" />
style="margin-left: 10px;"
class="avatar-uploader"
accept=".png, .jpg, .jpeg"
action=""
:show-file-list="false"
:auto-upload="false"
@change="uploadIconBaseChange"
>
<div style="width: 100px;height: 100px;position: relative;" v-if="info.iconBase64 != ''
&& info.iconBase64 != null && info.iconBase64 != ' '">
<img :src="info.iconBase64" class="avatar" />
<div style="position: absolute;top: 0px;left: 0px;z-index: 1;width: 100px;height: 100px;background: rgba(0,0,0,0.3);color: cornflowerblue;">
<el-icon style="position: absolute;top: 40px;left: 40px;z-index: 1;font-size: 20px;"
@click.stop="delIconBase"><Delete /></el-icon>
</div>
</div>
<div v-else>
<el-icon class="newavatar-uploader-icon"><Plus /></el-icon>
<div class="newavatar-uploader-text">物料图片</div>
</div>
</el-upload>
</el-form-item> </el-form-item>

View File

@ -115,6 +115,14 @@
</div> </div>
</div> </div>
</div> </div>
<div style="position: absolute;bottom: 0;left: 0;width: 100%;height: 70px;
font-weight: 400;
font-style: normal;
font-size: 30px;
color: #363636;
text-align: center;">
禁止处理涉密信息
</div>
</div> </div>
</template> </template>