addItem.vue 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. <template>
  2. <el-dialog :title="ruleForm.id ? '修改控制策略' : '添加控制策略'" v-model="isShowDialog" width="650px">
  3. <el-form
  4. ref="ruleFormRef"
  5. :model="ruleForm"
  6. :rules="rules"
  7. label-width="auto"
  8. status-icon
  9. >
  10. <el-form-item label="标题" prop="title" style="width: 388px;">
  11. <el-input clearable v-model="ruleForm.title" />
  12. </el-form-item>
  13. <el-form-item label="类型" prop="types">
  14. <el-radio-group v-model="ruleForm.types">
  15. <el-radio :label="1">手动</el-radio>
  16. <el-radio :label="2">自动</el-radio>
  17. </el-radio-group>
  18. </el-form-item>
  19. <el-form-item label="说明" prop="description" style="width: 388px;">
  20. <el-input v-model="ruleForm.description" type="textarea" />
  21. </el-form-item>
  22. <el-form-item label="参数配置" prop="param">
  23. <div style="width: 100%;">
  24. <div class="param-wrap" v-for="(item, index) in ruleForm.param" :key="index">
  25. <el-input clearable placeholder="key" v-model="item.key" />
  26. <el-input clearable placeholder="标题" v-model="item.title" />
  27. <el-select v-model="item.types" placeholder="请选择数据类型">
  28. <el-option-group v-for="group in typeData" :key="group.label" :label="group.label">
  29. <el-option v-for="item in group.options" :key="item.type" :label="item.title" :value="item.type" />
  30. </el-option-group>
  31. </el-select>
  32. <el-button v-if="index === ruleForm.param.length -1" @click="plusParam()">
  33. <el-icon>
  34. <ele-Plus />
  35. </el-icon>
  36. </el-button>
  37. <el-button v-else @click="minusParam(index)">
  38. <el-icon>
  39. <ele-Minus />
  40. </el-icon>
  41. </el-button>
  42. </div>
  43. </div>
  44. </el-form-item>
  45. </el-form>
  46. <div class="form-btn-wrap">
  47. <el-button type="primary" @click="onSubmit(ruleFormRef)"> 提交 </el-button>
  48. </div>
  49. </el-dialog>
  50. </template>
  51. <script lang="ts" setup>
  52. import { ref } from 'vue'
  53. import api from '/@/api/device';
  54. import policyApi from '/@/api/policy';
  55. import axios from 'axios';
  56. import { ElMessage } from 'element-plus';
  57. import type { FormInstance } from 'element-plus'
  58. import { getToken } from "/@/utils/auth";
  59. import { v4 as uuid } from "uuid";
  60. interface RuleForm {
  61. id: any
  62. title: string
  63. types: number
  64. description: string,
  65. param: any[],
  66. flowId: string,
  67. }
  68. const emit = defineEmits(['getList']);
  69. const headers = {
  70. Authorization: 'Bearer ' + getToken(),
  71. };
  72. const isShowDialog = ref(false);
  73. const ruleFormRef = ref<FormInstance>()
  74. const ruleForm = ref<RuleForm>({
  75. id: null,
  76. title: '',
  77. types: 2,
  78. description: '',
  79. param: [ {
  80. key: "",
  81. title: "",
  82. types: ""
  83. }],
  84. flowId: ''
  85. })
  86. // 数据类型下拉数据
  87. const typeData = ref([]);
  88. const validateParam = (rule: any, value: any, callback: any) => {
  89. if (value === '') {
  90. callback(new Error('请输入参数配置'))
  91. } else if (value) {
  92. verification(value).then(() => {
  93. callback()
  94. })
  95. .catch((e:string) => {
  96. callback(new Error(e))
  97. })
  98. } else {
  99. callback()
  100. }
  101. }
  102. const verification = (data:any) => {
  103. return new Promise(function(resolve, reject) {
  104. try {
  105. data.forEach((item:any, indexs:number) => {
  106. if (!item.key && !item.title && !item.types) {
  107. throw '参数配置未完善,请进行完善'
  108. }
  109. if (!item.key) {
  110. throw '第' + (indexs + 1) + '个参数配置的key未完善,请进行完善'
  111. } else if (!item.title) {
  112. throw '第' + (indexs + 1) + '个参数配置的标题未完善,请进行完善'
  113. } else if (!item.types) {
  114. throw '第' + (indexs + 1) + '个参数配置的数据类型未完善,请进行完善'
  115. }
  116. })
  117. } catch (e) {
  118. return reject(e)
  119. }
  120. resolve('成功')
  121. })
  122. }
  123. const rules = ref({
  124. title: [
  125. { required: true, message: '请输入标题', trigger: 'blur' },
  126. ],
  127. types: [
  128. {
  129. required: true,
  130. message: '请输入说明',
  131. trigger: 'change',
  132. },
  133. ],
  134. description: [
  135. { required: true, message: '请输入描述', trigger: 'blur' },
  136. ],
  137. param: [{ required: true, validator: validateParam, trigger: 'change' }],
  138. })
  139. const onSubmit = async (formEl: FormInstance | undefined) => {
  140. if (!formEl) return
  141. await formEl.validate();
  142. if (!ruleForm.value.id) {
  143. const id = uuid();
  144. await axios.post(
  145. import.meta.env.VITE_RULE_SERVER_URL + "/api/v1/rules/" + id,
  146. {
  147. ruleChain: {
  148. id: id,
  149. name: ruleForm.value.title,
  150. root: true,
  151. additionalInfo: {
  152. description: ruleForm.value.description,
  153. layoutX: "130",
  154. layoutY: "220",
  155. },
  156. },
  157. metadata: {
  158. nodes: [{
  159. "id": "node_2",
  160. "additionalInfo": {
  161. "layoutX": 606,
  162. "layoutY": 424
  163. },
  164. "type": "log",
  165. "name": "日志",
  166. "debugMode": true,
  167. "configuration": {
  168. "jsScript": "return 'Incoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
  169. }
  170. }],
  171. endpoints: [],
  172. connections: [],
  173. },
  174. },
  175. { headers }
  176. );
  177. ruleForm.value.flowId = id;
  178. } else {
  179. // 找到规则
  180. const { data } = (await axios.get(import.meta.env.VITE_RULE_SERVER_URL + "/api/v1/rules/" + ruleForm.value.flowId, { headers }).catch(() => {
  181. ElMessage.error("规则不存在");
  182. })) as any;
  183. // 修改名称和说明
  184. data.ruleChain.name = ruleForm.value.title;
  185. data.ruleChain.additionalInfo.description = ruleForm.value.description;
  186. // 保存
  187. await axios.post(import.meta.env.VITE_RULE_SERVER_URL + "/api/v1/rules/" + ruleForm.value.flowId, data, { headers });
  188. }
  189. const theApi = ruleForm.value.id ? policyApi.edit : policyApi.add;
  190. await theApi(ruleForm.value);
  191. ElMessage.success('操作成功');
  192. resetForm();
  193. isShowDialog.value = false;
  194. emit('getList');
  195. }
  196. const resetForm = () => {
  197. ruleFormRef.value && ruleFormRef.value.resetFields();
  198. ruleForm.value.param = [{
  199. key: "",
  200. title: "",
  201. types: ""
  202. }]
  203. }
  204. const plusParam = () => {
  205. ruleForm.value.param.push({
  206. key: '',
  207. title: '',
  208. types: ''
  209. })
  210. }
  211. const minusParam = (index:number) => {
  212. ruleForm.value.param.splice(index, 1);
  213. }
  214. // 打开弹窗
  215. const openDialog = (row?: any) => {
  216. resetForm();
  217. if (row) {
  218. policyApi.detail(row.id).then((res: any) => {
  219. const { id, title, types, description, paramData, flowId } = res.data;
  220. ruleForm.value = {
  221. id: id,
  222. title: title,
  223. types: types,
  224. description: description,
  225. param: paramData,
  226. flowId: flowId
  227. }
  228. });
  229. }
  230. api.product.getDataType({ status: -1 }).then((res: any) => {
  231. const data:any = Object.values(res.dataType)
  232. data.forEach((item:any, index:number) => {
  233. if (index == 0) {
  234. data[index]['label'] = '基础类型';
  235. data[index]['options'] = item;
  236. } else {
  237. data[index]['label'] = '扩展类型';
  238. data[index]['options'] = item.filter((i:any) => ['enum', 'array', 'object'].indexOf(i.type) === -1);
  239. }
  240. });
  241. typeData.value = data || [];
  242. });
  243. isShowDialog.value = true;
  244. };
  245. defineExpose({ openDialog })
  246. </script>
  247. <style lang="scss" scoped>
  248. .param-wrap {
  249. display: flex;
  250. justify-content: space-between;
  251. align-items: center;
  252. margin-bottom: 10px;
  253. .el-input,
  254. .el-select {
  255. width: 150px;
  256. }
  257. }
  258. .el-icon {
  259. margin-right: 0!important;
  260. }
  261. ::v-deep .el-dialog__body {
  262. position: relative;
  263. }
  264. .form-btn-wrap {
  265. position: absolute;
  266. bottom: 20px;
  267. right: 20px;
  268. display: flex;
  269. justify-content: flex-end;
  270. align-items: center;
  271. width: 100%;
  272. }
  273. </style>