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