|
@@ -29,31 +29,72 @@
|
|
|
v-slot:[`column_${index}`]="{ row }"
|
|
v-slot:[`column_${index}`]="{ row }"
|
|
|
>
|
|
>
|
|
|
<div :key="`column_${index}`" class="column_content">
|
|
<div :key="`column_${index}`" class="column_content">
|
|
|
- <div v-if="row[index].isOnlyShow">
|
|
|
|
|
|
|
+ <!-- 文本 -->
|
|
|
|
|
+ <div v-if="row[index].paramType == 7 || row[index].isOnlyShow">
|
|
|
{{ row[index].value }}
|
|
{{ row[index].value }}
|
|
|
</div>
|
|
</div>
|
|
|
- <el-input
|
|
|
|
|
- v-else
|
|
|
|
|
- v-model.number="row[index].value"
|
|
|
|
|
- :placeholder="
|
|
|
|
|
- row[index].formula
|
|
|
|
|
- ? row[index].formula.replace(/[\[\]]/g, '')
|
|
|
|
|
- : `请输入${row[index].title}`
|
|
|
|
|
- "
|
|
|
|
|
- :disabled="Boolean(row[index].formula)"
|
|
|
|
|
- @input="handleDataChange(row[index], row)"
|
|
|
|
|
- >
|
|
|
|
|
- <template v-if="!row[index].isOnlyShow" slot="append">
|
|
|
|
|
- <div style="width: 80px; height: 100%">
|
|
|
|
|
|
|
+ <!-- 数值 -->
|
|
|
|
|
+ <template v-else-if="row[index].paramType == 1">
|
|
|
|
|
+ <div style="display: flex">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="row[index].value"
|
|
|
|
|
+ :placeholder="
|
|
|
|
|
+ row[index].formula
|
|
|
|
|
+ ? row[index].formula.replace(/[\[\]]/g, '')
|
|
|
|
|
+ : `请输入${row[index].title}`
|
|
|
|
|
+ "
|
|
|
|
|
+ :disabled="Boolean(row[index].formula)"
|
|
|
|
|
+ :controls="false"
|
|
|
|
|
+ @input="handleDataChange(row)"
|
|
|
|
|
+ ></el-input-number>
|
|
|
|
|
+ <div style="width: 80px; height: 100%; flex-shrink: 0">
|
|
|
<DictSelection
|
|
<DictSelection
|
|
|
v-model="row[index].unit"
|
|
v-model="row[index].unit"
|
|
|
dictName="工艺参数单位"
|
|
dictName="工艺参数单位"
|
|
|
placeholder="单位"
|
|
placeholder="单位"
|
|
|
>
|
|
>
|
|
|
- </DictSelection>
|
|
|
|
|
- </div>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-input>
|
|
|
|
|
|
|
+ </DictSelection
|
|
|
|
|
+ ></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <!-- 公式 -->
|
|
|
|
|
+ <template v-else-if="row[index].paramType == 9">
|
|
|
|
|
+ <div style="display: flex">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="row[index].value"
|
|
|
|
|
+ :placeholder="
|
|
|
|
|
+ row[index].formula
|
|
|
|
|
+ ? row[index].formula.replace(/[\[\]]/g, '')
|
|
|
|
|
+ : `请输入${row[index].title}`
|
|
|
|
|
+ "
|
|
|
|
|
+ disabled
|
|
|
|
|
+ @input="handleDataChange(row)"
|
|
|
|
|
+ ></el-input>
|
|
|
|
|
+ <div style="width: 80px; height: 100%; flex-shrink: 0">
|
|
|
|
|
+ <DictSelection
|
|
|
|
|
+ v-model="row[index].unit"
|
|
|
|
|
+ dictName="工艺参数单位"
|
|
|
|
|
+ placeholder="单位"
|
|
|
|
|
+ >
|
|
|
|
|
+ </DictSelection
|
|
|
|
|
+ ></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <!-- 时间 -->
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-else-if="row[index].paramType == 5"
|
|
|
|
|
+ v-model="row[index].value"
|
|
|
|
|
+ type="datetime"
|
|
|
|
|
+ placeholder="选择日期时间"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ >
|
|
|
|
|
+ </el-date-picker>
|
|
|
|
|
+ <!-- 其他 -->
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-else
|
|
|
|
|
+ v-model="row[index].value"
|
|
|
|
|
+ placeholder="请输入内容"
|
|
|
|
|
+ ></el-input>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
</ele-pro-table>
|
|
</ele-pro-table>
|
|
@@ -92,31 +133,72 @@
|
|
|
v-slot:[`column_${index}`]="{ row }"
|
|
v-slot:[`column_${index}`]="{ row }"
|
|
|
>
|
|
>
|
|
|
<div :key="`column_${index}`" class="column_content">
|
|
<div :key="`column_${index}`" class="column_content">
|
|
|
- <div v-if="row[index].isOnlyShow">
|
|
|
|
|
|
|
+ <!-- 文本 -->
|
|
|
|
|
+ <div v-if="row[index].paramType == 7 || row[index].isOnlyShow">
|
|
|
{{ row[index].value }}
|
|
{{ row[index].value }}
|
|
|
</div>
|
|
</div>
|
|
|
- <el-input
|
|
|
|
|
- v-else
|
|
|
|
|
- v-model.number="row[index].value"
|
|
|
|
|
- :placeholder="
|
|
|
|
|
- row[index].formula
|
|
|
|
|
- ? row[index].formula.replace(/[\[\]]/g, '')
|
|
|
|
|
- : `请输入${row[index].title}`
|
|
|
|
|
- "
|
|
|
|
|
- :disabled="Boolean(row[index].formula)"
|
|
|
|
|
- @input="handleDataChange(row[index], row)"
|
|
|
|
|
- >
|
|
|
|
|
- <template v-if="!row[index].isOnlyShow" slot="append">
|
|
|
|
|
- <div style="width: 80px; height: 100%">
|
|
|
|
|
|
|
+ <!-- 数值 -->
|
|
|
|
|
+ <template v-else-if="row[index].paramType == 1">
|
|
|
|
|
+ <div style="display: flex">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="row[index].value"
|
|
|
|
|
+ :placeholder="
|
|
|
|
|
+ row[index].formula
|
|
|
|
|
+ ? row[index].formula.replace(/[\[\]]/g, '')
|
|
|
|
|
+ : `请输入${row[index].title}`
|
|
|
|
|
+ "
|
|
|
|
|
+ :disabled="Boolean(row[index].formula)"
|
|
|
|
|
+ :controls="false"
|
|
|
|
|
+ @input="handleDataChange(row)"
|
|
|
|
|
+ ></el-input-number>
|
|
|
|
|
+ <div style="width: 80px; height: 100%; flex-shrink: 0">
|
|
|
|
|
+ <DictSelection
|
|
|
|
|
+ v-model="row[index].unit"
|
|
|
|
|
+ dictName="工艺参数单位"
|
|
|
|
|
+ placeholder="单位"
|
|
|
|
|
+ >
|
|
|
|
|
+ </DictSelection
|
|
|
|
|
+ ></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <!-- 公式 -->
|
|
|
|
|
+ <template v-else-if="row[index].paramType == 9">
|
|
|
|
|
+ <div style="display: flex">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="row[index].value"
|
|
|
|
|
+ :placeholder="
|
|
|
|
|
+ row[index].formula
|
|
|
|
|
+ ? row[index].formula.replace(/[\[\]]/g, '')
|
|
|
|
|
+ : `请输入${row[index].title}`
|
|
|
|
|
+ "
|
|
|
|
|
+ disabled
|
|
|
|
|
+ @input="handleDataChange(row)"
|
|
|
|
|
+ ></el-input>
|
|
|
|
|
+ <div style="width: 80px; height: 100%; flex-shrink: 0">
|
|
|
<DictSelection
|
|
<DictSelection
|
|
|
v-model="row[index].unit"
|
|
v-model="row[index].unit"
|
|
|
dictName="工艺参数单位"
|
|
dictName="工艺参数单位"
|
|
|
placeholder="单位"
|
|
placeholder="单位"
|
|
|
>
|
|
>
|
|
|
- </DictSelection>
|
|
|
|
|
- </div>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-input>
|
|
|
|
|
|
|
+ </DictSelection
|
|
|
|
|
+ ></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <!-- 时间 -->
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-else-if="row[index].paramType == 5"
|
|
|
|
|
+ v-model="row[index].value"
|
|
|
|
|
+ type="datetime"
|
|
|
|
|
+ placeholder="选择日期时间"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ >
|
|
|
|
|
+ </el-date-picker>
|
|
|
|
|
+ <!-- 其他 -->
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-else
|
|
|
|
|
+ v-model="row[index].value"
|
|
|
|
|
+ placeholder="请输入内容"
|
|
|
|
|
+ ></el-input>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
</ele-pro-table>
|
|
</ele-pro-table>
|
|
@@ -154,31 +236,72 @@
|
|
|
v-slot:[`column_${index}`]="{ row }"
|
|
v-slot:[`column_${index}`]="{ row }"
|
|
|
>
|
|
>
|
|
|
<div :key="`column_${index}`" class="column_content">
|
|
<div :key="`column_${index}`" class="column_content">
|
|
|
- <div v-if="row[index].isOnlyShow">
|
|
|
|
|
|
|
+ <!-- 文本 -->
|
|
|
|
|
+ <div v-if="row[index].paramType == 7 || row[index].isOnlyShow">
|
|
|
{{ row[index].value }}
|
|
{{ row[index].value }}
|
|
|
</div>
|
|
</div>
|
|
|
- <el-input
|
|
|
|
|
- v-else
|
|
|
|
|
- v-model.number="row[index].value"
|
|
|
|
|
- :placeholder="
|
|
|
|
|
- row[index].formula
|
|
|
|
|
- ? row[index].formula.replace(/[\[\]]/g, '')
|
|
|
|
|
- : `请输入${row[index].title}`
|
|
|
|
|
- "
|
|
|
|
|
- :disabled="Boolean(row[index].formula)"
|
|
|
|
|
- @input="handleDataChange(row[index], row)"
|
|
|
|
|
- >
|
|
|
|
|
- <template v-if="!row[index].isOnlyShow" slot="append">
|
|
|
|
|
- <div style="width: 80px; height: 100%">
|
|
|
|
|
|
|
+ <!-- 数值 -->
|
|
|
|
|
+ <template v-else-if="row[index].paramType == 1">
|
|
|
|
|
+ <div style="display: flex">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="row[index].value"
|
|
|
|
|
+ :placeholder="
|
|
|
|
|
+ row[index].formula
|
|
|
|
|
+ ? row[index].formula.replace(/[\[\]]/g, '')
|
|
|
|
|
+ : `请输入${row[index].title}`
|
|
|
|
|
+ "
|
|
|
|
|
+ :disabled="Boolean(row[index].formula)"
|
|
|
|
|
+ :controls="false"
|
|
|
|
|
+ @input="handleDataChange(row)"
|
|
|
|
|
+ ></el-input>
|
|
|
|
|
+ <div style="width: 80px; height: 100%; flex-shrink: 0">
|
|
|
|
|
+ <DictSelection
|
|
|
|
|
+ v-model="row[index].unit"
|
|
|
|
|
+ dictName="工艺参数单位"
|
|
|
|
|
+ placeholder="单位"
|
|
|
|
|
+ >
|
|
|
|
|
+ </DictSelection
|
|
|
|
|
+ ></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <!-- 公式 -->
|
|
|
|
|
+ <template v-else-if="row[index].paramType == 9">
|
|
|
|
|
+ <div style="display: flex">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="row[index].value"
|
|
|
|
|
+ :placeholder="
|
|
|
|
|
+ row[index].formula
|
|
|
|
|
+ ? row[index].formula.replace(/[\[\]]/g, '')
|
|
|
|
|
+ : `请输入${row[index].title}`
|
|
|
|
|
+ "
|
|
|
|
|
+ disabled
|
|
|
|
|
+ @input="handleDataChange(row)"
|
|
|
|
|
+ ></el-input-number>
|
|
|
|
|
+ <div style="width: 80px; height: 100%; flex-shrink: 0">
|
|
|
<DictSelection
|
|
<DictSelection
|
|
|
v-model="row[index].unit"
|
|
v-model="row[index].unit"
|
|
|
dictName="工艺参数单位"
|
|
dictName="工艺参数单位"
|
|
|
placeholder="单位"
|
|
placeholder="单位"
|
|
|
>
|
|
>
|
|
|
- </DictSelection>
|
|
|
|
|
- </div>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-input>
|
|
|
|
|
|
|
+ </DictSelection
|
|
|
|
|
+ ></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <!-- 时间 -->
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-else-if="row[index].paramType == 5"
|
|
|
|
|
+ v-model="row[index].value"
|
|
|
|
|
+ type="datetime"
|
|
|
|
|
+ placeholder="选择日期时间"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ >
|
|
|
|
|
+ </el-date-picker>
|
|
|
|
|
+ <!-- 其他 -->
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-else
|
|
|
|
|
+ v-model="row[index].value"
|
|
|
|
|
+ placeholder="请输入内容"
|
|
|
|
|
+ ></el-input>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
</ele-pro-table>
|
|
</ele-pro-table>
|
|
@@ -225,6 +348,16 @@
|
|
|
ruleId: {
|
|
ruleId: {
|
|
|
type: [String, Number],
|
|
type: [String, Number],
|
|
|
default: ''
|
|
default: ''
|
|
|
|
|
+ },
|
|
|
|
|
+ // 单位
|
|
|
|
|
+ unit: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: ''
|
|
|
|
|
+ },
|
|
|
|
|
+ // 要求生产数量
|
|
|
|
|
+ formingNum: {
|
|
|
|
|
+ type: [Number],
|
|
|
|
|
+ default: 0
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
watch: {
|
|
watch: {
|
|
@@ -391,15 +524,18 @@
|
|
|
}
|
|
}
|
|
|
],
|
|
],
|
|
|
activeProductTaskName: '全部',
|
|
activeProductTaskName: '全部',
|
|
|
- keyword: ''
|
|
|
|
|
|
|
+ keyword: '',
|
|
|
|
|
+ _emitChangeTimer: null
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
methods: {
|
|
methods: {
|
|
|
- // 通知父组件数据变更
|
|
|
|
|
|
|
+ // 通知父组件数据变更(防抖 500ms)
|
|
|
emitChange() {
|
|
emitChange() {
|
|
|
- console.log('this.localDetails', this.localDetails);
|
|
|
|
|
- this.$emit('update:details', this.localDetails);
|
|
|
|
|
|
|
+ if (this._emitChangeTimer) clearTimeout(this._emitChangeTimer);
|
|
|
|
|
+ this._emitChangeTimer = setTimeout(() => {
|
|
|
|
|
+ this.$emit('update:details', this.localDetails);
|
|
|
|
|
+ }, 500);
|
|
|
},
|
|
},
|
|
|
// 构建统计数据
|
|
// 构建统计数据
|
|
|
async buildDetials(detials) {
|
|
async buildDetials(detials) {
|
|
@@ -431,23 +567,24 @@
|
|
|
this.localDetails[0].statisticsValue.length == 0) ||
|
|
this.localDetails[0].statisticsValue.length == 0) ||
|
|
|
this.localDetails[0].ruleId != this.ruleId
|
|
this.localDetails[0].ruleId != this.ruleId
|
|
|
) {
|
|
) {
|
|
|
|
|
+ const list = this.rulesDetailList
|
|
|
|
|
+ .filter((i) => i.statisticsType == 1)
|
|
|
|
|
+ .map((i) => {
|
|
|
|
|
+ return {
|
|
|
|
|
+ title: i.paramValue,
|
|
|
|
|
+ value: i.defaultValue,
|
|
|
|
|
+ formula: i.formula,
|
|
|
|
|
+ unit: i.unitName || this.unit,
|
|
|
|
|
+ paramType: i.paramType
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
// 已构建过统计数据
|
|
// 已构建过统计数据
|
|
|
this.localDetails[0] = {
|
|
this.localDetails[0] = {
|
|
|
...this.localDetails[0],
|
|
...this.localDetails[0],
|
|
|
ruleId: this.ruleId,
|
|
ruleId: this.ruleId,
|
|
|
statisticsType: 1,
|
|
statisticsType: 1,
|
|
|
- statisticsValue: [
|
|
|
|
|
- this.rulesDetailList
|
|
|
|
|
- .filter((i) => i.statisticsType == 1)
|
|
|
|
|
- .map((i) => {
|
|
|
|
|
- return {
|
|
|
|
|
- title: i.paramValue,
|
|
|
|
|
- value: i.defaultValue,
|
|
|
|
|
- formula: i.formula,
|
|
|
|
|
- unit: i.unitName
|
|
|
|
|
- };
|
|
|
|
|
- })
|
|
|
|
|
- ]
|
|
|
|
|
|
|
+ statisticsValue: [list]
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
// 构建物料和工序数据
|
|
// 构建物料和工序数据
|
|
@@ -455,6 +592,17 @@
|
|
|
},
|
|
},
|
|
|
// 构建物料和工序数据
|
|
// 构建物料和工序数据
|
|
|
async rebuildMaterialAndProcessData() {
|
|
async rebuildMaterialAndProcessData() {
|
|
|
|
|
+ if (this.unit) {
|
|
|
|
|
+ // 存在单位则 更新statisticsType为1的单位
|
|
|
|
|
+ this.localDetails[0].statisticsValue.forEach((rows) => {
|
|
|
|
|
+ rows.forEach((item) => {
|
|
|
|
|
+ if (!item.unit) {
|
|
|
|
|
+ item.unit = this.unit;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
let routingTaskList = [];
|
|
let routingTaskList = [];
|
|
|
let pickAndFeed = [];
|
|
let pickAndFeed = [];
|
|
|
|
|
|
|
@@ -486,7 +634,8 @@
|
|
|
title: i.paramValue,
|
|
title: i.paramValue,
|
|
|
value: i.defaultValue,
|
|
value: i.defaultValue,
|
|
|
formula: i.formula,
|
|
formula: i.formula,
|
|
|
- unit: i.unitName
|
|
|
|
|
|
|
+ unit: i.unitName || this.unit,
|
|
|
|
|
+ paramType: i.paramType
|
|
|
};
|
|
};
|
|
|
});
|
|
});
|
|
|
|
|
|
|
@@ -494,14 +643,18 @@
|
|
|
title: '领用量',
|
|
title: '领用量',
|
|
|
value: pick.pickQuantity,
|
|
value: pick.pickQuantity,
|
|
|
formula: '',
|
|
formula: '',
|
|
|
- unit: pick.pickUnit
|
|
|
|
|
|
|
+ unit: pick.pickUnit,
|
|
|
|
|
+ // 1数值类型
|
|
|
|
|
+ paramType: 1
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
data.unshift({
|
|
data.unshift({
|
|
|
title: '使用量',
|
|
title: '使用量',
|
|
|
value: pick.feedQuantity,
|
|
value: pick.feedQuantity,
|
|
|
formula: '',
|
|
formula: '',
|
|
|
- unit: pick.feedUnit
|
|
|
|
|
|
|
+ unit: pick.feedUnit,
|
|
|
|
|
+ // 1数值类型
|
|
|
|
|
+ paramType: 1
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
data.unshift({
|
|
data.unshift({
|
|
@@ -510,7 +663,9 @@
|
|
|
formula: '',
|
|
formula: '',
|
|
|
unit: '',
|
|
unit: '',
|
|
|
// 仅展示不计算和输入
|
|
// 仅展示不计算和输入
|
|
|
- isOnlyShow: true
|
|
|
|
|
|
|
+ isOnlyShow: true,
|
|
|
|
|
+ // 7文本类型
|
|
|
|
|
+ paramType: 7
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
data.unshift({
|
|
data.unshift({
|
|
@@ -521,7 +676,9 @@
|
|
|
// 仅展示不计算和输入
|
|
// 仅展示不计算和输入
|
|
|
isOnlyShow: true,
|
|
isOnlyShow: true,
|
|
|
// produceTaskName 工序名称
|
|
// produceTaskName 工序名称
|
|
|
- produceTaskName: pick.produceTaskName
|
|
|
|
|
|
|
+ produceTaskName: pick.produceTaskName,
|
|
|
|
|
+ // 7文本类型
|
|
|
|
|
+ paramType: 7
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
return data;
|
|
return data;
|
|
@@ -540,7 +697,8 @@
|
|
|
title: i.paramValue,
|
|
title: i.paramValue,
|
|
|
value: i.defaultValue,
|
|
value: i.defaultValue,
|
|
|
formula: i.formula,
|
|
formula: i.formula,
|
|
|
- unit: i.unitName
|
|
|
|
|
|
|
+ unit: i.unitName || this.unit,
|
|
|
|
|
+ paramType: i.paramType
|
|
|
};
|
|
};
|
|
|
});
|
|
});
|
|
|
|
|
|
|
@@ -550,7 +708,9 @@
|
|
|
formula: '',
|
|
formula: '',
|
|
|
unit: '',
|
|
unit: '',
|
|
|
// 仅展示不计算和输入
|
|
// 仅展示不计算和输入
|
|
|
- isOnlyShow: true
|
|
|
|
|
|
|
+ isOnlyShow: true,
|
|
|
|
|
+ // 7文本类型
|
|
|
|
|
+ paramType: 7
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
return data;
|
|
return data;
|
|
@@ -563,15 +723,13 @@
|
|
|
this.emitChange();
|
|
this.emitChange();
|
|
|
},
|
|
},
|
|
|
// 当数据变化时计算公式
|
|
// 当数据变化时计算公式
|
|
|
- handleDataChange(item, row) {
|
|
|
|
|
|
|
+ handleDataChange(row) {
|
|
|
// todo 计算公式
|
|
// todo 计算公式
|
|
|
- console.log('item', item);
|
|
|
|
|
- console.log('row', row);
|
|
|
|
|
// 寻找当前行的所有可计算项,进行计算更新
|
|
// 寻找当前行的所有可计算项,进行计算更新
|
|
|
const formulaItmes = row.filter((i) => i.formula);
|
|
const formulaItmes = row.filter((i) => i.formula);
|
|
|
|
|
|
|
|
formulaItmes.forEach((formulaItem) => {
|
|
formulaItmes.forEach((formulaItem) => {
|
|
|
- // 简单示例 公式为 [(][合格品量][+][取样量][)][/][接收量] 其中合格品量、取样量、接收量为标题在row中寻找对应value进行计算
|
|
|
|
|
|
|
+ // 简单示例 公式为 [(][合格品量][+][取样量][)][/][接收量]
|
|
|
const tokens = formulaItem.formula
|
|
const tokens = formulaItem.formula
|
|
|
? formulaItem.formula.match(/\[([^\]]+)\]/g) || []
|
|
? formulaItem.formula.match(/\[([^\]]+)\]/g) || []
|
|
|
: [];
|
|
: [];
|
|
@@ -584,6 +742,17 @@
|
|
|
expr += content;
|
|
expr += content;
|
|
|
} else {
|
|
} else {
|
|
|
const target = row.find((r) => r.title === content);
|
|
const target = row.find((r) => r.title === content);
|
|
|
|
|
+ // 特殊处理:当标题为“要求生产数量”且当前行未找到对应项时,用 this.formingNum 参与计算
|
|
|
|
|
+ if (!target && content === '要求生产数量') {
|
|
|
|
|
+ const formingVal = Number(this.formingNum);
|
|
|
|
|
+ if (!Number.isFinite(formingVal)) {
|
|
|
|
|
+ invalid = true;
|
|
|
|
|
+ expr = '';
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ expr += formingVal;
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
// 若对应的项不存在 或 value为空 则取消计算
|
|
// 若对应的项不存在 或 value为空 则取消计算
|
|
|
if (
|
|
if (
|
|
|
!target ||
|
|
!target ||
|
|
@@ -592,7 +761,7 @@
|
|
|
target.value === undefined
|
|
target.value === undefined
|
|
|
) {
|
|
) {
|
|
|
invalid = true;
|
|
invalid = true;
|
|
|
- expr = ''; // 置空表达式,后续将不计算
|
|
|
|
|
|
|
+ expr = '';
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
const num = Number(target.value);
|
|
const num = Number(target.value);
|
|
@@ -605,23 +774,16 @@
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
// 若无效则直接跳过后续计算 (expr 已被置空)
|
|
// 若无效则直接跳过后续计算 (expr 已被置空)
|
|
|
- if (/^[0-9+\-*/().\s]+$/.test(expr)) {
|
|
|
|
|
|
|
+ if (expr && /^[0-9+\-*/().\s]+$/.test(expr)) {
|
|
|
try {
|
|
try {
|
|
|
- console.log('expr', expr);
|
|
|
|
|
const result = Function(`"use strict";return (${expr})`)();
|
|
const result = Function(`"use strict";return (${expr})`)();
|
|
|
let value =
|
|
let value =
|
|
|
Number.isFinite(result) && !Number.isNaN(result) ? result : '';
|
|
Number.isFinite(result) && !Number.isNaN(result) ? result : '';
|
|
|
|
|
|
|
|
- if (value) {
|
|
|
|
|
- // 如果超出4位小数 则保留4位小数
|
|
|
|
|
- if (typeof value === 'number') {
|
|
|
|
|
- const dec = value.toString().split('.')[1];
|
|
|
|
|
- if (dec && dec.length > 4) {
|
|
|
|
|
- const parts = value.toString().split('.');
|
|
|
|
|
- if (parts[1] && parts[1].length > 4) {
|
|
|
|
|
- value = Number(parts[0] + '.' + parts[1].slice(0, 4));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (value !== '' && typeof value === 'number') {
|
|
|
|
|
+ const dec = value.toString().split('.')[1];
|
|
|
|
|
+ if (dec && dec.length > 4) {
|
|
|
|
|
+ value = Number(value.toFixed(4));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -706,32 +868,132 @@
|
|
|
},
|
|
},
|
|
|
getSummaries() {
|
|
getSummaries() {
|
|
|
const sums = [];
|
|
const sums = [];
|
|
|
- if (this.localDetails[0].statisticsValue.length == 0) {
|
|
|
|
|
|
|
+ // 优化:缓存公式解析、统一数值获取,减少重复正则与遍历
|
|
|
|
|
+ if (
|
|
|
|
|
+ !this.localDetails[0] ||
|
|
|
|
|
+ !this.localDetails[0].statisticsValue ||
|
|
|
|
|
+ this.localDetails[0].statisticsValue.length === 0
|
|
|
|
|
+ ) {
|
|
|
return sums;
|
|
return sums;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ const rows = this.localDetails[0].statisticsValue;
|
|
|
|
|
+ const firstRow = rows[0] || [];
|
|
|
sums.push('合计');
|
|
sums.push('合计');
|
|
|
- this.localDetails[0].statisticsValue.forEach((itemList, index) => {
|
|
|
|
|
- itemList.forEach((item, colIndex) => {
|
|
|
|
|
- if (item.isOnlyShow) {
|
|
|
|
|
- sums[colIndex + 1] = '';
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 缓存结构:{ formulaString: [{type:'op'|'num'|'ref', value:'+'|number|'列标题'}] }
|
|
|
|
|
+ if (!this._formulaCache) this._formulaCache = Object.create(null);
|
|
|
|
|
+
|
|
|
|
|
+ const parseFormula = (formula) => {
|
|
|
|
|
+ if (!formula) return [];
|
|
|
|
|
+ if (this._formulaCache[formula]) return this._formulaCache[formula];
|
|
|
|
|
+
|
|
|
|
|
+ // 提取 [xxx] 片段
|
|
|
|
|
+ const rawTokens = formula.match(/\[([^\]]+)\]/g) || [];
|
|
|
|
|
+ const tokens = [];
|
|
|
|
|
+ rawTokens.forEach((token) => {
|
|
|
|
|
+ const content = token.slice(1, -1).trim();
|
|
|
|
|
+ // 运算符/括号
|
|
|
|
|
+ if (['+', '-', '*', '/', '(', ')', '%'].includes(content)) {
|
|
|
|
|
+ tokens.push({ type: 'op', value: content });
|
|
|
} else {
|
|
} else {
|
|
|
- if (sums[colIndex + 1]) {
|
|
|
|
|
- if (isNaN(Number(item.value))) {
|
|
|
|
|
- sums[colIndex + 1] += 0;
|
|
|
|
|
- } else {
|
|
|
|
|
- sums[colIndex + 1] += Number(item.value) || 0;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // 引用列标题或特殊内置
|
|
|
|
|
+ tokens.push({ type: 'ref', value: content });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ this._formulaCache[formula] = tokens;
|
|
|
|
|
+ return tokens;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 辅助:安全数值
|
|
|
|
|
+ const toNum = (v) => {
|
|
|
|
|
+ const n = Number(v);
|
|
|
|
|
+ return Number.isFinite(n) ? n : 0;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 先累加所有“非公式数值列”
|
|
|
|
|
+ rows.forEach((row) => {
|
|
|
|
|
+ row.forEach((cell, colIndex) => {
|
|
|
|
|
+ const targetIndex = colIndex + 1;
|
|
|
|
|
+ if (sums[targetIndex] === undefined) sums[targetIndex] = '';
|
|
|
|
|
+
|
|
|
|
|
+ if (cell.isOnlyShow || cell.paramType !== 1) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (cell.formula) {
|
|
|
|
|
+ // 公式列占位为 0,后续再算
|
|
|
|
|
+ if (sums[targetIndex] === '') sums[targetIndex] = 0;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const num = Number(cell.value);
|
|
|
|
|
+ if (!Number.isFinite(num)) return;
|
|
|
|
|
+ if (typeof sums[targetIndex] !== 'number') sums[targetIndex] = 0;
|
|
|
|
|
+ sums[targetIndex] += num;
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 计算公式列(使用上面得到的合计值作为引用值)
|
|
|
|
|
+ firstRow.forEach((meta, colIndex) => {
|
|
|
|
|
+ if (!meta.formula) return;
|
|
|
|
|
+ const targetIndex = colIndex + 1;
|
|
|
|
|
+
|
|
|
|
|
+ const tokens = parseFormula(meta.formula);
|
|
|
|
|
+ if (!tokens.length) {
|
|
|
|
|
+ sums[targetIndex] = '';
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let expr = '';
|
|
|
|
|
+ let invalid = false;
|
|
|
|
|
+
|
|
|
|
|
+ for (const tk of tokens) {
|
|
|
|
|
+ if (invalid) break;
|
|
|
|
|
+ if (tk.type === 'op') {
|
|
|
|
|
+ expr += tk.value;
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 引用列/特殊引用
|
|
|
|
|
+ if (tk.value === '要求生产数量') {
|
|
|
|
|
+ const formingVal = Number(this.formingNum);
|
|
|
|
|
+ if (!Number.isFinite(formingVal)) {
|
|
|
|
|
+ invalid = true;
|
|
|
} else {
|
|
} else {
|
|
|
- if (isNaN(Number(item.value))) {
|
|
|
|
|
- sums[colIndex + 1] = 0;
|
|
|
|
|
- } else {
|
|
|
|
|
- sums[colIndex + 1] = Number(item.value) || 0;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ expr += formingVal;
|
|
|
}
|
|
}
|
|
|
|
|
+ continue;
|
|
|
}
|
|
}
|
|
|
- });
|
|
|
|
|
|
|
+ const refColIdx = firstRow.findIndex((i) => i.title === tk.value);
|
|
|
|
|
+ if (refColIdx === -1) {
|
|
|
|
|
+ invalid = true;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ const refVal = sums[refColIdx + 1];
|
|
|
|
|
+ if (!Number.isFinite(Number(refVal))) {
|
|
|
|
|
+ invalid = true;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ expr += toNum(refVal);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (invalid || !expr || !/^[0-9+\-*/().\s%]+$/.test(expr)) {
|
|
|
|
|
+ sums[targetIndex] = '';
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ let result = Function('"use strict";return (' + expr + ')')();
|
|
|
|
|
+ if (!Number.isFinite(result) || Number.isNaN(result)) {
|
|
|
|
|
+ sums[targetIndex] = '';
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const dec = result.toString().split('.')[1];
|
|
|
|
|
+ if (dec && dec.length > 4) result = Number(result.toFixed(4));
|
|
|
|
|
+ sums[targetIndex] = result;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ sums[targetIndex] = '';
|
|
|
|
|
+ }
|
|
|
});
|
|
});
|
|
|
- console.log('sums', sums);
|
|
|
|
|
|
|
+
|
|
|
return sums;
|
|
return sums;
|
|
|
},
|
|
},
|
|
|
// 添加行
|
|
// 添加行
|