editNode.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. <template>
  2. <div class="system-edit-dic-container">
  3. <el-dialog :title="(ruleForm.nodeId !== 0 ? '修改' : '添加') + '数据节点'" v-model="isShowDialog" width="769px">
  4. <el-form :model="ruleForm" ref="formRef" :rules="rules" size="default" label-width="110px">
  5. <el-form-item label="数据节点标识" prop="key">
  6. <el-input v-model="ruleForm.key" placeholder="请输入数据节点名称" :disabled="detail.lockKey==1" />
  7. </el-form-item>
  8. <el-form-item label="数据节点名称" prop="name">
  9. <el-input v-model="ruleForm.name" placeholder="请输入数据节点名称" />
  10. </el-form-item>
  11. <el-form-item label="是否主键" prop="isPk">
  12. <el-radio-group v-model="ruleForm.isPk">
  13. <el-radio :label="0">否</el-radio>
  14. <el-radio :label="1">是</el-radio>
  15. </el-radio-group>
  16. </el-form-item>
  17. <el-form-item label="数据类型" prop="dataType" v-if="detail.from == 1">
  18. <el-select v-model="ruleForm.dataType" filterable placeholder="请选择数据类型">
  19. <el-option v-for="item in tabData" :key="item.value" :label="item.label" :value="item.value" />
  20. </el-select>
  21. </el-form-item>
  22. <el-form-item label="取值项" prop="value" v-if="detail.from == 1">
  23. <el-input v-model="ruleForm.value" placeholder="请输入取值项" class="w-35" /><el-button type="success" @click="onTest">选择值</el-button>
  24. </el-form-item>
  25. <el-form-item label="取值项" prop="value" v-if="detail.from == 4">
  26. <el-select v-model="ruleForm.value" filterable placeholder="请选择数取值项" @change="getNodeList">
  27. <el-option v-for="item in propertyData" :key="item.key" :label="item.name" :value="item.key">
  28. <span style="float: left">{{ item.key }}</span>
  29. <span style="float: right; font-size: 13px">{{ item.name }}</span>
  30. </el-option>
  31. </el-select>
  32. </el-form-item>
  33. <el-form-item label="取值项" prop="value" v-if="detail.from == 2">
  34. <el-select v-model="ruleForm.value" filterable placeholder="请选择数取值项" @change="getDbList">
  35. <el-option v-for="item in dbData" :key="item.Name" :label="item.Comment" :value="item.Name">
  36. <span style="float: left">{{ item.Name }}</span>
  37. <span style="float: right; font-size: 13px">{{ item.Comment }}</span>
  38. </el-option>
  39. </el-select>
  40. </el-form-item>
  41. <el-divider content-position="left">规则表达式</el-divider>
  42. <div v-for="(item, index) in rule" :key="index">
  43. <el-form-item label="正则表达式">
  44. <el-input v-model="item.expression" placeholder="请输入规则表达式" />
  45. </el-form-item>
  46. <el-form-item label="替换内容">
  47. <el-input v-model="item.replace" placeholder="请输入替换内容" class="w-35" />
  48. <!-- <el-input v-model="rule[index].params.name" placeholder="请输入键值" class="w-35" />
  49. <el-input v-model="rule[index].params.value" placeholder="请输入值" class="w-35" /> -->
  50. <div class="conicon">
  51. <el-icon @click="delRule(index)" v-if="index > 0"><Delete /></el-icon>
  52. </div>
  53. </el-form-item>
  54. </div>
  55. <div style="padding: 10px">
  56. <el-button type="primary" class="addbutton" @click="addRule">增加</el-button>
  57. </div>
  58. </el-form>
  59. <template #footer>
  60. <span class="dialog-footer">
  61. <el-button @click="onCancel" size="default">取 消</el-button>
  62. <el-button type="primary" @click="onSubmit" size="default">{{ ruleForm.nodeId !== 0 ? '修 改' : '添 加' }}</el-button>
  63. </span>
  64. </template>
  65. </el-dialog>
  66. <el-dialog v-model="dialogVisible" title="点击蓝色key值进行选择" width="40%">
  67. <jsontree :data="jsonPathData" @handlePath="handlePath"></jsontree>
  68. <template #footer>
  69. <span class="dialog-footer">
  70. <el-button @click="dialogVisible = false">关闭</el-button>
  71. </span>
  72. </template>
  73. </el-dialog>
  74. </div>
  75. </template>
  76. <script lang="ts">
  77. import { reactive, toRefs, defineComponent, ref, unref } from 'vue';
  78. import api from '/@/api/datahub';
  79. import 'vue3-json-viewer/dist/index.css';
  80. import jsontree from '/@/components/jsontree/index.vue';
  81. import { ElMessage } from 'element-plus';
  82. import { Delete, Minus, Right } from '@element-plus/icons-vue';
  83. interface RuleFormState {
  84. nodeId: number;
  85. name: string;
  86. from: number;
  87. isPk: number;
  88. key: string;
  89. dataType: string;
  90. value: string;
  91. description: string;
  92. status: number;
  93. }
  94. interface DicState {
  95. isShowDialog: boolean;
  96. ruleForm: RuleFormState;
  97. rules: {};
  98. }
  99. export default defineComponent({
  100. name: 'Edit',
  101. components: { Delete, Minus, Right, jsontree },
  102. setup(prop, { emit }) {
  103. const editDicRef = ref();
  104. const formRef = ref<HTMLElement | null>(null);
  105. const state = reactive<DicState>({
  106. isShowDialog: false,
  107. dialogVisible: false,
  108. jsonPathData: [],
  109. jsonData: '',
  110. propertyData: [],
  111. dbData: [],
  112. config: {},
  113. detail: {},
  114. tabData: [
  115. {
  116. label: 'int',
  117. value: 'int',
  118. },
  119. {
  120. label: 'long',
  121. value: 'long',
  122. },
  123. {
  124. label: 'float',
  125. value: 'float',
  126. },
  127. {
  128. label: 'double',
  129. value: 'double',
  130. },
  131. {
  132. label: 'string',
  133. value: 'string',
  134. },
  135. {
  136. label: 'boolean',
  137. value: 'boolean',
  138. },
  139. {
  140. label: 'date',
  141. value: 'date',
  142. },
  143. ],
  144. ruledata: [
  145. {
  146. expression: '',
  147. replace: '',
  148. // params: {
  149. // name: '',
  150. // value: '',
  151. // },
  152. },
  153. ],
  154. rule: [
  155. {
  156. expression: '',
  157. replace: '',
  158. // params: {
  159. // name: '',
  160. // value: '',
  161. // },
  162. },
  163. ],
  164. ruleForm: {
  165. nodeId: 0,
  166. isPk: 0,
  167. name: '',
  168. key: '',
  169. dataType: '',
  170. value: '',
  171. rule: [],
  172. description: '',
  173. },
  174. rules: {
  175. key: [{ required: true, message: '数据节点标识不能为空', trigger: 'blur' }],
  176. name: [{ required: true, message: '数据节点名称不能为空', trigger: 'blur' }],
  177. isPk: [{ required: true, message: '请选择是否主键', trigger: 'blur' }],
  178. dataType: [{ required: true, message: '数据节点类型不能为空', trigger: 'blur' }],
  179. value: [{ required: true, message: '数据节点取值项不能为空', trigger: 'blur' }],
  180. },
  181. });
  182. const onTest = () => {
  183. if (state.detail.from == 1) {
  184. api.common.api(state.detail.sourceId).then((res: any) => {
  185. state.jsonData = JSON.parse(res.data);
  186. var jsonstr = jsonPath([], state.jsonData, '');
  187. state.jsonPathData = jsonstr;
  188. state.dialogVisible = true;
  189. });
  190. } else if (state.detail.from == 4) {
  191. api.common.devapi(state.detail.sourceId).then((res: any) => {
  192. state.jsonData = JSON.parse(res.data);
  193. var jsonstr = jsonPath([], state.jsonData, '');
  194. state.jsonPathData = jsonstr;
  195. state.dialogVisible = true;
  196. });
  197. }
  198. };
  199. const handlePath = (path) => {
  200. let data = path.slice(1);
  201. state.ruleForm.value = data;
  202. state.dialogVisible = false;
  203. };
  204. const delRule = (index) => {
  205. state.rule.splice(index, 1);
  206. };
  207. const addRule = () => {
  208. state.rule.push({
  209. expression: '',
  210. replace: '',
  211. // params: {
  212. // name: '',
  213. // value: '',
  214. // },
  215. });
  216. };
  217. // 打开弹窗
  218. const openDialog = (row: RuleFormState | null) => {
  219. resetForm();
  220. if (row?.nodeId) {
  221. state.ruleForm = row;
  222. var data = JSON.parse(row.rule);
  223. console.log(data);
  224. data.forEach((item, index) => {
  225. state.rule[index].expression = item.expression;
  226. state.rule[index].replace = item.replace;
  227. // state.rule[index].params.name = Object.keys(item.params);
  228. // state.rule[index].params.value = item.params[Object.keys(item.params)];
  229. });
  230. }
  231. api.common.detail(row.sourceId).then((res: any) => {
  232. state.detail = res.data;
  233. if (res.data.from == 4) {
  234. //propertyData
  235. api.node.getpropertyList({ key: res.data.deviceConfig.productKey }).then((re: any) => {
  236. state.propertyData = re;
  237. });
  238. }
  239. if (res.data.from == 2) {
  240. //propertyData
  241. api.common.getfields(row.sourceId).then((re: any) => {
  242. state.dbData = re.data;
  243. });
  244. }
  245. });
  246. state.ruleForm = row;
  247. state.isShowDialog = true;
  248. };
  249. const resetForm = () => {
  250. state.ruleForm = {
  251. nodeId: 0,
  252. name: '',
  253. isPk: 0,
  254. from: 1,
  255. key: '',
  256. rule: [],
  257. description: '',
  258. };
  259. };
  260. // 关闭弹窗
  261. const closeDialog = () => {
  262. state.isShowDialog = false;
  263. };
  264. // 取消
  265. const onCancel = () => {
  266. closeDialog();
  267. };
  268. // 新增
  269. const onSubmit = () => {
  270. const formWrap = unref(formRef) as any;
  271. if (!formWrap) return;
  272. formWrap.validate((valid: boolean) => {
  273. if (valid) {
  274. //修改rule数据
  275. // state.rule.forEach((item, index) => {
  276. // item.params[item.params.name] = item.params.value;
  277. // delete item.params.name;
  278. // delete item.params.value;
  279. // });
  280. state.ruleForm.rule = state.rule;
  281. if (state.ruleForm.nodeId !== 0) {
  282. //修改
  283. api.node.edit(state.ruleForm).then(() => {
  284. ElMessage.success('数据节点类型修改成功');
  285. closeDialog(); // 关闭弹窗
  286. emit('typeList');
  287. });
  288. } else {
  289. //添加
  290. api.node.add(state.ruleForm).then(() => {
  291. ElMessage.success('数据节点类型添加成功');
  292. closeDialog(); // 关闭弹窗
  293. emit('typeList');
  294. });
  295. }
  296. }
  297. });
  298. };
  299. const getNodeList = (e) => {
  300. state.propertyData.forEach((item, index) => {
  301. if (item.key === e) {
  302. state.ruleForm.dataType = item.valueType.type;
  303. }
  304. });
  305. };
  306. const getDbList = (e)=>{
  307. state.ruleForm.dataType = state.dbData[e].Type;
  308. }
  309. const onKeyclick = (e) => {
  310. //console.log(e);
  311. // if (e.target.innerText && e.target.className == 'jv-key') {
  312. // let str = e.target.innerText;
  313. // str = str.substr(0, str.length - 1);
  314. // state.ruleForm.value = str;
  315. // state.dialogVisible = false;
  316. // var con = {
  317. // ...state.jsonData,
  318. // };
  319. // // var jsonstr = getOrgIdArr([], str, con);
  320. // // state.ruleForm.value = jsonstr.join('.');
  321. // }
  322. };
  323. const jsonPath = (arr, json, basePath) => {
  324. // 生成jsonpath
  325. const type = validateType(json);
  326. if (type === 'object') {
  327. for (let key in json) {
  328. const item = {
  329. key,
  330. path: `${basePath}.${key}`,
  331. };
  332. const childType = validateType(json[key]);
  333. item.type = childType;
  334. if (childType === 'object' || childType === 'array') {
  335. item.leaf = true;
  336. item.children = [];
  337. jsonPath(item.children, json[key], item.path);
  338. } else {
  339. item.leaf = false;
  340. item.value = json[key];
  341. }
  342. arr.push(item);
  343. }
  344. } else if (type === 'array') {
  345. json.forEach((item, index) => {
  346. const childType = validateType(item);
  347. const obj = {
  348. key: index,
  349. };
  350. obj.type = childType;
  351. obj.path = `${basePath}.${index}`;
  352. if (childType === 'object' || childType === 'array') {
  353. (obj.leaf = true), (obj.children = []);
  354. jsonPath(obj.children, item, obj.path);
  355. } else {
  356. obj.value = item;
  357. obj.leaf = false;
  358. }
  359. arr.push(obj);
  360. });
  361. }
  362. return arr;
  363. };
  364. // 校验JSON数据类型
  365. const validateType = (val) => {
  366. let type = typeof val;
  367. if (type === 'object') {
  368. if (Array.isArray(val)) {
  369. return 'array';
  370. } else if (val === null) {
  371. return 'null';
  372. } else {
  373. return 'object';
  374. }
  375. } else {
  376. switch (type) {
  377. case 'boolean':
  378. return 'boolean';
  379. case 'string':
  380. return 'string';
  381. case 'number':
  382. return 'number';
  383. default:
  384. return 'error';
  385. }
  386. }
  387. };
  388. const getOrgIdArr = (parents, childNode, treeData) => {
  389. for (var key in treeData) {
  390. // 父节点查询条件
  391. if (key === childNode) {
  392. // 如果找到结果,保存当前节点
  393. parents.push(key);
  394. break;
  395. } else {
  396. if (treeData[key] instanceof Object) {
  397. // console.log(treeData[key]);
  398. parents.push(key);
  399. //没找到,遍历该节点的子节点
  400. getOrgIdArr(parents, childNode, treeData[key]);
  401. }
  402. }
  403. }
  404. return parents;
  405. };
  406. return {
  407. jsonPath,
  408. handlePath,
  409. validateType,
  410. getNodeList,
  411. getDbList,
  412. onKeyclick,
  413. getOrgIdArr,
  414. addRule,
  415. onTest,
  416. delRule,
  417. openDialog,
  418. closeDialog,
  419. onCancel,
  420. onSubmit,
  421. formRef,
  422. ...toRefs(state),
  423. };
  424. },
  425. });
  426. </script>
  427. <style>
  428. .el-input__wrapper {
  429. width: 98%;
  430. }
  431. .box-content {
  432. border: 1px solid #e8e8e8;
  433. margin: 10px;
  434. padding: 10px;
  435. }
  436. .content-f {
  437. display: flex;
  438. margin-bottom: 10px;
  439. }
  440. .content-f .el-input__wrapper {
  441. margin-right: 5px;
  442. }
  443. .addbutton {
  444. width: 100%;
  445. margin-top: 10px;
  446. }
  447. .conicon {
  448. width: 55px;
  449. height: 25px;
  450. font-size: 28px;
  451. line-height: 28px;
  452. cursor: pointer;
  453. }
  454. .jv-key {
  455. cursor: pointer;
  456. color: #0034f1;
  457. }
  458. </style>