equipment.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. <!-- 装备管理 -->
  2. <template>
  3. <Container :query-form="queryForm" class="three-model-container">
  4. <!-- 查询表单 -->
  5. <template #query-form>
  6. <el-form-item label="装备名称">
  7. <el-input
  8. v-model="queryForm.equipmentName"
  9. placeholder="输入装备名称"
  10. clearable
  11. @keyup.enter.native="handleQuery"
  12. />
  13. </el-form-item>
  14. <el-form-item label="装备类型">
  15. <el-select v-model="queryForm.equipmentType" placeholder="全部" clearable>
  16. <el-option v-for="(item, index) in zbTypeList" :key="index" :label="item.zbTypeName" :value="item.id"></el-option>
  17. </el-select>
  18. </el-form-item>
  19. </template>
  20. <!-- 顶部操作 -->
  21. <template #header-actions>
  22. <el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
  23. <el-button @click="resetQuery">重置</el-button>
  24. <el-button icon="el-icon-plus" @click="openAdd">新建</el-button>
  25. </template>
  26. <!-- 表格 -->
  27. <div class="table-container">
  28. <el-table
  29. ref="table"
  30. :data="tableData"
  31. border
  32. size="mini"
  33. highlight-current-row
  34. @selection-change="handleSelectionChange"
  35. >
  36. <el-table-column type="selection" width="55"/>
  37. <el-table-column type="index" label="序号" width="60"/>
  38. <el-table-column prop="zbTypeName" label="所属装备类型" align="center"/>
  39. <el-table-column prop="zbModelName" label="所属装备型号名称" align="center" show-overflow-tooltip/>
  40. <el-table-column prop="zbName" label="装备名称" show-overflow-tooltip/>
  41. <el-table-column prop="zbCode" label="装备编号" width="120" align="center"/>
  42. <el-table-column prop="ipAddress" label="IP地址" width="120" align="center"/>
  43. <el-table-column prop="port" label="端口" width="100" align="center"/>
  44. <el-table-column prop="communicationType" label="通讯方式" width="100" align="center">
  45. <template slot-scope="{ row }">
  46. <span v-if="row.communicationType === '0'">PDXP</span>
  47. <span v-else-if="row.communicationType === '1'">UDP</span>
  48. <span v-else>TCP</span>
  49. </template>
  50. </el-table-column>
  51. <el-table-column prop="connectionStatus" label="连通状态" width="100" align="center">
  52. <template slot-scope="{ row }">
  53. <span v-if="row.connectionStatus === 0">断开</span>
  54. <span v-else-if="row.connectionStatus === 1">连接</span>
  55. <span v-else>-</span>
  56. </template>
  57. </el-table-column>
  58. <el-table-column prop="createTime" label="创建时间" align="center" sortable/>
  59. <el-table-column prop="createBy" label="创建人" align="center" sortable/>
  60. <el-table-column label="操作" fixed="right" align="center" width="220">
  61. <template slot-scope="{ row }">
  62. <div class="action-bar">
  63. <el-button size="small" plain icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
  64. <el-button size="small" type="danger" icon="el-icon-delete" @click="handleDelete(row)">删除</el-button>
  65. </div>
  66. </template>
  67. </el-table-column>
  68. </el-table>
  69. <!-- 分页 -->
  70. <div class="pagination-container">
  71. <el-pagination
  72. background
  73. :current-page="pagination.currentPage"
  74. :page-sizes="[10, 20, 50]"
  75. :page-size="pagination.pageSize"
  76. layout="total, sizes, prev, pager, next, jumper"
  77. :total="pagination.total"
  78. @size-change="handleSizeChange"
  79. @current-change="handleCurrentChange"
  80. />
  81. </div>
  82. </div>
  83. <!-- 底部操作 -->
  84. <!--<template #footer-actions>-->
  85. <!-- <el-button icon="el-icon-download" @click="exportList">导出清单</el-button>-->
  86. <!-- <span class="footer-tips">选中 {{ selectedRows.length }} 项</span>-->
  87. <!--</template>-->
  88. <!-- 新增装备弹窗 -->
  89. <el-dialog
  90. :title="addOrUpdateTitle"
  91. :visible.sync="addVisible"
  92. width="720px"
  93. :class="['dark-dialog', null]"
  94. :close-on-click-modal="false"
  95. @closed="onAddClosed"
  96. >
  97. <el-form ref="addFormRef" :model="addForm" :rules="addRules" label-width="110px" size="small">
  98. <el-row :gutter="16">
  99. <el-col :span="12">
  100. <el-form-item label="所属装备类型" prop="zbTypeId">
  101. <el-select v-model="addForm.zbTypeId" placeholder="请选择所属装备类型">
  102. <el-option v-for="(item, index) in zbTypeList" :key="index" :label="item.zbTypeName" :value="item.id"></el-option>
  103. </el-select>
  104. </el-form-item>
  105. </el-col>
  106. <el-col :span="12">
  107. <el-form-item label="所属装备型号" prop="zbModelId">
  108. <el-select v-model="addForm.zbModelId" placeholder="请输入所属装备型号名称">
  109. <el-option v-for="(item, index) in zbModelList" :key="index" :label="item.zbModelName" :value="item.id"></el-option>
  110. </el-select>
  111. </el-form-item>
  112. </el-col>
  113. <el-col :span="24">
  114. <el-form-item label="装备名称" prop="zbName">
  115. <el-input v-model="addForm.zbName" placeholder="请输入装备名称" />
  116. </el-form-item>
  117. </el-col>
  118. <el-col :span="24">
  119. <el-form-item label="装备编号" prop="zbCode">
  120. <el-input v-model="addForm.zbCode" placeholder="请输入装备编号" />
  121. </el-form-item>
  122. </el-col>
  123. <el-col :span="12">
  124. <el-form-item label="IP地址" prop="ipAddress">
  125. <el-input
  126. v-model.trim="addForm.ipAddress"
  127. placeholder="请输入IP地址"
  128. />
  129. </el-form-item>
  130. </el-col>
  131. <el-col :span="12">
  132. <el-form-item label="端口号" prop="port">
  133. <el-input
  134. v-model.trim="addForm.port"
  135. placeholder="请输入端口号"
  136. />
  137. </el-form-item>
  138. </el-col>
  139. <el-col :span="12">
  140. <el-form-item label="通讯方式" prop="communicationType">
  141. <el-select v-model="addForm.communicationType">
  142. <el-option value="0" label="PDXP">PDXP</el-option>
  143. <el-option value="1" label="UDP">UDP</el-option>
  144. <el-option value="2" label="TCP">TCP</el-option>
  145. </el-select>
  146. </el-form-item>
  147. </el-col>
  148. <!--<el-col :span="12">-->
  149. <!-- <el-form-item label="状态" prop="connectionStatus">-->
  150. <!-- <el-select v-model="addForm.connectionStatus">-->
  151. <!-- <el-option :value="0" label="断开"></el-option>-->
  152. <!-- <el-option :value="1" label="连接"></el-option>-->
  153. <!-- </el-select>-->
  154. <!-- </el-form-item>-->
  155. <!--</el-col>-->
  156. </el-row>
  157. </el-form>
  158. <div slot="footer" class="dialog-footer">
  159. <el-button @click="addVisible=false">取 消</el-button>
  160. <el-button type="primary" @click="handleAddSubmit">确 定</el-button>
  161. </div>
  162. </el-dialog>
  163. </Container>
  164. </template>
  165. <script>
  166. import {getDataList, addEqu, editEqu, delEqu, getEquDetails, getAllEquTypes, getAllEquModels} from '@/api/equipment'
  167. export default {
  168. name: 'equipment',
  169. data() {
  170. return {
  171. addOrUpdateTitle: '新建',
  172. // 查询
  173. queryForm: {equipmentName: '', equipmentType: ''},
  174. // 列表&分页
  175. tableData: [],
  176. allData: [],
  177. selectedRows: [],
  178. pagination: {currentPage: 1, pageSize: 10, total: 0},
  179. // 新增弹窗
  180. addVisible: false,
  181. addForm: {
  182. id: '', // 主键(编辑时必填)
  183. zbTypeId: '', // 所属装备类型
  184. zbModelId: '', // 所属装备型号名称
  185. zbName: '', // 装备名称
  186. zbCode: '', // 装备编号
  187. ipAddress: '', // IP地址
  188. port: '', // 端口号
  189. communicationType: '',// 通讯方式(默认PDXP)
  190. // status: ''
  191. },
  192. addRules: {
  193. zbTypeId: [{required: true, message: '所属装备类型不能为空', trigger: 'change'}],
  194. zbModelId: [{required: true, message: '所属装备型号名称不能为空', trigger: 'change'}],
  195. zbName: [{required: true, message: '装备名称不能为空', trigger: 'blur'}],
  196. zbCode: [{required: true, message: '装备编号不能为空', trigger: 'blur'}],
  197. ipAddress: [
  198. { required: true, message: 'IP地址不能为空', trigger: 'blur' },
  199. {
  200. pattern: /^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$/,
  201. message: '请输入有效的IP地址(如:192.168.1.1)',
  202. trigger: 'blur'
  203. }
  204. ],
  205. port: [
  206. { required: true, message: '端口号不能为空', trigger: 'blur' },
  207. { pattern: /^\d+$/, message: '端口号只能输入数字', trigger: 'blur' },
  208. {
  209. validator: (rule, value, callback) => {
  210. const port = parseInt(value, 10)
  211. if (port < 1 || port > 65535) {
  212. callback(new Error('端口号必须在1-65535之间'))
  213. } else {
  214. callback()
  215. }
  216. },
  217. trigger: 'blur'
  218. }
  219. ],
  220. communicationType: [{required: true, message: '通讯方式不能为空', trigger: 'change'}]
  221. },
  222. zbTypeList: [],
  223. zbModelList: [],
  224. }
  225. },
  226. created() {
  227. this.handleQuery()
  228. this.getTypes()
  229. this.getModels()
  230. },
  231. methods: {
  232. // 获取所有装备类型
  233. getTypes() {
  234. getAllEquTypes().then(res => {
  235. if (res.code !==0) {
  236. return
  237. }
  238. this.zbTypeList = res.data
  239. })
  240. },
  241. // 获取所有装备型号
  242. getModels() {
  243. getAllEquModels().then(res => {
  244. if (res.code !==0) {
  245. return
  246. }
  247. this.zbModelList = res.data
  248. })
  249. },
  250. /* ====== 查询&分页 ====== */
  251. handleQuery() {
  252. let param = {
  253. pageNo: this.pagination.currentPage,
  254. pageSize: this.pagination.pageSize,
  255. ...this.queryForm
  256. }
  257. getDataList(param).then(res => {
  258. if (res.code !== 0) {
  259. return
  260. }
  261. this.tableData = res.data.records || []
  262. this.pagination.total = res.data.total
  263. console.log(res)
  264. }).catch(() => {
  265. })
  266. },
  267. resetQuery() {
  268. this.queryForm = {equipmentName: '', equipmentType: ''}
  269. this.pagination.currentPage = 1
  270. this.handleQuery()
  271. },
  272. handleSizeChange(size) {
  273. this.pagination.pageSize = size
  274. this.pagination.currentPage = 1
  275. this.handleQuery()
  276. },
  277. handleCurrentChange(p) {
  278. this.pagination.currentPage = p
  279. this.handleQuery()
  280. },
  281. /* ====== 表格操作 ====== */
  282. handleSelectionChange(val) {
  283. this.selectedRows = val
  284. },
  285. handleEdit(row) {
  286. this.addForm = {...row}
  287. // this.addForm.status = '0'
  288. // getEquDetails(row.id).then(res => {
  289. // console.log(res)
  290. // })
  291. this.addOrUpdateTitle = '编辑'
  292. this.addVisible = true
  293. },
  294. togglePublish(row) {
  295. row.modelCategory = row.modelCategory === 'published' ? 'draft' : 'published'
  296. this.$message.success('状态已更新')
  297. },
  298. handleDelete(row) {
  299. this.$confirm('确认删除?', '提示', {
  300. confirmButtonText: '确定',
  301. cancelButtonText: '取消',
  302. type: 'warning'
  303. }).then(() => {
  304. delEqu(row.id).then(res => {
  305. if (res.code !== 0) {
  306. return
  307. }
  308. this.$message.success('删除成功')
  309. this.handleQuery()
  310. }).catch(() => {
  311. })
  312. }).catch(()=>{})
  313. },
  314. /* ====== 新增或修改弹窗 ====== */
  315. openAdd() {
  316. this.addForm = {
  317. zbTypeId: '', // 所属装备类型
  318. zbModelId: '', // 所属装备型号名称
  319. zbName: '', // 装备名称
  320. zbCode: '', // 装备编号
  321. ipAddress: '', // IP地址
  322. port: '', // 端口号
  323. communicationType: '',// 通讯方式
  324. // connectionStatus: '',
  325. // status: ''
  326. }
  327. this.addOrUpdateTitle = '新建'
  328. this.addVisible = true
  329. this.$nextTick(() => {
  330. this.$refs.addFormRef && this.$refs.addFormRef.clearValidate()
  331. this.$refs.uploader && this.$refs.uploader.clearFiles()
  332. })
  333. },
  334. onAddClosed() {
  335. this.$refs.addFormRef && this.$refs.addFormRef.resetFields()
  336. },
  337. handleAddSubmit() {
  338. this.$refs.addFormRef.validate(valid => {
  339. if (!valid) return
  340. (this.addOrUpdateTitle === '编辑' ? editEqu : addEqu)(this.addForm).then(res => {
  341. if (res.code !== 0) {
  342. return
  343. }
  344. this.$message({
  345. message: '操作成功',
  346. type: 'info',
  347. duration: 500,
  348. onClose: () => {
  349. this.pagination.currentPage = 1
  350. this.addVisible = false
  351. this.handleQuery()
  352. }
  353. })
  354. })
  355. })
  356. },
  357. },
  358. }
  359. </script>
  360. <style lang="scss">
  361. .el-form-item__label {
  362. color: #fff !important;
  363. }
  364. .el-dialog__title {
  365. color: #e0e6ed !important;
  366. font-size: 16px !important;
  367. font-weight: bold !important;
  368. }
  369. .dark-dialog {
  370. .el-dialog {
  371. background: var(--dark-dialog-bg, #2d3a4b);
  372. border: 1px solid #425163;
  373. border-radius: 4px;
  374. &__header {
  375. border-bottom: 1px solid #425163;
  376. padding: 15px 20px;
  377. .el-dialog__title,
  378. .dark-dialog-title {
  379. color: #e0e6ed !important;
  380. font-size: 16px !important;
  381. font-weight: bold !important;
  382. }
  383. .el-dialog__headerbtn {
  384. .el-dialog__close {
  385. color: #8796ad;
  386. &:hover {
  387. color: #e0e6ed;
  388. }
  389. }
  390. }
  391. }
  392. &__body {
  393. color: #e0e6ed;
  394. padding: 20px;
  395. .el-descriptions {
  396. &__header {
  397. .el-descriptions__title {
  398. color: #e0e6ed;
  399. }
  400. }
  401. &__body {
  402. background: transparent;
  403. .el-descriptions-item__label {
  404. color: #8796ad;
  405. background: #1e2733;
  406. }
  407. .el-descriptions-item__content {
  408. color: #e0e6ed;
  409. background: #1e2733;
  410. }
  411. }
  412. }
  413. }
  414. &__footer {
  415. border-top: 1px solid #425163;
  416. padding: 10px 20px;
  417. text-align: right;
  418. .el-button {
  419. &.dark-button {
  420. background-color: #425163;
  421. border-color: #5a6b7d;
  422. color: #e0e6ed;
  423. &:hover {
  424. background-color: #5a6b7d;
  425. border-color: #677a8c;
  426. color: #ffffff;
  427. }
  428. }
  429. }
  430. }
  431. }
  432. }
  433. </style>
  434. <style>
  435. /* 统一表格暗色风格,消除白色条纹和容器 */
  436. .three-model-container .el-table,
  437. .three-model-container .el-table__fixed,
  438. .three-model-container .el-table__fixed-right {
  439. background: rgba(15, 31, 56, 0.86) !important;
  440. }
  441. .three-model-container .el-table__body-wrapper,
  442. .three-model-container .el-table__fixed-body-wrapper {
  443. background: rgba(15, 31, 56, 0.86) !important;
  444. }
  445. .three-model-container .el-table td,
  446. .three-model-container .el-table th.is-leaf {
  447. background: rgba(15, 31, 56, 0.86) !important;
  448. border-color: rgba(255, 255, 255, 0.08) !important;
  449. color: #e6efff;
  450. }
  451. .three-model-container .el-table td {
  452. color: #ffffff !important;
  453. }
  454. .three-model-container .el-table th {
  455. background: rgba(30, 55, 95, 0.85) !important;
  456. color: #ffffff !important;
  457. }
  458. .three-model-container .el-table th .cell {
  459. font-size: 18px !important;
  460. font-weight: 700 !important;
  461. }
  462. .three-model-container .el-table--striped .el-table__body tr.el-table__row--striped td {
  463. background: rgba(15, 31, 56, 0.9) !important;
  464. }
  465. .three-model-container .el-table__body tr:hover > td {
  466. background: rgba(30, 64, 175, 0.25) !important;
  467. }
  468. .three-model-container .el-table__current-row > td {
  469. background: rgba(64, 150, 255, 0.2) !important;
  470. }
  471. .three-model-container .el-table__fixed::before,
  472. .three-model-container .el-table__fixed-right::before,
  473. .three-model-container .el-table::before {
  474. background-color: rgba(255, 255, 255, 0.08) !important;
  475. }
  476. .three-model-container .el-table__gutter,
  477. .three-model-container .el-table__fixed-right .el-table__fixed-header-wrapper,
  478. .three-model-container .el-table__fixed-right .el-table__fixed-body-wrapper,
  479. .three-model-container .el-table__fixed .el-table__fixed-header-wrapper,
  480. .three-model-container .el-table__fixed .el-table__fixed-body-wrapper {
  481. background: rgba(15, 31, 56, 0.86) !important;
  482. }
  483. .pagination-container {
  484. margin-top: 14px;
  485. display: flex;
  486. justify-content: flex-end;
  487. }
  488. .action-bar {
  489. display: flex;
  490. justify-content: space-around;
  491. width: 100%;
  492. }
  493. .model-dialog .el-dialog {
  494. background: #0b254a;
  495. border: 1px solid #364a64;
  496. }
  497. .model-dialog .el-dialog__title {
  498. color: #e6efff;
  499. }
  500. .model-dialog .el-dialog__header,
  501. .model-dialog .el-dialog__footer {
  502. border-color: #364a64;
  503. }
  504. .model-dialog .el-upload-list__item {
  505. background: rgba(255, 255, 255, 0.04);
  506. border-color: #364a64;
  507. color: #e6efff;
  508. }
  509. .footer-tips {
  510. color: #94a3b8;
  511. margin-left: 10px;
  512. }
  513. </style>