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