quantum.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. <template>
  2. <view>
  3. <u-navbar :title="headline" autoBack placeholder></u-navbar>
  4. <view class="card_stamp">
  5. <view class="title_bluetooth">匹配蓝牙设备</view>
  6. <view class="center_in">
  7. <x-radar :BlueState="BlueState"></x-radar>
  8. </view>
  9. <view class="nearby_title">{{nearbyTitle}}</view>
  10. <view class="search_card">
  11. <u-button style="width: 200rpx;" size="small" type="warning" :text="searchTitle"
  12. @click="openBluetoothAdapter(searchType)"></u-button>
  13. </view>
  14. <view class="space_between">
  15. <view class="waybill_num">运单号: {{waybillNo}}</view>
  16. </view>
  17. <view class="waybill_numil" v-if="printType == 'record'">请选择运单温湿度时间段</view>
  18. <view class="card_waybill" v-for="(item,index) in timeQuantumList" :key="index" @click="selectChange(item)">
  19. <x-checkbox :label="item.title" :isChecked="item.isChecked"></x-checkbox>
  20. <view class="time_title">{{item.startTime}}</view>
  21. <view class="time_title">{{item.endTime}}</view>
  22. </view>
  23. <view class="card_bluetooth" v-if="pairedDeviceList.length > 0">
  24. <view class="equipment_title">已配对设备</view>
  25. <view class="card_equipment">
  26. <x-bluetooth :list="pairedDeviceList" text="打印" btnType="success" @connect="getPrint"></x-bluetooth>
  27. </view>
  28. </view>
  29. <view class="card_bluetooth">
  30. <view class="equipment_title">可连接设备</view>
  31. <view class="card_equipment">
  32. <x-bluetooth :list="devices" @connect="connect"></x-bluetooth>
  33. </view>
  34. </view>
  35. </view>
  36. </view>
  37. </template>
  38. <script>
  39. import {
  40. printList
  41. } from './waybill.js'
  42. import PrinterJobs from './gprint/printerjobs.js'
  43. import printerUtil from './gprint/printerutil.js'
  44. import util from './gprint/util.js'
  45. import drawQrcode from './gprint/weapp.qrcode.esm.js'
  46. import getCode128 from './gprint/code128'
  47. export default {
  48. data() {
  49. return {
  50. headline: '',
  51. barCodeShow: false,
  52. pairedDeviceList: [],
  53. matchingUnit: {},
  54. BlueState: true,
  55. nearbyTitle: '使用蓝牙设备打印...',
  56. searchTitle: '开始搜索',
  57. searchType: false,
  58. devices: [],
  59. deviceId: null,
  60. serviceId: null,
  61. characteristicId: null,
  62. waybillNo: '',
  63. printType: '',
  64. waybillList: {},
  65. humitureData: [],
  66. maxData: [],
  67. timeQuantumList: [],
  68. checkboxValue: [],
  69. userInfo: {},
  70. }
  71. },
  72. onLoad(value) {
  73. const arr = this.$cache.getCache('commodity')
  74. this.waybillList = JSON.parse(arr)
  75. var userInfo = this.$cache.getCache('userInfo')
  76. this.userInfo = userInfo
  77. if (value.printType == 'barCode') {
  78. this.headline = '条码打印'
  79. } else if (value.printType == 'record') {
  80. this.headline = '温湿度记录打印'
  81. this.getHumiture(value.waybillNo)
  82. }
  83. this.waybillNo = value.waybillNo
  84. this.printType = value.printType
  85. },
  86. methods: {
  87. openBluetoothAdapter(value) {
  88. var that = this
  89. if (value) {
  90. that.BlueState = true
  91. that.searchTitle = '开始搜索'
  92. that.nearbyTitle = '已停止蓝牙查找附近设备...'
  93. that.searchType = false
  94. } else {
  95. that.BlueState = false
  96. console.log('开始搜索')
  97. that.searchTitle = '停止搜索'
  98. that.nearbyTitle = '正通过蓝牙查找附近设备...'
  99. that.searchType = true
  100. uni.openBluetoothAdapter({ //打开蓝牙适配器接口
  101. success: (res) => { //已打开
  102. that.onDevice() //监听寻找到新设备的事件
  103. uni.getBluetoothAdapterState({ //获取本机蓝牙适配器状态
  104. success: function(res) {
  105. // console.log(res)
  106. if (res.available) {
  107. //搜索蓝牙
  108. //开始搜寻附近的蓝牙外围设备
  109. console.log("开始搜寻附近的蓝牙外围设备")
  110. uni.startBluetoothDevicesDiscovery({
  111. success(res) {
  112. console.log(res)
  113. }
  114. })
  115. } else {
  116. console.log('本机蓝牙不可用')
  117. }
  118. },
  119. })
  120. },
  121. fail: err => { //未打开
  122. uni.showToast({
  123. icon: 'none',
  124. title: '查看手机蓝牙是否打开'
  125. });
  126. }
  127. })
  128. }
  129. },
  130. onDevice() {
  131. var that = this
  132. //监听寻找到新设备的事件
  133. uni.onBluetoothDeviceFound(function(devices) {
  134. var re = JSON.parse(JSON.stringify(devices))
  135. if (re.devices[0].name != '') {
  136. let deviceId = re.devices[0].deviceId
  137. let name = re.devices[0].name
  138. that.devices.push({
  139. name: name,
  140. deviceId: deviceId,
  141. services: []
  142. })
  143. for (let i = 0; i < that.devices.length; i++) {
  144. for (let j = i + 1; j < that.devices.length; j++) {
  145. if (that.devices[i].deviceId == that.devices[j].deviceId) {
  146. that.devices.splice(j, 1);
  147. j--;
  148. }
  149. }
  150. }
  151. that.devices = that.devices
  152. }
  153. })
  154. },
  155. stopFindBule() {
  156. const that = this
  157. uni.stopBluetoothDevicesDiscovery({
  158. success: e => {
  159. that.searchTitle = '开始搜索'
  160. that.nearbyTitle = '已停止蓝牙查找附近设备...'
  161. that.searchType = false
  162. that.BlueState = true
  163. console.log('停止搜索蓝牙设备:' + e.errMsg);
  164. },
  165. fail: e => {
  166. console.log('停止搜索蓝牙设备失败,错误码:' + e.errCode);
  167. }
  168. });
  169. },
  170. connect(value) {
  171. // console.log(value, 66)
  172. this.createBLEConnection(value)
  173. },
  174. // item 是要连接的设备数据
  175. createBLEConnection(item) {
  176. let that = this;
  177. that.matchingUnit.deviceId = item.deviceId
  178. uni.showLoading({
  179. title: "连接中,请稍等",
  180. mask: true,
  181. });
  182. uni.createBLEConnection({
  183. deviceId: item.deviceId,
  184. success(res) {
  185. that.stopFindBule(); // 停止搜索蓝牙
  186. setTimeout(function() {
  187. that.getBLEDeviceServices(item); // 获取蓝牙的服务
  188. }, 2000)
  189. },
  190. fail(res) {
  191. uni.showToast({
  192. title: item.name + "蓝牙连接失败",
  193. icon: "none",
  194. });
  195. uni.hideLoading()
  196. }
  197. });
  198. },
  199. getBLEDeviceServices(item) {
  200. const that = this
  201. setTimeout(() => {
  202. uni.getBLEDeviceServices({
  203. // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
  204. deviceId: item.deviceId,
  205. complete(res) {
  206. let serviceId = ""
  207. if (res.services.length > 0) {
  208. for (var s = 0; s < res.services.length; s++) {
  209. let serviceId = res.services[s].uuid
  210. that.matchingUnit.serviceId = serviceId
  211. uni.getBLEDeviceCharacteristics({ //获取蓝牙设备某个服务中所有特征值(characteristic)
  212. // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
  213. deviceId: item.deviceId,
  214. // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
  215. serviceId: serviceId,
  216. success(res) {
  217. // console.log('获取服务成功')
  218. that.pairedDeviceList = []
  219. that.pairedDeviceList.push(item)
  220. var re = JSON.parse(JSON.stringify(res))
  221. for (var c = 0; c < re.characteristics.length; c++) {
  222. if (re.characteristics[c].properties.write ==
  223. true) {
  224. let uuid = re.characteristics[c].uuid
  225. that.matchingUnit.characteristicId = uuid
  226. break
  227. }
  228. }
  229. uni.hideLoading()
  230. }
  231. })
  232. }
  233. } else {
  234. uni.hideLoading()
  235. }
  236. },
  237. fail(res) {
  238. console.log(res)
  239. },
  240. })
  241. });
  242. },
  243. // 断开连接
  244. closeBLEConnection(item) {
  245. uni.closeBLEConnection({
  246. deviceId: item.deviceId,
  247. success: (res) => {
  248. // res.characteristics 特征值列表
  249. // 读写都需要用到特征值
  250. },
  251. fail: (res) => {
  252. console.log(res);
  253. },
  254. })
  255. },
  256. // 配对设备打印
  257. async getPrint(value) {
  258. this.deviceId = this.matchingUnit.deviceId
  259. this.serviceId = this.matchingUnit.serviceId
  260. this.characteristicId = this.matchingUnit.characteristicId
  261. if (this.printType == 'barCode') {
  262. const showFirstName = (name) => {
  263. let newStr;
  264. if (name.length === 2) {
  265. newStr = name.substr(0, 1) + '*';
  266. } else if (name.length > 2) {
  267. let char = '';
  268. for (let i = 0, len = name.length - 1; i < len; i++) {
  269. char += '*';
  270. }
  271. newStr = name.substr(0, 1) + char;
  272. } else {
  273. newStr = name;
  274. }
  275. return newStr;
  276. }
  277. const shippingAddress = (addres) => {
  278. let title;
  279. if (addres.length < 16) {
  280. title = addres + ' \n'
  281. } else {
  282. title = addres
  283. }
  284. return title
  285. }
  286. let printerJobs = new PrinterJobs();
  287. let codeValue = this.waybillNo
  288. const ENV = require('../../.env.js')
  289. let logistics = ENV.APP_LINK_URL + '/newInquiry?waybillNo=' + codeValue
  290. let code128 = getCode128(codeValue);
  291. let numArr = []
  292. if (this.waybillList.quantity != 0) {
  293. for (var i = 0; i < this.waybillList.quantity; i++) {
  294. let numa = i + 1
  295. numArr.push(numa)
  296. }
  297. } else {
  298. let numa = 1
  299. numArr.push(numa)
  300. }
  301. numArr.forEach((numitem, indexnum) => {
  302. printerJobs
  303. .setSize(1, 1)
  304. .setAlign('LT')
  305. .print('#' + this.userInfo.dept.name)
  306. .setAlign('CT')
  307. .printBarcode(code128)
  308. .setSize(1, 1)
  309. .setAlign('LT')
  310. .text(' ')
  311. .text(codeValue + ' \n')
  312. .print(printerUtil.fillLine())
  313. .setAlign('LT')
  314. .setSize(1, 2)
  315. .setSize(2, 1)
  316. .setBold()
  317. .text('收:')
  318. .setSize(1, 1)
  319. .setBold(false)
  320. .text(' ' + showFirstName(this.waybillList.senderAddressName))
  321. .text(' ' + this.waybillList.senderAddressPhone.substr(0, 3) + "****" + this
  322. .waybillList
  323. .senderAddressPhone.substr(7) + ' \n')
  324. .print(shippingAddress(this.waybillList.senderAddressDetails))
  325. .print(printerUtil.fillLine())
  326. .setSize(1, 2)
  327. .setSize(2, 1)
  328. .setBold()
  329. .text('寄:')
  330. .setSize(1, 1)
  331. .setBold(false)
  332. .text(' ' + showFirstName(this.waybillList.consigneeAddressName))
  333. .text(' ' + this.waybillList.consigneeAddressPhone.substr(0, 3) + "****" + this
  334. .waybillList
  335. .consigneeAddressPhone.substr(7) + ' \n')
  336. .print(shippingAddress(this.waybillList.consigneeAddressDetails))
  337. .print(printerUtil.fillLine())
  338. .text('备注:')
  339. .text('防拆标签码:' + this.waybillList.tamperProofLabel + ' \n')
  340. .setAlign('CT')
  341. .printQrcode(logistics)
  342. .print('扫码查询物流温湿度信息 \n')
  343. .println()
  344. })
  345. let buffer = printerJobs.buffer();
  346. this.printbuffs(buffer);
  347. } else {
  348. let printerJobs = new PrinterJobs();
  349. printerJobs
  350. .setSize(1, 1)
  351. .setAlign('lt')
  352. .print('#' + this.userInfo.dept.name)
  353. .print('运单号:' + this.waybillNo)
  354. .print('货物类型:' + this.waybillList.cargoType)
  355. .print('温度需求:' + this.waybillList.temperatureInterval)
  356. .print('配送要求:' + this.waybillList.deliveryCondition)
  357. .print('寄件人:' + this.waybillList.senderAddressName)
  358. .print('收件人:' + this.waybillList.consigneeAddressName)
  359. .print(printerUtil.fillLine())
  360. this.humitureData.forEach((item, index) => {
  361. // console.log(item,123)
  362. const exists = this.checkboxValue.some(Tid => Tid === item.id);
  363. if (item.isChecked) {
  364. // printerJobs
  365. // .print('设备号:' + item.sn)
  366. // .print('标识名:' + item.title)
  367. // .print('开始时间:' + item.startTime)
  368. // .print('结束时间:' + item.endTime)
  369. // .print(printerUtil.fillLine())
  370. item.arr.forEach((item1, index1) => {
  371. printerJobs
  372. .print('日期:' + item1.time + '单位℃ ')
  373. .text('时间 ')
  374. .text('|')
  375. .text(' ')
  376. .text('T1 ')
  377. .text(' ')
  378. .text('|')
  379. .text(' ')
  380. .text('T2 ')
  381. .text(' ')
  382. .text('|')
  383. .text(' ')
  384. .text('T3 ')
  385. .text(' ')
  386. .text('|')
  387. .text(' ')
  388. .text('T4 \n')
  389. item1.arr.forEach((item2, index2) => {
  390. printerJobs
  391. .text(`${item2[0].time}`)
  392. .text('|')
  393. .text(' ')
  394. .text(
  395. `${item2[0] == '---' ? '----' : character(item2[0].T_t) }`
  396. )
  397. .text(' ')
  398. .text('|')
  399. .text(' ')
  400. .text(
  401. `${item2[1] == '---' ? '----' : character(item2[1].T_t) }`
  402. )
  403. .text(' ')
  404. .text('|')
  405. .text(' ')
  406. .text(
  407. `${item2[2] == '---' ? '----' : character(item2[2].T_t) }`
  408. )
  409. .text(' ')
  410. .text('|')
  411. .text(' ')
  412. .text(
  413. `${item2[3] == '---' ? '----' : character(item2[3].T_t) }`
  414. )
  415. function character(value) {
  416. var arr = value.toFixed(1)
  417. if (arr.length == 3) {
  418. var arr1 = arr + ' '
  419. return arr1
  420. } else {
  421. return arr
  422. }
  423. }
  424. })
  425. })
  426. // printerJobs.println()
  427. }
  428. })
  429. printerJobs.println()
  430. let buffer = printerJobs.buffer();
  431. this.printbuffs(buffer);
  432. }
  433. },
  434. printbuffs(buffer) {
  435. // 1.并行调用多次会存在写失败的可能性
  436. // 2.建议每次写入不超过20字节
  437. // 分包处理,延时调用
  438. const maxChunk = 20;
  439. const delay = 20;
  440. for (let i = 0, j = 0, length = buffer.byteLength; i < length; i += maxChunk, j++) {
  441. let subPackage = buffer.slice(i, i + maxChunk <= length ? (i + maxChunk) : length);
  442. setTimeout(this.printbuff, j * delay, subPackage);
  443. }
  444. },
  445. printbuff(buffer) {
  446. let deviceId = this.deviceId;
  447. let serviceId = this.serviceId;
  448. let characteristicId = this.characteristicId;
  449. // console.log(deviceId, serviceId, characteristicId, 333)
  450. return new Promise((resolve, reject) => {
  451. uni.writeBLECharacteristicValue({
  452. deviceId,
  453. serviceId,
  454. characteristicId,
  455. value: buffer,
  456. success(res) {
  457. //console.log('message发送成功', JSON.stringify(res));
  458. resolve(res);
  459. },
  460. fail(err) {
  461. console.log('message发送失败', JSON.stringify(err));
  462. reject(err);
  463. }
  464. });
  465. });
  466. },
  467. // 获取设备信息探头
  468. getHumiture(waybillNo) {
  469. this.checkboxValue = []
  470. this.$api.get('/api/waybill-task', {
  471. waybillNo: waybillNo,
  472. }).then(res => {
  473. if (res.code == 200) {
  474. const arrlsist = res.data.list
  475. let arrList = []
  476. arrlsist.forEach((item, index) => {
  477. let dataList = {}
  478. dataList.id = item.id
  479. dataList.sn = item.sn
  480. dataList.deviceSensorList = item.deviceSensorList
  481. dataList.startTime = item.startTime
  482. dataList.endTime = item.endTime
  483. if (item.car.id) {
  484. dataList.title = item.car.carNo
  485. } else if (item.warehouse.id) {
  486. dataList.title = item.warehouse.name
  487. }
  488. arrList.push(dataList)
  489. })
  490. this.timeQuantumList = arrList
  491. this.timeQuantumList.forEach((item1, index1) => {
  492. item1.isChecked = true
  493. this.checkboxValue.push(item1.id)
  494. })
  495. this.humitureInfo(arrList)
  496. }
  497. })
  498. },
  499. // 选择打印
  500. selectChange(value) {
  501. this.timeQuantumList.forEach((item, index) => {
  502. if (value.id == item.id) {
  503. if (value.isChecked) {
  504. item.isChecked = false
  505. } else {
  506. item.isChecked = true
  507. }
  508. }
  509. if (item.isChecked) {
  510. this.checkboxValue = []
  511. this.checkboxValue.push(item.id)
  512. }
  513. })
  514. // console.log(this.humitureData,'------')
  515. this.$forceUpdate()
  516. },
  517. // 获取温湿度信息
  518. humitureInfo(value) {
  519. // console.log(printList(), 2666)
  520. // console.log(value, 25)
  521. let arrData = value
  522. let arrData1 = printList()
  523. arrData.forEach((item, index) => {
  524. let arr = []
  525. item.deviceSensorList.forEach((ote, te) => {
  526. arr.push(ote.T_id)
  527. })
  528. let params = {
  529. t_ids: arr,
  530. taskId: item.id,
  531. waybillNo: this.waybillNo,
  532. page: 1,
  533. pageSize: 9999,
  534. }
  535. // console.log(item,999)
  536. item.arr = []
  537. this.getWaybillTask(params).then(res => {
  538. const arrL = JSON.parse(JSON.stringify(res))
  539. const timeList = JSON.parse(JSON.stringify(res))
  540. const arrLil = res
  541. for (let i = 0; i < arrLil.length; i++) {
  542. for (let j = i + 1; j < arrLil.length; j++) {
  543. if (arrLil[i].T_time == arrLil[j].T_time) {
  544. arrLil.splice(j, 1);
  545. j--;
  546. }
  547. }
  548. }
  549. var resultArr = arrLil
  550. let list1 = []
  551. resultArr.forEach(k => {
  552. let arr1 = {
  553. T_sn: k.T_sn,
  554. time: k.T_time,
  555. arr: [],
  556. }
  557. list1.push(arr1)
  558. })
  559. this.maxData = list1
  560. for (let i = 0; i < timeList.length; i++) {
  561. for (let j = i + 1; j < timeList.length; j++) {
  562. if (timeList[i].time == timeList[j].time) {
  563. timeList.splice(j, 1);
  564. j--;
  565. }
  566. }
  567. }
  568. this.maxData.forEach((item3, index3) => {
  569. timeList.forEach((item2, index2) => {
  570. const result1 = arrL.find(fruit => fruit.T_id === 1 &&
  571. fruit.time === item2.time && fruit.T_time === item3
  572. .time)
  573. const result2 = arrL.find(fruit => fruit.T_id === 2 &&
  574. fruit.time === item2.time && fruit.T_time === item3
  575. .time)
  576. const result3 = arrL.find(fruit => fruit.T_id === 3 &&
  577. fruit.time === item2.time && fruit.T_time === item3
  578. .time)
  579. const result4 = arrL.find(fruit => fruit.T_id === 4 &&
  580. fruit.time === item2.time && fruit.T_time === item3
  581. .time)
  582. const flag = areAllUndefined(result1, result2, result3,
  583. result4)
  584. if (!flag) {
  585. let list2 = [
  586. result1 == undefined ? '---' : result1,
  587. result2 == undefined ? '---' : result2,
  588. result3 == undefined ? '---' : result3,
  589. result4 == undefined ? '---' : result4,
  590. ]
  591. item3.arr.push(list2)
  592. }
  593. function areAllUndefined(...args) {
  594. return args.every(arg => arg === undefined);
  595. }
  596. })
  597. })
  598. item.arr = this.maxData
  599. })
  600. })
  601. this.humitureData = arrData
  602. // console.log(this.humitureData, 26)
  603. },
  604. getWaybillTask(params) {
  605. return new Promise((resolve, reject) => {
  606. this.$api.post('/api/waybill-task/data', params).then(res => {
  607. if (res.code == 200) {
  608. let arr1 = res.data.list
  609. if (arr1) {
  610. let arr2 = []
  611. arr1.forEach(item1 => {
  612. const dateString = item1.T_time;
  613. const parts = dateString.split(" ")[0].split("-");
  614. const extractedDate = parts[0] + "-" + parts[1] + "-" + parts[
  615. 2];
  616. const parts1 = dateString.split(" ")[1].split(":");
  617. const extractedTime = parts1[0] + ":" + parts1[1];
  618. let arr3 = {
  619. T_sn: item1.T_sn,
  620. T_id: item1.T_id,
  621. T_time: extractedDate,
  622. T_t: item1.T_t,
  623. T_rh: item1.T_rh,
  624. time: extractedTime
  625. }
  626. arr2.push(arr3)
  627. })
  628. resolve(arr2)
  629. }
  630. }
  631. })
  632. });
  633. },
  634. }
  635. }
  636. </script>
  637. <style lang="scss">
  638. page {
  639. background-color: #fff;
  640. }
  641. .title_bluetooth {
  642. display: flex;
  643. justify-content: center;
  644. align-items: center;
  645. font-size: 40rpx;
  646. margin: 20rpx;
  647. font-weight: 600;
  648. }
  649. .nearby_title {
  650. display: flex;
  651. justify-content: center;
  652. align-items: center;
  653. font-size: 30rpx;
  654. margin: 20rpx;
  655. font-weight: 600;
  656. }
  657. .card_stamp {
  658. display: flex;
  659. flex-direction: column;
  660. padding: 30rpx 20rpx;
  661. }
  662. .search_card {
  663. display: flex;
  664. justify-content: center;
  665. align-items: center;
  666. }
  667. .card_bluetooth {
  668. margin-top: 20rpx;
  669. }
  670. .equipment_title {
  671. font-size: 28rpx;
  672. font-weight: 600;
  673. }
  674. .card_equipment {
  675. margin-top: 20rpx;
  676. min-height: 90rpx;
  677. box-shadow: 0 4rpx 24rpx 0 rgba(0, 0, 0, 0.1);
  678. padding: 10rpx 20rpx;
  679. border-radius: 10rpx;
  680. }
  681. .waybill_num {
  682. margin-top: 20rpx;
  683. font-size: 30rpx;
  684. font-weight: 600;
  685. }
  686. .waybill_numil {
  687. margin-top: 10rpx;
  688. font-size: 28rpx;
  689. color: #767a82;
  690. }
  691. .time_title {
  692. margin-top: 5rpx;
  693. font-size: 28rpx;
  694. }
  695. .card_waybill {
  696. display: flex;
  697. flex-direction: column;
  698. box-shadow: 1rpx 2rpx 14rpx rgba(0, 0, 0, .12);
  699. padding: 20rpx;
  700. border-radius: 10rpx;
  701. margin-top: 20rpx;
  702. }
  703. </style>