MixLabelPrinter.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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>
  30. <span :style="{ color: textColor }">号段范围:</span>
  31. <el-select v-model="labelTableName" style="width: 200px" @change="handleLabelRangeChange">
  32. <el-option v-for="item in labelRanges" :key="item.tableName" :label="item.labelRange" :value="item.tableName">
  33. <span v-html="analyzeFinishStatus(item.finishFlag)"></span>
  34. <el-divider direction="vertical"></el-divider>
  35. <span>{{ item.labelRange }}</span>
  36. </el-option>
  37. </el-select>
  38. </div>
  39. <div>
  40. 起始标签:
  41. <el-input v-model="startLabel" placeholder="请输入起始标签号" style="width: 200px" clearable></el-input>
  42. </div>
  43. <div>
  44. 打印数量:
  45. <el-input-number v-model="printCount" :min="1" :max="100" type="number" placeholder="请输入打印数量" style="width: 200px" clearable></el-input-number>
  46. </div>
  47. <div>打印操作:<el-button type="primary" style="width: 200px" @click="begnPrint">开始打印</el-button></div>
  48. </div>
  49. </div>
  50. </el-main>
  51. </el-container>
  52. </template>
  53. <script setup name="MixLabelPrinter">
  54. import { selectLabelRanges, selectBeginLabel, selectLabelPrinter, printLabel, reprintLabel, allPrinted } from '@/api/mix-label-printer/index'
  55. import { ElMessage, ElMessageBox } from 'element-plus'
  56. import { qrcanvas } from 'qrcanvas'
  57. import store from '@/store'
  58. import { initLodop, getLodop } from '@/utils/c-lodop'
  59. const windowSize = store.state.app.windowSize
  60. const leftBoxStyle = {
  61. height: windowSize.h - 25 + 'px',
  62. }
  63. const labelRanges = $ref([])
  64. const labelTableName = $ref(null)
  65. const currentLabelRange = $ref({})
  66. const startLabel = $ref(null)
  67. const printCount = $ref(1)
  68. const reprintWarning = $ref(1)
  69. const printedLabels = $ref([])
  70. const textColor = computed(() => {
  71. return currentLabelRange.finishFlag === 0 ? 'green' : 'red'
  72. })
  73. const analyzeFinishStatus = (val) => {
  74. return val === 0 ? '<span style="font-size:12px;color:green">未打完</span>' : '<span style="font-size:12px;color:red">已打完</span>'
  75. }
  76. const handleLabelRangeChange = (val) => {
  77. selectBeginLabel(val).then((begin) => {
  78. startLabel = begin
  79. })
  80. labelRanges.forEach((item) => {
  81. if (item.tableName === labelTableName) {
  82. currentLabelRange = item
  83. return
  84. }
  85. })
  86. }
  87. const begnPrint = async () => {
  88. if (!startLabel || startLabel.length < currentLabelRange.sliceIndex) {
  89. ElMessage({
  90. message: '请输入正确的起始标签!',
  91. type: 'error',
  92. duration: 2500,
  93. showClose: true,
  94. })
  95. return
  96. }
  97. printedLabels = []
  98. for (let i = 0; i < printCount; i++) {
  99. const labelIndex = Number(startLabel.substring(currentLabelRange.sliceIndex, startLabel.length)) + i
  100. if (labelIndex > currentLabelRange.endNumber) {
  101. ElMessage({
  102. message: '打印完成',
  103. type: 'success',
  104. duration: 2500,
  105. showClose: true,
  106. })
  107. return
  108. }
  109. const label = currentLabelRange.prefix + labelIndex
  110. await executePrint(label)
  111. .then((res) => {
  112. console.log('printed: ' + res.label)
  113. })
  114. .catch((e) => {
  115. console.log('canceled: ' + e)
  116. })
  117. }
  118. selectBeginLabel(labelTableName).then((begin) => {
  119. if (begin) {
  120. startLabel = begin
  121. }
  122. })
  123. }
  124. const executePrint = (label) => {
  125. return new Promise((resolve, reject) => {
  126. selectLabelPrinter(labelTableName, label).then((origin) => {
  127. if (origin.status === 0) {
  128. printLabel(labelTableName, label).then((firstPrint) => {
  129. printedLabels.push(firstPrint)
  130. setTimeout(() => {
  131. drawQrcoce(firstPrint.label)
  132. lodopPrint(firstPrint.label)
  133. console.log(label, currentLabelRange.maxLabel)
  134. if (label === currentLabelRange.maxLabel) {
  135. allPrinted(labelTableName).then((msg) => {
  136. console.log(msg)
  137. resolve(firstPrint)
  138. })
  139. } else {
  140. resolve(firstPrint)
  141. }
  142. }, 100)
  143. })
  144. } else {
  145. if (reprintWarning === 3) {
  146. reject(label)
  147. } else if (reprintWarning === 2) {
  148. executeReprint(origin, resolve)
  149. } else if (reprintWarning === 1) {
  150. ElMessageBox.confirm(`标签【${label}】已打印过,确定要重新打印吗?`, '提示', {
  151. type: 'warning',
  152. confirmButtonText: '确定',
  153. cancelButtonText: '取消',
  154. })
  155. .then(() => {
  156. executeReprint(origin, resolve)
  157. })
  158. .catch(() => {
  159. reject(label)
  160. })
  161. }
  162. }
  163. })
  164. })
  165. }
  166. const executeReprint = (origin, resolve) => {
  167. origin.tableName = labelTableName
  168. reprintLabel(origin).then((reprint) => {
  169. let found = false
  170. printedLabels.forEach((ele) => {
  171. if (ele.label === origin.label) {
  172. ele.reprint = 1
  173. found = true
  174. return
  175. }
  176. })
  177. if (!found) {
  178. printedLabels.push(reprint)
  179. }
  180. setTimeout(() => {
  181. document.getElementById(origin.label + 'qrcode').innerHTML = ''
  182. drawQrcoce(reprint.label)
  183. lodopPrint(reprint.label)
  184. resolve(reprint)
  185. }, 100)
  186. })
  187. }
  188. const drawQrcoce = (label) => {
  189. const labelCanvas = qrcanvas({
  190. data: label,
  191. size: 50,
  192. })
  193. document.getElementById(label + 'qrcode').appendChild(labelCanvas)
  194. }
  195. const lodopPrint = (label) => {
  196. const LODOP = getLodop()
  197. LODOP.PRINT_INIT('labels')
  198. LODOP.SET_PRINT_PAGESIZE(1, '50mm', '30mm', 'CreateCustomPage')
  199. LODOP.SET_PRINT_STYLE('Bold', 1)
  200. LODOP.ADD_PRINT_TEXT('8mm', '3mm', '32mm', '5mm', '泰和医院20人混采')
  201. LODOP.ADD_PRINT_BARCODE('14mm', '3mm', '32mm', '10mm', '128Auto', label)
  202. LODOP.ADD_PRINT_BARCODE('10mm', '35mm', '17mm', '17mm', 'QRCode', label)
  203. LODOP.PRINT()
  204. }
  205. onMounted(() => {
  206. initLodop()
  207. selectLabelRanges().then((ranges) => {
  208. labelRanges = ranges
  209. if (ranges && ranges.length > 0) {
  210. for (let index = 0; index < ranges.length; index++) {
  211. const item = ranges[index]
  212. if (item.finishFlag === 0) {
  213. currentLabelRange = item
  214. labelTableName = item.tableName
  215. selectBeginLabel(item.tableName).then((begin) => {
  216. startLabel = begin
  217. })
  218. return
  219. }
  220. }
  221. }
  222. })
  223. })
  224. </script>
  225. <style lang="scss" scoped>
  226. .main-wrapper {
  227. display: flex;
  228. padding: 12px;
  229. .left {
  230. width: 70%;
  231. display: flex;
  232. flex-wrap: wrap;
  233. overflow-y: auto;
  234. .label-box {
  235. width: 50mm;
  236. height: 30mm;
  237. background: white;
  238. display: flex;
  239. align-items: center;
  240. justify-content: center;
  241. align-items: center;
  242. justify-content: center;
  243. .label-text {
  244. margin-right: 2mm;
  245. font-size: 12px;
  246. font-weight: bold;
  247. > div {
  248. padding: 1mm 0 1mm 0;
  249. }
  250. }
  251. }
  252. }
  253. .right {
  254. padding: 8px 0 0 30px;
  255. width: 30%;
  256. > div {
  257. margin-bottom: 8px;
  258. }
  259. .reprint-box {
  260. margin-bottom: 12px;
  261. background: white;
  262. width: 220px;
  263. padding: 12px;
  264. border-radius: 4px;
  265. }
  266. }
  267. }
  268. </style>