华西海圻ELN前端工程
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

451 lines
15 KiB

<!-- 质量分装 -->
<template>
<div class="zl-container">
<div class="dialog-content">
<div class="header-container">
<div class="header-item" v-for="item in subConfig" :key="item.key">
<div class="header-title">{{ item.label }}</div>
<HandleFormItem fieldItemLabel = "质量分装" :fieldKey = item.fieldKey
:item="item" :error="formErrors[item.key]"
:type="item.type"
@blur = "(e)=>onCommonBlur(e,item.key)"
v-model="formData[item.key]" />
</div>
<!-- <div class="header-item">
<div class="header-title">分装数量</div>
<HandleFormItem fieldKey = "clfz_fzsl" @blur="onBlurFzsl" :item="integerInputNumberItem"
type = "inputNumber"
:error="formErrors.fzsl" v-model="formData.fzsl" />
</div>
<div class="header-item">
<div class="header-title">单位</div>
<div class="unit-select">
<HandleFormItem fieldKey = "clfz_dw" :item="unitItem" type="select" :error="formErrors.dw"
@blur="(e) => onCommonBlur(e, 'dw')" v-model="formData.dw" />
</div>
</div> -->
</div>
<div class="content-container">
<div class="header-container">
<div v-for="(item, index) in fzList" class="list-item" :key="index">
<div class="list-label">{{ formData.mybh }}-set{{ item.subCode }}</div>
<HandleFormItem fieldItemLabel = "质量分装" :fieldKey = "'clfz_set'+index+'_prenum'" :item="preInputNumberItem"
:error="hasError(index, 'prenum')"
:disabled="true"
type="inputNumber" @blur="onBlurFzNum(index,'prenum')" v-model="item.prenum" />
<HandleFormItem fieldItemLabel = "质量分装" :fieldKey = "'clfz_set'+index+'_actnum'" class="ml-5" :item="inputNumberItem"
:error="hasError(index, 'actnum')"
type="inputNumber" @blur="onBlurFzNum(index,'actnum')" v-model="item.actnum" />
<HandleFormItem
class="ml-5"
type="button"
:item="getButtonItem()"
@clickButton="(e)=>onGetValue(item)" />
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import HandleFormItem from '@/components/Template/HandleFormItem.vue';
import { EventBus } from '@/utils/eventBus';
import { getLatestSn } from '@/api/template';
import { isValueEmpty } from '@/utils/index.js';
export default {
inject: ['templateFillType'],
dicts: [
'business_tjdw',
],
components: {
HandleFormItem,
},
props: {
subData: {
type: Object,
default: () => ({})
},
},
data() {
return {
inputItem: {
type: "input",
fillType: "actFill",
disabled: true,
},
integerInputNumberItem: {
type: "inputNumber",
fillType: "actFill",
precision: 0,
maxlength: 3
},
inputNumberItem: {
type: "inputNumber",
fillType: "actFill",
label:"实际称量"
},
preInputNumberItem: {
type: "inputNumber",
fillType: "preFill",
label:"预计称量"
},
formData: {
mybh: "",//母液编号
fzsl: "",//分装数量
dw: "",//单位
},
fzList: [],//分装列表
// 错误状态字段
formErrors: {
fzsl: false,
dw: false,
},
fzListErrors: [], // 分装列表错误状态
uuid:"",//事件id
}
},
watch: {
subData:{
handler(newVal) {
if(newVal.formData){
this.formData = newVal.formData;
}
if(newVal.fzList){
this.fzList = newVal.fzList;
}
},
deep: true,
immediate: true,
},
// 监听formData的变化
formData: {
handler(newVal) {
this.onDataChange();
},
deep: true
},
// 监听fzList的变化
fzList: {
handler(newVal) {
this.onDataChange();
},
deep: true
}
},
computed: {
subConfig(){
return[
{
fieldKey:"clfz_mybh",
key:"mybh",
label:"母编号",
type:"input",
disabled: true,
fillType: "actFill",
},
{
fieldKey:"clfz_fzsl",
key:"fzsl",
label:"分装数量",
type:"inputNumber",
fillType: "preFill",
},
{
fieldKey:"clfz_dw",
key:"dw",
label:"单位",
type:"select",
options: this.dict.type.business_tjdw,
fillType: "preFill",
},
]
},
},
methods: {
updateFormData(data){
this.formData = {...this.formData,...data};
},
// 获取按钮项
getButtonItem() {
return {
fillType: "actFill",
buttonName:"获取值",
}
},
close() {
this.visible = false;
this.fzList = [];
this.formData = {};
this.resetErrors();
},
validateFormData() {
let isValid = true;
// 定义需要验证的基础字段配制
const baseFieldConfigs = this.subConfig;
// 验证基础字段
baseFieldConfigs.forEach(config => {
if (config.fillType === this.templateFillType) {
if (isValueEmpty(this.formData[config.key]) && !config.disabled) {
this.formErrors[config.key] = true;
isValid = false;
}
}
});
// 验证分装列表中的数值 - 根据字段的fillType和当前templateFillType比较
if (this.fzList && this.fzList.length > 0) {
for (let i = 0; i < this.fzList.length; i++) {
// 验证预填分装数量
if (this.preInputNumberItem.fillType === this.templateFillType) {
if (isValueEmpty(this.fzList[i].prenum)) {
this.fzListErrors.push({
rowIndex: i,
field: "prenum",
error: "请输入预填分装数量",
})
isValid = false;
}
}
// 验证实际分装数量
if (this.inputNumberItem.fillType === this.templateFillType) {
if (isValueEmpty(this.fzList[i].actnum)) {
this.fzListErrors.push({
rowIndex: i,
field: "actnum",
error: "请输入实际分装数量",
})
isValid = false;
}
}
}
}
return {valid: isValid,error:"质量分装数据没填完"};
},
resetErrors() {
// 重置表单错误状态
Object.keys(this.formErrors).forEach(key => {
this.formErrors[key] = false;
});
// 重置分装列表错误状态
this.fzListErrors.forEach((_, index) => {
this.fzListErrors = []
});
},
// 分装数量失去焦点时,根据数量生成分装列表
async onBlurFzsl(e) {
// 清除当前字段的错误状态
if (e) {
this.formErrors.fzsl = false;
}
// 清空现有列表
this.fzList = [];
this.fzListErrors = [];
const result = await getLatestSn({
pre: this.formData.mybh,
count: e,
type: 2,
})
if(result.code === 200){
const codes = result.data;
// 根据输入的数量生成新列表
for (let i = 0; i < e; i++) {
this.fzList.push({
prenum: "",
actnum: "",
subCode: codes[i],
});
}
const params = {
type: "fieldChanged",
newRecord: null,
resourceList: null,
}
EventBus.$emit("onModifyRecord", params);
}
},
onGetValue(item) {
item.actnum = 123;
console.log(item,"获取值")
this.fzList = [...this.fzList]
},
onCommonBlur(e,field) {
if (this.formData[field]) {
this.formErrors[field] = false;
}
if(field === 'fzsl'){
this.onBlurFzsl(e);
}
},
onBlurFzNum(index, field) {
if (this.fzList[index]) {
// 确保fzListErrors数组有足够的元素
if (this.fzListErrors.length <= index) {
this.$set(this.fzListErrors, index, false);
}
if (this.fzList[index][field]) {
// 有值的话就清空对应的错误信息
this.$set(this.fzListErrors, index, false);
} else {
// 没有值的话就边框标红
this.$set(this.fzListErrors, index, true);
}
}
},
verifyFzListError(index, field) {
// 如果index和field都为空,就全匹配
if (index === undefined && field === undefined) {
if (this.fzList && this.fzList.length > 0) {
// 清空现有错误信息
this.fzListErrors = [];
// 遍历fzList,没有值的就放到fzListErrors里面
for (let i = 0; i < this.fzList.length; i++) {
const item = this.fzList[i];
if (isValueEmpty(item.prenum)) {
this.fzListErrors.push({
rowIndex: i,
field: "prenum",
error: "请输入预填分装数量"
});
}
if (isValueEmpty(item.actnum)) {
this.fzListErrors.push({
rowIndex: i,
field: "actnum",
error: "请输入实际分装数量"
});
}
}
}
} else if (index !== undefined) {
// 如果index不为空,检查指定索引的项
if (this.fzList[index]) {
const item = this.fzList[index];
if (field === undefined) {
// 如果field为空,检查prenum和actnum
// 先移除该索引的所有错误信息
this.fzListErrors = this.fzListErrors.filter(err => err.rowIndex !== index);
// 没有值的就放到fzListErrors里面
if (isValueEmpty(item.prenum)) {
this.fzListErrors.push({
rowIndex: index,
field: "prenum",
error: "请输入预填分装数量"
});
}
if (isValueEmpty(item.actnum)) {
this.fzListErrors.push({
rowIndex: index,
field: "actnum",
error: "请输入实际分装数量"
});
}
} else {
// 如果field不为空,检查指定字段
// 先移除该索引和字段的错误信息
this.fzListErrors = this.fzListErrors.filter(err => !(err.rowIndex === index && err.field === field));
// 没有值的就放到fzListErrors里面
if (isValueEmpty(item[field])) {
this.fzListErrors.push({
rowIndex: index,
field: field,
error: field === "prenum" ? "请输入预填分装数量" : "请输入实际分装数量"
});
}
}
}
}
},
hasError(index, field) {
const o = this.fzListErrors.find((item)=>{
return item.rowIndex === index && item.field === field;
})
return o !== undefined;
},
// 数据变化处理方法
onDataChange() {
// 触发自定义事件,将数据变化传递给父组件
this.$emit('update', {
formData: this.formData,
fzList: this.fzList
});
},
}
}
</script>
<style lang="scss" scoped>
.zl-container{
// width: 1100px;
}
.dialog-content {
// padding: 20px;
}
.ml-5{
margin-left: 5px;
}
.unit-select {
width: 100px;
}
.content-item {
display: flex;
align-items: center;
}
.header-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 20px;
margin-top: 10px;
}
.header-item {
// box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
background: #fff;
border-radius: 4px;
display: flex;
align-items: center;
// padding: 20px;
}
.header-title {
// margin-bottom: 10px;
margin-right: 5px;
}
.content-container {
margin-top: 10px;
// padding: 20px;
// box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
// max-height: 50vh;
overflow: auto;
}
.ml-20 {
margin-left: 20px;
}
.list-item {
display: flex;
align-items: center;
// margin-top: 20px;
}
.list-label {
margin-right: 5px;
// width: 200px;
}
</style>