diff --git a/src/api/admin/enum-contracts.ts b/src/api/admin/enum-contracts.ts
index 00ace15..3203534 100644
--- a/src/api/admin/enum-contracts.ts
+++ b/src/api/admin/enum-contracts.ts
@@ -131,3 +131,8 @@ export const EnumPressureUnit = {
Psi: { name: 'psi', value: 'psi', desc: 'psi' },
Kpa: { name: 'kPa', value: 'kPa', desc: 'kPa' },
}
+
+export const EnumFeedingType = {
+ Percentage: { name: 'Percentage', value: 1, desc: '百分比' },
+ Volume: { name: 'Volume', value: 2, desc: '体积' },
+}
diff --git a/src/views/admin/template/components/culture-protocol-form.vue b/src/views/admin/template/components/culture-protocol-form.vue
index ef9554f..c0a15b5 100644
--- a/src/views/admin/template/components/culture-protocol-form.vue
+++ b/src/views/admin/template/components/culture-protocol-form.vue
@@ -62,8 +62,8 @@
v-if="state.form.equReactorId && state.reactorOptions.find(r => r.id === state.form.equReactorId)?.needExternalPump === true"
label="外置泵" prop="equPumpId" min-width="100">
- handlePumpChange(scope.$index)">
+ handlePumpChange(scope.$index)">
@@ -110,39 +110,87 @@
@@ -209,6 +257,10 @@ import { PumpApi } from '/@/api/admin/PumpApi'
import { UspFeedingConfigApi } from '/@/api/admin/UspFeedingConfigApi'
import type { CultureProtocolDto } from '/@/api/types/cultureprotocol'
import { ElMessageBox, ElMessage } from 'element-plus'
+import { toOptionsByValue } from '/@/utils/enum'
+import { EnumFeedingType } from '/@/api/admin/enum-contracts'
+import { DocumentCopy, Plus } from '@element-plus/icons-vue'
+
const { proxy } = getCurrentInstance() as any
defineProps({
@@ -251,6 +303,7 @@ const state = reactive({
cellTypeOptions: [],
configOptions: [] as Array<{ id: number; name: string; isTwo: number; }>,
selectedReactor: null as any,
+ feedingTypeOptions: toOptionsByValue(EnumFeedingType)
})
const { form } = toRefs(state)
@@ -296,7 +349,7 @@ function addTaskByPump(pumpNo: number) {
feedingPumpNo: pumpNo,
day: 0,
feedingTime: '',
- feedingType: 0,
+ feedingType: 1,
feedingVolumePercent: 0,
feedingVolume: 0
})
@@ -489,6 +542,25 @@ const checkPumps = () => {
// 提交表单
const onSure = async () => {
if (!formRef.value) return
+
+ state.form.feedingTasks.forEach(task => {
+ if (task.feedingTime) {
+ // 兼容 Date 对象或字符串
+ let dateObj = typeof task.feedingTime === 'string'
+ ? new Date(`1970-01-01T${task.feedingTime}`)
+ : task.feedingTime;
+ if (dateObj instanceof Date && !isNaN(dateObj.getTime())) {
+ const h = String(dateObj.getHours()).padStart(2, '0');
+ const m = String(dateObj.getMinutes()).padStart(2, '0');
+ const s = String(dateObj.getSeconds()).padStart(2, '0');
+ task.feedingTime = `${h}:${m}:${s}`;
+ } else if (typeof task.feedingTime === 'string' && task.feedingTime.length >= 8) {
+ // 已经是字符串,截取
+ task.feedingTime = task.feedingTime.slice(0, 8);
+ }
+ }
+ });
+
await formRef.value.validate(async (valid: boolean) => {
if (valid) {
state.sureLoading = true
@@ -710,6 +782,91 @@ const handleMediumChange = (index: number) => {
}
}
+// feedingType变更时动态调整补料体积输入规则
+function handleFeedingTypeChange(row: any, val: number | string | undefined): void {
+ const type = Number(val);
+ if (type === 1) {
+ // 百分比,两位小数,范围0-100
+ if (typeof row.feedingVolume === 'number') {
+ let v = Math.round(row.feedingVolume * 100) / 100;
+ if (v < 0) v = 0;
+ if (v > 100) v = 100;
+ row.feedingVolume = v;
+ } else {
+ row.feedingVolume = 0;
+ }
+ } else if (type === 2) {
+ // 体积,非负整数
+ if (typeof row.feedingVolume === 'number') {
+ let v = Math.floor(row.feedingVolume);
+ if (v < 0) v = 0;
+ row.feedingVolume = v;
+ } else {
+ row.feedingVolume = 0;
+ }
+ }
+}
+
+// 补料体积输入框动态属性
+function getFeedingVolumeProps(row: any) {
+ if (row.feedingType === 1) {
+ return { min: 0, max: 100, precision: 2, step: 0.01 };
+ return { min: 0, max: 100, precision: 2 };
+ } else if (row.feedingType === 2) {
+ return { min: 0, precision: 0 };
+ }
+ return { min: 0 };
+}
+
+// 天数+1并复制当前行数据
+function addDayCopy(row: any, pumpNo: number) {
+ const newRow = { ...row, day: Number(row.day) + 1 };
+ newRow.id = 0;
+ newRow.feedingPumpNo = pumpNo;
+ state.form.feedingTasks.push(newRow);
+ // 排序:只对当前泵编号的任务排序
+ const tasks = state.form.feedingTasks.filter(t => t.feedingPumpNo === pumpNo);
+ tasks.sort((a, b) => Number(a.day) - Number(b.day));
+ // 重新合并排序后的结果到原数组
+ let i = 0;
+ for (let idx = 0; idx < state.form.feedingTasks.length; idx++) {
+ if (state.form.feedingTasks[idx].feedingPumpNo === pumpNo) {
+ state.form.feedingTasks[idx] = tasks[i++];
+ }
+ }
+}
+
+// 批量粘贴补料时间
+function pasteFeedingTime(row: any, pumpNo: number) {
+ const time = row.feedingTime;
+ state.form.feedingTasks.forEach(task => {
+ if (task.feedingPumpNo === pumpNo && task !== row) {
+ task.feedingTime = time;
+ }
+ });
+}
+
+// 批量粘贴补料类型
+function pasteFeedingType(row: any, pumpNo: number) {
+ const type = row.feedingType;
+ state.form.feedingTasks.forEach(task => {
+ if (task.feedingPumpNo === pumpNo && task !== row) {
+ task.feedingType = type;
+ handleFeedingTypeChange(task, type); // 保证体积约束同步
+ }
+ });
+}
+
+// 批量粘贴补料体积
+function pasteFeedingVolume(row: any, pumpNo: number) {
+ const volume = row.feedingVolume;
+ state.form.feedingTasks.forEach(task => {
+ if (task.feedingPumpNo === pumpNo && task !== row) {
+ task.feedingVolume = volume;
+ }
+ });
+}
+
defineExpose({
open
})
@@ -730,6 +887,18 @@ defineExpose({
}
}
+.feeding-task-tabs {
+ margin-bottom: 0;
+
+ .el-tabs__header {
+ margin-bottom: 10px;
+ }
+
+ .el-tab-pane {
+ padding: 0 0 10px 0;
+ }
+}
+
.rule-item,
.task-item,
.pump-item {
@@ -750,4 +919,36 @@ defineExpose({
.mt-2 {
margin-top: 8px;
}
+
+.pretty-table {
+ border-radius: 8px;
+ box-shadow: 0 2px 8px #e0e7ef;
+ overflow: hidden;
+ margin-bottom: 10px;
+
+ .el-table__header th {
+ background: #f0f3fa;
+ color: #333;
+ font-weight: bold;
+ font-size: 15px;
+ border-bottom: 1.5px solid #e0e7ef;
+ }
+
+ .el-table__body tr:hover>td {
+ background: #e6f7ff !important;
+ }
+
+ .el-table__cell {
+ padding: 6px 0;
+ }
+}
+
+.pretty-delete-btn {
+ transition: background 0.2s;
+
+ &:hover {
+ background: #ffeded !important;
+ color: #f56c6c !important;
+ }
+}
\ No newline at end of file