parkingInfo.vue 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281
  1. <template>
  2. <el-row>
  3. <el-col :span="4">
  4. <div class="region">
  5. <div class="regionTitle">
  6. <div class="regionTitle-text">
  7. <el-text style="font-weight: 550">{{ $t.value.park }}</el-text>
  8. </div>
  9. <div class="regionTitle-icon">
  10. <el-icon
  11. size="large"
  12. color="#008000"
  13. @click="openRegion('创建区域', '')"
  14. >
  15. <Plus />
  16. </el-icon>
  17. <el-icon
  18. style="padding-left: 5px"
  19. size="large"
  20. color="#4682b4"
  21. >
  22. <Refresh />
  23. </el-icon>
  24. </div>
  25. </div>
  26. <el-menu
  27. default-active="0"
  28. background-color="#f5f5f5"
  29. >
  30. <el-menu-item
  31. v-for="(item,val) in regionList"
  32. :key="item.ID"
  33. :index="val.toString()"
  34. @click="changeRegion(item)"
  35. >
  36. <div style="display: flex;justify-content: space-between; align-items: center;width: 100%">
  37. <span>{{ item.lot_name }}}</span>
  38. <div>
  39. <el-icon @click.stop="openRegion('编辑区域', item)">
  40. <edit />
  41. </el-icon>
  42. <el-icon @click.stop="deleteRegion(item.ID)">
  43. <delete />
  44. </el-icon>
  45. </div>
  46. </div>
  47. </el-menu-item>
  48. </el-menu>
  49. </div>
  50. </el-col>
  51. <el-col
  52. :span="19"
  53. style="margin-left: 40px"
  54. >
  55. <el-tabs
  56. v-model="activeName"
  57. class="demo-tabs"
  58. @tab-click="handleClick"
  59. >
  60. <el-tab-pane
  61. :label="$t.value.booth"
  62. name="detail"
  63. >
  64. <el-form inline>
  65. <el-form-item>
  66. <el-button
  67. icon="Plus"
  68. text
  69. type="success"
  70. @click="openPosition('岗亭新增','')"
  71. >
  72. {{ $t.value.new }}
  73. </el-button>
  74. </el-form-item>
  75. <el-form-item>
  76. <el-button
  77. icon="Refresh"
  78. text
  79. type="primary"
  80. @click="getGuardBoothList"
  81. >{{ $t.value.reload }}
  82. </el-button>
  83. </el-form-item>
  84. </el-form>
  85. <el-table
  86. size="small"
  87. :data="positionList"
  88. height="605"
  89. >
  90. <el-table-column
  91. :label="$t.value.coding"
  92. align="center"
  93. width="100"
  94. prop="booth_code"
  95. />
  96. <el-table-column
  97. :label="$t.value.Name"
  98. align="center"
  99. width="250"
  100. prop="booth_name"
  101. />
  102. <el-table-column
  103. :label="$t.value.IpAddress"
  104. align="center"
  105. width="250"
  106. prop="ip_address"
  107. />
  108. <el-table-column
  109. :label="$t.value.Remarks"
  110. align="center"
  111. prop="description"
  112. />
  113. <el-table-column
  114. :label="$t.value.Action"
  115. align="center"
  116. >
  117. <template #default="scope">
  118. <el-button
  119. text
  120. type="primary"
  121. icon="edit"
  122. @click="openPosition('岗亭编辑', scope.row)"
  123. >
  124. {{ $t.value.modify }}
  125. </el-button>
  126. <el-button
  127. text
  128. type="primary"
  129. icon="delete"
  130. @click="delPosition(scope.row.ID)"
  131. >
  132. {{ $t.value.remove }}
  133. </el-button>
  134. </template>
  135. </el-table-column>
  136. </el-table>
  137. <div style="width: 100%;display: flex;justify-content: end">
  138. <el-pagination
  139. :current-page="searchGuardBooth.page"
  140. :page-size="searchGuardBooth.page_size"
  141. :page-sizes="[10, 30, 50, 100]"
  142. :total="guardTotal"
  143. layout="total, sizes, prev, pager, next, jumper"
  144. style="padding-right: 10px"
  145. @current-change="handleCurrentChange"
  146. @size-change="handleSizeChange"
  147. />
  148. </div>
  149. </el-tab-pane>
  150. <el-tab-pane
  151. :label="$t.value.access"
  152. name="people"
  153. >
  154. <el-form inline>
  155. <el-form-item>
  156. <el-button
  157. icon="Plus"
  158. text
  159. type="success"
  160. @click="openChannel('通道新增','')"
  161. >{{ $t.value.new }}
  162. </el-button>
  163. </el-form-item>
  164. <el-form-item>
  165. <el-button
  166. icon="Refresh"
  167. text
  168. type="primary"
  169. @click="getChannelList"
  170. >{{ $t.value.reload }}
  171. </el-button>
  172. </el-form-item>
  173. </el-form>
  174. <el-table
  175. size="small"
  176. :data="channelList"
  177. height="605"
  178. >
  179. <el-table-column
  180. :label="$t.value.coding"
  181. align="center"
  182. width="100"
  183. prop="channel_code"
  184. />
  185. <el-table-column
  186. :label="$t.value.Name"
  187. align="center"
  188. width="250"
  189. prop="channel_name"
  190. />
  191. <el-table-column
  192. v-slot="scope"
  193. :label="$t.value.Direction"
  194. align="center"
  195. width="150"
  196. >
  197. {{ scope.row.direction === 'in' ? '进' : '出' }}
  198. </el-table-column>
  199. <el-table-column
  200. :label="$t.value.Allow"
  201. align="center"
  202. width="200"
  203. >
  204. <template #default="scope">
  205. <el-button
  206. plain
  207. :type="scope.row.allow_temporary ? 'success' : 'danger'"
  208. >
  209. {{ scope.row.allow_temporary ? '允许' : '不允许' }}
  210. </el-button>
  211. </template>
  212. </el-table-column>
  213. <el-table-column
  214. :label="$t.value.booth + 'Id'"
  215. align="center"
  216. prop="booth_id"
  217. />
  218. <el-table-column
  219. v-slot="scope"
  220. :label="$t.value.Action"
  221. align="center"
  222. >
  223. <el-button
  224. type="primary"
  225. icon="edit"
  226. text
  227. @click="openChannel('通道编辑', scope.row)"
  228. >{{ $t.value.modify }}
  229. </el-button>
  230. <el-button
  231. type="primary"
  232. icon="delete"
  233. text
  234. @click="removeChannel(scope.row.ID)"
  235. >{{ $t.value.remove }}
  236. </el-button>
  237. </el-table-column>
  238. </el-table>
  239. <div style="width: 100%;display: flex;justify-content: end">
  240. <el-pagination
  241. :current-page="queryChannelData.page"
  242. :page-size="queryChannelData.page_size"
  243. :page-sizes="[10, 30, 50, 100]"
  244. :total="channelTotal"
  245. layout="total, sizes, prev, pager, next, jumper"
  246. style="padding-right: 10px"
  247. @current-change="handleCurrentChannel"
  248. @size-change="handleSizeChannel"
  249. />
  250. </div>
  251. </el-tab-pane>
  252. <el-tab-pane
  253. :label="$t.value.device"
  254. name="department"
  255. >
  256. <el-form inline>
  257. <el-form-item>
  258. <el-button
  259. icon="Plus"
  260. text
  261. type="success"
  262. @click="openDevice('新增设备','')"
  263. >{{ $t.value.new }}
  264. </el-button>
  265. </el-form-item>
  266. <el-form-item>
  267. <el-button
  268. icon="Refresh"
  269. text
  270. type="primary"
  271. @click="getDeviceList"
  272. >{{ $t.value.reload }}
  273. </el-button>
  274. </el-form-item>
  275. </el-form>
  276. <el-table
  277. size="small"
  278. :data="deviceList"
  279. height="605"
  280. >
  281. <el-table-column
  282. :label="$t.value.coding"
  283. align="center"
  284. width="100"
  285. prop="device_code"
  286. />
  287. <el-table-column
  288. :label="$t.value.Name"
  289. align="center"
  290. width="250"
  291. prop="device_name"
  292. />
  293. <el-table-column
  294. :label="$t.value.Type"
  295. align="center"
  296. width="150"
  297. prop="connect_type"
  298. />
  299. <el-table-column
  300. :label="$t.value.IpAddress"
  301. align="center"
  302. width="200"
  303. prop="ip_address"
  304. />
  305. <el-table-column
  306. :label="$t.value.Port"
  307. align="center"
  308. width="150"
  309. prop="port"
  310. />
  311. <el-table-column
  312. :label="$t.value.Enable"
  313. align="center"
  314. width="150"
  315. >
  316. <template #default="scope">
  317. <el-button
  318. :type="scope.row.is_active ? 'success' : 'danger'"
  319. plain
  320. >
  321. {{ scope.row.is_active ? '启用' : '不启用' }}
  322. </el-button>
  323. </template>
  324. </el-table-column>
  325. <el-table-column
  326. :label="$t.value.Action"
  327. align="center"
  328. >
  329. <template #default="scope">
  330. <el-button
  331. type="primary"
  332. icon="Link"
  333. text
  334. @click="connectDevice(scope.row)"
  335. >{{ $t.value.Connect }}
  336. </el-button>
  337. <el-button
  338. type="primary"
  339. icon="edit"
  340. text
  341. @click="openDevice('编辑设备', scope.row)"
  342. >{{ $t.value.modify }}
  343. </el-button>
  344. <el-button
  345. type="primary"
  346. icon="delete"
  347. text
  348. @click="removeDevice(scope.row.ID)"
  349. >{{ $t.value.remove }}
  350. </el-button>
  351. </template>
  352. </el-table-column>
  353. </el-table>
  354. <div style="width: 100%;display: flex;justify-content: end">
  355. <el-pagination
  356. :current-page="searchDeviceData.page"
  357. :page-size="searchDeviceData.page_size"
  358. :page-sizes="[10, 30, 50, 100]"
  359. :total="deviceTotal"
  360. layout="total, sizes, prev, pager, next, jumper"
  361. style="padding-right: 10px"
  362. @current-change="handleCurrentDevice"
  363. @size-change="handleSizeDevice"
  364. />
  365. </div>
  366. </el-tab-pane>
  367. </el-tabs>
  368. </el-col>
  369. <el-dialog
  370. v-model="positionShow"
  371. :title="positionTitle"
  372. width="600"
  373. >
  374. <el-form label-width="120">
  375. <el-form-item :label="$t.value.park +':'">
  376. <el-select
  377. v-model="positionRegionName"
  378. placeholder="请选择停车区域"
  379. @change="changePositionRegion"
  380. >
  381. <el-option
  382. v-for="item in regionList"
  383. :key="item.ID"
  384. :value="item.lot_name"
  385. />
  386. </el-select>
  387. </el-form-item>
  388. <el-form-item :label="$t.value.BoothCode + ':'">
  389. <el-input v-model="positionData.booth_code" />
  390. </el-form-item>
  391. <el-form-item :label="$t.value.BoothName + ':'">
  392. <el-input v-model="positionData.booth_name" />
  393. </el-form-item>
  394. <el-form-item :label="$t.value.IpAddress +':'">
  395. <el-input v-model="positionData.ip_address" />
  396. </el-form-item>
  397. <el-form-item :label="$t.value.Remarks + ':'">
  398. <el-input
  399. v-model="positionData.description"
  400. type="textarea"
  401. />
  402. </el-form-item>
  403. </el-form>
  404. <template #footer>
  405. <div class="dialog-footer">
  406. <el-button @click="positionShow = false">
  407. {{ $t.value.Cancel }}
  408. </el-button>
  409. <el-button
  410. type="primary"
  411. @click="addPosition"
  412. >
  413. {{ $t.value.Confirm }}
  414. </el-button>
  415. </div>
  416. </template>
  417. </el-dialog>
  418. <el-dialog
  419. v-model="channelShow"
  420. :title="channelTitle"
  421. width="600"
  422. >
  423. <el-form>
  424. <el-form-item :label="$t.value.Passage_Booth + ':'">
  425. <el-select
  426. v-model="channelPositionName"
  427. @change="changeChannelPosition"
  428. >
  429. <el-option
  430. v-for="item in positionList"
  431. :key="item.ID"
  432. :value="item.booth_name"
  433. :label="item.booth_name"
  434. />
  435. </el-select>
  436. </el-form-item>
  437. <el-form-item :label="$t.value.Passage_Code + ':'">
  438. <el-input v-model="channelData.channel_code" />
  439. </el-form-item>
  440. <el-form-item :label="$t.value.Passage_Name + ':'">
  441. <el-input v-model="channelData.channel_name" />
  442. </el-form-item>
  443. <el-form-item :label="$t.value.Entry_Exit + ':'">
  444. <el-radio-group
  445. v-model="channelData.direction"
  446. size="large"
  447. fill="#409eff"
  448. >
  449. <el-radio-button
  450. :label="$t.value.advance"
  451. value="in"
  452. />
  453. <el-radio-button
  454. :label="$t.value.out"
  455. value="out"
  456. />
  457. </el-radio-group>
  458. </el-form-item>
  459. <el-form-item :label="$t.value.Allow + ':'">
  460. <el-radio-group
  461. v-model="channelData.allow_temporary"
  462. size="large"
  463. fill="#409eff"
  464. >
  465. <el-radio-button
  466. :label="$t.value.yes"
  467. :value="false"
  468. />
  469. <el-radio-button
  470. :label="$t.value.no"
  471. :value="true"
  472. />
  473. </el-radio-group>
  474. </el-form-item>
  475. <el-form-item :label="$t.value.Remarks + ':'">
  476. <el-input
  477. v-model="channelData.description"
  478. type="textarea"
  479. />
  480. </el-form-item>
  481. </el-form>
  482. <template #footer>
  483. <div class="dialog-footer">
  484. <el-button @click="channelShow = false">
  485. {{ $t.value.Cancel }}
  486. </el-button>
  487. <el-button
  488. type="primary"
  489. @click="channelOperation"
  490. >
  491. {{ $t.value.Confirm }}
  492. </el-button>
  493. </div>
  494. </template>
  495. </el-dialog>
  496. <el-dialog
  497. v-model="deviceShow"
  498. :title="deviceTitle"
  499. width="600"
  500. >
  501. <el-form label-width="150">
  502. <el-form-item :label="$t.value.Device_Channel + ':'">
  503. <el-select
  504. v-model="deviceChannelName"
  505. @change="changeDeviceChannel"
  506. >
  507. <el-option
  508. v-for="item in channelList"
  509. :key="item.ID"
  510. :value="item.channel_name"
  511. :label="item.channel_name"
  512. />
  513. </el-select>
  514. </el-form-item>
  515. <el-form-item :label="$t.value.Device_Name + ':'">
  516. <el-input v-model="deviceData.device_name" />
  517. </el-form-item>
  518. <el-form-item :label="$t.value.Device_Code + ':'">
  519. <el-input v-model="deviceData.device_code" />
  520. </el-form-item>
  521. <el-form-item :label="$t.value.Connection_Mode + ':'">
  522. <el-select v-model="deviceData.connect_type">
  523. <el-option
  524. label="tcp"
  525. value="tcp"
  526. />
  527. <el-option
  528. label="serial"
  529. value="serial"
  530. />
  531. </el-select>
  532. </el-form-item>
  533. <el-form-item
  534. v-show="deviceData.connect_type === 'tcp'"
  535. :label="$t.value.IpAddress + ':'"
  536. >
  537. <el-input v-model="deviceData.ip_address" />
  538. </el-form-item>
  539. <el-form-item
  540. v-show="deviceData.connect_type === 'tcp'"
  541. :label="$t.value.Port + ':'"
  542. >
  543. <el-input
  544. v-model="deviceData.port"
  545. type="number"
  546. />
  547. </el-form-item>
  548. <el-form-item
  549. v-show="deviceData.connect_type === 'serial'"
  550. label="串口名称:"
  551. >
  552. <el-input v-model="deviceData.com_port" />
  553. </el-form-item>
  554. <el-form-item
  555. v-show="deviceData.connect_type === 'serial'"
  556. label="串口波特率:"
  557. >
  558. <el-input
  559. v-model="deviceData.baud_rate"
  560. type="number"
  561. />
  562. </el-form-item>
  563. <el-form-item :label="$t.value.Enable + ':'">
  564. <el-radio-group
  565. v-model="deviceData.is_active"
  566. size="large"
  567. fill="#409eff"
  568. >
  569. <el-radio-button
  570. :label="$t.value.no"
  571. :value="false"
  572. />
  573. <el-radio-button
  574. :label="$t.value.yes"
  575. :value="true"
  576. />
  577. </el-radio-group>
  578. </el-form-item>
  579. <el-form-item :label="$t.value.Remarks + ':'">
  580. <el-input
  581. v-model="deviceData.description"
  582. type="textarea"
  583. />
  584. </el-form-item>
  585. </el-form>
  586. <template #footer>
  587. <div class="dialog-footer">
  588. <el-button @click="deviceShow = false">{{ $t.value.Cancel }}</el-button>
  589. <el-button
  590. type="primary"
  591. @click="deviceOperation"
  592. >
  593. {{ $t.value.Confirm }}
  594. </el-button>
  595. </div>
  596. </template>
  597. </el-dialog>
  598. <el-dialog
  599. v-model="regionShow"
  600. :title="regionTitle"
  601. width="500"
  602. >
  603. <el-form label-width="90">
  604. <el-form-item label="区域编码:">
  605. <el-input v-model="regionData.lot_code" />
  606. </el-form-item>
  607. <el-form-item label="区域名称:">
  608. <el-input v-model="regionData.lot_name" />
  609. </el-form-item>
  610. <el-form-item label="区域容量:">
  611. <el-input
  612. v-model="regionData.capacity"
  613. type="number"
  614. />
  615. </el-form-item>
  616. <el-form-item label="备注:">
  617. <el-input
  618. v-model="regionData.description"
  619. type="textarea"
  620. />
  621. </el-form-item>
  622. </el-form>
  623. <template #footer>
  624. <div class="dialog-footer">
  625. <el-button @click="regionShow = false">{{ $t.value.Cancel }}</el-button>
  626. <el-button
  627. type="primary"
  628. @click="regionOperation"
  629. >
  630. {{ $t.value.Confirm }}
  631. </el-button>
  632. </div>
  633. </template>
  634. </el-dialog>
  635. </el-row>
  636. </template>
  637. <script setup>
  638. // import sign from '@/assets/sign.png'
  639. import { ref, reactive, onMounted } from 'vue'
  640. import {
  641. addGuardBooth,
  642. obtainGuardBoothList,
  643. editGuardBooth,
  644. deleteGuardBooth,
  645. } from '@/api/guardBooth'
  646. import {
  647. addChannel,
  648. editChannel,
  649. obtainChannelList,
  650. deleteChannel
  651. } from '@/api/channel'
  652. import { addDevice, obtainDeviceList, editDevice, deleteDevice, joinDevice } from '@/api/device'
  653. import { addPullOver, editPullOver, obtainPullOverList, removePullOver } from '@/api/pullOver'
  654. import { ElMessage, ElMessageBox } from 'element-plus'
  655. import { t } from '@/lang/index.js'
  656. const activeName = ref('detail')
  657. const handleClick = () => {
  658. }
  659. const positionShow = ref(false)
  660. const positionTitle = ref('岗亭新增')
  661. // 岗亭数据.......................................
  662. const positionRegionName = ref('')
  663. const positionData = reactive({
  664. id: 0,
  665. booth_code: '',
  666. booth_name: '',
  667. ip_address: '',
  668. description: '',
  669. parking_lot_id: 0
  670. })
  671. const guardTotal = ref(0)
  672. const positionList = reactive([])
  673. const addPosition = () => {
  674. if (positionTitle.value === '岗亭新增') {
  675. if (positionData.parking_lot_id === 0) {
  676. ElMessage.error('请选择停车区域')
  677. return
  678. }
  679. if (positionData.booth_name === '' || positionData.booth_code === '' || positionData.ip_address === '') {
  680. ElMessage.error('请将除备注以外的信息填写完整')
  681. return
  682. }
  683. addGuardBooth(positionData).then(res => {
  684. if (res.code === 0) {
  685. ElMessage.success('添加成功')
  686. positionShow.value = false
  687. getGuardBoothList()
  688. }
  689. })
  690. } else {
  691. if (positionData.parking_lot_id === 0) {
  692. ElMessage.error('请选择停车区域')
  693. return
  694. }
  695. if (positionData.booth_name === '' || positionData.booth_code === '' || positionData.ip_address === '') {
  696. ElMessage.error('请将除备注以外的信息填写完整')
  697. return
  698. }
  699. editGuardBooth(positionData).then(res => {
  700. if (res.code === 0) {
  701. ElMessage.success('更新成功')
  702. positionShow.value = false
  703. getGuardBoothList()
  704. }
  705. })
  706. }
  707. }
  708. const changePositionRegion = (val) => {
  709. regionList.forEach(item => {
  710. if (item.lot_name === val) {
  711. positionData.parking_lot_id = item.ID
  712. }
  713. })
  714. }
  715. const openPosition = (head, data) => {
  716. positionTitle.value = head
  717. positionShow.value = true
  718. if (head === '岗亭编辑') {
  719. positionData.id = data.ID
  720. positionData.booth_code = data.booth_code
  721. positionData.booth_name = data.booth_name
  722. positionData.ip_address = data.ip_address
  723. positionData.description = data.description
  724. positionData.parking_lot_id = data.parking_lot_id
  725. regionList.forEach(item => {
  726. if (item.ID === data.parking_lot_id) {
  727. positionRegionName.value = item.lot_name
  728. }
  729. })
  730. } else {
  731. positionData.ip_address = ''
  732. positionData.description = ''
  733. positionData.booth_code = ''
  734. positionData.booth_name = ''
  735. positionData.parking_lot_id = 0
  736. positionRegionName.value = ''
  737. }
  738. }
  739. const searchGuardBooth = reactive({
  740. parking_lot_id: 0,
  741. booth_code: '',
  742. booth_name: '',
  743. page: 1,
  744. page_size: 10
  745. })
  746. const handleCurrentChange = (val) => {
  747. searchGuardBooth.page = val
  748. getGuardBoothList()
  749. }
  750. const handleSizeChange = (val) => {
  751. searchGuardBooth.page_size = val
  752. searchGuardBooth.page = 1
  753. getGuardBoothList()
  754. }
  755. const getGuardBoothList = () => {
  756. obtainGuardBoothList(searchGuardBooth).then(res => {
  757. if (res.code === 0) {
  758. positionList.length = 0
  759. positionList.push(...res.data.list)
  760. guardTotal.value = res.data.total
  761. }
  762. })
  763. }
  764. const delPosition = (id) => {
  765. ElMessageBox.confirm(
  766. '确定要删除该岗亭吗?',
  767. '提示',
  768. {
  769. confirmButtonText: '确认',
  770. cancelButtonText: '取消',
  771. type: 'warning',
  772. }
  773. )
  774. .then(() => {
  775. deleteGuardBooth(id).then(res => {
  776. if (res.code === 0) {
  777. ElMessage({
  778. type: 'success',
  779. message: '删除成功',
  780. })
  781. getGuardBoothList()
  782. } else {
  783. ElMessage({
  784. type: 'error',
  785. message: '删除失败',
  786. })
  787. }
  788. })
  789. })
  790. .catch(() => {
  791. ElMessage({
  792. type: 'info',
  793. message: '取消删除',
  794. })
  795. })
  796. }
  797. // 通道管理...................................................
  798. // 通道数据
  799. const channelShow = ref(false)
  800. const deviceTitle = ref('')
  801. const queryChannelData = reactive({
  802. parking_lot_id: 0,
  803. channel_code: '',
  804. channel_name: '',
  805. direction: '',
  806. page: 1,
  807. page_size: 10,
  808. allow_temporary: false
  809. })
  810. const channelPositionName = ref('')
  811. const channelData = reactive({
  812. id: 0,
  813. channel_code: '',
  814. channel_name: '',
  815. direction: 'in',
  816. allow_temporary: false,
  817. description: '',
  818. booth_id: 0,
  819. })
  820. const channelTitle = ref('通道新增')
  821. const channelList = reactive([])
  822. const changeChannelPosition = (val) => {
  823. positionList.forEach(item => {
  824. if (item.booth_name === val) {
  825. channelData.booth_id = item.ID
  826. }
  827. })
  828. }
  829. const channelTotal = ref(0)
  830. const openChannel = (head, data) => {
  831. channelTitle.value = head
  832. channelShow.value = true
  833. if (head === '通道编辑') {
  834. channelData.id = data.ID
  835. channelData.channel_code = data.channel_code
  836. channelData.channel_name = data.channel_name
  837. channelData.allow_temporary = data.allow_temporary
  838. channelData.direction = data.direction
  839. channelData.description = data.description
  840. channelData.booth_id = data.booth_id
  841. channelList.forEach(item => {
  842. if (item.ID === data.booth_id) {
  843. channelPositionName.value = item.booth_name
  844. }
  845. })
  846. } else {
  847. channelData.channel_code = ''
  848. channelData.channel_name = ''
  849. channelData.allow_temporary = false
  850. channelData.direction = 'in'
  851. channelData.description = ''
  852. channelData.booth_id = 0
  853. channelPositionName.value = ''
  854. }
  855. }
  856. const channelOperation = () => {
  857. if (channelTitle.value === '通道新增') {
  858. if (channelData.booth_id === 0) {
  859. ElMessage.error('请选择岗亭')
  860. return
  861. }
  862. if (channelData.channel_name === '' || channelData.channel_code === '') {
  863. ElMessage.error('请将除备注以外的信息填写完整')
  864. return
  865. }
  866. addChannel(channelData).then(res => {
  867. console.log('添加通道操作', res.data)
  868. if (res.code === 0) {
  869. ElMessage.success('添加成功')
  870. channelShow.value = false
  871. getChannelList()
  872. }
  873. })
  874. } else {
  875. if (channelData.booth_id === 0) {
  876. ElMessage.error('请选择岗亭')
  877. return
  878. }
  879. if (channelData.channel_name === '' || channelData.channel_code === '') {
  880. ElMessage.error('请将除备注以外的信息填写完整')
  881. return
  882. }
  883. editChannel(channelData).then(res => {
  884. if (res.code === 0) {
  885. ElMessage.success('更新成功')
  886. channelShow.value = false
  887. getChannelList()
  888. }
  889. })
  890. }
  891. }
  892. const handleCurrentChannel = (val) => {
  893. queryChannelData.page = val
  894. getChannelList()
  895. }
  896. const handleSizeChannel = (val) => {
  897. queryChannelData.page_size = val
  898. queryChannelData.page = 1
  899. getChannelList()
  900. }
  901. const getChannelList = () => {
  902. obtainChannelList(queryChannelData).then(res => {
  903. if (res.code === 0) {
  904. console.log(res.data)
  905. channelList.length = 0
  906. channelList.push(...res.data.list)
  907. channelTotal.value = res.data.total
  908. }
  909. })
  910. }
  911. const removeChannel = (id) => {
  912. ElMessageBox.confirm(
  913. t.value.deletePassageTip,
  914. t.value.tip,
  915. {
  916. confirmButtonText: t.value.Confirm,
  917. cancelButtonText: t.value.Cancel,
  918. type: 'warning',
  919. }
  920. )
  921. .then(() => {
  922. deleteChannel(id).then(res => {
  923. if (res.code === 0) {
  924. ElMessage({
  925. type: 'success',
  926. message: t.value.deleteSuccess,
  927. })
  928. getChannelList()
  929. } else {
  930. ElMessage({
  931. type: 'error',
  932. message: t.value.deleteFailed,
  933. })
  934. }
  935. })
  936. })
  937. .catch(() => {
  938. ElMessage({
  939. type: 'info',
  940. message: t.value.cancelDelete,
  941. })
  942. })
  943. }
  944. // 设备管理...............................................
  945. const deviceData = reactive({
  946. id: 0,
  947. parking_lot_id: 0,
  948. device_code: '',
  949. device_name: '',
  950. baud_rate: 0,
  951. ip_address: '',
  952. port: 0,
  953. com_port: '',
  954. description: '',
  955. connect_type: '',
  956. is_active: false,
  957. channel_id: 0
  958. })
  959. const deviceChannelName = ref('')
  960. const deviceShow = ref(false)
  961. const openDevice = (head, data) => {
  962. deviceTitle.value = head
  963. deviceShow.value = true
  964. if (head === '编辑设备') {
  965. deviceData.id = data.ID
  966. deviceData.device_code = data.device_code
  967. deviceData.device_name = data.device_name
  968. deviceData.baud_rate = data.baud_rate
  969. deviceData.ip_address = data.ip_address
  970. deviceData.port = data.port
  971. deviceData.com_port = data.com_port
  972. deviceData.description = data.description
  973. deviceData.connect_type = data.connect_type
  974. deviceData.channel_id = data.channel_id
  975. deviceData.is_active = data.is_active
  976. channelList.forEach(item => {
  977. if (item.ID === data.channel_id) {
  978. deviceChannelName.value = item.channel_name
  979. }
  980. })
  981. } else {
  982. deviceData.device_code = ''
  983. deviceData.device_name = ''
  984. deviceData.baud_rate = 0
  985. deviceData.ip_address = ''
  986. deviceData.port = 0
  987. deviceData.com_port = ''
  988. deviceData.description = ''
  989. deviceData.connect_type = 'tcp'
  990. deviceData.channel_id = 0
  991. deviceData.is_active = false
  992. deviceChannelName.value = ''
  993. }
  994. }
  995. const deviceOperation = async() => {
  996. deviceData.baud_rate = Number(deviceData.baud_rate)
  997. deviceData.port = Number(deviceData.port)
  998. if (deviceTitle.value === '新增设备') {
  999. await addDevice(deviceData).then(res => {
  1000. if (res.code === 0) {
  1001. ElMessage.success('添加成功')
  1002. deviceShow.value = false
  1003. getDeviceList()
  1004. } else {
  1005. ElMessage.error(res.data.msg)
  1006. }
  1007. })
  1008. } else {
  1009. await editDevice(deviceData).then(res => {
  1010. if (res.code === 0) {
  1011. ElMessage.success('编辑成功')
  1012. deviceShow.value = false
  1013. getDeviceList()
  1014. } else {
  1015. ElMessage.error('编辑失败')
  1016. }
  1017. })
  1018. }
  1019. }
  1020. const deviceList = reactive([])
  1021. const changeDeviceChannel = (val) => {
  1022. channelList.forEach(item => {
  1023. if (item.channel_name === val) {
  1024. deviceData.channel_id = item.ID
  1025. }
  1026. })
  1027. }
  1028. const deviceTotal = ref(0)
  1029. const handleCurrentDevice = (val) => {
  1030. searchDeviceData.page = val
  1031. getDeviceList()
  1032. }
  1033. const handleSizeDevice = (val) => {
  1034. searchDeviceData.page_size = val
  1035. searchDeviceData.page = 1
  1036. getDeviceList()
  1037. }
  1038. const searchDeviceData = reactive({
  1039. parking_lot_id: 0,
  1040. device_code: '',
  1041. device_type: '',
  1042. device_name: '',
  1043. status: '',
  1044. page: 1,
  1045. page_size: 10
  1046. })
  1047. const getDeviceList = async() => {
  1048. await obtainDeviceList(searchDeviceData).then(res => {
  1049. if (res.code === 0) {
  1050. deviceList.length = 0
  1051. if (res.data.list !== null) {
  1052. deviceList.push(...res.data.list)
  1053. deviceTotal.value = res.data.total
  1054. }
  1055. }
  1056. })
  1057. }
  1058. const removeDevice = async(id) => {
  1059. ElMessageBox.confirm(
  1060. t.value.deleteDeviceTip,
  1061. t.value.tip,
  1062. {
  1063. confirmButtonText: t.value.Confirm,
  1064. cancelButtonText: t.value.Cancel,
  1065. type: 'warning',
  1066. }
  1067. )
  1068. .then(() => {
  1069. deleteDevice(id).then(res => {
  1070. if (res.code === 0) {
  1071. ElMessage({
  1072. type: 'success',
  1073. message: '删除成功',
  1074. })
  1075. getDeviceList()
  1076. } else {
  1077. ElMessage({
  1078. type: 'error',
  1079. message: '删除失败',
  1080. })
  1081. }
  1082. })
  1083. })
  1084. .catch(() => {
  1085. ElMessage({
  1086. type: 'info',
  1087. message: '取消删除',
  1088. })
  1089. })
  1090. }
  1091. const connectDevice = async(data) => {
  1092. await joinDevice(data.ID).then(res => {
  1093. if (res.code === 0) {
  1094. ElMessage.success('连接成功')
  1095. } else {
  1096. ElMessage.error(res.data.msg)
  1097. }
  1098. })
  1099. }
  1100. // 停车区域....................................
  1101. const regionList = reactive([])
  1102. // 查询停车区域
  1103. const getRegionList = async() => {
  1104. await obtainPullOverList().then(res => {
  1105. if (res.code === 0) {
  1106. regionList.length = 0
  1107. regionList.push(...res.data.list)
  1108. }
  1109. })
  1110. }
  1111. // 停车区域操作
  1112. const regionData = reactive({
  1113. id: 0,
  1114. lot_code: '',
  1115. lot_name: '',
  1116. capacity: 0,
  1117. description: ''
  1118. })
  1119. const regionShow = ref(false)
  1120. const regionTitle = ref('创建区域')
  1121. const openRegion = (head, data) => {
  1122. regionTitle.value = head
  1123. regionShow.value = true
  1124. if (head === '编辑区域') {
  1125. regionData.id = data.ID
  1126. regionData.lot_code = data.lot_code
  1127. regionData.lot_name = data.lot_name
  1128. regionData.capacity = data.capacity
  1129. regionData.description = data.description
  1130. } else {
  1131. regionData.lot_code = ''
  1132. regionData.lot_name = ''
  1133. regionData.capacity = 0
  1134. regionData.description = ''
  1135. }
  1136. }
  1137. const regionOperation = async() => {
  1138. if (regionTitle.value === '创建区域') {
  1139. regionData.capacity = Number(regionData.capacity)
  1140. await addPullOver(regionData).then(res => {
  1141. if (res.code === 0) {
  1142. getRegionList()
  1143. ElMessage.success('创建成功')
  1144. regionShow.value = false
  1145. }
  1146. })
  1147. } else {
  1148. await editPullOver(regionData).then(res => {
  1149. if (res.code === 0) {
  1150. getRegionList()
  1151. ElMessage.success('修改成功')
  1152. regionShow.value = false
  1153. }
  1154. })
  1155. }
  1156. }
  1157. const deleteRegion = (id) => {
  1158. ElMessageBox.confirm(
  1159. '确定要删除该停车区域吗?',
  1160. '提示',
  1161. {
  1162. confirmButtonText: '确认',
  1163. cancelButtonText: '取消',
  1164. type: 'warning',
  1165. }
  1166. )
  1167. .then(() => {
  1168. removePullOver(id).then(res => {
  1169. if (res.code === 0) {
  1170. ElMessage({
  1171. type: 'success',
  1172. message: '删除成功',
  1173. })
  1174. getRegionList()
  1175. } else {
  1176. ElMessage({
  1177. type: 'error',
  1178. message: '删除失败',
  1179. })
  1180. }
  1181. })
  1182. })
  1183. .catch(() => {
  1184. ElMessage({
  1185. type: 'info',
  1186. message: '取消删除',
  1187. })
  1188. })
  1189. }
  1190. const changeRegion = async(item) => {
  1191. searchGuardBooth.parking_lot_id = item.ID
  1192. queryChannelData.parking_lot_id = item.ID
  1193. searchDeviceData.parking_lot_id = item.ID
  1194. await getGuardBoothList()
  1195. await getChannelList()
  1196. await getDeviceList()
  1197. }
  1198. onMounted(async() => {
  1199. await getRegionList()
  1200. if (regionList.length !== 0) {
  1201. searchGuardBooth.parking_lot_id = regionList[0].ID
  1202. queryChannelData.parking_lot_id = regionList[0].ID
  1203. searchDeviceData.parking_lot_id = regionList[0].ID
  1204. await getGuardBoothList()
  1205. await getChannelList()
  1206. await getDeviceList()
  1207. }
  1208. })
  1209. </script>
  1210. <style scoped lang="scss">
  1211. .region {
  1212. width: 100%;
  1213. height: 800px;
  1214. background-color: #f5f5f5;
  1215. .regionTitle {
  1216. width: 100%;
  1217. height: 40px;
  1218. display: flex;
  1219. border-bottom: 1px solid;
  1220. background-color: #b9b8b8;
  1221. .regionTitle-text {
  1222. width: 70%;
  1223. height: 40px;
  1224. display: flex;
  1225. align-items: center;
  1226. padding-left: 10px;
  1227. }
  1228. .regionTitle-icon {
  1229. width: 20%;
  1230. height: 40px;
  1231. display: flex;
  1232. align-items: center;
  1233. }
  1234. }
  1235. }
  1236. .basicInformation {
  1237. height: 40px;
  1238. background-color: #f8fafd;
  1239. display: flex;
  1240. }
  1241. .operation {
  1242. width: 100%;
  1243. height: 50px;
  1244. margin-top: 5px;
  1245. }
  1246. </style>