wyg
2024-06-14 a57dc2fae73d6e0dd315a120ca43ee685a6c7b7c
提交 | 用户 | 时间
a57dc2 1 <template>
W 2   <div class="panel-tab__content">
3     <el-form size="mini" label-width="90px" @submit.native.prevent>
4       <el-form-item label="表单" prop="formKey">
5         <el-select v-model="formKey" placeholder="请选择表单" @change="updateElementFormKey" clearable>
6           <el-option v-for="item in formOptions" :key="item.formId" :label="item.formName" :value="`key_${item.formId}`" />
7         </el-select>
8       </el-form-item>
9       <el-form-item prop="localScope">
10         <span slot="label">
11           <el-tooltip content="若为节点表单,则表单信息仅在此节点可用,默认为全局表单,表单信息在整个流程实例中可用" placement="top-start">
12             <i class="header-icon el-icon-info"></i>
13           </el-tooltip>
14           <span>节点表单</span>
15         </span>
16         <el-switch :disabled="type === 'StartEvent'" v-model="localScope" active-text="是" inactive-text="否" @change="updateElementFormScope()" />
17       </el-form-item>
18 <!--      <el-form-item label="表单标识">-->
19 <!--        <el-input v-model="formKey" clearable @change="updateElementFormKey" />-->
20 <!--      </el-form-item>-->
21 <!--      <el-form-item label="业务标识">-->
22 <!--        <el-select v-model="businessKey" @change="updateElementBusinessKey">-->
23 <!--          <el-option v-for="i in fieldList" :key="i.id" :value="i.id" :label="i.label" />-->
24 <!--          <el-option label="无" value="" />-->
25 <!--        </el-select>-->
26 <!--      </el-form-item>-->
27     </el-form>
28
29     <!--字段列表-->
30 <!--    <div class="element-property list-property">-->
31 <!--      <el-divider><i class="el-icon-coin"></i> 表单字段</el-divider>-->
32 <!--      <el-table :data="fieldList" size="mini" max-height="240" border fit>-->
33 <!--        <el-table-column label="序号" type="index" width="50px" />-->
34 <!--        <el-table-column label="字段名称" prop="label" min-width="80px" show-overflow-tooltip />-->
35 <!--        <el-table-column label="字段类型" prop="type" min-width="80px" :formatter="row => fieldType[row.type] || row.type" show-overflow-tooltip />-->
36 <!--        <el-table-column label="默认值" prop="defaultValue" min-width="80px" show-overflow-tooltip />-->
37 <!--        <el-table-column label="操作" width="90px">-->
38 <!--          <template slot-scope="{ row, $index }">-->
39 <!--            <el-button size="mini" type="text" @click="openFieldForm(row, $index)">编辑</el-button>-->
40 <!--            <el-divider direction="vertical" />-->
41 <!--            <el-button size="mini" type="text" style="color: #ff4d4f" @click="removeField(row, $index)">移除</el-button>-->
42 <!--          </template>-->
43 <!--        </el-table-column>-->
44 <!--      </el-table>-->
45 <!--    </div>-->
46 <!--    <div class="element-drawer__button">-->
47 <!--      <el-button size="mini" type="primary" icon="el-icon-plus" @click="openFieldForm(null, -1)">添加字段</el-button>-->
48 <!--    </div>-->
49
50     <!--字段配置侧边栏-->
51 <!--    <el-drawer :visible.sync="fieldModelVisible" title="字段配置" :size="`${width}px`" append-to-body destroy-on-close>-->
52 <!--      <el-form :model="formFieldForm" label-width="90px" size="mini" @submit.native.prevent>-->
53 <!--        <el-form-item label="字段ID">-->
54 <!--          <el-input v-model="formFieldForm.id" clearable />-->
55 <!--        </el-form-item>-->
56 <!--        <el-form-item label="类型">-->
57 <!--          <el-select v-model="formFieldForm.typeType" placeholder="请选择字段类型" clearable @change="changeFieldTypeType">-->
58 <!--            <el-option v-for="(value, key) of fieldType" :label="value" :value="key" :key="key" />-->
59 <!--          </el-select>-->
60 <!--        </el-form-item>-->
61 <!--        <el-form-item label="类型名称" v-if="formFieldForm.typeType === 'custom'">-->
62 <!--          <el-input v-model="formFieldForm.type" clearable />-->
63 <!--        </el-form-item>-->
64 <!--        <el-form-item label="名称">-->
65 <!--          <el-input v-model="formFieldForm.label" clearable />-->
66 <!--        </el-form-item>-->
67 <!--        <el-form-item label="时间格式" v-if="formFieldForm.typeType === 'date'">-->
68 <!--          <el-input v-model="formFieldForm.datePattern" clearable />-->
69 <!--        </el-form-item>-->
70 <!--        <el-form-item label="默认值">-->
71 <!--          <el-input v-model="formFieldForm.defaultValue" clearable />-->
72 <!--        </el-form-item>-->
73 <!--      </el-form>-->
74
75 <!--      &lt;!&ndash; 枚举值设置 &ndash;&gt;-->
76 <!--      <template v-if="formFieldForm.type === 'enum'">-->
77 <!--        <el-divider key="enum-divider" />-->
78 <!--        <p class="listener-filed__title" key="enum-title">-->
79 <!--          <span><i class="el-icon-menu"></i>枚举值列表:</span>-->
80 <!--          <el-button size="mini" type="primary" @click="openFieldOptionForm(null, -1, 'enum')">添加枚举值</el-button>-->
81 <!--        </p>-->
82 <!--        <el-table :data="fieldEnumList" size="mini" key="enum-table" max-height="240" border fit>-->
83 <!--          <el-table-column label="序号" width="50px" type="index" />-->
84 <!--          <el-table-column label="枚举值编号" prop="id" min-width="100px" show-overflow-tooltip />-->
85 <!--          <el-table-column label="枚举值名称" prop="name" min-width="100px" show-overflow-tooltip />-->
86 <!--          <el-table-column label="操作" width="90px">-->
87 <!--            <template slot-scope="{ row, $index }">-->
88 <!--              <el-button size="mini" type="text" @click="openFieldOptionForm(row, $index, 'enum')">编辑</el-button>-->
89 <!--              <el-divider direction="vertical" />-->
90 <!--              <el-button size="mini" type="text" style="color: #ff4d4f" @click="removeFieldOptionItem(row, $index, 'enum')">移除</el-button>-->
91 <!--            </template>-->
92 <!--          </el-table-column>-->
93 <!--        </el-table>-->
94 <!--      </template>-->
95
96 <!--      &lt;!&ndash; 校验规则 &ndash;&gt;-->
97 <!--      <el-divider key="validation-divider" />-->
98 <!--      <p class="listener-filed__title" key="validation-title">-->
99 <!--        <span><i class="el-icon-menu"></i>约束条件列表:</span>-->
100 <!--        <el-button size="mini" type="primary" @click="openFieldOptionForm(null, -1, 'constraint')">添加约束</el-button>-->
101 <!--      </p>-->
102 <!--      <el-table :data="fieldConstraintsList" size="mini" key="validation-table" max-height="240" border fit>-->
103 <!--        <el-table-column label="序号" width="50px" type="index" />-->
104 <!--        <el-table-column label="约束名称" prop="name" min-width="100px" show-overflow-tooltip />-->
105 <!--        <el-table-column label="约束配置" prop="config" min-width="100px" show-overflow-tooltip />-->
106 <!--        <el-table-column label="操作" width="90px">-->
107 <!--          <template slot-scope="{ row, $index }">-->
108 <!--            <el-button size="mini" type="text" @click="openFieldOptionForm(row, $index, 'constraint')">编辑</el-button>-->
109 <!--            <el-divider direction="vertical" />-->
110 <!--            <el-button size="mini" type="text" style="color: #ff4d4f" @click="removeFieldOptionItem(row, $index, 'constraint')">移除</el-button>-->
111 <!--          </template>-->
112 <!--        </el-table-column>-->
113 <!--      </el-table>-->
114
115 <!--      &lt;!&ndash; 表单属性 &ndash;&gt;-->
116 <!--      <el-divider key="property-divider" />-->
117 <!--      <p class="listener-filed__title" key="property-title">-->
118 <!--        <span><i class="el-icon-menu"></i>字段属性列表:</span>-->
119 <!--        <el-button size="mini" type="primary" @click="openFieldOptionForm(null, -1, 'property')">添加属性</el-button>-->
120 <!--      </p>-->
121 <!--      <el-table :data="fieldPropertiesList" size="mini" key="property-table" max-height="240" border fit>-->
122 <!--        <el-table-column label="序号" width="50px" type="index" />-->
123 <!--        <el-table-column label="属性编号" prop="id" min-width="100px" show-overflow-tooltip />-->
124 <!--        <el-table-column label="属性值" prop="value" min-width="100px" show-overflow-tooltip />-->
125 <!--        <el-table-column label="操作" width="90px">-->
126 <!--          <template slot-scope="{ row, $index }">-->
127 <!--            <el-button size="mini" type="text" @click="openFieldOptionForm(row, $index, 'property')">编辑</el-button>-->
128 <!--            <el-divider direction="vertical" />-->
129 <!--            <el-button size="mini" type="text" style="color: #ff4d4f" @click="removeFieldOptionItem(row, $index, 'property')">移除</el-button>-->
130 <!--          </template>-->
131 <!--        </el-table-column>-->
132 <!--      </el-table>-->
133
134 <!--      &lt;!&ndash; 底部按钮 &ndash;&gt;-->
135 <!--      <div class="element-drawer__button">-->
136 <!--        <el-button size="mini">取 消</el-button>-->
137 <!--        <el-button size="mini" type="primary" @click="saveField">保 存</el-button>-->
138 <!--      </div>-->
139 <!--    </el-drawer>-->
140
141     <el-dialog :visible.sync="fieldOptionModelVisible" :title="optionModelTitle" width="600px" append-to-body destroy-on-close>
142       <el-form :model="fieldOptionForm" size="mini" label-width="96px" @submit.native.prevent>
143         <el-form-item label="编号/ID" v-if="fieldOptionType !== 'constraint'" key="option-id">
144           <el-input v-model="fieldOptionForm.id" clearable />
145         </el-form-item>
146         <el-form-item label="名称" v-if="fieldOptionType !== 'property'" key="option-name">
147           <el-input v-model="fieldOptionForm.name" clearable />
148         </el-form-item>
149         <el-form-item label="配置" v-if="fieldOptionType === 'constraint'" key="option-config">
150           <el-input v-model="fieldOptionForm.config" clearable />
151         </el-form-item>
152         <el-form-item label="值" v-if="fieldOptionType === 'property'" key="option-value">
153           <el-input v-model="fieldOptionForm.value" clearable />
154         </el-form-item>
155       </el-form>
156       <template slot="footer">
157         <el-button size="mini" @click="fieldOptionModelVisible = false">取 消</el-button>
158         <el-button size="mini" type="primary" @click="saveFieldOption">确 定</el-button>
159       </template>
160     </el-dialog>
161   </div>
162 </template>
163
164 <script>
165 import { listForm } from "@/api/workflow/form";
166
167 export default {
168   name: "ElementForm",
169   props: {
170     id: String,
171     type: String
172   },
173   inject: {
174     prefix: "prefix",
175     width: "width"
176   },
177   data() {
178     return {
179       formOptions: [],
180       formKey: "",
181       localScope: false,
182       businessKey: "",
183       optionModelTitle: "",
184       fieldList: [],
185       formFieldForm: {},
186       fieldType: {
187         long: "长整型",
188         string: "字符串",
189         boolean: "布尔类",
190         date: "日期类",
191         enum: "枚举类",
192         custom: "自定义类型"
193       },
194       formFieldIndex: -1, // 编辑中的字段, -1 为新增
195       formFieldOptionIndex: -1, // 编辑中的字段配置项, -1 为新增
196       fieldModelVisible: false,
197       fieldOptionModelVisible: false,
198       fieldOptionForm: {}, // 当前激活的字段配置项数据
199       fieldOptionType: "", // 当前激活的字段配置项弹窗 类型
200       fieldEnumList: [], // 枚举值列表
201       fieldConstraintsList: [], // 约束条件列表
202       fieldPropertiesList: [] // 绑定属性列表
203     };
204   },
205   watch: {
206     id: {
207       immediate: true,
208       handler(val) {
209         val && val.length && this.$nextTick(() => this.resetFormList());
210       }
211     }
212   },
213   created() {
214     /** 查询流程分类列表 */
215     this.getFormList();
216   },
217   methods: {
218     /** 查询表单列表 */
219     getFormList() {
220       listForm().then(response => this.formOptions = response.rows)
221     },
222     resetFormList() {
223       this.bpmnELement = window.bpmnInstances.bpmnElement;
224       this.formKey = this.bpmnELement.businessObject.formKey;
225       this.localScope = this.bpmnELement.businessObject.localScope;
226       // 获取元素扩展属性 或者 创建扩展属性
227       this.elExtensionElements =
228         this.bpmnELement.businessObject.get("extensionElements") || window.bpmnInstances.moddle.create("bpmn:ExtensionElements", { values: [] });
229       // 获取元素表单配置 或者 创建新的表单配置
230       // this.formData =
231       //   this.elExtensionElements.values.filter(ex => ex.$type === `${this.prefix}:FormData`)?.[0] ||
232       //   window.bpmnInstances.moddle.create(`${this.prefix}:FormData`, { fields: [] });
233       // 业务标识 businessKey, 绑定在 formData 中
234       // this.businessKey = this.formData.businessKey;
235
236       // 保留剩余扩展元素,便于后面更新该元素对应属性
237       this.otherExtensions = this.elExtensionElements.values.filter(ex => ex.$type !== `${this.prefix}:FormData`);
238
239       // 复制原始值,填充表格
240       // this.fieldList = JSON.parse(JSON.stringify(this.formData.fields || []));
241
242       // 更新元素扩展属性,避免后续报错
243       // this.updateElementExtensions();
244     },
245     updateElementFormKey() {
246       window.bpmnInstances.modeling.updateProperties(this.bpmnELement, { formKey: this.formKey });
247     },
248     updateElementFormScope() {
249       window.bpmnInstances.modeling.updateProperties(this.bpmnELement, { localScope: this.localScope });
250     },
251     updateElementBusinessKey() {
252       window.bpmnInstances.modeling.updateModdleProperties(this.bpmnELement, this.formData, { businessKey: this.businessKey });
253     },
254     // 根据类型调整字段type
255     changeFieldTypeType(type) {
256       this.$set(this.formFieldForm, "type", type === "custom" ? "" : type);
257     },
258
259     // 打开字段详情侧边栏
260     openFieldForm(field, index) {
261       this.formFieldIndex = index;
262       if (index !== -1) {
263         const FieldObject = this.formData.fields[index];
264         this.formFieldForm = JSON.parse(JSON.stringify(field));
265         // 设置自定义类型
266         this.$set(this.formFieldForm, "typeType", !this.fieldType[field.type] ? "custom" : field.type);
267         // 初始化枚举值列表
268         field.type === "enum" && (this.fieldEnumList = JSON.parse(JSON.stringify(FieldObject?.values || [])));
269         // 初始化约束条件列表
270         this.fieldConstraintsList = JSON.parse(JSON.stringify(FieldObject?.validation?.constraints || []));
271         // 初始化自定义属性列表
272         this.fieldPropertiesList = JSON.parse(JSON.stringify(FieldObject?.properties?.values || []));
273       } else {
274         this.formFieldForm = {};
275         // 初始化枚举值列表
276         this.fieldEnumList = [];
277         // 初始化约束条件列表
278         this.fieldConstraintsList = [];
279         // 初始化自定义属性列表
280         this.fieldPropertiesList = [];
281       }
282       this.fieldModelVisible = true;
283     },
284     // 打开字段 某个 配置项 弹窗
285     openFieldOptionForm(option, index, type) {
286       this.fieldOptionModelVisible = true;
287       this.fieldOptionType = type;
288       this.formFieldOptionIndex = index;
289       if (type === "property") {
290         this.fieldOptionForm = option ? JSON.parse(JSON.stringify(option)) : {};
291         return (this.optionModelTitle = "属性配置");
292       }
293       if (type === "enum") {
294         this.fieldOptionForm = option ? JSON.parse(JSON.stringify(option)) : {};
295         return (this.optionModelTitle = "枚举值配置");
296       }
297       this.fieldOptionForm = option ? JSON.parse(JSON.stringify(option)) : {};
298       return (this.optionModelTitle = "约束条件配置");
299     },
300
301     // 保存字段 某个 配置项
302     saveFieldOption() {
303       if (this.formFieldOptionIndex === -1) {
304         if (this.fieldOptionType === "property") {
305           this.fieldPropertiesList.push(this.fieldOptionForm);
306         }
307         if (this.fieldOptionType === "constraint") {
308           this.fieldConstraintsList.push(this.fieldOptionForm);
309         }
310         if (this.fieldOptionType === "enum") {
311           this.fieldEnumList.push(this.fieldOptionForm);
312         }
313       } else {
314         this.fieldOptionType === "property" && this.fieldPropertiesList.splice(this.formFieldOptionIndex, 1, this.fieldOptionForm);
315         this.fieldOptionType === "constraint" && this.fieldConstraintsList.splice(this.formFieldOptionIndex, 1, this.fieldOptionForm);
316         this.fieldOptionType === "enum" && this.fieldEnumList.splice(this.formFieldOptionIndex, 1, this.fieldOptionForm);
317       }
318       this.fieldOptionModelVisible = false;
319       this.fieldOptionForm = {};
320     },
321     // 保存字段配置
322     saveField() {
323       const { id, type, label, defaultValue, datePattern } = this.formFieldForm;
324       const Field = window.bpmnInstances.moddle.create(`${this.prefix}:FormField`, { id, type, label });
325       defaultValue && (Field.defaultValue = defaultValue);
326       datePattern && (Field.datePattern = datePattern);
327       // 构建属性
328       if (this.fieldPropertiesList && this.fieldPropertiesList.length) {
329         const fieldPropertyList = this.fieldPropertiesList.map(fp => {
330           return window.bpmnInstances.moddle.create(`${this.prefix}:Property`, { id: fp.id, value: fp.value });
331         });
332         Field.properties = window.bpmnInstances.moddle.create(`${this.prefix}:Properties`, { values: fieldPropertyList });
333       }
334       // 构建校验规则
335       if (this.fieldConstraintsList && this.fieldConstraintsList.length) {
336         const fieldConstraintList = this.fieldConstraintsList.map(fc => {
337           return window.bpmnInstances.moddle.create(`${this.prefix}:Constraint`, { name: fc.name, config: fc.config });
338         });
339         Field.validation = window.bpmnInstances.moddle.create(`${this.prefix}:Validation`, { constraints: fieldConstraintList });
340       }
341       // 构建枚举值
342       if (this.fieldEnumList && this.fieldEnumList.length) {
343         Field.values = this.fieldEnumList.map(fe => {
344           return window.bpmnInstances.moddle.create(`${this.prefix}:Value`, { name: fe.name, id: fe.id });
345         });
346       }
347       // 更新数组 与 表单配置实例
348       if (this.formFieldIndex === -1) {
349         this.fieldList.push(this.formFieldForm);
350         this.formData.fields.push(Field);
351       } else {
352         this.fieldList.splice(this.formFieldIndex, 1, this.formFieldForm);
353         this.formData.fields.splice(this.formFieldIndex, 1, Field);
354       }
355       this.updateElementExtensions();
356       this.fieldModelVisible = false;
357     },
358
359     // 移除某个 字段的 配置项
360     removeFieldOptionItem(option, index, type) {
361       if (type === "property") {
362         this.fieldPropertiesList.splice(index, 1);
363         return;
364       }
365       if (type === "enum") {
366         this.fieldEnumList.splice(index, 1);
367         return;
368       }
369       this.fieldConstraintsList.splice(index, 1);
370     },
371     // 移除 字段
372     removeField(field, index) {
373       this.fieldList.splice(index, 1);
374       this.formData.fields.splice(index, 1);
375       this.updateElementExtensions();
376     },
377
378     updateElementExtensions() {
379       // 更新回扩展元素
380       const newElExtensionElements = window.bpmnInstances.moddle.create(`bpmn:ExtensionElements`, {
381         values: this.otherExtensions.concat(this.formData)
382       });
383       // 更新到元素上
384       window.bpmnInstances.modeling.updateProperties(this.bpmnELement, {
385         extensionElements: newElExtensionElements
386       });
387     }
388   }
389 };
390 </script>