create.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. <template>
  2. <el-card class="system-dic-container" style="position: relative;">
  3. <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
  4. <el-tab-pane label="新建服务器" name="first">
  5. <el-collapse v-model="activeViewName">
  6. <el-collapse-item title="基本信息" name="1">
  7. <div class="collapse-wrap">
  8. <el-form style="width: 600px;margin: 0 auto;" :model="form" label-width="98px">
  9. <el-form-item label="名称">
  10. <el-input v-model="form.name" placeholder="请填写名称" />
  11. </el-form-item>
  12. <el-form-item label="类型">
  13. <el-select @change="handleChangeType" v-model="form.types" placeholder="请选择类型">
  14. <el-option
  15. v-for="dict in network_server_type"
  16. :key="dict.value"
  17. :label="dict.label"
  18. :value="dict.value">
  19. </el-option>
  20. </el-select>
  21. </el-form-item>
  22. <el-form-item v-if="form.types == 'tcp'" label="粘拆包规则">
  23. <el-select @change="initData" v-model="stickValue" placeholder="请选择类型">
  24. <el-option
  25. v-for="dict in stick_type"
  26. :key="dict.value"
  27. :label="dict.label"
  28. :value="dict.value">
  29. </el-option>
  30. </el-select>
  31. </el-form-item>
  32. <el-form-item v-if="form.types == 'tcp' && stickValue">
  33. <el-form-item v-if="stickValue == '分隔符'" class="flex-column" label="分隔符">
  34. <el-input v-model="stick['delimit,omitempty']" placeholder="请填写分隔符" />
  35. </el-form-item>
  36. <el-form-item v-if="stickValue == '自定义脚本'" class="flex-column" label="自定义脚本">
  37. <el-input v-model="stick['custom,omitempty']" placeholder="请填写自定义脚本" />
  38. </el-form-item>
  39. <el-form-item v-if="stickValue == '固定长度'" class="flex-column" label="固定长度">
  40. <el-input type="number" v-model="stick['fixedLen,omitempty']" placeholder="请填写固定长度" />
  41. </el-form-item>
  42. <el-form-item v-if="stickValue == '长度字段'" class="flex-column" label="长度">
  43. <el-input type="number" v-model="stick['len,omitempty']['len']" placeholder="请填写长度" />
  44. </el-form-item>
  45. <el-form-item v-if="stickValue == '长度字段'" class="flex-column" label="偏移量">
  46. <el-input type="number" v-model="stick['len,omitempty']['offset']" placeholder="请填写偏移量" />
  47. </el-form-item>
  48. <el-form-item v-if="stickValue == '长度字段'" class="flex-column" label="大小端">
  49. <el-select v-model="stick['len,omitempty']['endian']" placeholder="请选择大小端">
  50. <el-option label="大端" value="大端" />
  51. <el-option label="小端" value="小端" />
  52. </el-select>
  53. </el-form-item>
  54. </el-form-item>
  55. <el-form-item label="地址">
  56. <el-input v-model="form.addr" placeholder="端口号" />
  57. </el-form-item>
  58. <el-form-item label="开启TLS">
  59. <el-radio-group v-model="form.isTls" class="ml-4">
  60. <el-radio :label="1">是</el-radio>
  61. <el-radio :label="0">否</el-radio>
  62. </el-radio-group>
  63. </el-form-item>
  64. <el-form-item v-if="form.isTls == 1 && form.types != 'mqtt_server'" label="选择证书">
  65. <el-select v-model="form.certificateId" placeholder="请选择证书">
  66. <el-option
  67. v-for="item in certificateList"
  68. :key="item.id"
  69. :label="item.name"
  70. :value="item.id">
  71. </el-option>
  72. </el-select>
  73. </el-form-item>
  74. <el-form-item v-if="form.isTls == 1 && form.types == 'mqtt_server'" label="接入方式">
  75. <el-select v-model="form.authType" placeholder="选择接入方式">
  76. <el-option label="Basic" :value="1" />
  77. <el-option label="AccessToken" :value="2" />
  78. <!-- <el-option label="证书" :value="3" /> -->
  79. </el-select>
  80. <el-form-item v-if="form.authType == 1" class="flex-column" label="用户名">
  81. <el-input v-model="form.authUser" placeholder="请填写用户名" />
  82. </el-form-item>
  83. <el-form-item v-if="form.authType == 1" class="flex-column" label="密码">
  84. <el-input v-model="form.authPasswd" placeholder="请填写密码" />
  85. </el-form-item>
  86. <el-form-item v-if="form.authType == 2" class="flex-column" label="Aceess Token">
  87. <el-input v-model="form.accessToken" placeholder="请填写Aceess Token" />
  88. </el-form-item>
  89. </el-form-item>
  90. <el-form-item label="启用">
  91. <el-switch :active-value="1" :inactive-value="0" v-model="form.status" />
  92. </el-form-item>
  93. </el-form>
  94. </div>
  95. </el-collapse-item>
  96. <el-collapse-item title="注册包" name="2">
  97. <el-form style="width: 600px;margin: 0 auto;" :model="form" label-width="98px">
  98. <el-form-item label="正则表达式">
  99. <el-input v-model="form.register.regex" placeholder="请填写名称" />
  100. </el-form-item>
  101. </el-form>
  102. </el-collapse-item>
  103. <el-collapse-item title="协议适配" name="3">
  104. <el-form style="width: 600px;margin: 0 auto;" :model="form" label-width="98px">
  105. <el-form-item label="协议">
  106. <el-select v-model="form.protocol.name" placeholder="请选择协议适配">
  107. <el-option
  108. v-for="dict in network_protocols"
  109. :key="dict.value"
  110. :label="dict.label"
  111. :value="dict.value">
  112. </el-option>
  113. <!-- <el-option label="Modbus RTU" value="Modbus RTU" />
  114. <el-option label="Modbus TCP" value="Modbus TCP" />
  115. <el-option label="Omron Hostlink" value="Omron Hostlink" />
  116. <el-option label="Omron FINS UDP" value="Omron FINS UDP" />
  117. <el-option label="Omron FINS TCP" value="Omron FINS TCP" />
  118. <el-option label="Simatic S7-200 Smart" value="Simatic S7-200 Smart" />
  119. <el-option label="Simatic S7-200" value="Simatic S7-200" />
  120. <el-option label="Simatic S7-300" value="Simatic S7-300" />
  121. <el-option label="Simatic S7-400" value="Simatic S7-400" />
  122. <el-option label="Simatic S7-1200" value="Simatic S7-1200" />
  123. <el-option label="Simatic S7-1500" value="Simatic S7-1500" /> -->
  124. </el-select>
  125. </el-form-item>
  126. <el-form-item label="协议参数">
  127. <codeEditor class="params" ref="mirrorRef"
  128. :mode="resourceModalPro.mode"
  129. :content="resourceModalPro.content"
  130. >
  131. </codeEditor>
  132. </el-form-item>
  133. </el-form>
  134. </el-collapse-item>
  135. </el-collapse>
  136. </el-tab-pane>
  137. <!-- <el-tab-pane label="专家视图" name="second">
  138. <h1>专家视图</h1>
  139. </el-tab-pane> -->
  140. </el-tabs>
  141. <div style="position: absolute;right:20px;top: 20px;">
  142. <el-button size="medium" @click="goBack">取消</el-button>
  143. <el-button @click="submit" size="medium" type="primary">提交</el-button>
  144. </div>
  145. <!-- <codeEditor ref="mirrorRef"
  146. :mode="resourceModalPro.mode"
  147. :content="resourceModalPro.content"
  148. >
  149. </codeEditor> -->
  150. </el-card>
  151. </template>
  152. <script lang="ts">
  153. import { toRefs, reactive, onMounted, ref, defineComponent, getCurrentInstance, watch } from 'vue';
  154. import { Delete, Edit, Search, Share, Upload } from '@element-plus/icons-vue';
  155. import { ElMessageBox, ElMessage, FormInstance } from 'element-plus';
  156. import type { TabsPaneContext } from 'element-plus'
  157. import codeEditor from '/@/components/codeEditor/index.vue'
  158. import serverDetail from './component/serverDetail.vue'
  159. import { useRoute, useRouter } from 'vue-router';
  160. import api from '/@/api/network';
  161. import api2 from '/@/api/system';
  162. interface TableDataState {
  163. // ids: number[];
  164. // id: string;
  165. activeViewName: string[];
  166. resourceModalPro: {
  167. mode: string,
  168. content: string,
  169. // content: object,
  170. },
  171. detail: object,
  172. form: object,
  173. certificateList: object[];
  174. stick: {
  175. // 分隔符
  176. "delimit,omitempty": string,
  177. // 自定义脚本
  178. "custom,omitempty": string,
  179. // 固定长度
  180. "fixedLen,omitempty": number,
  181. // 长度字段
  182. "len,omitempty": {
  183. "len": number,
  184. "offset": number,
  185. "endian": string
  186. }
  187. };
  188. stick_type: object[];
  189. stickValue: string;
  190. }
  191. export default defineComponent({
  192. name: 'serverCreate',
  193. components: { codeEditor, serverDetail },
  194. props: {
  195. type: {
  196. type: String,
  197. default: ''
  198. }
  199. },
  200. setup(props, context) {
  201. const { proxy } = getCurrentInstance() as any;
  202. const route = useRoute();
  203. const router = useRouter();
  204. const { network_server_type, network_protocols } = proxy.useDict('network_server_type', 'network_protocols');
  205. const state = reactive<TableDataState>({
  206. stickValue: "",
  207. stick: {
  208. "delimit,omitempty": "",
  209. "custom,omitempty": "",
  210. "fixedLen,omitempty": 0,
  211. "len,omitempty": {
  212. "len": 0,
  213. "offset": 0,
  214. "endian": ""
  215. }
  216. },
  217. stick_type: [
  218. {
  219. label: "分隔符",
  220. value: "分隔符"
  221. },
  222. {
  223. label: "自定义脚本",
  224. value: "自定义脚本"
  225. },
  226. {
  227. label: "固定长度",
  228. value: "固定长度"
  229. },
  230. {
  231. label: "长度字段",
  232. value: "长度字段"
  233. }
  234. ],
  235. resourceModalPro: {
  236. mode: '',
  237. content: ''
  238. },
  239. detail:{},
  240. activeViewName: ['1','2','3'],
  241. certificateList: [],
  242. form:{
  243. id: "",
  244. // AccessToken
  245. accessToken: "",
  246. // 认证密码
  247. authPasswd: "",
  248. // 认证用户
  249. authUser: "",
  250. // 认证方式(1=Basic,2=AccessToken,3=证书)
  251. authType: 3,
  252. // 是否开启TLS
  253. isTls: 0,
  254. // 证书id
  255. certificateId: "",
  256. // 名称
  257. name: '',
  258. // 类型
  259. types: 'tcp',
  260. // 禁用
  261. status: 0,
  262. // 地址
  263. addr: '',
  264. register: {
  265. regex: "^\w+$"
  266. },
  267. // 协议适配
  268. protocol: {
  269. name: "ModbusTCP",
  270. options: {}
  271. },
  272. // 心跳包
  273. heartbeat: {
  274. enable: false,
  275. hex: "",
  276. regex: "^\\w+$",
  277. text: "",
  278. timeout: 30
  279. },
  280. // 设备
  281. devices: []
  282. }
  283. });
  284. const mirrorRef = ref('mirrorRef')
  285. const activeName = ref('first')
  286. const getDetail = () => {
  287. const id = route.params && route.params.id;
  288. api.tunnel.getDetail({"id": id}).then((res: any) => {
  289. state.detail = res
  290. })
  291. };
  292. const submit = () => {
  293. if(!state.form.id) {
  294. delete state.form.id;
  295. }
  296. let params = {
  297. ...state.form,
  298. "stick": {
  299. ...state.stick
  300. }
  301. }
  302. if(mirrorRef.value.getValue()) {
  303. state.form.protocol.options = eval("(" + mirrorRef.value.getValue() + ")")
  304. }
  305. // return
  306. api.server.addItem(params).then((res: any) => {
  307. ElMessage.success('添加成功')
  308. goBack()
  309. // const { list, total, page } = res
  310. // state.data = list
  311. // state.total = total
  312. // state.param.page = page
  313. });
  314. };
  315. const goBack = () => {
  316. router.go(-1);
  317. }
  318. onMounted(() => {
  319. let obj = {}
  320. var jsonData = JSON.stringify(obj);
  321. state.resourceModalPro.content = JSON.stringify(JSON.parse(jsonData),null,4);
  322. getCertificateList()
  323. });
  324. const handleClick = (tab: TabsPaneContext, event: Event) => {
  325. }
  326. const getCertificateList = () => {
  327. api2.certificate.getList().then((res: any) => {
  328. state.certificateList = res.Info;
  329. })
  330. }
  331. const initData = () => {
  332. state.stick = {
  333. "delimit,omitempty": "",
  334. "custom,omitempty": "",
  335. "fixedLen,omitempty": 0,
  336. "len,omitempty": {
  337. "len": 0,
  338. "offset": 0,
  339. "endian": ""
  340. }
  341. }
  342. }
  343. const handleChangeType = () => {
  344. if(state.form.types != 'mqtt_server' && state.form.isTls == 1) {
  345. state.form.authType = 3
  346. return;
  347. }
  348. if(state.form.isTls == 0) {
  349. state.form.authType = ""
  350. }
  351. }
  352. watch(
  353. () => state.form.types,
  354. (value) => {
  355. getCertificateList()
  356. // api.certificate.getList();
  357. }
  358. );
  359. watch(
  360. () => state.form.isTls,
  361. (value) => {
  362. if(value == 0) {
  363. state.form.authType = ""
  364. }
  365. // api.certificate.getList();
  366. }
  367. );
  368. return {
  369. Edit,
  370. mirrorRef,
  371. activeName,
  372. getDetail,
  373. handleClick,
  374. network_server_type,
  375. network_protocols,
  376. // editDicRef,
  377. // editAttrRef,
  378. // editFunRef,
  379. // editEventRef,
  380. // editTabRef,
  381. getCertificateList,
  382. submit,
  383. goBack,
  384. initData,
  385. handleChangeType,
  386. ...toRefs(props),
  387. ...toRefs(state),
  388. };
  389. },
  390. });
  391. </script>
  392. <style>
  393. .CodeMirror {
  394. width: 100%;
  395. height: 600px;
  396. font-size: 16px;
  397. }
  398. </style>
  399. <style lang="scss" scoped>
  400. ::v-deep .el-collapse-item__header {
  401. position: relative;
  402. padding-left: 20px;
  403. .el-collapse-item__arrow {
  404. margin: 0!important;
  405. position: absolute;
  406. left: 0;
  407. right: 0;
  408. }
  409. }
  410. ::v-deep .el-input,
  411. ::v-deep .el-input-number {
  412. width: 500px;
  413. }
  414. ::v-deep .params {
  415. width: 600px;
  416. }
  417. ::v-deep .flex-column {
  418. display: flex;
  419. flex-direction: column;
  420. .el-form-item__label {
  421. justify-content: flex-start;
  422. }
  423. }
  424. </style>