printTag.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. <template>
  2. <view class="printTag">
  3. <view class="print-nums flex flex_column align_center justify_center">
  4. <view>打印数量</view>
  5. <view class="u-ninput">
  6. <u-number-box :min="1" v-model="printNum" color="#000" bg-color="#fff" size="30" :input-height="70" :input-width="100"></u-number-box>
  7. </view>
  8. </view>
  9. <view class="shelf-info">
  10. <view class="shelf-info-title">
  11. <view>{{infoData&&infoData.shelfName || '--'}}</view>
  12. <view class="pno">{{infoData&&infoData.shelfPlaceCode}}</view>
  13. </view>
  14. <view>产品编码:{{fromPage == 'smdy'?infoData.productCode : infoData.productEntity&&infoData.productEntity.code}}</view>
  15. <view>产品名称:{{fromPage == 'smdy'?infoData.productName : infoData.productEntity&&infoData.productEntity.productName}}</view>
  16. <view>{{fromPage == 'smdy'?'实发':'库存'}}数量:{{fromPage == 'smdy'?infoData.confirmQty : infoData.qty}}</view>
  17. </view>
  18. <view class="buttons flex align_center justify_center">
  19. <view v-if="fromPage == 'bdtq'"><u-button @click="cansel" shape="circle" plain>返回列表</u-button></view>
  20. <view v-if="fromPage == 'smdy'"><u-button @click="cansel" shape="circle" plain>重新扫描</u-button></view>
  21. <view>
  22. <kk-printer ref="kkprinter" @startPrint="startPrint"></kk-printer>
  23. </view>
  24. </view>
  25. </view>
  26. </template>
  27. <script>
  28. import { shelfDetail } from '@/api/shelf'
  29. import kkPrinter from '@/components/kk-printer/index.vue';
  30. export default {
  31. components:{
  32. kkPrinter
  33. },
  34. data() {
  35. return {
  36. infoData: null,
  37. fromPage: '',
  38. printInfo: null,
  39. printNum: 0
  40. }
  41. },
  42. onLoad(options) {
  43. const _this = this
  44. _this.fromPage = options.page
  45. _this.infoData = options.data ? JSON.parse(options.data) : {},
  46. _this.printNum = _this.fromPage == 'smdy' ? _this.infoData.confirmQty : _this.infoData.qty
  47. _this.printNum = _this.printNum||1
  48. console.log(_this.infoData)
  49. },
  50. onUnload() {
  51. // this.$refs.kkprinter.closeConnect()
  52. this.printNum = 1
  53. this.infoData = null
  54. this.printInfo = null
  55. this.fromPage = ''
  56. },
  57. methods: {
  58. cansel(){
  59. uni.$emit('refreshBL')
  60. uni.navigateBack()
  61. },
  62. // 获取打印内容
  63. getPrintContent(){
  64. const _this = this
  65. const myDate = new Date()
  66. if(_this.fromPage == 'bdtq'){
  67. _this.printInfo = {
  68. dealerName: _this.$store.state.vuex_userData.orgName,
  69. shelfName: _this.infoData.shelfName || '',
  70. productCode: _this.infoData.productEntity&&_this.infoData.productEntity.code || '',
  71. productName: _this.infoData.productEntity&&_this.infoData.productEntity.productName || '',
  72. shelfPlaceCode: _this.infoData.shelfPlaceCode || '',
  73. currentInven: _this.printNum,
  74. printDate: myDate.toLocaleDateString() +' '+myDate.getHours() +':'+myDate.getMinutes() +':'+myDate.getSeconds(),
  75. printUser: _this.$store.state.vuex_userData.username,
  76. barCode: `dealerSn=${_this.$store.state.vuex_userData.orgSn}&shelfSn=${_this.infoData.shelfSn}&productSn=${_this.infoData.productEntity&&_this.infoData.productEntity.productSn}&productCode=${_this.infoData.productEntity&&_this.infoData.productEntity.code}&shelfPlaceCode=${_this.infoData.shelfPlaceCode}&shelfPlaceSn=${_this.infoData.shelfPlaceSn}`
  77. }
  78. }else if(_this.fromPage == 'smdy'){
  79. _this.printInfo = {
  80. dealerName: _this.$store.state.vuex_userData.orgName,
  81. shelfName: _this.infoData.shelfName || '',
  82. productCode: _this.infoData.productCode || '',
  83. productName: _this.infoData.productName || '',
  84. shelfPlaceCode: _this.infoData.shelfPlaceCode || '',
  85. currentInven: _this.printNum,
  86. printDate: myDate.toLocaleDateString() +' '+myDate.getHours() +':'+myDate.getMinutes() +':'+myDate.getSeconds(),
  87. printUser: _this.$store.state.vuex_userData.username,
  88. barCode: `dealerSn=${_this.$store.state.vuex_userData.orgSn}&shelfSn=${_this.infoData.shelfSn}&productSn=${_this.infoData.productSn}&productCode=${_this.infoData.productCode}&shelfPlaceCode=${_this.infoData.shelfPlaceCode}&shelfPlaceSn=${_this.infoData.shelfPlaceSn}`
  89. }
  90. }
  91. console.log('printInfo-----------',_this.printInfo)
  92. },
  93. getBytesCount(str){
  94. var bytesCount = 0;
  95. if (str != null) {
  96. for (var i = 0; i < str.length; i++) {
  97. var c = str.charAt(i);
  98. if (c.match(/[^\x00-\xff]/ig) != null) //全角
  99. {
  100. bytesCount += 2;
  101. } else {
  102. bytesCount += 1;
  103. }
  104. }
  105. }
  106. return bytesCount;
  107. },
  108. // JS 包含中文的字符串按固定长度拆分换行算法
  109. getTextRows(str,iPageSize){
  110. var strArray = [];
  111. var tempStr = "";
  112. var iTotalLength = this.getBytesCount(str);
  113. for (var i = 0; i < str.length; i++) {
  114. var iCount = this.getBytesCount(str[i]);
  115. var iCountTemp = this.getBytesCount(tempStr);
  116. //iCountTemp + iCount >= iPageSize 这里可能出现两种情况:
  117. //长度等于 iPageSize 或 等于 iPageSize + 1(最后一个为中文字符就等于 9 + 2 情况)
  118. if (iCountTemp + iCount >= iPageSize) {
  119. tempStr += str[i];
  120. strArray.push(tempStr);
  121. // console.log("iCountTemp + iCount >= iPageSize " + tempStr)
  122. tempStr = "";
  123. } else {
  124. tempStr += str[i];
  125. }
  126. }
  127. // //最后一次尾巴
  128. if (tempStr.length > 0){
  129. strArray.push(tempStr)
  130. }
  131. return strArray
  132. },
  133. textFormat(command,text,maxFontNums,left,top,lightHeight,align,fontSize){
  134. let rowTop = top
  135. const textArr = this.getTextRows(text.replace(/\s+/g, ' '),maxFontNums*2)
  136. const rows = textArr.length
  137. for(let i=0;i<rows;i++){
  138. if(align=="center"){
  139. const ltxt = textArr[i]
  140. const ltlen = ltxt.replace(/[^x00-xFF]/g,'**').length/2
  141. command.setText(left+((maxFontNums-ltlen)/2)*lightHeight, rowTop, "TSS24.BF2", fontSize, fontSize, ltxt)
  142. }
  143. else{
  144. command.setText(left, rowTop, "TSS24.BF2", fontSize, fontSize, textArr[i])
  145. }
  146. rowTop = rowTop+lightHeight
  147. }
  148. return rowTop
  149. },
  150. // 打印
  151. startPrint(opt,tsc,blesdk){
  152. console.log(opt,'opt')
  153. this.getPrintContent()
  154. if(this.printInfo.currentInven<=0){
  155. uni.showToast({
  156. icon:"none",
  157. title: "请选择打印数量"
  158. })
  159. this.$refs.kkprinter.onPrintFail()
  160. return
  161. }
  162. let top = 10 // 距离顶部10点像素
  163. const left = 24 // 距离左边
  164. const lightHeight = 24 // 行高3mm,1mm = 8点
  165. const pageW = 40 // 页签宽度mm
  166. const pageH = 30 // 页签高度mm
  167. const maxFontNums = Math.floor((pageW*8-left*2)/lightHeight) // 每行最多字体数
  168. let rightTop = 0
  169. let rightLeft = Math.floor(maxFontNums*0.7)*lightHeight
  170. // 初始化打印机
  171. const command = tsc.jpPrinter.createNew()
  172. command.init()
  173. command.setSize(pageW, pageH) // 标签纸张宽高,单位mm
  174. command.setGap(2) // 标签上下间距,单位mm
  175. command.setCls() // 清除缓冲区数据
  176. // 经销商文字高度,是否换行
  177. top = this.textFormat(command,this.printInfo.dealerName,maxFontNums,left,top,lightHeight,"center",1)
  178. // 数字货架名称文字
  179. top = top+10
  180. rightTop = top
  181. const lwidth = Math.floor(maxFontNums*0.6)
  182. rightLeft = (lwidth + 1.5) * lightHeight
  183. top = this.textFormat(command,this.printInfo.shelfName,lwidth,left,top,lightHeight,"left",1)
  184. // 产品编码
  185. top = top+10
  186. top = this.textFormat(command,this.printInfo.productCode,lwidth,left,top,lightHeight,"left",1)
  187. // 产品名称
  188. top = top+5
  189. top = this.textFormat(command,this.printInfo.productName,lwidth,left,top,lightHeight,"left",1)
  190. // 货位号
  191. this.textFormat(command,this.printInfo.shelfPlaceCode,maxFontNums-lwidth,rightLeft,rightTop,lightHeight,"center",1)
  192. // 二维码
  193. const qrtop = rightTop +lightHeight+10
  194. command.setQR(rightLeft, qrtop, "L", 3, "A", this.printInfo.barCode)
  195. command.setPagePrint(1,this.printInfo.currentInven) // 打印分数1,每个标签重发打印2次
  196. console.log("开始打印了",command.getData())
  197. blesdk.senBlData(opt.deviceId, opt.serviceId, opt.writeId, command.getData(), this.onPrintSuccess);
  198. },
  199. // 打印成功
  200. onPrintSuccess(){
  201. // uni.navigateBack()
  202. this.$refs.kkprinter.onPrintSuccess()
  203. }
  204. }
  205. }
  206. </script>
  207. <style lang="less">
  208. .printTag{
  209. background-color: #fff;
  210. width: 100vh;
  211. padding: 50rpx 30rpx;
  212. .print-nums{
  213. padding: 50rpx 30rpx;
  214. color: #999;
  215. font-size: 32rpx;
  216. > view{
  217. padding: 20rpx 0;
  218. }
  219. .u-ninput{
  220. border: 2rpx solid #eee;
  221. border-radius: 50rpx;
  222. padding: 0 12rpx;
  223. }
  224. /deep/ .u-icon-disabled{
  225. background: #fff!important;
  226. }
  227. /deep/ .u-number-input{
  228. margin: 0 2rpx;
  229. border: 2rpx solid #eee;
  230. border-top: 0;
  231. border-bottom: 0;
  232. }
  233. /deep/ .u-icon-plus, /deep/ .u-icon-minus{
  234. border-radius: 50rpx;
  235. }
  236. }
  237. .shelf-info{
  238. background-color: #f8f8f8;
  239. padding: 30rpx;
  240. border-radius: 12rpx;
  241. color: #707070;
  242. .shelf-info-title{
  243. font-size: 32rpx;
  244. color: #222222;
  245. display: flex;
  246. justify-content: space-between;
  247. margin-bottom: 10rpx;
  248. .pno{
  249. background: rgba(3, 54, 146, 0.15);
  250. border-radius: 100rpx;
  251. padding: 4rpx 20rpx;
  252. color: #033692;
  253. font-size: 26rpx;
  254. }
  255. }
  256. }
  257. .buttons{
  258. padding: 50rpx 0;
  259. > view{
  260. width: 36%;
  261. margin: 0 2%;
  262. }
  263. }
  264. }
  265. </style>