humiture.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. <template>
  2. <!-- 温湿度 -->
  3. <view>
  4. <u-navbar title="温湿度记录" autoBack placeholder></u-navbar>
  5. <view class="card_qiucharts" v-if="userType == 'customer'">
  6. <view class="card_echart">
  7. <qiun-data-charts type="gauge" :opts="opts" :chartData="chartData" />
  8. </view>
  9. <view class="card_echart">
  10. <qiun-data-charts type="gauge" :opts="opts1" :chartData="chartData1" />
  11. </view>
  12. </view>
  13. <view v-else>
  14. <view v-if="humitureList.length > 0">
  15. <view class="card_particulars" v-for="(item,index) in humitureList" :key="index">
  16. <view class="card_describe">
  17. <view @click="selectChangeil(item)">
  18. <x-checkbox :label="item.title" :isChecked="item.isChecked"></x-checkbox>
  19. </view>
  20. <!-- <view class="describe_title">{{item.title}}</view> -->
  21. <!-- <view class="describe_time">{{item.startTime}}</view>
  22. <view class="describe_time">{{item.endTime}}</view> -->
  23. </view>
  24. <view class="dateTime_card" style="margin: 20rpx 10rpx;">
  25. <uni-datetime-picker v-model="item.datetimeRange" type="datetimerange"
  26. @change="changeDatetime($event,item)" />
  27. </view>
  28. <view class="humiture_details" @click="foldingPanel(item)">
  29. <view class="title_details">温湿度</view>
  30. <view style="display: flex;">
  31. <view class="title_blue title_details">查看详情</view>
  32. <u-icon name="arrow-down"></u-icon>
  33. </view>
  34. </view>
  35. <view v-show="item.collapseil">
  36. <x-humiture ref="humiture" :startTime="item.datetimeRange[0]" :endTime="item.datetimeRange[1]"
  37. :taskId="item.id" :waybillNo="waybillNo" :current="item.presentNum"
  38. :probeList="item.deviceSensorList"></x-humiture>
  39. </view>
  40. </view>
  41. </view>
  42. <view style="margin-top: 30%;" v-else>
  43. <u-empty mode="data" text="当前没有温湿度记录"></u-empty>
  44. </view>
  45. </view>
  46. <view style="width: 100%;height: 230rpx;"></view>
  47. <view class="card_btn"
  48. v-if="humitureList.length > 0 && waybillData.status != 1 || waybillData.status != 2 || waybillData.status != 3 || waybillData.status != 9">
  49. <u-button style="margin-bottom: 20rpx;" type="primary"
  50. @click="humidityRecording('send')">发送温湿度记录PDF</u-button>
  51. <u-button style="margin-bottom: 20rpx;" type="success"
  52. @click="humidityRecording('print')">打印温湿度记录</u-button>
  53. </view>
  54. <view class="card_stop">
  55. <u-modal :show="show" confirmText="停止" showCancelButton :buttonReverse="true" @cancel="cancel"
  56. @confirm="confirm">
  57. <view class="slot-content" style="width: 100%;">
  58. <view>{{stoprecording}}</view>
  59. <view style="width: 100%;">
  60. <view style="padding: 10px 0px;font-size: 30rpx;color: #ff9900;">选择停止时间:</view>
  61. <uni-datetime-picker v-model="stopTime" type="datetime" @change="changeStopTime" />
  62. </view>
  63. </view>
  64. </u-modal>
  65. </view>
  66. <u-popup :show="shareShow" mode="center" round="5" closeable @close="shareShow = false">
  67. <view style="padding: 0rpx 30rpx 30rpx 30rpx;margin-top: 50rpx; width: 400rpx;">
  68. <u-button style="margin: 20rpx 0rpx;" type="success" text="发送邮箱" @click="sendingMailbox"></u-button>
  69. <u-button type="primary" text="分享微信好友" @click="shareWechatFriends"></u-button>
  70. </view>
  71. </u-popup>
  72. <u-popup :show="emailShow" mode="center" round="5" closeable @close="close">
  73. <view style="padding: 30rpx;">
  74. <view style="margin-top: 20rpx;width: 600rpx;">
  75. <view class="email_title" style="margin-bottom: 10rpx;">运单号:{{waybillNo}}</view>
  76. <view class="card_email">
  77. <span class="email_title">邮箱地址:</span>
  78. <view style="margin-top: 20rpx;">
  79. <u--input v-model="email" placeholder="请输入邮箱" border="surround"></u--input>
  80. </view>
  81. </view>
  82. </view>
  83. <view style="margin-top: 20rpx;">
  84. <u-button type="primary" :loading="sendLoading" text="发送" @click="confirmSend"></u-button>
  85. </view>
  86. </view>
  87. </u-popup>
  88. </view>
  89. </template>
  90. <script>
  91. const FileShare = uni.requireNativePlugin('life-FileShare');
  92. export default {
  93. data() {
  94. return {
  95. show: false,
  96. orderList: {},
  97. humitureList: [],
  98. userType: '',
  99. myChart: null,
  100. chartData: {},
  101. chartData1: {},
  102. opts: {
  103. color: ["#3592FE"],
  104. padding: undefined,
  105. title: {
  106. // name: "66℃",
  107. fontSize: 25,
  108. color: "#3592FE",
  109. offsetY: 0
  110. },
  111. subtitle: {
  112. name: "当前温度",
  113. fontSize: 15,
  114. color: "#1890ff",
  115. offsetY: 0
  116. },
  117. extra: {
  118. gauge: {
  119. type: "progress",
  120. width: 20,
  121. labelColor: "#666666",
  122. startAngle: 0.75,
  123. endAngle: 0.25,
  124. // startNumber: 5,
  125. // endNumber: 35,
  126. labelFormat: "",
  127. splitLine: {
  128. fixRadius: -10,
  129. splitNumber: 10,
  130. width: 15,
  131. color: "#FFFFFF",
  132. childNumber: 5,
  133. childWidth: 12
  134. },
  135. pointer: {
  136. width: 24,
  137. color: "auto"
  138. }
  139. }
  140. },
  141. },
  142. opts1: {
  143. color: ["#67C23A"],
  144. padding: 20,
  145. title: {
  146. // name: "66℃",
  147. fontSize: 25,
  148. color: "#2fc25b",
  149. offsetY: 0
  150. },
  151. subtitle: {
  152. name: "当前湿度",
  153. fontSize: 15,
  154. color: "#67C23A",
  155. offsetY: 0
  156. },
  157. extra: {
  158. gauge: {
  159. type: "progress",
  160. width: 20,
  161. labelColor: "#000000",
  162. startAngle: 0.75,
  163. endAngle: 0.25,
  164. // startNumber: 0,
  165. // endNumber: 100,
  166. labelFormat: "",
  167. splitLine: {
  168. fixRadius: -10,
  169. splitNumber: 10,
  170. width: 15,
  171. color: "#67C23A",
  172. childNumber: 5,
  173. childWidth: 12
  174. },
  175. labelOffset: 20,
  176. pointer: {
  177. width: 24,
  178. color: "auto"
  179. }
  180. }
  181. },
  182. },
  183. datetimeRange: [],
  184. waybillNo: '',
  185. waybillData: [],
  186. shareShow: false,
  187. stoprecording: '打印前需停止记录,是否继续?',
  188. stopTime: this.getDateTime(new Date()),
  189. humitureType: '',
  190. checkboxValue: [],
  191. emailShow: false,
  192. email: '',
  193. sendLoading: false,
  194. humidityFlag: false,
  195. }
  196. },
  197. onLoad(option) {
  198. this.waybillNo = option.waybillNo
  199. // 获取运单详情
  200. this.waybillDetails(option.waybillNo)
  201. },
  202. mounted() {
  203. var userInfo = this.$cache.getCache('userInfo')
  204. this.userType = userInfo.userType
  205. var orderList = this.$cache.getCache('orderDetails')
  206. this.orderList = orderList
  207. if (this.userType == 'customer') {
  208. this.getServerData();
  209. } else {
  210. this.getList()
  211. }
  212. },
  213. methods: {
  214. getList() {
  215. this.$api.get('/api/waybill-task', {
  216. waybillNo: this.waybillNo,
  217. }).then(res => {
  218. if (res.code == 200) {
  219. this.humitureList = JSON.parse(JSON.stringify(res.data.list))
  220. this.humitureList.forEach((item, index) => {
  221. this.checkboxValue.push(item.id)
  222. item.isChecked = true
  223. item.title = ''
  224. item.collapseil = false
  225. item.datetimeRange = []
  226. item.datetimeRange.push(item.startTime)
  227. if (item.endTime) {
  228. item.datetimeRange.push(item.endTime)
  229. } else {
  230. item.datetimeRange.push(this.getDateTime(new Date()))
  231. }
  232. if (item.car.id) {
  233. item.title = item.car.carNo
  234. } else if (item.warehouse.id) {
  235. item.title = item.warehouse.name
  236. } else if (item.coolerBox.id) {
  237. item.title = item.coolerBox.name
  238. }
  239. })
  240. }
  241. })
  242. },
  243. // 获取运单详情
  244. waybillDetails(waybillNo) {
  245. this.$api.get('/api/waybill/' + waybillNo).then(res => {
  246. if (res.code == 200) {
  247. this.waybillData = res.data
  248. }
  249. })
  250. },
  251. // 发送邮箱
  252. sendingMailbox() {
  253. this.shareShow = false
  254. this.emailShow = true
  255. },
  256. // 分享微信好友
  257. shareWechatFriends() {
  258. uni.showLoading({
  259. title: '获取温湿度记录中,请稍等',
  260. mask: true,
  261. });
  262. this.$api.post('/api/waybill/temperature-pdf-url', {
  263. waybillNo: this.waybillNo,
  264. waybillTaskIds: this.checkboxValue,
  265. }).then(res => {
  266. if (res.code == 200) {
  267. let arrData = res.data.split("/");
  268. var dtask = plus.downloader.createDownload(res.data, {
  269. filename: "_doc/pdf/" + arrData[3]
  270. }, function(d, status) {
  271. // 下载完成
  272. if (status == 200) {
  273. FileShare.render({
  274. type: "WX", //QQ为QQ,微信为WX,系统默认是SYSTEM,不填写默认SYSTEM
  275. filePath: plus.io.convertLocalFileSystemURL(d.filename),
  276. }, result => {
  277. uni.hideLoading()
  278. });
  279. } else {
  280. console.log("Download failed: " + status);
  281. }
  282. });
  283. dtask.start();
  284. } else {
  285. this.shareShow = false
  286. uni.$u.toast('发送失败')
  287. }
  288. uni.hideLoading()
  289. }).catch(() => {
  290. uni.hideLoading()
  291. })
  292. return
  293. },
  294. // 发送邮箱
  295. confirmSend() {
  296. if (this.email) {
  297. let flag = validateEmail(this.email)
  298. if (flag) {
  299. if (!this.sendLoading) {
  300. this.sendLoading = true
  301. let arrTo = []
  302. arrTo.push(this.email)
  303. this.$api.post('/api/waybill/send-mail', {
  304. waybillNo: this.waybillNo,
  305. humidityShow: this.humidityFlag,
  306. to: arrTo,
  307. waybillTaskIds: this.checkboxValue,
  308. }).then(res => {
  309. if (res.code == 200) {
  310. uni.$u.toast(res.msg)
  311. this.email = ''
  312. this.emailShow = false
  313. } else {
  314. this.emailShow = false
  315. uni.$u.toast('发送失败')
  316. }
  317. this.sendLoading = false
  318. }).catch(() => {
  319. this.sendLoading = false
  320. })
  321. }
  322. } else {
  323. uni.$u.toast('邮箱格式错误')
  324. }
  325. } else {
  326. uni.$u.toast('请输入邮箱')
  327. }
  328. // 如果邮箱格式正确,输出 true,否则输出 false
  329. function validateEmail(email) {
  330. const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
  331. return emailRegex.test(email);
  332. }
  333. },
  334. // 打印温湿度记录
  335. humidityRecording(type) {
  336. this.humitureType = type
  337. if ([4, 5, 10].includes(this.waybillData.status)) {
  338. if (type == 'send') {
  339. this.stoprecording = '发送温湿度记录前需停止记录,是否继续?'
  340. } else {
  341. this.stoprecording = '打印前需停止记录,是否继续?'
  342. }
  343. this.show = true
  344. } else {
  345. if (type == 'send') {
  346. this.shareShow = true
  347. } else {
  348. if (this.waybillData.id) {
  349. this.$cache.setCache('commodity', JSON.stringify(this.waybillData))
  350. uni.navigateTo({
  351. url: '/pages/order/quantum?waybillNo=' + this.waybillData.waybillNo +
  352. '&printType=record'
  353. });
  354. } else {
  355. uni.$u.toast('暂无运单详情数据,无法打印!')
  356. }
  357. }
  358. }
  359. },
  360. cancel() {
  361. this.show = false
  362. },
  363. // 确定停止记录
  364. confirm() {
  365. if (this.stopTime) {
  366. this.$api.post('/api/waybill/stop-record', {
  367. waybillNo: this.waybillData.waybillNo,
  368. startTime: this.stopTime,
  369. }).then(res => {
  370. if (res.code == 200) {
  371. if (this.humitureType == 'send') {
  372. this.show = false
  373. this.shareShow = true
  374. } else {
  375. if (this.waybillData.id) {
  376. this.$cache.setCache('commodity', JSON.stringify(this.waybillData))
  377. uni.navigateTo({
  378. url: '/pages/order/quantum?waybillNo=' + this.waybillData
  379. .waybillNo +
  380. '&printType=record'
  381. });
  382. } else {
  383. uni.$u.toast('暂无运单详情数据,无法打印!')
  384. }
  385. }
  386. } else {
  387. uni.$u.toast(res.data.msg)
  388. }
  389. this.show = false
  390. }).catch(() => {
  391. this.show = false
  392. })
  393. } else {
  394. uni.$u.toast('请选择停止时间')
  395. }
  396. },
  397. // 选择停止时间
  398. changeStopTime(time) {
  399. this.stopTime = time
  400. },
  401. // 折叠面板
  402. foldingPanel(value) {
  403. this.humitureList.forEach((item, index) => {
  404. if (item.id == value.id) {
  405. if (item.collapseil) {
  406. item.collapseil = false
  407. } else {
  408. this.$refs.humiture[index].getlistil(item.deviceSensorList[0].T_id)
  409. item.collapseil = true
  410. }
  411. }
  412. })
  413. this.$forceUpdate()
  414. },
  415. change(e) {
  416. if (e[0].status == 'open') {
  417. this.humitureList.forEach((item, index) => {
  418. this.$refs.humiture[index].getlistil(item.deviceSensorList[0].T_id)
  419. })
  420. }
  421. },
  422. getServerData() {
  423. this.$api.post('/api/waybill-task/newest-locus', {
  424. waybillNo: this.waybillNo,
  425. }).then((res) => {
  426. if (res.code == 200) {
  427. this.opts.title.name = res.data.T_t + '℃'
  428. this.opts.extra.gauge.startNumber = res.data.T_tl
  429. this.opts.extra.gauge.endNumber = res.data.T_tu
  430. this.opts1.title.name = res.data.T_rh + '℃'
  431. this.opts1.extra.gauge.startNumber = res.data.T_rhl
  432. this.opts1.extra.gauge.endNumber = res.data.T_rhu
  433. let arr = (res.data.T_t - res.data.T_tl) / (res.data.T_tu - res.data.T_tl)
  434. let arr1 = (res.data.T_rh - res.data.T_rhl) / (res.data.T_rhu - res.data.T_rhl)
  435. let value = {
  436. categories: [{
  437. "value": 0.2,
  438. "color": "#1890ff"
  439. }, {
  440. "value": 0.8,
  441. "color": "#2fc25b"
  442. }, {
  443. "value": 1,
  444. "color": "#f04864"
  445. }],
  446. series: [{
  447. data: arr.toFixed(1)
  448. }]
  449. };
  450. let value1 = {
  451. categories: [{
  452. "value": 0.2,
  453. "color": "#1890ff"
  454. }, {
  455. "value": 0.8,
  456. "color": "#2fc25b"
  457. }, {
  458. "value": 1,
  459. "color": "#f04864"
  460. }],
  461. series: [{
  462. data: arr1.toFixed(1)
  463. }]
  464. };
  465. this.chartData = JSON.parse(JSON.stringify(value));
  466. this.chartData1 = JSON.parse(JSON.stringify(value1));
  467. }
  468. })
  469. },
  470. // 选择某段温湿度数据
  471. selectChangeil(value) {
  472. this.humitureList.forEach((item, index) => {
  473. if (value.id == item.id) {
  474. if (value.isChecked) {
  475. item.isChecked = false
  476. } else {
  477. item.isChecked = true
  478. }
  479. }
  480. })
  481. this.selectChange(value.id)
  482. this.$forceUpdate()
  483. },
  484. // 选择打印
  485. selectChange(stingId) {
  486. const result = this.checkboxValue
  487. const index = result.indexOf(stingId)
  488. if (index > -1) {
  489. result.splice(index, 1)
  490. } else {
  491. result.push(stingId)
  492. }
  493. this.checkboxValue = result
  494. },
  495. // 时间范围选择
  496. changeDatetime(value, item) {
  497. this.humitureList.forEach((item1, index) => {
  498. if (item1.id == item.id) {
  499. setTimeout(() => {
  500. item.datetimeRange = value
  501. // this.getDatas()
  502. this.$refs.humiture[index].getlistil(item.deviceSensorList[0].T_id)
  503. }, 500)
  504. }
  505. })
  506. this.$forceUpdate()
  507. },
  508. close() {
  509. this.emailShow = false
  510. this.email = ''
  511. },
  512. getDateTime(date, addZero = true) {
  513. return `${this.getDate(date, addZero)} ${this.getTime(date, addZero)}`
  514. },
  515. getDate(date, addZero = true) {
  516. date = new Date(date)
  517. const year = date.getFullYear()
  518. const month = date.getMonth() + 1
  519. const day = date.getDate()
  520. return `${year}-${addZero ? this.addZero(month) : month}-${addZero ? this.addZero(day) : day}`
  521. },
  522. getTime(date, addZero = true) {
  523. date = new Date(date)
  524. const hour = date.getHours()
  525. const minute = date.getMinutes()
  526. const second = date.getSeconds()
  527. return this.hideSecond ?
  528. `${addZero ? this.addZero(hour) : hour}:${addZero ? this.addZero(minute) : minute}` :
  529. `${addZero ? this.addZero(hour) : hour}:${addZero ? this.addZero(minute) : minute}:${addZero ? this.addZero(second) : second}`
  530. },
  531. addZero(num) {
  532. if (num < 10) {
  533. num = `0${num}`
  534. }
  535. return num
  536. }
  537. }
  538. }
  539. </script>
  540. <style lang="scss">
  541. .card_particulars {
  542. display: flex;
  543. flex-direction: column;
  544. padding-top: 20rpx;
  545. margin: 30rpx 20rpx 20rpx 20rpx;
  546. border-radius: 20rpx;
  547. background-color: #fff;
  548. }
  549. .card_describe {
  550. padding-left: 20rpx;
  551. padding-bottom: 20rpx;
  552. border-bottom: 1rpx solid #EBEEF5;
  553. }
  554. .describe_title {
  555. font-size: 30rpx;
  556. font-weight: 600;
  557. }
  558. .describe_time {
  559. font-size: 28rpx;
  560. }
  561. .humiture_details {
  562. display: flex;
  563. justify-content: space-between;
  564. align-items: center;
  565. padding: 20rpx;
  566. }
  567. .title_blue {
  568. color: #2979ff;
  569. margin-right: 10rpx;
  570. }
  571. .title_details {
  572. font-size: 28rpx;
  573. }
  574. ::v-deep .u-collapse-item__content__text {
  575. padding: 0rpx 0rpx 30rpx 0rpx;
  576. }
  577. ::v-deep .u-line {
  578. display: none;
  579. }
  580. .card_qiucharts {
  581. display: flex;
  582. align-items: center;
  583. flex-direction: column;
  584. }
  585. .card_echart {
  586. width: 80%;
  587. height: 500rpx;
  588. }
  589. .card_echart {
  590. width: 80%;
  591. height: 500rpx;
  592. }
  593. .dateTime_card ::v-deep .icon-calendar {
  594. display: none;
  595. }
  596. .card_btn {
  597. position: fixed;
  598. left: 0;
  599. right: 0;
  600. bottom: 0;
  601. padding-left: 30rpx;
  602. padding-right: 30rpx;
  603. padding-top: 20rpx;
  604. background-color: #fff;
  605. padding-bottom: constant(safe-area-inset-bottom); //兼容 IOS<11.2
  606. padding-bottom: env(safe-area-inset-bottom); //兼容 IOS>11.2
  607. }
  608. .card_stop ::v-deep .u-modal__button-group {
  609. border-top: 1px solid #e5e5e5;
  610. }
  611. </style>