add 培养方案页面
This commit is contained in:
parent
f42b22dc0a
commit
acd9fcf076
93
src/api/admin/CultureProtocolApi.ts
Normal file
93
src/api/admin/CultureProtocolApi.ts
Normal file
@ -0,0 +1,93 @@
|
||||
import { RequestParams } from './http-client'
|
||||
import { ContentType, HttpClient } from './http-client'
|
||||
import type {
|
||||
CultureProtocolDto,
|
||||
CultureProtocolPageInput,
|
||||
CultureProtocolPageResponse,
|
||||
CultureProtocolOutput,
|
||||
CultureProtocolAddInput,
|
||||
CultureProtocolUpdateInput
|
||||
} from '/@/api/types/cultureprotocol'
|
||||
|
||||
export class CultureProtocolApi extends HttpClient {
|
||||
/**
|
||||
* 获取分页列表
|
||||
*/
|
||||
getPage = (data: CultureProtocolPageInput, params: RequestParams = {}) =>
|
||||
this.request<CultureProtocolPageResponse>({
|
||||
path: `/api/admin/culture-protocol/get-page`,
|
||||
method: 'POST',
|
||||
body: data,
|
||||
type: ContentType.Json,
|
||||
...params,
|
||||
})
|
||||
|
||||
/**
|
||||
* 获取单条数据
|
||||
*/
|
||||
get = (params: { id: number }, requestParams: RequestParams = {}) =>
|
||||
this.request<CultureProtocolOutput>({
|
||||
path: `/api/admin/culture-protocol/get`,
|
||||
method: 'GET',
|
||||
query: params,
|
||||
...requestParams,
|
||||
})
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
add = (data: CultureProtocolAddInput, params: RequestParams = {}) =>
|
||||
this.request<any>({
|
||||
path: `/api/admin/culture-protocol/add`,
|
||||
method: 'POST',
|
||||
body: data,
|
||||
type: ContentType.Json,
|
||||
...params,
|
||||
})
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*/
|
||||
update = (data: CultureProtocolUpdateInput, params: RequestParams = {}) =>
|
||||
this.request<any>({
|
||||
path: `/api/admin/culture-protocol/update`,
|
||||
method: 'PUT',
|
||||
body: data,
|
||||
type: ContentType.Json,
|
||||
...params,
|
||||
})
|
||||
|
||||
/**
|
||||
* 软删除
|
||||
*/
|
||||
softDelete = (params: { id: number }, requestParams: RequestParams = {}) =>
|
||||
this.request<any>({
|
||||
path: `/api/admin/culture-protocol/soft-delete`,
|
||||
method: 'DELETE',
|
||||
query: params,
|
||||
...requestParams,
|
||||
})
|
||||
|
||||
/**
|
||||
* 复制培养方案
|
||||
*/
|
||||
copy = (params: { id: number; reactorId: number }, requestParams: RequestParams = {}) =>
|
||||
this.request<any>({
|
||||
path: `/api/admin/culture-protocol/copy`,
|
||||
method: 'POST',
|
||||
body: params,
|
||||
type: ContentType.Json,
|
||||
...requestParams,
|
||||
})
|
||||
|
||||
/**
|
||||
* 切换培养方案状态
|
||||
*/
|
||||
toggleStatus = (params: { id: number; isEnabled: boolean }, requestParams: RequestParams = {}) =>
|
||||
this.request<any>({
|
||||
path: `/api/admin/culture-protocol/toggle-status`,
|
||||
method: 'POST',
|
||||
query: params,
|
||||
...requestParams,
|
||||
})
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { ReactorPageInput, ReactorPageResponse, ReactorOutput, ReactorAddInput, ReactorUpdateInput, ReactorTypeEnumListOutput } from '/@/api/types/ReactorType'
|
||||
import { ReactorPageInput, ReactorPageResponse, ReactorOutput, ReactorAddInput, ReactorUpdateInput, ReactorTypeEnumListOutput } from '/@/api/types/reactorType'
|
||||
import { RequestParams } from './http-client'
|
||||
import { ContentType, HttpClient } from './http-client'
|
||||
|
||||
|
@ -75,8 +75,10 @@ export interface ReactorDto {
|
||||
createdTime?: string | null
|
||||
/** 修改时间 */
|
||||
modifiedTime?: string | null
|
||||
/** 压力单位 */
|
||||
pressureUnit?: string | null
|
||||
/** 压力单位 */
|
||||
pressureUnit?: string | null
|
||||
/** 是否外置泵 */
|
||||
isExternalPump?: boolean
|
||||
}
|
||||
|
||||
/** 反应器添加和更新输入接口 */
|
||||
|
146
src/api/types/cultureprotocol.ts
Normal file
146
src/api/types/cultureprotocol.ts
Normal file
@ -0,0 +1,146 @@
|
||||
import { ServiceResponse } from './response'
|
||||
import { ServiceRequestPage } from './pageInput'
|
||||
import { PageResponse } from './pageResponse'
|
||||
|
||||
// 过滤条件
|
||||
export interface CultureProtocolFilter {
|
||||
/** 设备编号 */
|
||||
keyWord?: string | null
|
||||
/** 开始时间 */
|
||||
stDate?: string | null
|
||||
/** 结束时间 */
|
||||
edDate?: string | null
|
||||
/** 反应器Id */
|
||||
equReactorId?: number | null
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 培养方案实体接口
|
||||
*/
|
||||
export interface CultureProtocolPageDto {
|
||||
/** 主键ID */
|
||||
id: number
|
||||
/** 培养方案名称 */
|
||||
cultureProtocolName: string
|
||||
/** 反应器ID */
|
||||
equReactorId: number
|
||||
/** 补料秤ID */
|
||||
equFeedingScaleId: number
|
||||
/** 培养天数 */
|
||||
days: number
|
||||
/** 初始工作体积 */
|
||||
initialWorkingVolume: number
|
||||
/** 初始工作培养基ID */
|
||||
initialWorkingMediumId: number
|
||||
/** 转种细胞体积 */
|
||||
transferCellVolume: number
|
||||
/** 转种细胞类型ID */
|
||||
transferCellTypeId: number
|
||||
/** 实验组ID */
|
||||
experimentalGroupId: number
|
||||
/** 葡萄糖补料验证 */
|
||||
glucoseFeedingVerification: boolean
|
||||
/** 备注 */
|
||||
remark: string
|
||||
/** 是否启用 */
|
||||
enabled: boolean
|
||||
/** 创建时间 */
|
||||
createdTime: string
|
||||
}
|
||||
|
||||
export interface CultureProtocolDto {
|
||||
/** 主键ID */
|
||||
id: number
|
||||
/** 培养方案名称 */
|
||||
cultureProtocolName: string
|
||||
/** 反应器ID */
|
||||
equReactorId?: number
|
||||
/** 补料秤ID */
|
||||
equFeedingScaleId?: number
|
||||
/** 培养天数 */
|
||||
days: number
|
||||
/** 初始工作体积 */
|
||||
initialWorkingVolume: number
|
||||
/** 初始工作培养基ID */
|
||||
initialWorkingMediumId: number
|
||||
/** 转种细胞体积 */
|
||||
transferCellVolume: number
|
||||
/** 转种细胞类型ID */
|
||||
transferCellTypeId: number
|
||||
/** 葡萄糖补料验证 */
|
||||
glucoseFeedingVerification: boolean
|
||||
/** 备注 */
|
||||
remark: string
|
||||
/** 自动葡萄糖补料规则 */
|
||||
autoGlucoseFeedingRules: AutoGlucoseFeedingRule[]
|
||||
/** 补料任务 */
|
||||
feedingTasks: FeedingTask[]
|
||||
/** 固定补料泵配置 */
|
||||
fixedFeedingPumps: FixedFeedingPump[]
|
||||
}
|
||||
|
||||
/** 自动葡萄糖补料规则 */
|
||||
export interface AutoGlucoseFeedingRule {
|
||||
/** 主键ID */
|
||||
id: number
|
||||
/** 培养方案ID */
|
||||
cultureProtocolId: number
|
||||
/** 培养开始天数 */
|
||||
cultureDayStarting: number
|
||||
/** 培养结束天数 */
|
||||
cultureDayEnding: number
|
||||
/** 下限值 */
|
||||
lowerLimit: number
|
||||
/** 补料目标值 */
|
||||
feedingTo: number
|
||||
/** 下限操作符 */
|
||||
lowerLimitOperator: string
|
||||
/** 计算模式 */
|
||||
calculationMode: number
|
||||
}
|
||||
|
||||
/** 补料任务 */
|
||||
export interface FeedingTask {
|
||||
/** 主键ID */
|
||||
id: number
|
||||
/** 培养方案ID */
|
||||
cultureProtocolId: number
|
||||
/** 补料泵编号 */
|
||||
feedingPumpNo: number
|
||||
/** 培养天数 */
|
||||
day: number
|
||||
/** 补料时间 */
|
||||
feedingTime: string
|
||||
/** 补料类型 */
|
||||
feedingType: number
|
||||
/** 补料体积百分比 */
|
||||
feedingVolumePercent: number
|
||||
/** 补料体积 */
|
||||
feedingVolume: number
|
||||
}
|
||||
|
||||
/** 固定补料泵配置 */
|
||||
export interface FixedFeedingPump {
|
||||
/** 主键ID */
|
||||
id: number
|
||||
/** 培养方案ID */
|
||||
cultureProtocolId?: number
|
||||
/** 配置ID */
|
||||
configId?: number
|
||||
/** 补料泵编号 */
|
||||
feedingPumpNo: number
|
||||
/** 物料定义袋ID */
|
||||
itemDefBagID?: number
|
||||
/** 物料定义培养基ID */
|
||||
itemDefFeedingMediumID?: number
|
||||
/** 设备泵ID */
|
||||
equPumpId?: number
|
||||
}
|
||||
|
||||
export type CultureProtocolPageInput = ServiceRequestPage<CultureProtocolFilter>
|
||||
export type CultureProtocolPageResponse = ServiceResponse<PageResponse<CultureProtocolPageDto>>;
|
||||
|
||||
export type CultureProtocolOutput = ServiceResponse<CultureProtocolDto>;
|
||||
export type CultureProtocolAddInput = CultureProtocolDto;
|
||||
export type CultureProtocolUpdateInput = CultureProtocolDto;
|
@ -1,5 +1,5 @@
|
||||
import { ServiceResponse } from './response';
|
||||
import { ServiceRequstPage } from './pageInput'
|
||||
import { ServiceRequestPage } from './pageInput'
|
||||
import { PageResponse } from './pageResponse'
|
||||
|
||||
// 过滤
|
||||
@ -93,7 +93,7 @@ export interface RevokeTypeEnumItem {
|
||||
label: string
|
||||
}
|
||||
|
||||
export type RevokeReasonPageInput = ServiceRequstPage<RevokeReasonFilter>;
|
||||
export type RevokeReasonPageInput = ServiceRequestPage<RevokeReasonFilter>;
|
||||
export type RevokeReasonPageResponse = ServiceResponse<PageResponse<RevokeReasonPageDto>>;
|
||||
|
||||
export type RevokeReasonOutput = ServiceResponse<RevokeReasonDto[]>;
|
||||
|
515
src/views/admin/template/components/culture-protocol-form.vue
Normal file
515
src/views/admin/template/components/culture-protocol-form.vue
Normal file
@ -0,0 +1,515 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog v-model="state.showDialog" destroy-on-close :title="title" draggable :close-on-click-modal="false"
|
||||
:close-on-press-escape="false" width="65%" append-to-body>
|
||||
<el-form :model="form" ref="formRef" size="default" label-width="120px">
|
||||
<el-tabs v-model="state.activeTab">
|
||||
<!-- 基本信息 -->
|
||||
<el-tab-pane label="基本信息" name="basic">
|
||||
<div class="form-section">
|
||||
<el-row :gutter="25">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-form-item label="方案名称" prop="cultureProtocolName"
|
||||
:rules="[{ required: true, message: '请输入方案名称', trigger: ['blur', 'change'] }]">
|
||||
<el-input v-model="form.cultureProtocolName" clearable placeholder="请输入方案名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-form-item label="培养天数" prop="days"
|
||||
:rules="[{ required: true, message: '请输入培养天数', trigger: ['blur', 'change'] }]">
|
||||
<el-input-number v-model="form.days" :min="1" style="width: 100%" placeholder="请输入培养天数" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-form-item label="反应器" prop="equReactorId"
|
||||
:rules="[{ required: true, message: '请选择反应器', trigger: ['blur', 'change'] }]">
|
||||
<el-select v-model="form.equReactorId" placeholder="请选择反应器" style="width: 100%">
|
||||
<el-option v-for="item in state.reactorOptions" :key="item.id" :label="item.name"
|
||||
:value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-form-item label="补料秤" prop="equFeedingScaleId"
|
||||
:rules="[{ required: true, message: '请选择补料秤', trigger: ['blur', 'change'] }]">
|
||||
<el-select v-model="form.equFeedingScaleId" placeholder="请选择补料秤" style="width: 100%">
|
||||
<el-option v-for="item in state.scaleOptions" :key="item.id" :label="item.name"
|
||||
:value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-form-item label="初始工作体积" prop="initialWorkingVolume"
|
||||
:rules="[{ required: true, message: '请输入初始工作体积', trigger: ['blur', 'change'] }]">
|
||||
<el-input-number v-model="form.initialWorkingVolume" :min="0" :precision="2" style="width: 100%"
|
||||
placeholder="请输入初始工作体积" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-form-item label="转种细胞体积" prop="transferCellVolume"
|
||||
:rules="[{ required: true, message: '请输入转种细胞体积', trigger: ['blur', 'change'] }]">
|
||||
<el-input-number v-model="form.transferCellVolume" :min="0" :precision="2" style="width: 100%"
|
||||
placeholder="请输入转种细胞体积" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-form-item label="葡萄糖补料验证">
|
||||
<el-switch v-model="form.glucoseFeedingVerification" active-text="是" inactive-text="否" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24">
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 固定补料泵 -->
|
||||
<el-tab-pane label="固定补料泵" name="pumps">
|
||||
<div class="form-section">
|
||||
<el-table :data="form.fixedFeedingPumps" border style="width: 100%">
|
||||
<el-table-column label="补料泵编号" prop="feedingPumpNo" width="120">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.feedingPumpNo" disabled />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-if="state.form.equReactorId && state.reactorOptions.find(r => r.id === state.form.equReactorId)?.needExternalPump === true"
|
||||
label="外置泵"
|
||||
prop="equPumpId"
|
||||
min-width="200"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.equPumpId" placeholder="请选择外置泵" style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in state.pumpOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物料定义袋" prop="itemDefBagID" min-width="200">
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.itemDefBagID" placeholder="请选择物料定义袋" style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in state.bagOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="补料培养基" prop="itemDefFeedingMediumID" min-width="200">
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.itemDefFeedingMediumID" placeholder="请选择补料培养基" style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in state.mediumOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 补料任务 -->
|
||||
<el-tab-pane label="补料任务" name="tasks">
|
||||
<div class="form-section">
|
||||
<div v-for="(task, index) in form.feedingTasks" :key="index" class="task-item">
|
||||
<el-row :gutter="25">
|
||||
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6">
|
||||
<el-form-item :label="index === 0 ? '补料泵编号' : ''"
|
||||
:prop="'feedingTasks.' + index + '.feedingPumpNo'">
|
||||
<el-input-number v-model="task.feedingPumpNo" :min="1" style="width: 100%" placeholder="泵编号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6">
|
||||
<el-form-item :label="index === 0 ? '培养天数' : ''" :prop="'feedingTasks.' + index + '.day'">
|
||||
<el-input-number v-model="task.day" :min="1" style="width: 100%" placeholder="天数" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6">
|
||||
<el-form-item :label="index === 0 ? '补料时间' : ''" :prop="'feedingTasks.' + index + '.feedingTime'">
|
||||
<el-time-picker v-model="task.feedingTime" format="HH:mm" style="width: 100%"
|
||||
placeholder="补料时间" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6">
|
||||
<el-form-item :label="index === 0 ? '补料体积' : ''" :prop="'feedingTasks.' + index + '.feedingVolume'">
|
||||
<el-input-number v-model="task.feedingVolume" :min="0" :precision="2" style="width: 100%"
|
||||
placeholder="补料体积" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-button type="danger" icon="ele-Delete" circle @click="removeTask(index)"
|
||||
v-if="form.feedingTasks.length > 1" />
|
||||
</div>
|
||||
<el-button type="primary" icon="ele-Plus" @click="addTask">添加任务</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 自动葡萄糖补料规则 -->
|
||||
<el-tab-pane label="自动葡萄糖补料规则" name="glucose">
|
||||
<div class="form-section">
|
||||
<div v-for="(rule, index) in form.autoGlucoseFeedingRules" :key="index" class="rule-item">
|
||||
<el-row :gutter="25">
|
||||
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6">
|
||||
<el-form-item :label="index === 0 ? '培养开始天数' : ''"
|
||||
:prop="'autoGlucoseFeedingRules.' + index + '.cultureDayStarting'">
|
||||
<el-input-number v-model="rule.cultureDayStarting" :min="0" style="width: 100%"
|
||||
placeholder="开始天数" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6">
|
||||
<el-form-item :label="index === 0 ? '培养结束天数' : ''"
|
||||
:prop="'autoGlucoseFeedingRules.' + index + '.cultureDayEnding'">
|
||||
<el-input-number v-model="rule.cultureDayEnding" :min="0" style="width: 100%"
|
||||
placeholder="结束天数" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6">
|
||||
<el-form-item :label="index === 0 ? '下限值' : ''"
|
||||
:prop="'autoGlucoseFeedingRules.' + index + '.lowerLimit'">
|
||||
<el-input-number v-model="rule.lowerLimit" :min="0" :precision="2" style="width: 100%"
|
||||
placeholder="下限值" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6">
|
||||
<el-form-item :label="index === 0 ? '补料目标值' : ''"
|
||||
:prop="'autoGlucoseFeedingRules.' + index + '.feedingTo'">
|
||||
<el-input-number v-model="rule.feedingTo" :min="0" :precision="2" style="width: 100%"
|
||||
placeholder="目标值" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-button type="danger" icon="ele-Delete" circle @click="removeRule(index)"
|
||||
v-if="form.autoGlucoseFeedingRules.length > 1" />
|
||||
</div>
|
||||
<el-button type="primary" icon="ele-Plus" @click="addRule">添加规则</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="onSure" size="default" :loading="state.sureLoading">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="admin/culture-protocol/form">
|
||||
import { reactive, toRefs, ref, getCurrentInstance, onMounted } from 'vue'
|
||||
import { CultureProtocolApi } from '/@/api/admin/CultureProtocolApi'
|
||||
import { ReactorApi } from '/@/api/admin/ReactorApi'
|
||||
import { UspscaleApi } from '/@/api/admin/UspscaleApi'
|
||||
import { ItemDefFeedingMediumApi } from '/@/api/admin/item-def-feeding-medium'
|
||||
import { ItemDefBagApi } from '/@/api/admin/item-def-bag'
|
||||
import type { CultureProtocolDto } from '/@/api/types/cultureprotocol'
|
||||
|
||||
const { proxy } = getCurrentInstance() as any
|
||||
|
||||
defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'ok'): void
|
||||
}>()
|
||||
|
||||
const formRef = ref()
|
||||
const state = reactive({
|
||||
showDialog: false,
|
||||
sureLoading: false,
|
||||
activeTab: 'basic',
|
||||
form: {
|
||||
id: 0,
|
||||
cultureProtocolName: '',
|
||||
equReactorId: undefined,
|
||||
equFeedingScaleId: undefined,
|
||||
days: 0,
|
||||
initialWorkingVolume: 0,
|
||||
initialWorkingMediumId: 0,
|
||||
transferCellVolume: 0,
|
||||
transferCellTypeId: 0,
|
||||
glucoseFeedingVerification: true,
|
||||
enabled: true,
|
||||
remark: '',
|
||||
autoGlucoseFeedingRules: [],
|
||||
feedingTasks: [],
|
||||
fixedFeedingPumps: []
|
||||
} as CultureProtocolDto,
|
||||
reactorOptions: [] as Array<{ id: number; name: string; needExternalPump: boolean }>,
|
||||
scaleOptions: [] as Array<{ id: number; name: string }>,
|
||||
mediumOptions: [] as Array<{ id: number; name: string }>,
|
||||
cellTypeOptions: [],
|
||||
bagOptions: [] as Array<{ id: number; name: string }>,
|
||||
pumpOptions: [] as Array<{ id: number; name: string }>,
|
||||
})
|
||||
|
||||
const { form } = toRefs(state)
|
||||
|
||||
onMounted(() => {
|
||||
getReactorOptions()
|
||||
getScaleOptions()
|
||||
getMediumOptions()
|
||||
getBagOptions()
|
||||
})
|
||||
|
||||
// 打开对话框
|
||||
const open = async (row: any = {}, isCopy = false) => {
|
||||
proxy.$modal.loading()
|
||||
|
||||
if (row.id > 0) {
|
||||
const res = await new CultureProtocolApi().get({ id: row.id }, { loading: true })
|
||||
if (res?.success) {
|
||||
let formData = res.data as CultureProtocolDto
|
||||
if (isCopy) {
|
||||
formData.id = 0
|
||||
formData.cultureProtocolName = formData.cultureProtocolName + ' - 副本'
|
||||
}
|
||||
state.form = formData
|
||||
}
|
||||
} else {
|
||||
state.form = {
|
||||
id: 0,
|
||||
cultureProtocolName: '',
|
||||
equReactorId: undefined,
|
||||
equFeedingScaleId: undefined,
|
||||
days: 0,
|
||||
initialWorkingVolume: 0,
|
||||
initialWorkingMediumId: 0,
|
||||
transferCellVolume: 0,
|
||||
transferCellTypeId: 0,
|
||||
glucoseFeedingVerification: true,
|
||||
remark: '',
|
||||
autoGlucoseFeedingRules: [],
|
||||
feedingTasks: [],
|
||||
fixedFeedingPumps: defaultPumps
|
||||
}
|
||||
}
|
||||
|
||||
state.showDialog = true
|
||||
proxy.$modal.closeLoading()
|
||||
}
|
||||
|
||||
// 添加规则
|
||||
const addRule = () => {
|
||||
state.form.autoGlucoseFeedingRules.push({
|
||||
id: 0,
|
||||
cultureProtocolId: 0,
|
||||
cultureDayStarting: 0,
|
||||
cultureDayEnding: 0,
|
||||
lowerLimit: 0,
|
||||
feedingTo: 0,
|
||||
lowerLimitOperator: '',
|
||||
calculationMode: 0
|
||||
})
|
||||
}
|
||||
|
||||
// 移除规则
|
||||
const removeRule = (index: number) => {
|
||||
state.form.autoGlucoseFeedingRules.splice(index, 1)
|
||||
}
|
||||
|
||||
// 添加任务
|
||||
const addTask = () => {
|
||||
state.form.feedingTasks.push({
|
||||
id: 0,
|
||||
cultureProtocolId: 0,
|
||||
feedingPumpNo: 0,
|
||||
day: 0,
|
||||
feedingTime: '',
|
||||
feedingType: 0,
|
||||
feedingVolumePercent: 0,
|
||||
feedingVolume: 0
|
||||
})
|
||||
}
|
||||
|
||||
// 移除任务
|
||||
const removeTask = (index: number) => {
|
||||
state.form.feedingTasks.splice(index, 1)
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSure = async () => {
|
||||
if (!formRef.value) return
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
state.sureLoading = true
|
||||
try {
|
||||
const api = new CultureProtocolApi()
|
||||
const res = state.form.id
|
||||
? await api.update(state.form)
|
||||
: await api.add(state.form)
|
||||
if (res.success) {
|
||||
proxy.$modal.msgSuccess(state.form.id ? '修改成功' : '新增成功')
|
||||
state.showDialog = false
|
||||
emit('ok')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(state.form.id ? '修改失败:' : '新增失败:', error)
|
||||
} finally {
|
||||
state.sureLoading = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 取消按钮
|
||||
const onCancel = () => {
|
||||
state.showDialog = false
|
||||
reset()
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
const reset = () => {
|
||||
if (formRef.value) {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
state.form = {
|
||||
id: 0,
|
||||
cultureProtocolName: '',
|
||||
equReactorId: undefined,
|
||||
equFeedingScaleId: undefined,
|
||||
days: 0,
|
||||
initialWorkingVolume: 0,
|
||||
initialWorkingMediumId: 0,
|
||||
transferCellVolume: 0,
|
||||
transferCellTypeId: 0,
|
||||
glucoseFeedingVerification: true,
|
||||
remark: '',
|
||||
autoGlucoseFeedingRules: [],
|
||||
feedingTasks: [],
|
||||
fixedFeedingPumps: defaultPumps
|
||||
}
|
||||
}
|
||||
|
||||
const getReactorOptions = async () => {
|
||||
try {
|
||||
const res = await new ReactorApi().getPage({
|
||||
currentPage: 1,
|
||||
pageSize: 10000
|
||||
})
|
||||
|
||||
if (res?.success) {
|
||||
state.reactorOptions = res.data?.list?.map(item => ({
|
||||
id: item.id ?? 0,
|
||||
name: item.productID ?? '',
|
||||
needExternalPump: item.isExternalPump === true
|
||||
})) ?? []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取反应器列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const getScaleOptions = async () => {
|
||||
const res = await new UspscaleApi().getPage({
|
||||
currentPage: 1,
|
||||
pageSize: 10000
|
||||
})
|
||||
|
||||
if (res?.success) {
|
||||
state.scaleOptions = res.data?.list?.filter(item => item.isFeedingScale === true).map(item => ({
|
||||
id: item.id ?? 0,
|
||||
name: item.deviceNo ?? ''
|
||||
})) ?? []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取补料培养基列表
|
||||
const getMediumOptions = async () => {
|
||||
const res = await new ItemDefFeedingMediumApi().getPage({
|
||||
currentPage: 1,
|
||||
pageSize: 10000
|
||||
})
|
||||
|
||||
if (res?.success) {
|
||||
state.mediumOptions = res.data?.list?.map(item => ({
|
||||
id: item.id ?? 0,
|
||||
name: item.mediumName ?? ''
|
||||
})) ?? []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取物料定义袋列表
|
||||
const getBagOptions = async () => {
|
||||
const res = await new ItemDefBagApi().getPage({
|
||||
currentPage: 1,
|
||||
pageSize: 10000
|
||||
})
|
||||
|
||||
if (res?.success) {
|
||||
state.bagOptions = res.data?.list?.map(item => ({
|
||||
id: item.id ?? 0,
|
||||
name: item.itemDescription ?? ''
|
||||
})) ?? []
|
||||
}
|
||||
}
|
||||
|
||||
const defaultPumps = [
|
||||
{ id: 0, cultureProtocolId: undefined, configId: undefined, feedingPumpNo: 1, itemDefBagID: undefined, itemDefFeedingMediumID: undefined, equPumpId: undefined },
|
||||
{ id: 0, cultureProtocolId: undefined, configId: undefined, feedingPumpNo: 2, itemDefBagID: undefined, itemDefFeedingMediumID: undefined, equPumpId: undefined },
|
||||
{ id: 0, cultureProtocolId: undefined, configId: undefined, feedingPumpNo: 3, itemDefBagID: undefined, itemDefFeedingMediumID: undefined, equPumpId: undefined },
|
||||
{ id: 0, cultureProtocolId: undefined, configId: undefined, feedingPumpNo: 4, itemDefBagID: undefined, itemDefFeedingMediumID: undefined, equPumpId: undefined },
|
||||
{ id: 0, cultureProtocolId: undefined, configId: undefined, feedingPumpNo: 5, itemDefBagID: undefined, itemDefFeedingMediumID: undefined, equPumpId: undefined },
|
||||
{ id: 0, cultureProtocolId: undefined, configId: undefined, feedingPumpNo: 6, itemDefBagID: undefined, itemDefFeedingMediumID: undefined, equPumpId: undefined },
|
||||
{ id: 0, cultureProtocolId: undefined, configId: undefined, feedingPumpNo: 7, itemDefBagID: undefined, itemDefFeedingMediumID: undefined, equPumpId: undefined },
|
||||
{ id: 0, cultureProtocolId: undefined, configId: undefined, feedingPumpNo: 8, itemDefBagID: undefined, itemDefFeedingMediumID: undefined, equPumpId: undefined }
|
||||
]
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form-section {
|
||||
margin-bottom: 20px;
|
||||
padding: 20px;
|
||||
background-color: #f5f7fa;
|
||||
border-radius: 4px;
|
||||
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20px;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
.rule-item,
|
||||
.task-item,
|
||||
.pump-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.el-button {
|
||||
margin-left: 10px;
|
||||
margin-top: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.mt-2 {
|
||||
margin-top: 8px;
|
||||
}
|
||||
</style>
|
285
src/views/admin/template/index.vue
Normal file
285
src/views/admin/template/index.vue
Normal file
@ -0,0 +1,285 @@
|
||||
<template>
|
||||
<MyLayout>
|
||||
<el-card v-show="state.showQuery" class="my-query-box mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
|
||||
<el-form :inline="true" label-width="auto" @submit.stop.prevent>
|
||||
<el-form-item label="方案名称">
|
||||
<el-input v-model="state.filter.keyWord" placeholder="请输入方案名称" @keyup.enter="onQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="反应器">
|
||||
<el-select v-model="state.filter.equReactorId" placeholder="请选择反应器" clearable style="width: 150px">
|
||||
<el-option
|
||||
v-for="item in state.reactorOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间">
|
||||
<el-date-picker
|
||||
v-model="state.filter.stDate"
|
||||
type="date"
|
||||
placeholder="开始日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 150px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间">
|
||||
<el-date-picker
|
||||
v-model="state.filter.edDate"
|
||||
type="date"
|
||||
placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 150px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="ele-Search" @click="onQuery">查询</el-button>
|
||||
<el-button v-auth="'api:admin:culture-protocol:add'" type="primary" icon="ele-Plus" @click="onAdd">新增</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card class="my-fill mt8" shadow="never">
|
||||
<div class="my-tools-box mb8 my-flex my-flex-between">
|
||||
<div>
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
v-if="state.showProtocolList"
|
||||
:data="state.protocolListData"
|
||||
style="width: 100%"
|
||||
v-loading="state.loading"
|
||||
row-key="id"
|
||||
border
|
||||
>
|
||||
<el-table-column prop="cultureProtocolName" label="方案名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="days" label="培养天数" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column prop="initialWorkingVolume" label="初始工作体积" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="葡萄糖补料验证" width="150" align="center" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<el-tag type="success" v-if="row.glucoseFeedingVerification">是</el-tag>
|
||||
<el-tag type="info" v-else>否</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100" align="center" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<el-tag type="success" v-if="row.enabled">启用</el-tag>
|
||||
<el-tag type="danger" v-else>禁用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createdUserName" label="创建者" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column prop="createdTime" label="创建时间" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="240" fixed="right" header-align="center" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-if="auth('api:admin:culture-protocol:update')"
|
||||
icon="ele-EditPen"
|
||||
size="small"
|
||||
text
|
||||
type="primary"
|
||||
@click="onEdit(row)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="auth('api:admin:culture-protocol:copy')"
|
||||
icon="ele-CopyDocument"
|
||||
size="small"
|
||||
text
|
||||
type="success"
|
||||
@click="onCopy(row)"
|
||||
>复制</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="auth('api:admin:culture-protocol:soft-delete')"
|
||||
icon="ele-Delete"
|
||||
size="small"
|
||||
text
|
||||
type="danger"
|
||||
@click="onDelete(row)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="my-flex my-flex-end" style="margin-top: 10px">
|
||||
<el-pagination
|
||||
v-model:currentPage="state.pageInput.currentPage"
|
||||
v-model:page-size="state.pageInput.pageSize"
|
||||
:total="state.total"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
size="small"
|
||||
background
|
||||
@size-change="onSizeChange"
|
||||
@current-change="onCurrentChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<culture-protocol-form ref="protocolFormRef" :title="state.protocolFormTitle" @ok="Query" />
|
||||
</MyLayout>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="admin/culture-protocol">
|
||||
import { ref, reactive, onMounted, getCurrentInstance, onBeforeMount, defineAsyncComponent } from 'vue'
|
||||
import { CultureProtocolApi } from '/@/api/admin/CultureProtocolApi'
|
||||
import type { CultureProtocolDto, CultureProtocolPageInput, CultureProtocolPageDto } from '/@/api/types/cultureprotocol'
|
||||
import eventBus from '/@/utils/mitt'
|
||||
import { auth } from '/@/utils/authFunction'
|
||||
import { ReactorApi } from '/@/api/admin/ReactorApi'
|
||||
|
||||
// 引入组件
|
||||
const CultureProtocolForm = defineAsyncComponent(() => import('./components/culture-protocol-form.vue'))
|
||||
|
||||
const { proxy } = getCurrentInstance() as any
|
||||
|
||||
const protocolFormRef = ref()
|
||||
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
protocolFormTitle: '',
|
||||
filter: {
|
||||
keyWord: '',
|
||||
stDate: '',
|
||||
edDate: '',
|
||||
equReactorId: null as number | null
|
||||
},
|
||||
total: 0,
|
||||
pageInput: {
|
||||
currentPage: 1,
|
||||
pageSize: 20,
|
||||
} as CultureProtocolPageInput,
|
||||
protocolListData: [] as Array<CultureProtocolPageDto>,
|
||||
showQuery: true,
|
||||
showProtocolList: true,
|
||||
reactorOptions: [] as Array<{ id: number; name: string }>,
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
Query()
|
||||
getReactorOptions()
|
||||
})
|
||||
|
||||
const onQuery = () => {
|
||||
Query()
|
||||
}
|
||||
|
||||
const Query = async () => {
|
||||
state.loading = true
|
||||
state.pageInput.filter = state.filter
|
||||
const res = await new CultureProtocolApi().getPage(state.pageInput).catch(() => {
|
||||
state.loading = false
|
||||
})
|
||||
|
||||
state.protocolListData = res?.data?.list ?? []
|
||||
state.total = res?.data?.total ?? 0
|
||||
state.loading = false
|
||||
}
|
||||
|
||||
const onAdd = () => {
|
||||
state.protocolFormTitle = '新增培养方案'
|
||||
protocolFormRef.value?.open()
|
||||
}
|
||||
|
||||
const onEdit = (row: CultureProtocolDto) => {
|
||||
state.protocolFormTitle = '编辑培养方案'
|
||||
protocolFormRef.value?.open(row)
|
||||
}
|
||||
|
||||
const onCopy = (row: CultureProtocolDto) => {
|
||||
state.protocolFormTitle = '复制培养方案'
|
||||
protocolFormRef.value?.open(row, true)
|
||||
}
|
||||
|
||||
const onDelete = (row: CultureProtocolDto) => {
|
||||
proxy.$modal.confirm('确认要删除该记录吗?').then(async () => {
|
||||
try {
|
||||
const res = await new CultureProtocolApi().softDelete({ id: row.id! })
|
||||
if (res.success) {
|
||||
proxy.$modal.msgSuccess('删除成功')
|
||||
Query()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('删除失败:', error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const onSizeChange = (val: number) => {
|
||||
state.pageInput.pageSize = val
|
||||
Query()
|
||||
}
|
||||
|
||||
const onCurrentChange = (val: number) => {
|
||||
state.pageInput.currentPage = val
|
||||
Query()
|
||||
}
|
||||
|
||||
const getReactorOptions = async () => {
|
||||
try {
|
||||
const res = await new ReactorApi().getPage({
|
||||
currentPage: 1,
|
||||
pageSize: 10000
|
||||
})
|
||||
|
||||
if (res?.success) {
|
||||
state.reactorOptions = res.data?.list?.map(item => ({
|
||||
id: item.id ?? 0,
|
||||
name: item.productID ?? ''
|
||||
})) ?? []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取反应器列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const getReactorDescription = async (reactorId: number) => {
|
||||
return state.reactorOptions.find(item => item.id === reactorId)?.name ?? ''
|
||||
}
|
||||
|
||||
const onReset = () => {
|
||||
state.filter = {
|
||||
keyWord: '',
|
||||
stDate: '',
|
||||
edDate: '',
|
||||
equReactorId: null
|
||||
}
|
||||
onQuery()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.my-query-box {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.my-fill {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.my-flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.my-flex-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.my-flex-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.mt8 {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.mb8 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
@ -1,137 +0,0 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" :title="title" width="500px" append-to-body destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-form-item label="反应器名称" prop="reactorName">
|
||||
<el-input v-model="form.reactorName" placeholder="请输入反应器名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="反应器类型" prop="reactorType">
|
||||
<el-select v-model="form.reactorType" placeholder="请选择反应器类型" style="width: 100%">
|
||||
<el-option v-for="item in reactorTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio :label="true">启用</el-radio>
|
||||
<el-radio :label="false">禁用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { ReactorApi } from '../../../../api/admin/ReactorApi'
|
||||
import type { ReactorDto, ReactorTypeEnumItem } from '../../../../api/types/reactorType'
|
||||
|
||||
const props = defineProps<{
|
||||
title: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'ok'): void
|
||||
}>()
|
||||
|
||||
const visible = ref(false)
|
||||
const formRef = ref()
|
||||
const reactorTypeOptions = ref<ReactorTypeEnumItem[]>([])
|
||||
|
||||
const form = reactive<ReactorDto>({
|
||||
reactorName: '',
|
||||
reactorType: '',
|
||||
status: true
|
||||
})
|
||||
|
||||
const rules = {
|
||||
reactorName: [
|
||||
{ required: true, message: '请输入反应器名称', trigger: 'blur' },
|
||||
{ min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
|
||||
],
|
||||
reactorType: [
|
||||
{ required: true, message: '请选择反应器类型', trigger: 'change' }
|
||||
],
|
||||
status: [
|
||||
{ required: true, message: '请选择状态', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
|
||||
/** 获取反应器类型枚举列表 */
|
||||
const getReactorTypeOptions = async () => {
|
||||
try {
|
||||
const res = await new ReactorApi().getReactorTypeEnumList()
|
||||
reactorTypeOptions.value = res.data ?? []
|
||||
} catch (error) {
|
||||
console.error('获取反应器类型枚举列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = (row?: ReactorDto) => {
|
||||
visible.value = true
|
||||
if (row) {
|
||||
Object.assign(form, row)
|
||||
}
|
||||
}
|
||||
|
||||
/** 提交表单 */
|
||||
const submitForm = async () => {
|
||||
if (!formRef.value) return
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
try {
|
||||
const api = new ReactorApi()
|
||||
const res = form.id
|
||||
? await api.update(form)
|
||||
: await api.add(form)
|
||||
if (res.success) {
|
||||
ElMessage.success(form.id ? '修改成功' : '新增成功')
|
||||
visible.value = false
|
||||
emit('ok')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(form.id ? '修改失败:' : '新增失败:', error)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
visible.value = false
|
||||
reset()
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const reset = () => {
|
||||
if (formRef.value) {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: undefined,
|
||||
reactorName: '',
|
||||
reactorType: '',
|
||||
status: true
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getReactorTypeOptions()
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
@ -1,224 +0,0 @@
|
||||
<template>
|
||||
<my-layout>
|
||||
<el-card class="my-query-box mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
|
||||
<el-form :inline="true" label-width="auto" :label-position="'left'" @submit.stop.prevent>
|
||||
<el-form-item label="反应器名称" prop="reactorName">
|
||||
<el-input v-model="state.filter.keyWord" placeholder="请输入反应器名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="反应器类型" prop="reactorType">
|
||||
<el-select v-model="state.filter.reactorType" placeholder="请选择反应器类型" clearable style="width: 200px">
|
||||
<el-option v-for="item in state.reactorTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="state.filter.status" placeholder="请选择状态" clearable style="width: 200px">
|
||||
<el-option label="启用" :value="true" />
|
||||
<el-option label="禁用" :value="false" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间">
|
||||
<el-date-picker v-model="state.filter.startTime" type="datetime" placeholder="选择开始时间"
|
||||
format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" style="width: 180px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间">
|
||||
<el-date-picker v-model="state.filter.endTime" type="datetime" placeholder="选择结束时间"
|
||||
format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" style="width: 180px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="ele-Search" @click="handleQuery">查询</el-button>
|
||||
<el-button v-auth="'api:admin:reactor:add'" type="primary" icon="ele-Plus" @click="handleAdd">新增</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card class="my-fill mt8" shadow="never">
|
||||
<el-table v-loading="loading" :data="state.reactorList" row-key="id" style="width: 100%" border>
|
||||
<el-table-column prop="reactorName" label="反应器名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="反应器类型" min-width="120" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
{{ getReactorTypeName(row.reactorType) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.status ? 'success' : 'danger'">
|
||||
{{ row.status ? '启用' : '禁用' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createdUserName" label="创建者" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column prop="createdTime" label="创建时间" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="180" fixed="right" header-align="center" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button v-auth="'api:admin:reactor:update'" icon="ele-EditPen" size="small" text type="primary"
|
||||
@click="handleEdit(row)">编辑</el-button>
|
||||
<el-button v-auth="'api:admin:reactor:soft-delete'" icon="ele-Delete" size="small" text type="danger"
|
||||
@click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="my-flex my-flex-end" style="margin-top: 10px">
|
||||
<el-pagination v-model:current-page="state.pageInput.currentPage" v-model:page-size="state.pageInput.pageSize"
|
||||
:total="state.total" :page-sizes="[10, 20, 50, 100]" size="small" background @size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange" layout="total, sizes, prev, pager, next, jumper" />
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<reactor-form ref="formRef" :title="state.formTitle" @ok="getList" />
|
||||
</my-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, onBeforeMount } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { ReactorApi } from '../../../api/admin/ReactorApi'
|
||||
import eventBus from '/@/utils/mitt'
|
||||
import type {
|
||||
ReactorPageInput,
|
||||
ReactorDto,
|
||||
ReactorTypeEnumItem
|
||||
} from '../../../api/types/reactorType'
|
||||
|
||||
import ReactorForm from './components/reactor-form.vue'
|
||||
|
||||
const loading = ref(false)
|
||||
const formRef = ref()
|
||||
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
formTitle: '',
|
||||
total: 0,
|
||||
filter: {
|
||||
keyWord: "",
|
||||
reactorType: "",
|
||||
status: null,
|
||||
startTime: "",
|
||||
endTime: ""
|
||||
},
|
||||
pageInput: {
|
||||
currentPage: 1,
|
||||
pageSize: 20,
|
||||
} as ReactorPageInput,
|
||||
reactorList: [] as Array<ReactorDto>,
|
||||
reactorTypeOptions: [] as ReactorTypeEnumItem[]
|
||||
})
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
state.pageInput.filter = state.filter
|
||||
try {
|
||||
const res = await new ReactorApi().getPage(state.pageInput)
|
||||
state.reactorList = res.data?.list || []
|
||||
state.total = res.data?.total || 0
|
||||
} catch (error) {
|
||||
console.error('获取列表失败:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取反应器类型枚举列表 */
|
||||
const getReactorTypeOptions = async () => {
|
||||
try {
|
||||
const res = await new ReactorApi().getReactorTypeEnumList()
|
||||
state.reactorTypeOptions = res.data ?? []
|
||||
} catch (error) {
|
||||
console.error('获取反应器类型枚举列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const getReactorTypeName = (reactorType: string) => {
|
||||
const item = state.reactorTypeOptions.find(item => item.value === Number(reactorType))
|
||||
return item?.label || ''
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
state.pageInput.currentPage = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
state.formTitle = '新增反应器'
|
||||
formRef.value?.open()
|
||||
}
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleEdit = (row: ReactorDto) => {
|
||||
state.formTitle = '编辑反应器'
|
||||
formRef.value?.open(row)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = (row: ReactorDto) => {
|
||||
ElMessageBox.confirm('确认要删除该记录吗?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
try {
|
||||
const res = await new ReactorApi().softDelete({ id: row.id! })
|
||||
if (res.success) {
|
||||
ElMessage.success('删除成功')
|
||||
getList()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('删除失败:', error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** 每页条数改变 */
|
||||
const handleSizeChange = (val: number) => {
|
||||
state.pageInput.pageSize = val
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 当前页改变 */
|
||||
const handleCurrentChange = (val: number) => {
|
||||
state.pageInput.currentPage = val
|
||||
getList()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getReactorTypeOptions()
|
||||
getList()
|
||||
eventBus.on('refreshReactor', getList)
|
||||
})
|
||||
|
||||
onBeforeMount(() => {
|
||||
eventBus.off('refreshReactor')
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.my-query-box {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.my-fill {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.my-flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.my-flex-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.mt8 {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.mb8 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user