|
|
- <template>
- <div class="step-container">
- <el-button v-if="isShowAddStep()" type="primary" @click="addStep" icon="el-icon-plus">添加步骤</el-button>
- <div class="step-list">
- <draggable v-model="steps" ghost-class="ghost" handle=".drag-handle" @end="onDragEnd" :animation="200">
- <div v-for="(step, index) in steps" :key="step.id" class="step-list-item">
- <div class="step-content">
- <i class="el-icon-rank drag-handle" v-if="templateFillType === 'preFill'" style="cursor: move; margin-right: 10px; margin-top: 6px;"></i>
- <span class="step-title">{{ index + 1 }}</span>
- <HandleFormItem type="select" placeholder="请选择" class="step-type-select" :item="stepSelectConfig"
- v-model="step.type" @change="onTypeChange(index)" />
- <!-- 根据步骤类型显示对应的表单 -->
- <component class="flex1" :sn="step.type" :is="getStepComponent(step.type)" :formData="step.formData"
- @update="onFormUpdate(index, $event)" :stepIndex = "index" :ref="'stepCompRef_' + index">
- </component>
- <div v-if="templateFillType === 'preFill'" class="step-header-item">
- <el-popconfirm
- @confirm="removeStep(index)"
- title="确定删除当前步骤吗?"
- >
- <el-button type="text" slot="reference" icon="el-icon-delete"
- class="delete-btn"></el-button>
- </el-popconfirm>
- </div>
- </div>
- </div>
- </draggable>
- </div>
- </div>
- </template>
-
- <script>
- import draggable from 'vuedraggable';
- import { duplicateResource,justUpdateFilledFormData } from '@/utils/index.js';
- import HandleFormItem from './HandleFormItem.vue';
- import Czdd from './StepComponents/ry/czdd.vue';//溶液-操作地点
- import Czhj from './StepComponents/ry/czhj.vue';//溶液-操作方法
- import Xzrq from './StepComponents/ry/xzrq.vue';//溶液-选择容器
- import Jrry from './StepComponents/ry/jrry.vue';//溶液-加入溶液
- import Tpjydd from './StepComponents/ry/tpjydd.vue';//溶液-天平校验(单点)
- import Tpjysd from './StepComponents/ry/tpjysd.vue';//溶液-天平校验(双点)
- import Qywz from './StepComponents/ry/qywz.vue';//溶液-取用物质
- import Clfcz from './StepComponents/ry/clfcz.vue';//溶液-称量(非传值)
- import Clcz from './StepComponents/ry/clcz.vue';//溶液-称量(传值)
- import Bdtj from './StepComponents/ry/bdtj.vue';//溶液-标定(体积)
- import Bdzl from './StepComponents/ry/bdzl.vue';//溶液-标定(质量)
- import Tjphcz from './StepComponents/ry/tjphcz.vue';//溶液-调节PH(传值)
- import Tjphfcz from './StepComponents/ry/tjphfcz.vue';//溶液-调节PH(非传值)
- import Lx from './StepComponents/ry/lx.vue';//溶液-离心
- import Hwhy from './StepComponents/ry/hwhy.vue';//溶液-恒温混匀
- import Zyhy from './StepComponents/ry/zyhy.vue';//溶液-振摇混匀
- import Wxhy from "./StepComponents/ry/wxhy.vue";//溶液-涡旋混匀
- import Ddhy from "./StepComponents/ry/ddhy.vue";//溶液-颠倒混匀
- import Ym from "./StepComponents/ry/ym.vue";//溶液-研磨
- import Jb from "./StepComponents/ry/jb.vue";//溶液-搅拌
- import Jrjb from "./StepComponents/ry/jrjb.vue";//溶液-加热搅拌
- import Cs from "./StepComponents/ry/cs.vue";//溶液-超声
- import Sy from "./StepComponents/ry/sy.vue";//溶液-水浴
- import Zy from "./StepComponents/ry/zy.vue";//溶液-正压
- import Dc from "./StepComponents/ry/dc.vue";//溶液-氮吹
- import Jd from "./StepComponents/ry/jd.vue";//溶液-解冻
- import Jz from "./StepComponents/ry/jz.vue";//溶液-静置
- import Glzd from "./StepComponents/ry/glzd.vue";//溶液-过滤(自动)
- import Glsd from "./StepComponents/ry/glsd.vue";//溶液-过滤(手动)
- import Fy from "./StepComponents/ry/fy.vue";//溶液-孵育
- import Qcyy from "./StepComponents/ry/qcyy.vue";//溶液-取出原药
- import Frdrq from "./StepComponents/ry/frdrq.vue";//溶液-复溶(多容器)
- import Fr from "./StepComponents/ry/fr.vue";//溶液-复溶
- import Hb from "./StepComponents/ry/hb.vue";//溶液-合并
- import Rs from "./StepComponents/ry/rs.vue";//溶液-染色
- import Js from "./StepComponents/ry/js.vue";//溶液-计数
- import Mj from "./StepComponents/ry/mj.vue";//溶液-灭菌
- import Fs from "./StepComponents/ry/fs.vue";//溶液-复苏
- import Fb from "./StepComponents/ry/fb.vue";//溶液-封板
- import Zlfz from "./StepComponents/ry/zlfz.vue";//溶液-质量分装
-
- //罗开凡新增
- import kbyq from "./StepComponents/ry/kbyq.vue";//溶液-空白仪器
- import kbsjgsp from "./StepComponents/ry/kbsjgsp.vue";//溶液-空白(试剂/供试品)
- import kb from "./StepComponents/ry/kb.vue";//溶液-空白
- import jr from "./StepComponents/ry/jr.vue";//溶液-加热
- //罗开凡新增
-
- //表配置
- import jrry_b from './StepComponents/b/jrry_b.vue';//表配置-加入溶液
- //表配置-离心:使用溶液-离心
- import cl from './StepComponents/b/cl.vue';//表配置-称量
- //表配置-超声:使用溶液-超声
- //表配置-恒温混匀:使用溶液-恒温混匀
- //表配置-振摇混匀:使用溶液-振摇混匀
- //表配置-涡旋混匀:使用溶液-涡旋混匀
- //表配置-颠倒混匀:使用溶液-颠倒混匀
-
- //表配置-搅拌:使用溶液-搅拌
- //表配置-加热搅拌:使用溶液-加热搅拌
- //表配置-水浴:使用溶液-水浴
- //表配置-正压:使用溶液-正压
- //表配置-氮吹:使用溶液-氮吹
- //表配置-过滤(自动):使用溶液-过滤(自动)
- //表配置-过滤(手动):使用溶液-过滤(手动)
- //表配置-静置:使用溶液-静置
- //表配置-解冻:使用溶液-解冻
- //表配置-孵育:使用溶液-孵育
- //表配置-复溶:使用溶液-复溶
-
-
- //生物样品分析
- //生物样品分析-解冻:使用溶液-解冻
- //生物样品分析-涡旋混匀:使用溶液-涡旋混匀
- //生物样品分析-选择容器:使用溶液-选择容器
- import jryp from './StepComponents/swypfx/jryp.vue';//生物样品分析-加入样品
- //生物样品分析-衍生反应:使用溶液-离心
- import hhspe from './StepComponents/swypfx/hhspe.vue';//生物样品分析-活化(SPE)
- //生物样品分析-平衡(SPE):使用溶液-活化(SPE)
- //生物样品分析-上样(SPE):使用溶液-活化(SPE)
- //生物样品分析-淋洗(SPE):使用溶液-活化(SPE)
- //生物样品分析-洗脱(SPE):使用溶液-活化(SPE)
- import zyfc from './StepComponents/swypfx/zyfc.vue';//生物样品分析-转移(分层)
- //生物样品分析-氮吹:使用溶液-氮吹
- //生物样品分析-正压:使用溶液-正压
- //生物样品分析-孵育:使用溶液-孵育
- //生物样品分析-复溶:使用溶液-复溶
-
-
-
- //色谱匀浆组织表
- import jszz from './StepComponents/spyjzzb/jszz.vue';//色谱匀浆组织表-剪碎组织
- //色谱匀浆组织表-称取组织:使用色谱匀浆组织表-剪碎组织
- //色谱匀浆组织表-匀浆液混合:使用色谱匀浆组织表-剪碎组织
-
- import { public_templateStepList } from '@/api/business/public/public';
-
-
- // const stepTypes = [
- // { label: '操作地点', value: 'czdd' },
- // { label: '操作方法', value: 'czhj' },
- // { label: '选择容器', value: 'xzrq' },
- // { label: '加入溶液', value: 'jrry' },
- // { label: '天平校验(单点)', value: 'tpjydd' },
- // { label: '天平校验(双点)', value: 'tpjysd' },
- // { label: '取用物质', value: 'qywz' },
- // { label: '称量(非传值)', value: 'clfcz' },
- // { label: '称量(传值)', value: 'clcz' },
- // { label: '标定(体积)', value: 'bdtj' },
- // { label: '标定(质量)', value: 'bdzl' },
- // { label: '调节PH(传值)', value: 'tjphcz' },
- // { label: '调节PH(非传值)', value: 'tjphfcz' },
- // { label: '离心', value: 'lx' },
- // { label: '恒温混匀', value: 'hwhy' },
- // { label: '振摇混匀', value: 'zyhy' },
- // { label: '涡旋混匀', value: 'wxhy' },
- // { label: '颠倒混匀', value: 'ddhy' },
- // { label: '研磨', value: 'ym' },
- // { label: '搅拌', value: 'jb' },
- // { label: '加热搅拌', value: 'jrjb' },
- // { label: '超声', value: 'cs' },
- // { label: '水浴', value: 'sy' },
- // { label: '正压', value: 'zy' },
- // { label: '氮吹', value: 'dc' },
- // { label: '解冻', value: 'jd' },
- // { label: '静置', value: 'jz' },
- // { label: '过滤(自动)', value: 'glzd' },
- // { label: '过滤(手动)', value: 'glsd' },
- // { label: '孵育', value: 'fy' },
- // { label: '取出原药', value: 'qcyy' },
- // { label: '复溶(多容器)', value: 'frdrq' },
- // { label: '复溶', value: 'fr' },
- // { label: '合并', value: 'hb' },
- // { label: '染色', value: 'rs' },
- // { label: '计数', value: 'js' },
- // { label: '灭菌', value: 'mj' },
- // { label: '复苏', value: 'fs' },
- // { label: '封板', value: 'fb' },
- // { label: '质量分装', value: 'zlfz' },
-
- // ];
-
- export default {
- inject: ['templateFillType','templateData'],
- name: 'Step',
- props: {
- formData: {
- type: Array,
- default: () => []
- }
- },
- data() {
- return {
- stepSelectConfig: {
- options: [],
- fillType: "preFill",
- placeholder: "请选择步骤类型"
- },
- steps: [],
- stepId: 1,
- componentMap: null
- }
- },
- components: {
- draggable,
- HandleFormItem,
- Czdd,
- Czhj,
- Xzrq,
- Jrry,
- Tpjydd,
- Tpjysd,
- Qywz,
- Clfcz,
- Clcz,
- Bdtj,
- Bdzl,
- Tjphcz,
- Tjphfcz,
- Lx,
- Hwhy,
- Zyhy,
- Wxhy,
- Ddhy,
- Ym,
- Jb,
- Jrjb,
- Cs,
- Sy,
- Zy,
- Dc,
- Jd,
- Jz,
- Glzd,
- Glsd,
- Fy,
- Qcyy,
- Frdrq,
- Fr,
- Hb,
- Rs,
- Js,
- Mj,
- Fs,
- Fb,
- Zlfz,
- //罗开凡新增
- kbyq,
- kbsjgsp,
- kb,
- jr,
- //罗开凡新增
-
- //表配置
- jrry_b,
- cl,
-
- //生物样品分析
- jryp,
- hhspe,
- zyfc,
-
- //色谱匀浆组织表
- jszz,
- },
- computed: {
- stepComponentMap() {
- if (!this.componentMap) {
- this.componentMap = {
- 'czdd': 'Czdd',
- 'czhj': 'Czhj',
- 'xzrq': 'Xzrq',
- 'jrry': 'Jrry',
- 'tpjydd': 'Tpjydd',
- 'tpjysd': 'Tpjysd',
- 'qywz': 'Qywz',
- 'clfcz': 'Clfcz',
- 'clcz': 'Clcz',
- 'bdtj': 'Bdtj',
- 'bdzl': 'Bdzl',
- 'tjphcz': 'Tjphcz',
- 'tjphfcz': 'Tjphfcz',
- 'lx': 'Lx',
- 'hwhy': 'Hwhy',
- 'zyhy': 'Zyhy',
- 'wxhy': 'Wxhy',
- 'ddhy': 'Ddhy',
- 'ym': 'Ym',
- 'jb': 'Jb',
- 'jrjb': 'Jrjb',
- 'sy': 'Sy',
- 'zy': 'Zy',
- 'cs': 'Cs',
- 'dc': 'Dc',
- 'jd': 'Jd',
- 'jz': 'Jz',
- 'glzd': 'Glzd',
- 'glsd': 'Glsd',
- 'fy': 'Fy',
- 'qcyy': 'Qcyy',
- 'frdrq': 'Frdrq',
- 'fr': 'Fr',
- 'hb': 'Hb',
- 'rs': 'Rs',
- 'js': 'Js',
- 'mj': 'Mj',
- 'fs': 'Fs',
- 'fb': 'Fb',
- 'zlfz': 'Zlfz',
-
- //罗开凡新增
- 'kbyq': 'kbyq',
- 'kbsjgsp': 'kbsjgsp',
- 'kb': 'kb',
- 'jr': 'jr',
- // 'fz': 'fz',
- //罗开凡新增
-
- //标配配置
- 'jrry_b': 'jrry_b',
- 'cl': 'cl',
- 'lx_b': 'Lx',
- 'cs_b': 'Cs',
- 'hwhy_b': 'Hwhy',
- 'zyhy_b': 'Zyhy',
- 'wxhy_b': 'Wxhy',
- 'ddhy_b': 'Ddhy',
-
- 'jb_b': 'Jb',
- 'jrjb_b': 'Jrjb',
- 'sy_b': 'Sy',
- 'zy_b': 'Zy',
- 'dc_b': 'Dc',
- 'glzd_b': 'Glzd',
- 'glsd_b': 'Glsd',
- 'jz_b': 'Jz',
- 'jd_b': 'Jd',
- 'fy_b': 'Fy',
- 'fr_b': 'Fr',
-
- //生物样品分析
- 'jd_swypfx': 'Jd',
- 'jryp': 'jryp',
- 'ysfy': 'Lx',
- 'hhspe': 'hhspe',
-
- 'phspe': 'hhspe',
- 'syspe': 'hhspe',
- 'lxspe': 'hhspe',
- 'xtspe': 'hhspe',
- 'zyfc': 'zyfc',
-
-
- //色谱匀浆组织表
- 'jszz':'jszz',
- 'cqzz':'jszz',
- 'yjyhh':'jszz',
-
- }
- }
- return this.componentMap
- }
- },
-
- created() {
- // // 初始化步骤数据
- // if (this.value && this.value.length > 0) {
- // this.steps = this.value.map((step) => ({
- // id: this.stepId++,
- // type: step.type || '',
- // formData: step.formData || {}
- // }))
- // } else {
- // // 默认添加一个步骤
- // this.addStep()
- // }
- this.getStepList()
- },
- watch: {
- // steps: {
- // handler(newVal) {
- // this.$emit('input', newVal);
- // },
- // deep: true
- // },
- formData: {
- handler(newVal) {
- if (!newVal || newVal.length === 0) return
- this.steps = newVal;
- },
- deep: true,
- immediate: true
- }
- },
- methods: {
- onDragEnd(evt) {
- justUpdateFilledFormData();
- },
-
- getStepList(){
- public_templateStepList({templateId:this.templateData.templateId}).then(response => {
- let options = []
- _.forEach(response.data,(item)=>{
- options.push({ label: item.name, value: item.sn })
- })
- this.stepSelectConfig.options = options
- });
- },
- isShowAddStep() {
- return this.templateFillType === 'preFill';
- },
- addStep() {
- try {
- this.steps.push({
- id: this.stepId++,
- type: '',
- formData: {}
- })
- this.$emit('step-added', this.steps.length)
- } catch (error) {
- console.error('添加步骤失败:', error)
- this.$message.error('添加步骤失败,请重试')
- }
- },
-
- removeStep(index) {
-
- if (this.steps.length > 1) {
- const removedStep = this.steps.splice(index, 1)[0]
- this.$emit('step-removed', { index, step: removedStep, remaining: this.steps.length })
- } else {
- this.$message.warning('至少需要保留一个步骤')
- }
- },
-
- onTypeChange(index) {
- // 切换步骤类型时重置表单数据,并确保数据更新
- const oldType = this.steps[index].type
- this.$set(this.steps[index], 'formData', {})
- // 可选:添加类型变化的回调
- this.$emit('step-type-changed', {
- index,
- newType: this.steps[index].type,
- oldType
- })
- },
-
- onFormUpdate(stepIndex, formData) {
- this.steps[stepIndex].formData = formData
- },
-
- getStepComponent(type) {
- // 使用计算属性中的映射,提高性能
- return this.stepComponentMap[type]
- },
-
- // 公共方法:获取所有步骤数据
- getFormData() {
- return new Promise(async (resolve, reject) => {
- // 检查是否有步骤数据
- if (this.steps.length === 0) {
- // this.$message.error(this.$t('template.common.addStepError'))
- reject({ errorType: "step" });
- return
- }
-
- try {
- const stepData = await Promise.all(
- this.steps.map(async (step, index) => {
- const stepComponentRef = this.$refs[`stepCompRef_${index}`];
- if (stepComponentRef && stepComponentRef.length > 0) {
- try {
- const stepFormData = await stepComponentRef[0].getFormData();
- return { type: step.type, formData: stepFormData }
- } catch (error) {
- // 如果某个步骤的getFormData方法失败,抛出错误
- throw error;
- }
- } else {
- // 如果没有找到组件引用,返回原始数据
- return { type: step.type, formData: step.formData }
- }
- })
- );
- resolve({ stepData });
- } catch (error) {
- reject(error);
- }
- })
- },
- getStepResource(){
- const sj = [];
- let yq = [];
- this.steps.map((step, index) => {
- const stepComponentRef = this.$refs[`stepCompRef_${index}`];
- if(stepComponentRef && stepComponentRef.length > 0){
- const {sjResource,yqResource} = this.$refs[`stepCompRef_${index}`][0]?.getSjResource();
- if(sjResource && sjResource.length > 0){
- sj.push(...sjResource);
- }
- if(yqResource && yqResource.length > 0){
- yq.push(...yqResource);
- }
- }
- })
- const resource = duplicateResource(sj, yq);
- return { sjResource: resource.sj, yqResource: resource.yq };
- },
-
- // 直接获取表单数据,不做校验
- getFilledFormData() {
- const stepData = this.steps.map((step, index) => {
- const stepComponentRef = this.$refs[`stepCompRef_${index}`];
- if(stepComponentRef && stepComponentRef.length > 0){
- const stepFormData = this.$refs[`stepCompRef_${index}`][0]?.getFilledFormData();
- return { type: step.type, formData: stepFormData }
- }else{
- return { type: step.type, formData: step.formData }
- }
- })
- return { stepData }
- },
-
- // 公共方法:设置步骤数据
- setStepData(data) {
- if (Array.isArray(data)) {
- this.steps = data.map(step => ({
- id: this.stepId++,
- type: step.type || '',
- formData: step.formData || {}
- }))
- }
- },
-
- // 公共方法:重置所有步骤
- resetSteps() {
- this.steps = [{
- id: this.stepId++,
- type: '',
- formData: {}
- }]
- this.$emit('steps-reset')
- },
-
- // 公共方法:获取指定步骤的数据
- getStepDataByIndex(index) {
- if (index >= 0 && index < this.steps.length) {
- return {
- type: this.steps[index].type,
- formData: this.steps[index].formData
- }
- }
- return null
- },
-
- // 公共方法:验证所有步骤
- async validateSteps() {
- const errors = []
- for (let index = 0; index < this.steps.length; index++) {
- const step = this.steps[index];
-
- if (!step.type) {
- errors.push(`步骤 ${index + 1}: 请选择步骤类型`)
- continue;
- }
-
- // 获取当前步骤的组件实例
- const stepComponentRef = this.$refs[`stepCompRef_${index}`];
- if (stepComponentRef && stepComponentRef.length > 0) {
- try {
- // 调用子组件的getFormData方法进行验证(不抛出错误,只验证)
- await stepComponentRef[0].validateAndMarkRed();
- } catch (error) {
- // validateAndMarkRed方法不应该抛出错误,但如果有的话捕获它
- console.error(`步骤 ${index + 1} 验证时出错:`, error);
- }
- }
- }
- return {
- isValid: errors.length === 0,
- errors
- }
- },
-
- // 公共方法:批量导入步骤数据
- importSteps(stepDataArray) {
- if (Array.isArray(stepDataArray)) {
- this.steps = stepDataArray.map((step, index) => ({
- id: this.stepId++,
- type: step.type || '',
- formData: step.formData || {}
- }))
- this.$emit('steps-imported', this.steps.length)
- }
- },
-
- // 公共方法:获取步骤统计信息
- getStepStatistics() {
- const stats = {
- total: this.steps.length,
- byType: {},
- filled: 0
- }
-
- this.steps.forEach(step => {
- // 统计各类型数量
- if (step.type) {
- stats.byType[step.type] = (stats.byType[step.type] || 0) + 1
- }
-
- // 统计已填写的步骤
- if (step.type && Object.keys(step.formData).length > 0) {
- stats.filled++
- }
- })
-
- return stats
- }
- },
-
- }
- </script>
-
- <style lang="scss" scoped>
- .step-container {
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
- margin-top: 24px;
- padding: 24px;
- border-radius: 5px 5px;
-
- .step-header {
- margin-bottom: 20px;
- padding: 15px;
- background: #f5f7fa;
- border-radius: 6px;
- }
- .flex1 {
- flex:1
- }
- .step-list {
- padding-top: 10px;
- .step-list-item {
- page-break-inside: avoid;
- padding-top: 10px;
- border-radius: 6px;
- overflow: hidden;
- transition: background-color 0.2s;
-
- &:hover {
- // background-color: #f5f7fa;
- }
-
- &.ghost {
- background-color: transparent !important;
- }
-
- .drag-handle {
- color: #909399;
- transition: color 0.2s;
-
- &:hover {
- color: #409eff;
- }
- }
-
- .step-title {
- margin-right: 10px;
- margin-top: 6px;
- }
-
- .step-type-select {
- width: 200px;
- margin-right: 10px;
- max-width: 200px;
- }
-
- .delete-btn {
- color: #f56c6c;
-
- &:hover {
- color: #f78989;
- }
-
- &:disabled {
- color: #c0c4cc;
- }
- }
-
- .step-content {
- display: flex;
- align-items: flex-start;
- }
- }
- }
- }
- </style>
|