tables.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. <template>
  2. <!-- tables -->
  3. <div class="tables_grid">
  4. <el-table ref="tableRef" style="width: 100%" tooltip-effect="dark myTooltips" :show-header="showHeader"
  5. class="table-style" :data="tableData" :border="border" :row-key="(val) => rowKey(val)" @cell-click="cellClick"
  6. @selection-change="handleSelectionChange">
  7. <template v-for="(item,index) in tableList">
  8. <el-table-column :fixed="suspension ? 'right' : false" :label="item.label" :width="item.colWidth" align="center"
  9. v-if="item.field == 'action'">
  10. <template slot-scope="scope">
  11. <div style="display: flex;align-items: center;justify-content: center;">
  12. <div v-for="disk in item.labelButton" :key="disk.key" class="btn_table">
  13. <el-button :class="disk.modality" :type="disk.style" :icon="disk.icon" size="mini"
  14. :disabled="jurisdiction(scope.row,disk.type)" @click="buttonData(scope.row,disk.type)">
  15. {{ disk.label }}
  16. </el-button>
  17. </div>
  18. </div>
  19. </template>
  20. </el-table-column>
  21. <el-table-column class="card_unpack_btn" :fixed="suspension ? 'right' : false" :label="item.label"
  22. :width="unpackWidth" align="center" v-else-if="item.field == 'unpackBtn'">
  23. <template slot="header" slot-scope="scope">
  24. <div class="unpack_card">
  25. <div v-if="!iconFlag">{{item.label}}</div>
  26. <i class="card_unpack" :class="iconFlag ? 'el-icon-s-fold' : 'el-icon-s-unfold'" @click="getUnpack"></i>
  27. </div>
  28. </template>
  29. <template slot-scope="scope">
  30. <div class="center_in" v-if="!iconFlag">
  31. <div v-for="disk in item.labelButton" :key="disk.key" class="btn_table">
  32. <el-button :class="disk.modality" :type="disk.style" :icon="disk.icon" size="mini"
  33. :disabled="jurisdiction(scope.row,disk.type)" @click="buttonData(scope.row,disk.type)">
  34. {{ disk.label }}
  35. </el-button>
  36. </div>
  37. </div>
  38. <div v-else :key="index">
  39. <el-popover placement="top" trigger="click" v-model="scope.row.visible">
  40. <div class="center_in">
  41. <div v-for="disk in item.labelButton" :key="disk.key" class="btn_table">
  42. <el-button :class="disk.modality" :type="disk.style" :icon="disk.icon" size="mini"
  43. :disabled="jurisdiction(scope.row,disk.type)" @click="buttonData(scope.row,disk.type)">
  44. {{ disk.label }}
  45. </el-button>
  46. </div>
  47. </div>
  48. <el-tag style="cursor: pointer;" size="mini" slot="reference">操作</el-tag>
  49. </el-popover>
  50. </div>
  51. </template>
  52. </el-table-column>
  53. <el-table-column :label="item.label" align="center" v-else-if="item.field == 'multistage'">
  54. <template v-for="(child,cgindex) in item.children">
  55. <el-table-column :prop="child.field" :label="child.label" :width="child.colWidth" :align="child.align">
  56. <template slot-scope="scope">
  57. <div v-if="child.field == 'suitableForColdTime'">≥{{scope.row[child.field]}}min</div>
  58. <div
  59. v-else-if="child.field == 'iceRaftRecord.suitableForCold' && scope.row.iceRaftRecord.suitableForCold">
  60. {{nestedField(scope.row,child.field)}}℃
  61. </div>
  62. <div v-else>{{nestedField(scope.row,child.field)}}</div>
  63. </template>
  64. </el-table-column>
  65. </template>
  66. </el-table-column>
  67. <el-table-column :label="item.label" align="center"
  68. v-else-if="item.field == 'receiptImg' || item.field == 'receiptsign'">
  69. <template slot-scope="scope">
  70. <el-image style="width: 60px; height: 60px" :src="scope.row[item.field]"
  71. :preview-src-list="getImage(scope.row[item.field])"></el-image>
  72. </template>
  73. </el-table-column>
  74. <el-table-column :prop="item.field" :label="item.label" :width="item.colWidth" :align="item.align"
  75. v-else-if="['provUser.isorders','provUser.userType','customer.type','tbFillData.productMediaId','iceRaftRecord.status'].includes(item.field)">
  76. <template slot-scope="scope">
  77. <div :style="{color: filterColoril(scope.row,item.options,item.field)}">
  78. {{initDictvalue(scope.row,item.options,item.field)}}
  79. </div>
  80. </template>
  81. </el-table-column>
  82. <el-table-column :prop="item.field" :label="item.label" :width="item.colWidth" :align="item.align"
  83. v-else-if="['userId','paymentType','paymentStatus','assignmentStatus', 'type', 'status', 'storeId', 'personCode', 'optType', 'corrosion', 'crackle', 'deform', 'damage', 'safeAnnex', 'gasPressure', 'bodyDeform', 'fillingLeak', 'bodyTemperature', 'filledLeak', 'warnSign', 'fillLabel', 'seal','addressType'].includes(item.field)">
  84. <template slot-scope="scope">
  85. <div :style="{color: filterColor(scope.row,item.options,item.field)}">
  86. {{initDictvalueil(scope.row,item.options,item.field)}}
  87. </div>
  88. </template>
  89. </el-table-column>
  90. <el-table-column :prop="item.field" :label="item.label" :width="item.colWidth" :align="item.align"
  91. v-else-if="item.field == 'myStatus'">
  92. <template slot-scope="scope">
  93. <div :style="{color: myfilterColor(scope.row,item.options,item.field)}">
  94. {{myInitDictvalueil(scope.row,item.options,item.field)}}
  95. </div>
  96. </template>
  97. </el-table-column>
  98. <el-table-column :prop="item.field" :label="item.label" :width="item.colWidth" :align="item.align"
  99. v-else-if="item.field == 'region'">
  100. <template slot-scope="scope">
  101. <div>{{scope.row.provinceName}}{{scope.row.cityName}}{{scope.row.regionName}}</div>
  102. </template>
  103. </el-table-column>
  104. <el-table-column :prop="item.field" :label="item.label" :width="item.colWidth" :align="item.align"
  105. v-else-if="item.field == 'deviceData.T_t'">
  106. <template slot-scope="scope">
  107. <div>{{scope.row.deviceData.T_t || ''}}</div>
  108. </template>
  109. </el-table-column>
  110. <el-table-column :prop="item.field" :label="item.label" :width="item.colWidth" :align="item.align"
  111. v-else-if="item.field == 'location'">
  112. <template slot-scope="scope">
  113. <div v-if="scope.row.iceRaftRecord">
  114. <div v-if="scope.row.iceRaftRecord.outStorageTime == ''">{{scope.row.iceRaftRecord.iceLocker.name}}</div>
  115. <div v-else>{{scope.row.iceRaftRecord.coolerBox.name}}
  116. </div>
  117. </div>
  118. <div v-else>
  119. <div v-if="scope.row.outStorageTime == ''">{{scope.row.iceLocker.name}}</div>
  120. <div v-else>{{scope.row.coolerBox.name}}
  121. </div>
  122. </div>
  123. </template>
  124. </el-table-column>
  125. <el-table-column :prop="item.field" :label="item.label" :width="item.colWidth" :align="item.align"
  126. v-else-if="item.field == 'freezeClaim'">
  127. <template slot-scope="scope">
  128. <div v-if="scope.row[item.field]">≥{{scope.row[item.field]}}h</div>
  129. <div v-else-if="scope.row.iceRaftRecord">
  130. <span v-if="scope.row.iceRaftRecord.status">≥{{scope.row.iceRaftRecord.freezeClaim}}h</span>
  131. </div>
  132. </template>
  133. </el-table-column>
  134. <el-table-column :prop="item.field" :label="item.label" :width="item.colWidth" :align="item.align"
  135. v-else-if="item.field == 'freezeDuration'">
  136. <template slot-scope="scope">
  137. <div v-if="scope.row.iceRaftRecord">{{ formatMinutes(scope.row.iceRaftRecord.freezeDuration) }}</div>
  138. <div v-else>{{ formatMinutes(scope.row.freezeDuration) }}</div>
  139. </template>
  140. </el-table-column>
  141. <el-table-column :prop="item.field" :label="item.label" :width="item.colWidth" :align="item.align"
  142. v-else-if="item.field == 'assessStar'">
  143. <template slot-scope="scope">
  144. <el-rate disabled v-model="scope.row.assessStar"></el-rate>
  145. <el-tooltip class="item" effect="dark" :content="scope.row.assessContent" placement="top">
  146. <div class="cell el-tooltip">{{scope.row.assessContent}}</div>
  147. </el-tooltip>
  148. </template>
  149. </el-table-column>
  150. <el-table-column :prop="item.field" :label="item.label" :width="item.colWidth" :align="item.align"
  151. v-else-if="item.field == 'deliveryDuration'">
  152. <template slot-scope="scope">
  153. <div>{{formatMinutes(scope.row[item.field]) || ''}}</div>
  154. </template>
  155. </el-table-column>
  156. <el-table-column type="index" :fixed="item.boxhead ? true : false" :width="item.colWidth" :label="item.label"
  157. :align="item.align" v-else-if="item.field == 'index'">
  158. </el-table-column>
  159. <el-table-column type="selection" v-model="selectionList" :reserve-selection="true" width="55"
  160. v-else-if="item.field == 'selection'"></el-table-column>
  161. <el-table-column :show-overflow-tooltip="true" :prop="item.field" :label="item.label" :width="item.colWidth"
  162. :align="item.align" v-else>
  163. </el-table-column>
  164. </template>
  165. </el-table>
  166. </div>
  167. </template>
  168. <script>
  169. import {
  170. putUpdateStatus
  171. } from '@/api/waybill'
  172. import {
  173. orderStatus,
  174. rectificationState
  175. } from '@/assets/js/blockSort'
  176. export default {
  177. props: {
  178. // 表格边框
  179. border: {
  180. type: Boolean,
  181. default: () => false,
  182. },
  183. // 是否显示表头
  184. showHeader: {
  185. type: Boolean,
  186. default: () => true,
  187. },
  188. // 表格数据
  189. tableList: {
  190. type: Array,
  191. default: () => [],
  192. },
  193. // 表格label数据
  194. tableData: {
  195. type: Array,
  196. default: () => [],
  197. },
  198. // 网关数据
  199. detailGateway: {
  200. type: Array,
  201. default: () => [],
  202. },
  203. // 语言数据
  204. detailLanguage: {
  205. type: Array,
  206. default: () => [],
  207. },
  208. // 是否悬浮
  209. suspension: {
  210. type: Boolean,
  211. default: () => false,
  212. },
  213. // 历史记录按钮显示控制
  214. historyFlag: {
  215. type: Boolean,
  216. default: () => false,
  217. },
  218. // 头部高度
  219. tableHeight: {
  220. type: String,
  221. default: () => '',
  222. },
  223. // 操作按钮宽度
  224. controlswidth: {
  225. type: String,
  226. default: () => '370px',
  227. }
  228. },
  229. data() {
  230. return {
  231. orderStatusList: orderStatus(),
  232. waybillIds: [],
  233. selectionList: [],
  234. iconFlag: false,
  235. unpackWidth: '',
  236. visible: false,
  237. }
  238. },
  239. watch: {
  240. controlswidth: {
  241. handler: function(newUser, oldUser) {
  242. this.unpackWidth = newUser
  243. },
  244. immediate: true,
  245. deep: true,
  246. }
  247. },
  248. methods: {
  249. getImage(image) {
  250. let arr = []
  251. arr.push(image)
  252. return arr
  253. },
  254. // 嵌套字段
  255. nestedField(event, type) {
  256. let propertyName = type.split(".")
  257. let name = ''
  258. if (event[propertyName[0]] != undefined) {
  259. if (event[propertyName[0]][propertyName[1]]) {
  260. name = event[propertyName[0]][propertyName[1]]
  261. }
  262. }
  263. return name
  264. },
  265. // 文字匹配
  266. initDictvalue(value, list, type) {
  267. let propertyName = type.split(".")
  268. let name = ''
  269. if (list) {
  270. list.forEach(item => {
  271. if (value[propertyName[0]][propertyName[1]] == item.value) {
  272. name = item.label
  273. }
  274. })
  275. }
  276. return name
  277. },
  278. filterColoril(value, list, type) {
  279. let propertyName = type.split(".")
  280. let color = ''
  281. if (list) {
  282. list.forEach(item => {
  283. if (value[propertyName[0]][propertyName[1]] == item.value) {
  284. color = item.bgcolor
  285. }
  286. })
  287. }
  288. return color
  289. },
  290. // 普通类型文字匹配
  291. initDictvalueil(value, list, type) {
  292. let name = ''
  293. if (list) {
  294. list.forEach(item => {
  295. if (value[type] === item.value) {
  296. name = item.label
  297. }
  298. })
  299. }
  300. return name
  301. },
  302. // tag颜色获取
  303. filterColor(value, list, type) {
  304. let color = ''
  305. if (list) {
  306. list.forEach(item => {
  307. if (value[type] === item.value) {
  308. color = item.bgcolor
  309. }
  310. })
  311. }
  312. return color
  313. },
  314. // 总分钟格式化
  315. formatMinutes(totalMinutes) {
  316. if (totalMinutes) {
  317. const hours = Math.floor(totalMinutes / 60); // 计算小时
  318. const minutes = totalMinutes % 60; // 计算分钟(余数)
  319. return `${hours}h${minutes}m`;
  320. } else {
  321. return ''
  322. }
  323. },
  324. // 我的运单
  325. myInitDictvalueil(value, list, type) {
  326. if ([1, 2, 3].includes(value.status)) {
  327. return list[0].label
  328. } else if ([4, 5, 6, 7].includes(value.status)) {
  329. return list[1].label
  330. } else if (value.status == 8) {
  331. return list[2].label
  332. }
  333. },
  334. myfilterColor(value, list, type) {
  335. if ([1, 2, 3].includes(value.status)) {
  336. return list[0].bgcolor
  337. } else if ([4, 5, 6, 7].includes(value.status)) {
  338. return list[1].bgcolor
  339. } else if (value.status == 8) {
  340. return list[2].bgcolor
  341. }
  342. },
  343. // 城市筛选
  344. cityScreening(value, list, type) {
  345. function getChildById(parentArray, id) {
  346. for (let i = 0; i < parentArray.length; i++) {
  347. if (parentArray[i].value === id) { // 如果当前元素的ID与目标ID相等,则返回该元素
  348. return parentArray[i];
  349. } else if (parentArray[i].children && Array.isArray(parentArray[i].children)) { // 判断当前元素是否有子节点且类型为数组
  350. const result = getChildById(parentArray[i].children, id); // 对子节点进行递归调用
  351. if (result !== null) { // 若子节点存在结果,则返回该结果
  352. return result;
  353. }
  354. }
  355. }
  356. return null; // 没有找到符合条件的元素时返回null
  357. }
  358. var name = getChildById(list, value[type])
  359. if (name != null) {
  360. return name.label
  361. }
  362. },
  363. // 权限按钮
  364. jurisdiction(row, type) {
  365. if (this.historyFlag) {
  366. if (row.status != '4' && type == 'edit') {
  367. return false
  368. } else if (row.status == '1' && type == 'del' || row.status == '2' && type == 'del') {
  369. return false
  370. } else {
  371. return true
  372. }
  373. } else {
  374. return false
  375. }
  376. },
  377. // 选择tables某一项
  378. cellClick(row) {
  379. this.$emit('cellClick', row)
  380. },
  381. // 选择多行数据
  382. handleSelectionChange(row) {
  383. this.selectionList = row
  384. let arrID = []
  385. const arr = row
  386. arr.forEach(item => {
  387. // const option = {
  388. // id: item.id,
  389. // status: item.status,
  390. // }
  391. // arrID.push(option)
  392. // arrID.push(item.id)
  393. arrID.push(item)
  394. })
  395. this.waybillIds = JSON.parse(JSON.stringify(arrID))
  396. },
  397. // 操作按钮
  398. buttonData(row, type) {
  399. // console.log(row, type, '操作按钮')
  400. this.$emit("buttonData", row, type);
  401. },
  402. // 删除订单
  403. deleteOrder(row) {
  404. this.$confirm('此操作将永久删除该订单, 是否继续?', '提示', {
  405. confirmButtonText: '确定',
  406. cancelButtonText: '取消',
  407. type: 'warning'
  408. }).then(() => {
  409. let arrOrderId = []
  410. arrOrderId.push(row.id)
  411. putUpdateStatus({
  412. id: arrOrderId,
  413. status: 8,
  414. }).then(res => {
  415. if (res.code == 200) {
  416. this.$message({
  417. message: '操作成功',
  418. type: 'success'
  419. });
  420. }
  421. })
  422. }).catch(() => {})
  423. },
  424. // 清空选中项
  425. clearSelected() {
  426. this.$nextTick(() => {
  427. this.$refs.tableRef.clearSelection();
  428. })
  429. },
  430. rowKey(val) {
  431. if (val.id) {
  432. return val.id
  433. } else {
  434. if (val.T_id) {
  435. return val.T_id + Math.random()
  436. } else {
  437. return val.T_sn
  438. }
  439. }
  440. },
  441. // 展开收起
  442. getUnpack() {
  443. if (this.iconFlag) {
  444. this.unpackWidth = this.controlswidth
  445. this.iconFlag = false
  446. } else {
  447. this.unpackWidth = '70px'
  448. this.iconFlag = true
  449. }
  450. }
  451. }
  452. }
  453. </script>
  454. <style scoped lang="scss">
  455. ::v-deep .el-table__fixed-right {
  456. transition: width 0.15s;
  457. -webkit-transition: width 0.15s;
  458. -moz-transition: width 0.15s;
  459. -webkit-transition: width 0.15s;
  460. -o-transition: width 0.15s;
  461. }
  462. .btn_table:nth-of-type(n+2) {
  463. margin-left: 10px;
  464. }
  465. .el-button--mini {
  466. padding: 5px;
  467. }
  468. .deleteBtn {
  469. color: #ff6665;
  470. }
  471. .icon_play {
  472. font-size: 25px;
  473. color: #83FF00;
  474. }
  475. .icon_pause {
  476. font-size: 25px;
  477. color: #FF9494;
  478. }
  479. .title_play {
  480. font-size: 15px;
  481. color: #83FF00;
  482. margin-left: 10px;
  483. }
  484. .title_pause {
  485. font-size: 15px;
  486. color: #FF9494;
  487. margin-left: 10px;
  488. }
  489. .card_operation {
  490. display: flex;
  491. align-items: center;
  492. justify-content: center;
  493. cursor: pointer;
  494. }
  495. .gateway_title {
  496. color: #59fe6d;
  497. }
  498. .gateway_title1 {
  499. color: #34d9f4;
  500. }
  501. .operator_title {
  502. color: #fff;
  503. }
  504. .unpack_card {
  505. display: flex;
  506. align-items: center;
  507. justify-content: center;
  508. }
  509. .card_unpack {
  510. cursor: pointer;
  511. font-size: 25px;
  512. margin-left: 10px;
  513. }
  514. </style>
  515. <style>
  516. .myTooltips {
  517. max-width: 50%;
  518. }
  519. </style>