task.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. <template>
  2. <div class="form">
  3. <el-form :model="form" label-width="130px" ref="ruleFormRef">
  4. <el-form-item label="节点名称" prop="name" :rules="[{ required: true, message: '请输入节点名称', trigger: 'blur' }]">
  5. <el-input v-model="form.name" placeholder="请输入节点名称" clearable></el-input>
  6. </el-form-item>
  7. <el-form-item label="节点编码" prop="code" :rules="[{ required: true, message: '请输入节点编码', trigger: 'blur' }]">
  8. <el-input v-model="form.code" disabled placeholder="请输入节点编码" clearable></el-input>
  9. </el-form-item>
  10. <el-form-item label="处理人" prop="handlerType" :rules="[{ required: true, message: '请选择处理人', trigger: 'change' }]">
  11. <el-select v-model="form.handlerType" class="w100" placeholder="请选择处理人" @change="changeOptions">
  12. <el-option v-for="item in handlerTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
  13. </el-select>
  14. </el-form-item>
  15. <!-- 选择其他 -->
  16. <el-form-item
  17. v-if="[0, 1, 2].includes(form.handlerType)"
  18. :label="itemName"
  19. prop="handlerClassifiesOrgin"
  20. :rules="[{ required: true, message: `请选择${itemName}`, trigger: 'change' }]"
  21. >
  22. <el-select v-model="form.handlerClassifiesOrgin" multiple filterable class="w100" @change="getSelectValue" value-key="id">
  23. <el-option v-for="item in selectList" :key="item.id" :label="item.name" :value="item" />
  24. </el-select>
  25. </el-form-item>
  26. <!-- 选择用户 -->
  27. <el-form-item
  28. v-if="[3].includes(form.handlerType)"
  29. :label="itemName"
  30. prop="handlerClassifiesOrgin"
  31. :rules="[{ required: true, message: `请选择${itemName}`, trigger: 'change' }]"
  32. >
  33. <el-select
  34. v-model="form.handlerClassifiesOrgin"
  35. multiple
  36. filterable
  37. remote
  38. class="w100"
  39. reserve-keyword
  40. placeholder="请输入用户名称"
  41. remote-show-suffix
  42. :remote-method="remoteMethod"
  43. :loading="loading"
  44. @change="getSelectValue"
  45. value-key="id"
  46. >
  47. <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item" />
  48. </el-select>
  49. </el-form-item>
  50. <!-- 部门 -->
  51. <el-form-item
  52. v-if="[4].includes(form.handlerType)"
  53. :label="itemName"
  54. prop="handlerClassifiesOrgin"
  55. :rules="[{ required: true, message: `请选择${itemName}`, trigger: 'change' }]"
  56. >
  57. <el-tree-select
  58. :props="{ label: 'orgName' }"
  59. node-key="orgCode"
  60. class="w100"
  61. ref="treeSelectRef"
  62. v-model="form.handlerClassifiesOrgin"
  63. :data="orgData"
  64. multiple
  65. :render-after-expand="false"
  66. show-checkbox
  67. @check-change="checkChange"
  68. check-strictly
  69. default-expand-all
  70. filterable
  71. />
  72. </el-form-item>
  73. <el-form-item label="节点属性" prop="businessProperty" :rules="[{ required: true, message: '请选择节点属性', trigger: 'change' }]">
  74. <el-select v-model="form.businessProperty" class="w100" placeholder="请选择节点属性">
  75. <el-option v-for="item in businessPropertyOptions" :key="item.value" :label="item.label" :value="item.value" />
  76. </el-select>
  77. </el-form-item>
  78. <el-form-item label="会签" prop="countersignMode" :rules="[{ required: true, message: '请选择会签', trigger: 'change' }]">
  79. <el-select v-model="form.countersignMode" class="w100" placeholder="请选择会签">
  80. <el-option v-for="item in countersignModeList" :key="item.value" :label="item.label" :value="item.value" />
  81. </el-select>
  82. </el-form-item>
  83. <el-form-item label="节点过滤策略" prop="pathPolicy" :rules="[{ required: false, message: '请选择节点过滤策略', trigger: 'change' }]">
  84. <el-select v-model="form.pathPolicy" class="w100" placeholder="请选择节点过滤策略">
  85. <el-option v-for="item in pathPolicyOptions" :key="item.key" :label="item.value" :value="item.key" />
  86. </el-select>
  87. </el-form-item>
  88. <el-form-item label="会签结束节点" prop="countersignEndStepCode" v-if="form.countersignEndStepCode">
  89. <el-select v-model="form.countersignEndStepCode" class="w100" disabled>
  90. <el-option v-for="item in nodesOptions" :key="item.id" :label="item.text.value" :value="item.id" />
  91. </el-select>
  92. </el-form-item>
  93. <el-form-item label="组件配置" prop="components" :rules="[{ required: false, message: '请选择组件配置', trigger: 'change' }]">
  94. <el-checkbox-group v-model="form.components">
  95. <el-checkbox :label="item.dicDataValue" v-for="item in stepPropertiesOptions" :key="item.id">{{item.dicDataName}}</el-checkbox>
  96. </el-checkbox-group>
  97. </el-form-item>
  98. </el-form>
  99. </div>
  100. </template>
  101. <script lang="ts" setup name="flowNode">
  102. import { reactive, watch, onMounted, ref } from 'vue';
  103. import { baseData, getSelectList,queryUser } from '/@/api/system/workflow';
  104. import { getCanUseOrg } from '/@/api/system/user';
  105. import { removeDuplicate } from '/@/utils/arrayOperation';
  106. const ruleFormRef = ref<RefType>();
  107. // 定义属性
  108. const props = defineProps<{
  109. modelValue: any;
  110. }>();
  111. // 注意:ref不能与model一样,相同的话表单双向绑定将会失效
  112. const form = reactive<Record<string, any>>({
  113. ...props.modelValue, // 传入的数据
  114. handlerClassifiesOrgin: [], // 选择的数据
  115. handlerClassifies: [], // 选择的数据
  116. handlerType: '', // 处理人类型
  117. businessProperty: '', // 节点属性
  118. countersignMode: '', // 会签
  119. countersignStartStepCode: '', // 会签开始节点
  120. countersignEndStepCode: '', // 会签结束节点
  121. pathPolicy: '', // 节点过滤策略
  122. });
  123. const emits = defineEmits(['update:modelValue']); // 定义事件
  124. const loading = ref(false); // 加载
  125. watch(
  126. () => form,
  127. () => {
  128. emits('update:modelValue', Object.assign(props.modelValue, form));
  129. },
  130. { deep: true }
  131. );
  132. // 选择处理人获取数据
  133. // 处理人
  134. const handlerTypeOptions = ref<EmptyArrayType>() as any;
  135. // 下拉内容
  136. const selectList = ref<EmptyArrayType>() as any;
  137. // 会签
  138. const itemName = ref<string>('');
  139. const changeOptions = (e: any) => {
  140. form.handlerClassifiesOrgin = [];
  141. form.handlerClassifies = '[]';
  142. itemName.value = handlerTypeOptions.value[e].label;
  143. if ([0, 1, 2].includes(e)) {
  144. getSelectList(e).then((res: any) => {
  145. selectList.value = res.result ?? [];
  146. selectList.value = selectList.value.map((item: any) => ({
  147. id: item.key,
  148. name: item.value,
  149. }));
  150. });
  151. }
  152. if (e === 4) {
  153. getOrgListFn();
  154. }
  155. };
  156. // 远程搜索用户名称
  157. // 指定用户列表
  158. const userList = ref<any>();
  159. const remoteMethod = (query: string) => {
  160. if (query !== '') {
  161. loading.value = true;
  162. queryUser({ name: query }).then((res: any) => {
  163. loading.value = false;
  164. const newUsers = res.result.map((item: any) => {
  165. return {
  166. ...item,
  167. name: !item.name.includes('-') ? item.name + '-' + item.organization.orgName : item.name
  168. };
  169. });
  170. userList.value = removeDuplicate([ ...newUsers,...userList.value], 'id');
  171. });
  172. }
  173. };
  174. // 获取可用组织
  175. const getOrgListFn = () => {
  176. getCanUseOrg().then((res: any) => {
  177. orgData.value = res?.result ?? [];
  178. });
  179. };
  180. const treeSelectRef = ref<RefType>();
  181. // 选择部门
  182. const checkChange = () => {
  183. const data = treeSelectRef.value.getCheckedNodes();
  184. let arr: EmptyArrayType;
  185. arr = data.map((v: any) => {
  186. return {
  187. id: v.orgCode,
  188. name: v.orgName,
  189. };
  190. });
  191. // 使用模板字符串
  192. form.handlerClassifies = `${JSON.stringify(arr)}`;
  193. };
  194. // 获取选择对象
  195. const getSelectValue = (query: any[]) => {
  196. let arr:EmptyArrayType;
  197. arr = query.map((item: any) => ({ name: item.name, id: item.id }));
  198. // 使用模板字符串
  199. form.handlerClassifies = `${JSON.stringify(arr)}`;
  200. };
  201. // 会签
  202. const countersignModeList = ref<EmptyArrayType>() as any;
  203. // 节点属性
  204. const businessPropertyOptions = ref<EmptyArrayType>() as any;
  205. // 部门
  206. const orgData = ref<EmptyArrayType>() as any;
  207. // 组件
  208. const stepPropertiesOptions = ref<EmptyArrayType>() as any;
  209. //
  210. const pathPolicyOptions = ref<EmptyArrayType>() as any;
  211. // 会签结束节点
  212. const nodesOptions = ref([] as any);
  213. onMounted(async () => {
  214. // 获取页面基础数据
  215. const res: any = await baseData();
  216. handlerTypeOptions.value = res.result?.handlerTypeOptions ?? [];
  217. handlerTypeOptions.value = handlerTypeOptions.value.map((item: any) => ({
  218. value: item.key,
  219. label: item.value,
  220. }));
  221. countersignModeList.value = res.result?.countersignMode ?? [];
  222. countersignModeList.value = countersignModeList.value.map((item: any) => ({
  223. value: item.key,
  224. label: item.value,
  225. }));
  226. businessPropertyOptions.value = res.result?.businessPropertyOptions ?? [];
  227. businessPropertyOptions.value = businessPropertyOptions.value.map((item: any) => ({
  228. value: item.key,
  229. label: item.value,
  230. }));
  231. stepPropertiesOptions.value = res.result?.stepPropertiesOptions ?? [];
  232. pathPolicyOptions.value = res.result?.pathPolicyOptions ?? [];
  233. // 合并表单
  234. Object.assign(form, props.modelValue);
  235. if (form.handlerClassifies.includes('[')) {
  236. switch (form.handlerType) {
  237. case 0:
  238. case 1:
  239. case 2:
  240. form.handlerClassifiesOrgin = JSON.parse(form.handlerClassifies);
  241. break;
  242. case 3:
  243. userList.value = form.handlerClassifiesOrgin = JSON.parse(form.handlerClassifies);
  244. break;
  245. case 4:
  246. form.handlerClassifiesOrgin = JSON.parse(form.handlerClassifies).map((v: any) => v.id);
  247. break;
  248. default:
  249. break;
  250. }
  251. }
  252. if ([0, 1, 2].includes(form.handlerType)) {
  253. const res: any = await getSelectList(form.handlerType);
  254. selectList.value = res.result ?? [];
  255. selectList.value = selectList.value.map((item: any) => ({
  256. id: item.key,
  257. name: item.value,
  258. }));
  259. if (handlerTypeOptions.value.length) itemName.value = handlerTypeOptions.value[form.handlerType].label;
  260. } else if ([3].includes(form.handlerType)) {
  261. if (handlerTypeOptions.value.length) itemName.value = handlerTypeOptions.value[form.handlerType].label;
  262. } else if ([4].includes(form.handlerType)) {
  263. if (handlerTypeOptions.value.length) itemName.value = handlerTypeOptions.value[form.handlerType].label;
  264. getOrgListFn();
  265. }
  266. nodesOptions.value = form.summaryNodes ?? [];
  267. });
  268. // 导入属性及方法给外部调用
  269. defineExpose({
  270. ruleFormRef,
  271. });
  272. </script>