edit.vue 14 KB

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