index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. <template>
  2. <div >
  3. <ag-grid-layout
  4. toolbar
  5. :table-height="tableHeight"
  6. theme="ag-theme-alpine"
  7. :column-defs="columnDefs"
  8. :row-data="rowData"
  9. :locale-text="localeText"
  10. :grid-options="gridOptions"
  11. :default-col-def="defaultColDef"
  12. :animate-rows="true"
  13. :row-selection="rowSelection"
  14. :enable-cell-change-flash="true"
  15. @filterChanged="filterModifed"
  16. @sortChanged="gridSortChange"
  17. >
  18. <!-- @rowDoubleClicked="getList"-->
  19. <div slot="toolbar" class="inner-toolbar">
  20. <div class="toolbar-search">
  21. <en-table-search :placeholder="this.$t('action.keywords')" @search="handlerSearch" />
  22. </div>
  23. </div>
  24. <el-pagination
  25. v-if="pageData"
  26. slot="pagination"
  27. :current-page="pageData.page_no"
  28. :page-sizes="[10, 20, 50, 100]"
  29. :page-size="pageData.page_size"
  30. layout="total, sizes, prev, pager, next, jumper"
  31. :total="pageData.data_total"
  32. @size-change="handlePageSizeChange"
  33. @current-change="handlePageCurrentChange"
  34. />
  35. </ag-grid-layout>
  36. <!-- <en-table-layout-->
  37. <!-- toolbar-->
  38. <!-- pagination-->
  39. <!-- :table-data="tableData"-->
  40. <!-- :height="tableHeight"-->
  41. <!-- :loading="loading"-->
  42. <!-- @selection-change="selectFun"-->
  43. <!-- @sort-change="tableSort"-->
  44. <!-- >-->
  45. <!-- &lt;!&ndash;工具栏&ndash;&gt;-->
  46. <!-- <div slot="toolbar" class="inner-toolbar" />-->
  47. <!-- &lt;!&ndash;表头&ndash;&gt;-->
  48. <!-- <template slot="table-columns">-->
  49. <!-- <el-table-column prop="id" sortable="custom" :label="识别码" width="200" align="center" />-->
  50. <!-- <el-table-column prop="device_name" sortable="custom" :label="别名" width="200" align="center" />-->
  51. <!-- <el-table-column prop="device_wifi_mac" sortable="custom" :label="mac地址" width="200" align="center" />-->
  52. <!-- <el-table-column prop="device_eth_ip" sortable="custom" :label="IP地址" width="200" align="center" />-->
  53. <!-- <el-table-column prop="partid" sortable="custom" :label="科室ID" width="200" align="center" />-->
  54. <!-- <el-table-column :label="操作" align="center">-->
  55. <!-- <template slot-scope="scope">-->
  56. <!-- <el-button type="primary" size="mini" @click="setPartBoard(scope.row)">设定</el-button>-->
  57. <!-- <el-button type="primary" size="mini" @click="setBoard(scope.row)">设置</el-button>-->
  58. <!-- <el-button type="danger" size="mini" @click="handlerDelete(scope.row.id)">删除</el-button>-->
  59. <!-- </template>-->
  60. <!-- </el-table-column>-->
  61. <!-- </template>-->
  62. <!-- &lt;!&ndash;翻页&ndash;&gt;-->
  63. <!-- <el-pagination-->
  64. <!-- v-if="pageData"-->
  65. <!-- slot="pagination"-->
  66. <!-- :current-page="pageData.page_no"-->
  67. <!-- :page-sizes="[10, 20, 50, 100]"-->
  68. <!-- :page-size="pageData.page_size"-->
  69. <!-- layout="total, sizes, prev, pager, next, jumper"-->
  70. <!-- :total="pageData.data_total"-->
  71. <!-- @size-change="handlePageSizeChange"-->
  72. <!-- @current-change="handlePageCurrentChange"-->
  73. <!-- />-->
  74. <!-- </en-table-layout>-->
  75. <el-dialog :title="this.$t('board.boardSet')" :visible.sync="formshow" width="50%">
  76. <el-form ref="editform" v-model="boardConfig" label-width="120px">
  77. <fieldset>
  78. <legend>{{ this.$t('board.statusTime') }}</legend>
  79. <el-form-item :label="this.$t('board.screenFirst')">
  80. <el-input v-model="boardConfig.staySeconds[0]" clearable :placeholder="this.$t('board.screenFirstSet')" type="number">
  81. <template slot="append">{{ second }}</template>
  82. </el-input>
  83. </el-form-item>
  84. <el-form-item :label="this.$t('board.screenSecond')">
  85. <el-input v-model="boardConfig.staySeconds[1]" clearable :placeholder="this.$t('board.screenSecondSet')" type="number">
  86. <template slot="append">{{ second }}</template>
  87. </el-input>
  88. </el-form-item>
  89. <el-form-item v-for="(item,index) in boardTitles" :key="index" :label="labelStr(index)">
  90. <el-input v-model="boardConfig.staySeconds[index+2]" clearable :placeholder="labelStr(index)" type="number">
  91. <template slot="append">{{ second }}</template>
  92. </el-input>
  93. </el-form-item>
  94. </fieldset>
  95. <fieldset class="margin-top-sm">
  96. <legend>{{ this.$t('board.screenFixedSet') }}</legend>
  97. <el-form-item label-width="80">
  98. <el-radio-group v-model="boardConfig.stayIndex">
  99. <el-radio :label="0">{{ this.$t('board.noFixed') }}</el-radio>
  100. <el-radio :label="1">{{ this.$t('board.screenFirst') }}</el-radio>
  101. <el-radio :label="2">{{ this.$t('board.screenSecond') }}</el-radio>
  102. <el-radio v-for="(item,index) in boardTitles" :key="index" :label="(index+3)" > {{ labelStr(index) }}</el-radio>
  103. </el-radio-group>
  104. </el-form-item>
  105. </fieldset>
  106. </el-form>
  107. <div slot="footer" class="dialog-footer">
  108. <el-button @click="formshow = false">{{ this.$t('action.cancel') }}</el-button>
  109. <el-button type="primary" @click="updateBoard()">{{ this.$t('action.yes') }}</el-button>
  110. </div>
  111. </el-dialog>
  112. </div>
  113. </template>
  114. <script>
  115. import { AG_GRID_LOCALE_CN } from '@/utils/AgGridVueLocaleCn'
  116. import ButtonCellRender from '../../components/AgGridCellRender/ButtonCellRender'
  117. import ListFilter from '@/components/AgGridCustomFilter/ListFilter'
  118. import RadioFilter from '@/components/AgGridCustomFilter/RadioFilter'
  119. // import { DeviceUrl } from '@/utils/domain'
  120. import * as API_Device from '@/api/ncs_device'
  121. import * as API_FrameGroup from '@/api/ncs_frameGroup'
  122. import * as API_Board from '@/api/ncs_board'
  123. const DeviceUrl = domain.DeviceUrl
  124. export default {
  125. name: 'Index',
  126. components: { ButtonCellRender, ListFilter, RadioFilter },
  127. data() {
  128. return {
  129. /** 列表参数 */
  130. params: {
  131. page_size: 20,
  132. page_no: 1,
  133. fixedCondition: '(part_id=' + this.$store.getters.partId + ' OR part_id=0) AND device_type=17'
  134. },
  135. treeData: [],
  136. /** ag-grid参数 **/
  137. pageData: [],
  138. loading: false,
  139. errorId: null,
  140. shopVisible: false,
  141. columnDefs: null,
  142. rowData: null,
  143. defaultColDef: null,
  144. gridOptions: null,
  145. gridApi: null,
  146. columnApi: null,
  147. localeText: AG_GRID_LOCALE_CN,
  148. filterState: null,
  149. rowSelection: null,
  150. frameworkComponents: null,
  151. second: this.$t('action.second'),
  152. websock: null,
  153. boardObj: {},
  154. boardConfig: {
  155. staySeconds: [30, 30],
  156. stayIndex: 0
  157. },
  158. boardTitles: [],
  159. formshow: false,
  160. rules: {
  161. device_type: [
  162. { required: true, message: this.$t('deviceManage.deviceTypeMsg'), trigger: 'blur' }
  163. ]
  164. }
  165. }
  166. },
  167. computed: {
  168. tableHeight() {
  169. return this.mainAreaHeight - 130
  170. }
  171. },
  172. beforeMount() {
  173. this.gridOptions = {}
  174. this.columnDefs = [
  175. {
  176. headerName: '#',
  177. headerCheckboxSelection: true,
  178. headerCheckboxSelectionFilteredOnly: true,
  179. checkboxSelection: true,
  180. sortable: false, filter: false,
  181. width: 100,
  182. resizable: false,
  183. valueGetter: this.hashValueGetter
  184. },
  185. { headerName: 'ID', field: 'id', sortable: true, filter: 'agNumberColumnFilter', width: 130 },
  186. {
  187. headerName: this.$t('board.name'), field: 'name', sortable: true, filter: 'agTextColumnFilter', width: 150
  188. },
  189. {
  190. headerName: this.$t('board.ethMac'), field: 'eth_mac', sortable: true, filter: 'agTextColumnFilter', flex: 1
  191. },
  192. {
  193. headerName: this.$t('board.partId'), field: 'part_id', sortable: true, filter: 'agNumberColumnFilter', width: 150
  194. },
  195. {
  196. headerName: this.$t('action.setUp'), field: 'id',
  197. cellRendererFramework: 'ButtonCellRender',
  198. cellRendererParams: {
  199. onClick: this.handEdit,
  200. label: this.$t('board.setUpThisPart'),
  201. buttonType: 'primary',
  202. buttonSize: 'mini'
  203. },
  204. filter: false,
  205. pinned: 'right',
  206. lockPinned: true,
  207. width: 150,
  208. resizable: false,
  209. sortable: false
  210. },
  211. {
  212. headerName: this.$t('action.settings'), field: 'id',
  213. cellRendererFramework: 'ButtonCellRender',
  214. cellRendererParams: {
  215. onClick: this.setBoard,
  216. label: this.$t('board.boardSet'),
  217. buttonType: 'primary',
  218. buttonSize: 'mini'
  219. },
  220. filter: false,
  221. pinned: 'right',
  222. lockPinned: true,
  223. width: 150,
  224. resizable: false,
  225. sortable: false
  226. },
  227. {
  228. headerName: this.$t('action.delete'), field: 'shop_id',
  229. cellRendererFramework: 'ButtonCellRender',
  230. cellRendererParams: param => {
  231. return {
  232. onClick: this.deleteSingle,
  233. label: this.$t('action.delete'),
  234. buttonType: 'danger',
  235. buttonSize: 'mini'
  236. }
  237. },
  238. pinned: 'right',
  239. lockPinned: true,
  240. width: 100,
  241. resizable: false,
  242. filter: false,
  243. sortable: false
  244. }
  245. ]
  246. this.defaultColDef = {
  247. sortable: true,
  248. resizable: true,
  249. comparator: this.dateCustomComparator,
  250. filterParams: {
  251. debounceMs: 200,
  252. newRowsAction: 'keep',
  253. textCustomComparator: this.textCustomComparator,
  254. comparator: this.dateCustomComparator
  255. }
  256. }
  257. this.rowSelection = 'multiple'
  258. },
  259. mounted() {
  260. window.onresize = this.windowResize
  261. this.gridApi = this.gridOptions.api
  262. this.gridColumnApi = this.gridOptions.columnApi
  263. // 设置默认排序字段,应用列状态之后会触发 gridSortChange 函数,会调用getlist,后面不需要再调用this.getlist
  264. this.gridColumnApi.applyColumnState({
  265. state: [
  266. {
  267. colId: 'id',
  268. sort: 'asc'
  269. }
  270. ]
  271. })
  272. this.getFrameTree()
  273. this.getBoardTitles()
  274. this.initWebSocket()
  275. },
  276. methods: {
  277. /** 表格行选择变化记录选中行数据*/
  278. selectFun: function(val) {
  279. this.multipleSelection = val
  280. },
  281. windowResize() {
  282. this.$set(this, 'mainAreaHeight', Number(document.documentElement.clientHeight) - 84)
  283. },
  284. deleteSingle(row) {
  285. this.handlerDelete(row.id)
  286. },
  287. handlerDelete(ids) {
  288. this.$confirm(this.$t('action.sureDelete'), this.$t('action.waring'), {
  289. confirmButtonText: this.$t('action.yes'),
  290. cancelButtonText: this.$t('action.cancel'),
  291. type: 'warning'
  292. }).then(() => {
  293. API_Device.remove(ids).then(
  294. response => {
  295. this.getList()
  296. this.$message({
  297. type: 'success',
  298. message: this.$t('action.deleted')
  299. })
  300. }
  301. ).catch(response => {
  302. this.$message({
  303. type: 'info',
  304. message: response.message
  305. })
  306. })
  307. }).catch(() => {
  308. this.$message({
  309. type: 'info',
  310. message: this.$t('action.cancelDelete')
  311. })
  312. })
  313. },
  314. /** 分页大小发生改变 */
  315. handlePageSizeChange(size) {
  316. this.params.page_size = size
  317. this.getList()
  318. },
  319. /** 分页页数发生改变 */
  320. handlePageCurrentChange(page) {
  321. this.params.page_no = page
  322. this.getList()
  323. },
  324. /** 加载列表数据 */
  325. getList() {
  326. this.loading = true
  327. const param = this.MixinClone(this.params)
  328. API_Device.getList(param).then(response => {
  329. this.loading = false
  330. this.rowData = [...response.data]
  331. this.pageData = {
  332. page_no: response.page_no,
  333. page_size: response.page_size,
  334. data_total: response.data_total
  335. }
  336. this.$nextTick(() => {
  337. const node = this.gridApi.getDisplayedRowAtIndex(0)
  338. if (node !== null && node !== undefined) {
  339. node.setSelected(true)
  340. }
  341. })
  342. }).catch(() => {
  343. this.loading = false
  344. })
  345. },
  346. /** 处理搜索 */
  347. handlerSearch(keywords) {
  348. this.params.query = keywords
  349. this.getList()
  350. },
  351. /** 处理字段排序 */
  352. tableSort(column) {
  353. if (column.order !== null) {
  354. this.params.sort = column.prop
  355. this.params.dir = column.order === 'ascending' ? 'asc' : 'desc'
  356. } else {
  357. this.params.sort = null
  358. this.params.dir = null
  359. }
  360. this.getList()
  361. },
  362. gridSortChange(param) {
  363. const columnState = param.columnApi.getColumnState()
  364. // 排序状态
  365. const sortState = columnState.filter(function(s) {
  366. return s.sort != null
  367. }).map(function(s) {
  368. return {
  369. colId: s.colId,
  370. sort: s.sort,
  371. sortIndex: s.sortIndex
  372. }
  373. }).sort(function(a, b) {
  374. return a.sortIndex - b.sortIndex
  375. })
  376. if (sortState.length > 0) {
  377. if (sortState.length === 1) {
  378. this.params.sort = sortState[0].colId
  379. this.params.dir = sortState[0].sort
  380. } else {
  381. let sortstring = ''
  382. sortState.forEach(function(item) {
  383. sortstring += item.colId + ' ' + item.sort + ','
  384. })
  385. this.params.sort = sortstring.substring(0, sortstring.length - 1)
  386. this.params.dir = ' '
  387. }
  388. } else {
  389. delete this.params.sort
  390. delete this.params.dir
  391. }
  392. this.getList()
  393. console.log(sortState)
  394. },
  395. /**
  396. * 获取空间结构树形数据
  397. * */
  398. getFrameTree() {
  399. return new Promise((resolve, reject) => {
  400. API_FrameGroup.getframestruct(this.$store.getters.partId, 3).then(res => {
  401. this.treeData = res.frameTree
  402. resolve()
  403. }).catch(err => {
  404. reject(err)
  405. })
  406. })
  407. },
  408. setBoard(row) {
  409. this.boardObj = { ...row }
  410. this.formshow = true
  411. if (this.boardObj.config === null || this.boardObj.config === '') { // 没有配置看板时,设置默认值
  412. if (this.boardTitles.length > 0) {
  413. this.boardTitles.forEach((item, index) => {
  414. this.boardConfig.staySeconds[index + 2] = 30 // 添加默认时间
  415. })
  416. }
  417. } else {
  418. this.boardConfig = JSON.parse(this.boardObj.config)
  419. }
  420. // if (this.boardObj.device_hard_ver) this.stayIndex = Number(this.boardObj.device_hard_ver)
  421. },
  422. getBoardTitles() {
  423. API_Board.getBoardTitles(this.$store.getters.partId).then(res => {
  424. this.boardTitles = res
  425. })
  426. },
  427. updateBoard() {
  428. this.boardConfig.staySeconds=[this.boardConfig.staySeconds[0],this.boardConfig.staySeconds[1],...this.boardTitles.map((p,index)=>Number(this.boardConfig.staySeconds[index+2]))]
  429. if (this.boardConfig.staySeconds.length !== this.boardTitles.length + 2) {
  430. this.$message.success(this.$t('board.statusTimeSetMsg'))
  431. return false
  432. }
  433. this.boardConfig.staySeconds = this.boardConfig.staySeconds.map(p => Number(p))
  434. this.boardObj.config = JSON.stringify(this.boardConfig)
  435. API_Device.update(this.boardObj.id, this.boardObj).then(() => {
  436. this.$message.success(this.$t('action.settingsSuccess'))
  437. this.getList()
  438. this.formshow = false
  439. }).catch(response => {
  440. this.getList()
  441. this.formshow = false
  442. })
  443. },
  444. /**
  445. * 设定到科室
  446. * @param row
  447. */
  448. handEdit(row) {
  449. row.part_id = this.$store.getters.partId
  450. row.frame_id = this.treeData[0].id
  451. API_Device.update(row.id, row).then(res => {
  452. this.$message.success(this.$t('action.setUpSuccess'))
  453. this.gridApi.redrawRows()
  454. }).catch(response => {
  455. this.getList()
  456. })
  457. },
  458. filterModifed(param) {
  459. console.log(param)
  460. var model = param.api.getFilterModel()
  461. console.log('model', JSON.stringify(model))
  462. this.params.filter = JSON.stringify(model)
  463. this.getList()
  464. },
  465. initWebSocket: function() {
  466. var stockbase = DeviceUrl.replace('http', 'ws')
  467. this.websock = new WebSocket(stockbase + '/boardinfo/0/' + this.$store.getters.uuid)
  468. this.websock.onopen = this.websocketonopen
  469. this.websock.onerror = this.websocketonerror
  470. this.websock.onmessage = this.websocketonmessage
  471. this.websock.onclose = this.websocketclose
  472. },
  473. websocketonopen: function() {
  474. this.$message.success(this.$t('board.webSocketSuccess'))
  475. console.log(this.$t('deviceManage.webSocketSuccess'))
  476. },
  477. websocketonerror: function(e) {
  478. console.log(this.$t('deviceManage.webSocketError'))
  479. },
  480. websocketonmessage: function(e) {
  481. this.getList()
  482. },
  483. websocketclose: function(e) {
  484. console.log('connection closed (' + e.code + ')')
  485. },
  486. labelStr(index) {
  487. return this.$t('board.the') + (index + 3) + this.$t('board.screen')
  488. },
  489. }
  490. }
  491. </script>
  492. <style scoped>
  493. fieldset{
  494. border-style: solid;
  495. border-color: #DCDFE6;
  496. border-width: 1px;
  497. }
  498. .margin-top-sm{margin-top: 20px}
  499. </style>