index.vue 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. <template>
  2. <div class="subPage">
  3. <div class="system-table-search">
  4. <div class="flex-h">
  5. <div class="flex-item flex-h">
  6. <el-button size="mini" v-if="!businessStatus" type="danger" @click="open">营业</el-button>
  7. <el-button size="mini" v-else type="submit" @click="close">歇业</el-button>
  8. </div>
  9. <ul>
  10. <li>
  11. <el-select v-model="CaseId" placeholder="请选择案场">
  12. <el-option
  13. v-for="item in cases"
  14. :key="item.CaseId"
  15. :label="item.CaseName"
  16. :value="item.CaseId">
  17. </el-option>
  18. </el-select>
  19. </li>
  20. </ul>
  21. <el-button
  22. size="mini"
  23. type="primary" @click="init">搜索</el-button>
  24. </div>
  25. <div class="moreFilter"></div>
  26. </div>
  27. <div class="order-list-box">
  28. <div style='position:relative;' v-for="(item,index) in list" :key="index">
  29. <div>
  30. <div style="padding:25px 20px 5px;border-bottom:2px solid #cccccc;display:flex;align-items: center;">
  31. <!-- <i class="iconfont icon-yinchenglogo" style="font-size:70px;color:red;position: relative;bottom: 20px;margin-right:10px;"></i> -->
  32. <img :src="item.AreaIcon" style="width:70px;height:70px;margin-right:10px;">
  33. <div style="display:inline-block;">
  34. <span style="display:block;font-size:20px;font-weight:700;width:180px;white-space: initial;">{{item.AreaName + item.TableNo}}</span>
  35. <span style="display:block;margin-top:10px">下单时间:{{toolClass.dateFormat(item.CreateDate)}}</span>
  36. <span style="display:block;margin-top:10px">已等待:<span style="color:red;font-weight:700;">{{leftTimes[item.OrdersId]}}</span></span>
  37. </div>
  38. </div>
  39. <div style="padding:10px 20px 5px;border-bottom:1px solid #cccccc;" v-for='(item1,index1) in item.Goods' :key='index1'>
  40. <div style="display:flex;justify-content: space-between;align-items: center;padding-right: 10px;"><span>{{item1.GoodsName}}</span><span style="display:inline-block;width:20%;text-align:right" v-if='!item1.SpecName'>× {{item1.Number}}</span></div>
  41. <div style="margin-top:8px;" v-if='item1.SpecName'>
  42. <span style="display:inline-block;width:75%;text-align:left;color:#cccccc">{{item1.SpecName}}</span>
  43. <span style="display:inline-block;width:20%;text-align:right">× {{item1.Number}}</span>
  44. </div>
  45. </div>
  46. <div style="padding:10px 20px;border-bottom:1px solid #cccccc;white-space: normal;">备注:{{item.Remark}}</div>
  47. <div style="padding:10px 20px;" @click="printPdf(`item${index}`)">下单人:{{item.UserName}}</div>
  48. </div>
  49. <div class="print-area" :class="'item_' + item.OrdersId" style="width:180px;">
  50. <div style="padding:0px 10px 5px;border-bottom:2px solid #cccccc;">
  51. <div style="display:inline-block;">
  52. <img class="topIcon" style="display:block;width:60%;margin:0 0 20px 0px;" src="http://jingcheng-resourceplat.oss-cn-shanghai.aliyuncs.com/upload/111101940020.png" alt="">
  53. <span style="display:block;font-size:20px;font-weight:700;text-align: center;"> <img width='30px' :src='item.AreaIconWhite' alt=""> {{item.AreaName + item.TableNo}}</span>
  54. </div>
  55. </div>
  56. <div style="padding:10px 10px 5px;border-bottom:1px solid #cccccc;" v-for='(item1,index1) in item.Goods' :key='index1'>
  57. <div style="font-size:12px;"><span style="display:inline-block;width:75%;text-align:left;">{{item1.GoodsName}}</span><span style="display:inline-block;width:22%;text-align:right;font-size:12px;" v-if='!item1.SpecName'>× {{item1.Number}}</span></div>
  58. <div style="margin-top:8px;" v-if='item1.SpecName'>
  59. <span style="display:inline-block;width:75%;text-align:left;color:#cccccc;font-size:12px;">{{item1.SpecName}}</span>
  60. <span style="display:inline-block;width:20%;text-align:right;font-size:12px;">× {{item1.Number}}</span>
  61. </div>
  62. </div>
  63. <div style="padding:10px 10px 5px;border-bottom:1px solid #cccccc;">
  64. <div style="font-size:12px;">下单人:{{item.UserName}}</div>
  65. <span style="display:block;margin-top:10px;font-size:12px;">下单时间:{{toolClass.dateFormat(item.CreateDate)}}</span>
  66. </div>
  67. <div style="padding:10px 10px;font-size:12px;">备注:{{item.Remark}}</div>
  68. <div style="text-align: right;font-size: 12px;">城的空间.城咖啡</div>
  69. <div style="height:10px"></div>
  70. </div>
  71. <div class="btns">
  72. <span @click="cancel(item.OrdersId,index)">取消</span>
  73. <span @click="submit(item.OrdersId,index)">确定</span>
  74. </div>
  75. </div>
  76. </div>
  77. </div>
  78. </template>
  79. <script>
  80. import { createNamespacedHelpers, mapState, mapActions } from 'vuex'
  81. import { getLodop } from '@/util/LodopFuncs'
  82. import { formatTimeBySeconds } from '@/util/util'
  83. import { replaceURLParams } from '@/util/ajax'
  84. // const WebSocket = require('ws')
  85. const { mapState: mapOrderState, mapActions: mapOrderActions } = createNamespacedHelpers('goodsorder')
  86. var LODOP
  87. export default {
  88. name: '',
  89. data () {
  90. return {
  91. total: 0,
  92. postData: { // 表格搜索条件
  93. phone: '', // 手机号
  94. page: 1, // 当前页码
  95. pagesize: 10, // 请求数据量
  96. },
  97. currentList: [],
  98. leftTimes: {},
  99. business: false,
  100. caseid: '',
  101. websockets: {},
  102. interval: () => { }
  103. }
  104. },
  105. computed: {
  106. ...mapOrderState({
  107. list: x => (x.ordersList || {}).list || [],
  108. businessStatus: x => x.businessStatus
  109. }),
  110. ...mapState({
  111. cases: x => x.app.cases.list,
  112. defaultCaseId: x => x.app.cases.default,
  113. userInfo: x => x.app.user
  114. }),
  115. CaseId: {
  116. get () {
  117. return this.caseid || this.defaultCaseId
  118. },
  119. set (val) {
  120. this.caseid = val
  121. }
  122. }
  123. },
  124. created () {
  125. this.updateSystemInfo().then(() => {
  126. console.log(this.CaseId)
  127. if (this.CaseId) {
  128. this.init()
  129. }
  130. })
  131. },
  132. mounted () {
  133. setTimeout(window.location.reload, 600 * 1000)
  134. },
  135. beforeRouteLeave (to, from, next) {
  136. // 导航离开该组件的对应路由时调用
  137. // 可以访问组件实例 `this`
  138. console.log(this.websockets)
  139. Object.keys(this.websockets).forEach((key) => {
  140. console.log(key, this.websockets[key])
  141. this.websockets[key].close()
  142. })
  143. this.websockets = {}
  144. next()
  145. },
  146. methods: {
  147. init () {
  148. Object.keys(this.websockets).forEach((key) => {
  149. console.log(key, this.websockets[key])
  150. this.websockets[key].close()
  151. })
  152. this.websockets = {}
  153. // console.log('init')
  154. var param = []
  155. if (!this.CaseId) {
  156. this.$message({
  157. type: 'info',
  158. message: '请先选择案场'
  159. })
  160. return
  161. }
  162. clearInterval(this.interval)
  163. console.log(this.CaseId)
  164. this.GetOrdersList({ caseid: this.CaseId }).then((res) => {
  165. for (var n = 0; n < (res.list || []).length; n++) {
  166. if (res.list[n].IsIntimidate === 0) {
  167. param.push(res.list[n].OrdersId)
  168. }
  169. }
  170. var bool = true
  171. var timer = setInterval(() => {
  172. if (param.length && bool) {
  173. bool = false
  174. this.printPdf(`item_${param[0]}`)
  175. this.putPrintGoodsOrder({
  176. id: param[0]
  177. }).then(() => {
  178. param.splice(0, 1)
  179. bool = true
  180. })
  181. } else {
  182. clearInterval(timer)
  183. }
  184. }, 300)
  185. this.getBusinessStatus(this.CaseId).then(() => {
  186. if (this.businessStatus) {
  187. this.initWebSocket()
  188. }
  189. })
  190. })
  191. this.refreshList()
  192. },
  193. refreshList () {
  194. this.interval = setInterval(() => {
  195. const now = (new Date()).valueOf()
  196. this.leftTimes = this.list.reduce((acc, it) => {
  197. const showDT = now - ((new Date(it.CreateDate)).valueOf())
  198. return { ...acc, [`${it.OrdersId}`]: formatTimeBySeconds(showDT) }
  199. }, {})
  200. }, 1000)
  201. },
  202. timeOut (c) {
  203. let cTime = new Date(c).valueOf()
  204. let time = new Date().valueOf()
  205. let s = parseInt((time - cTime) / 1000)
  206. let m = parseInt(s / 60)
  207. s = s - m * 60
  208. m = m < 10 ? '0' + m : m
  209. s = s < 10 ? '0' + s : s
  210. return `${m} : ${s}`
  211. },
  212. ...mapOrderActions([
  213. 'GetOrdersList',
  214. 'openBusiness',
  215. 'closeBusiness',
  216. 'checkOrder',
  217. 'cancelOrder',
  218. 'getBusinessStatus',
  219. 'updateList',
  220. 'putPrintGoodsOrder',
  221. ]),
  222. ...mapActions([
  223. 'updateSystemInfo'
  224. ]),
  225. submit (id, index) {
  226. this.$confirm('确定完成此饮品?', '提示', {
  227. confirmButtonText: '确定',
  228. cancelButtonText: '取消',
  229. type: 'warning'
  230. }).then((res) => {
  231. this.checkOrder({ id: id }).then(() => {
  232. this.$message({
  233. type: 'success',
  234. message: '确认订单成功'
  235. })
  236. this.list.splice(index, 1)
  237. this.updateList({ list: this.list })
  238. })
  239. }).catch((res) => {
  240. this.$message({
  241. type: 'info',
  242. message: '已取消操作'
  243. })
  244. })
  245. },
  246. cancel (id, index) {
  247. this.$confirm('确定取消此饮品?', '提示', {
  248. confirmButtonText: '确定',
  249. cancelButtonText: '取消',
  250. type: 'warning'
  251. }).then((res) => {
  252. this.cancelOrder({ id: id }).then(() => {
  253. this.$message({
  254. type: 'success',
  255. message: '取消订单成功'
  256. })
  257. this.list.splice(index, 1)
  258. this.updateList({ list: this.list })
  259. })
  260. }).catch((res) => {
  261. this.$message({
  262. type: 'info',
  263. message: '已取消操作'
  264. })
  265. })
  266. },
  267. printPdf (cl) {
  268. this.CreateOneFormPage(cl)
  269. LODOP.PRINT()
  270. },
  271. CreateOneFormPage (cl) {
  272. LODOP = getLodop()
  273. LODOP.PRINT_INIT('订单')
  274. LODOP.SET_PRINT_PAGESIZE(3, 480, 40, '')
  275. LODOP.ADD_PRINT_HTM(0, 0, document.getElementsByClassName(cl)[0].offsetWidth, document.getElementsByClassName(cl)[0].offsetHeight, document.getElementsByClassName(cl)[0].innerHTML)
  276. },
  277. initWebSocket () {
  278. console.log('initWebSocket')
  279. // console.log(this.user)
  280. let caseid = this.CaseId
  281. let id = this.userInfo.UserId
  282. const wsPath = this.$api.system.notify.newGoodsOrders.url
  283. const wsRealPath = replaceURLParams(wsPath, { grps: caseid, id })
  284. this.newWebsocket(wsRealPath)
  285. },
  286. websocketonmessage (e) {
  287. // let oldList = this.list
  288. let newList = JSON.parse(e.data).data.refreshOnlineGoodsOrders
  289. // let newinfo = newList.filter(x => this.list.filter(item => item.OrdersId === x.OrdersId).length === 0)
  290. this.updateList({ list: this.list.concat(newList) }).then(() => {
  291. newList.forEach((it) => {
  292. // console.log('it:', it)
  293. this.printPdf(`item_${it.OrdersId}`)
  294. this.putPrintGoodsOrder({
  295. id: it.OrdersId
  296. })
  297. })
  298. })
  299. },
  300. newWebsocket (wsRealPath) {
  301. const ws = this.websockets[wsRealPath]
  302. if (!ws) {
  303. const url = `${window.location.origin.replace('http', 'ws')}${wsRealPath}?token=${localStorage.getItem('JWT')}`
  304. this.websockets[wsRealPath] = new WebSocket(url)
  305. this.websockets[wsRealPath].onopen = console.log
  306. this.websockets[wsRealPath].onmessage = this.websocketonmessage
  307. this.websockets[wsRealPath].onclose = console.log
  308. setInterval(() => this.websockets[wsRealPath].send(10), 120000)
  309. }
  310. },
  311. open () {
  312. if (!this.CaseId) {
  313. this.$message({
  314. type: 'info',
  315. message: '请先选择案场'
  316. })
  317. return
  318. }
  319. this.openBusiness(this.CaseId).then(() => {
  320. this.init()
  321. })
  322. },
  323. close () {
  324. if (!this.CaseId) {
  325. this.$message({
  326. type: 'info',
  327. message: '请先选择案场'
  328. })
  329. return
  330. }
  331. this.closeBusiness(this.CaseId)
  332. }
  333. }
  334. }
  335. </script>
  336. <!-- Add "scoped" attribute to limit CSS to this component only -->
  337. <style lang="scss" scoped>
  338. @import "page.scss";
  339. </style>