MixLabelPrinter.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. <template>
  2. <el-container>
  3. <el-main>
  4. <div class="main-wrapper">
  5. <div class="left" :style="leftBoxStyle">
  6. <div v-for="itm in printedLabels" :key="itm.label" style="margin: 0 8px 8px 0">
  7. <div class="label-box">
  8. <div class="label-text">
  9. <div>泰和医院20人混采</div>
  10. <div>
  11. {{ itm.label }}
  12. <el-tag v-if="itm.reprint === 1" type="warning">重打</el-tag>
  13. </div>
  14. </div>
  15. <div :id="itm.label + 'qrcode'"></div>
  16. </div>
  17. </div>
  18. </div>
  19. <div class="right">
  20. <div class="reprint-box">
  21. <el-radio-group v-model="reprintWarning">
  22. <el-radio :label="1">重打时提示,让我决定是否重打</el-radio>
  23. <div style="height: 8px"></div>
  24. <el-radio :label="2">重打时不提示,直接打印</el-radio>
  25. <div style="height: 8px"></div>
  26. <el-radio :label="3">重打时跳过,不打印</el-radio>
  27. </el-radio-group>
  28. </div>
  29. <div>号段范围:<el-input v-model="labelRange" style="width: 180px" readonly></el-input></div>
  30. <div>
  31. 起始标签:
  32. <el-input v-model="startLabel" placeholder="请输入起始标签号" style="width: 180px" clearable></el-input>
  33. </div>
  34. <div>
  35. 打印数量:
  36. <el-input-number v-model="printCount" :min="1" :max="100" type="number" placeholder="请输入打印数量" style="width: 180px" clearable></el-input-number>
  37. </div>
  38. <div>打印操作:<el-button type="primary" style="width: 180px" @click="begnPrint">开始打印</el-button></div>
  39. </div>
  40. </div>
  41. </el-main>
  42. </el-container>
  43. </template>
  44. <script setup name="MixLabelPrinter">
  45. import { selectMaxLabelRange, selectLabelPrinter, printLabel, reprintLabel } from '@/api/mix-label-printer/index'
  46. import { ElMessage, ElMessageBox } from 'element-plus'
  47. import { qrcanvas } from 'qrcanvas'
  48. import store from '@/store'
  49. import { initLodop, getLodop } from '@/utils/c-lodop'
  50. const windowSize = store.state.app.windowSize
  51. const leftBoxStyle = {
  52. height: windowSize.h - 25 + 'px',
  53. }
  54. const labelRange = $ref(null)
  55. const startLabel = $ref(null)
  56. const printCount = $ref(1)
  57. const excutable = $ref(false)
  58. const reprintWarning = $ref(1)
  59. const printedLabels = $ref([])
  60. const begnPrint = async () => {
  61. if (!startLabel.startsWith('01180')) {
  62. ElMessageBox.alert('请输入正确的起始标签!', '提示', {
  63. type: 'error',
  64. confirmButtonText: '确定',
  65. }).then(() => {})
  66. return
  67. }
  68. excutable = true
  69. for (let i = 0; i < printCount; i++) {
  70. if (excutable) {
  71. const labelIndex = Number(startLabel.substring(5, startLabel.length)) + i
  72. if (labelIndex > 76000) {
  73. ElMessage({
  74. message: '打印完成。',
  75. type: 'success',
  76. duration: 2500,
  77. showClose: true,
  78. })
  79. return
  80. }
  81. const label = '01180' + labelIndex
  82. await executePrint(label)
  83. .then((res) => {
  84. console.log('printed:', res.label)
  85. })
  86. .catch((e) => {
  87. console.log('canceled: ' + e)
  88. })
  89. }
  90. }
  91. }
  92. const executePrint = (label) => {
  93. return new Promise((resolve, reject) => {
  94. selectLabelPrinter(label).then((origin) => {
  95. if (origin.status === 0) {
  96. printLabel(label).then((firstPrint) => {
  97. printedLabels.push(firstPrint)
  98. setTimeout(() => {
  99. drawQrcoce(firstPrint.label)
  100. lodopPrint(firstPrint.label)
  101. resolve(firstPrint)
  102. }, 100)
  103. })
  104. } else {
  105. if (reprintWarning === 3) {
  106. reject(label)
  107. } else if (reprintWarning === 2) {
  108. executeReprint(origin, resolve)
  109. } else if (reprintWarning === 1) {
  110. ElMessageBox.confirm(`标签【${label}】已打印过,确定要重新打印吗?`, '提示', {
  111. type: 'warning',
  112. confirmButtonText: '确定',
  113. cancelButtonText: '取消',
  114. })
  115. .then(() => {
  116. executeReprint(origin, resolve)
  117. })
  118. .catch(() => {
  119. reject(label)
  120. })
  121. }
  122. }
  123. })
  124. })
  125. }
  126. const executeReprint = (origin, resolve) => {
  127. reprintLabel(origin).then((reprint) => {
  128. let found = false
  129. printedLabels.forEach((ele) => {
  130. if (ele.label === origin.label) {
  131. ele.reprint = 1
  132. found = true
  133. return
  134. }
  135. })
  136. if (!found) {
  137. printedLabels.push(reprint)
  138. }
  139. setTimeout(() => {
  140. document.getElementById(origin.label + 'qrcode').innerHTML = ''
  141. drawQrcoce(reprint.label)
  142. lodopPrint(reprint.label)
  143. resolve(reprint)
  144. }, 100)
  145. })
  146. }
  147. const drawQrcoce = (label) => {
  148. const labelCanvas = qrcanvas({
  149. data: label,
  150. size: 50,
  151. })
  152. document.getElementById(label + 'qrcode').appendChild(labelCanvas)
  153. }
  154. const lodopPrint = (label) => {
  155. const LODOP = getLodop()
  156. LODOP.PRINT_INIT('labels')
  157. LODOP.SET_PRINT_PAGESIZE(1, '50mm', '30mm', 'CreateCustomPage')
  158. LODOP.ADD_PRINT_TEXT('10mm', '4mm', '30mm', '5mm', '泰和医院20人混采')
  159. LODOP.ADD_PRINT_TEXT('15mm', '4mm', '30mm', '5mm', label)
  160. LODOP.ADD_PRINT_BARCODE('9mm', '32mm', '17mm', '17mm', 'QRCode', label)
  161. // LODOP.SET_PRINT_STYLE('FontSize', 18)
  162. // LODOP.ADD_PRINT_TEXT('11mm', '6mm', '50mm', '5mm', '信息科-杜虎')
  163. LODOP.PRINT()
  164. // LODOP.PREVIEW()
  165. }
  166. const endPrint = () => {
  167. excutable = false
  168. }
  169. onMounted(() => {
  170. initLodop()
  171. selectMaxLabelRange().then((origin) => {
  172. labelRange = origin.range
  173. startLabel = origin.advise
  174. })
  175. })
  176. </script>
  177. <style lang="scss" scoped>
  178. .main-wrapper {
  179. display: flex;
  180. padding: 12px;
  181. .left {
  182. width: 70%;
  183. display: flex;
  184. flex-wrap: wrap;
  185. overflow-y: auto;
  186. .label-box {
  187. width: 50mm;
  188. height: 30mm;
  189. background: white;
  190. display: flex;
  191. align-items: center;
  192. justify-content: center;
  193. align-items: center;
  194. justify-content: center;
  195. .label-text {
  196. margin-right: 2mm;
  197. font-size: 12px;
  198. font-weight: bold;
  199. > div {
  200. padding: 1mm 0 1mm 0;
  201. }
  202. }
  203. }
  204. }
  205. .right {
  206. padding: 8px 0 0 30px;
  207. width: 30%;
  208. > div {
  209. margin-bottom: 8px;
  210. }
  211. .reprint-box {
  212. margin-bottom: 12px;
  213. background: white;
  214. width: 220px;
  215. padding: 12px;
  216. border-radius: 4px;
  217. }
  218. }
  219. }
  220. </style>