art:条形码生成并打印的组件
This commit is contained in:
parent
861b77aa93
commit
d089737967
@ -4027,6 +4027,63 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "批量生成条形码",
|
||||||
|
"name": "generateBarcodes",
|
||||||
|
"method": "post",
|
||||||
|
"path": "/material/{id}/generate-barcodes",
|
||||||
|
"response": {
|
||||||
|
"typeArgs": [
|
||||||
|
{
|
||||||
|
"typeArgs": [],
|
||||||
|
"typeName": "string",
|
||||||
|
"isDefsType": false,
|
||||||
|
"templateIndex": -1,
|
||||||
|
"compileTemplateKeyword": "#/definitions/",
|
||||||
|
"enum": [],
|
||||||
|
"typeProperties": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeName": "Array",
|
||||||
|
"isDefsType": false,
|
||||||
|
"templateIndex": -1,
|
||||||
|
"compileTemplateKeyword": "#/definitions/",
|
||||||
|
"enum": [],
|
||||||
|
"typeProperties": []
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "物料id",
|
||||||
|
"required": true,
|
||||||
|
"in": "path",
|
||||||
|
"name": "id",
|
||||||
|
"dataType": {
|
||||||
|
"typeArgs": [],
|
||||||
|
"typeName": "number",
|
||||||
|
"isDefsType": false,
|
||||||
|
"templateIndex": -1,
|
||||||
|
"compileTemplateKeyword": "#/definitions/",
|
||||||
|
"enum": [],
|
||||||
|
"typeProperties": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "条形码数量",
|
||||||
|
"required": true,
|
||||||
|
"in": "query",
|
||||||
|
"name": "count",
|
||||||
|
"dataType": {
|
||||||
|
"typeArgs": [],
|
||||||
|
"typeName": "number",
|
||||||
|
"isDefsType": false,
|
||||||
|
"templateIndex": -1,
|
||||||
|
"compileTemplateKeyword": "#/definitions/",
|
||||||
|
"enum": [],
|
||||||
|
"typeProperties": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "分页查询物料列表",
|
"description": "分页查询物料列表",
|
||||||
"name": "materials",
|
"name": "materials",
|
||||||
|
29
src/api/material/mods/material/generateBarcodes.ts
Normal file
29
src/api/material/mods/material/generateBarcodes.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* @desc 批量生成条形码
|
||||||
|
*/
|
||||||
|
import { defaultSuccess, defaultError, http } from '@/plugins/axios'
|
||||||
|
import type { AxiosResponse } from 'axios'
|
||||||
|
export interface Params {
|
||||||
|
/** 条形码数量 */
|
||||||
|
count: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function (
|
||||||
|
/** 物料id */
|
||||||
|
id: number,
|
||||||
|
|
||||||
|
params: Params,
|
||||||
|
success: (data: Array<string>) => void = defaultSuccess,
|
||||||
|
fail: (error: { code: string; error?: string }) => void = defaultError,
|
||||||
|
): Promise<void> {
|
||||||
|
return http({
|
||||||
|
method: 'post',
|
||||||
|
url: `/material/${id}/generate-barcodes`,
|
||||||
|
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
.then((data: AxiosResponse<Array<string>, unknown>) => {
|
||||||
|
success(data.data)
|
||||||
|
})
|
||||||
|
.catch((error: { code: string; error?: string }) => fail(error))
|
||||||
|
}
|
@ -2,16 +2,18 @@
|
|||||||
* @description 物料管理
|
* @description 物料管理
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
import saveOrUpdateMaterial from './saveOrUpdateMaterial';
|
import saveOrUpdateMaterial from './saveOrUpdateMaterial'
|
||||||
import all from './all';
|
import all from './all'
|
||||||
import detail from './detail';
|
import detail from './detail'
|
||||||
import deleteMaterial from './deleteMaterial';
|
import deleteMaterial from './deleteMaterial'
|
||||||
import materials from './materials';
|
import generateBarcodes from './generateBarcodes'
|
||||||
|
import materials from './materials'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
saveOrUpdateMaterial,
|
saveOrUpdateMaterial,
|
||||||
all,
|
all,
|
||||||
detail,
|
detail,
|
||||||
deleteMaterial,
|
deleteMaterial,
|
||||||
materials,
|
generateBarcodes,
|
||||||
};
|
materials,
|
||||||
|
}
|
||||||
|
11
src/components.d.ts
vendored
11
src/components.d.ts
vendored
@ -13,15 +13,15 @@ declare module 'vue' {
|
|||||||
ACard: typeof import('ant-design-vue/es')['Card']
|
ACard: typeof import('ant-design-vue/es')['Card']
|
||||||
ACol: typeof import('ant-design-vue/es')['Col']
|
ACol: typeof import('ant-design-vue/es')['Col']
|
||||||
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
|
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
|
||||||
ADatePicker: typeof import('ant-design-vue/es')['DatePicker']
|
|
||||||
ADivider: typeof import('ant-design-vue/es')['Divider']
|
|
||||||
ADrawer: typeof import('ant-design-vue/es')['Drawer']
|
ADrawer: typeof import('ant-design-vue/es')['Drawer']
|
||||||
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
|
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
|
||||||
|
AFlex: typeof import('ant-design-vue/es')['Flex']
|
||||||
AFloatButton: typeof import('ant-design-vue/es')['FloatButton']
|
AFloatButton: typeof import('ant-design-vue/es')['FloatButton']
|
||||||
AForm: typeof import('ant-design-vue/es')['Form']
|
AForm: typeof import('ant-design-vue/es')['Form']
|
||||||
AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
||||||
AImage: typeof import('ant-design-vue/es')['Image']
|
AImage: typeof import('ant-design-vue/es')['Image']
|
||||||
AInput: typeof import('ant-design-vue/es')['Input']
|
AInput: typeof import('ant-design-vue/es')['Input']
|
||||||
|
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
|
||||||
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
||||||
AInputSearch: typeof import('ant-design-vue/es')['InputSearch']
|
AInputSearch: typeof import('ant-design-vue/es')['InputSearch']
|
||||||
ALayout: typeof import('ant-design-vue/es')['Layout']
|
ALayout: typeof import('ant-design-vue/es')['Layout']
|
||||||
@ -35,25 +35,18 @@ declare module 'vue' {
|
|||||||
AModal: typeof import('ant-design-vue/es')['Modal']
|
AModal: typeof import('ant-design-vue/es')['Modal']
|
||||||
APageHeader: typeof import('ant-design-vue/es')['PageHeader']
|
APageHeader: typeof import('ant-design-vue/es')['PageHeader']
|
||||||
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
||||||
ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
|
|
||||||
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
|
||||||
AResult: typeof import('ant-design-vue/es')['Result']
|
|
||||||
ARow: typeof import('ant-design-vue/es')['Row']
|
ARow: typeof import('ant-design-vue/es')['Row']
|
||||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||||
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
||||||
ASpace: typeof import('ant-design-vue/es')['Space']
|
ASpace: typeof import('ant-design-vue/es')['Space']
|
||||||
AStatistic: typeof import('ant-design-vue/es')['Statistic']
|
|
||||||
ASteps: typeof import('ant-design-vue/es')['Steps']
|
|
||||||
ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
|
ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
|
||||||
ASwitch: typeof import('ant-design-vue/es')['Switch']
|
ASwitch: typeof import('ant-design-vue/es')['Switch']
|
||||||
ATable: typeof import('ant-design-vue/es')['Table']
|
ATable: typeof import('ant-design-vue/es')['Table']
|
||||||
ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
||||||
ATabs: typeof import('ant-design-vue/es')['Tabs']
|
ATabs: typeof import('ant-design-vue/es')['Tabs']
|
||||||
ATag: typeof import('ant-design-vue/es')['Tag']
|
ATag: typeof import('ant-design-vue/es')['Tag']
|
||||||
ATextarea: typeof import('ant-design-vue/es')['Textarea']
|
|
||||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||||
ATransfer: typeof import('ant-design-vue/es')['Transfer']
|
ATransfer: typeof import('ant-design-vue/es')['Transfer']
|
||||||
ATree: typeof import('ant-design-vue/es')['Tree']
|
|
||||||
ATypographyLink: typeof import('ant-design-vue/es')['TypographyLink']
|
ATypographyLink: typeof import('ant-design-vue/es')['TypographyLink']
|
||||||
ATypographyParagraph: typeof import('ant-design-vue/es')['TypographyParagraph']
|
ATypographyParagraph: typeof import('ant-design-vue/es')['TypographyParagraph']
|
||||||
ATypographyTitle: typeof import('ant-design-vue/es')['TypographyTitle']
|
ATypographyTitle: typeof import('ant-design-vue/es')['TypographyTitle']
|
||||||
|
121
src/views/stock/material/print-code.vue
Normal file
121
src/views/stock/material/print-code.vue
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-flex gap="middle" horizontal>
|
||||||
|
<span class="ant-form-text">请输入打印的条码数量:</span>
|
||||||
|
<a-form-item name="input-number" no-style>
|
||||||
|
<a-input-number v-model:value="inputRef" :min="1" :max="10" @change="fetchAndPrintBarcodes(inputRef)" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<button @click="printCode">打印条形码</button>
|
||||||
|
</a-flex>
|
||||||
|
<div id="barcodes-container">
|
||||||
|
<!-- 条形码将被动态插入到这里 -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import JsBarcode from 'jsbarcode'
|
||||||
|
import printJS from 'print-js'
|
||||||
|
import api from '@/api'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
// 接收父组件传递的条形码数量
|
||||||
|
materialId: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const inputRef = ref(0)
|
||||||
|
|
||||||
|
const printCode = () => {
|
||||||
|
const container = document.getElementById('barcodes-container')
|
||||||
|
if (!container) {
|
||||||
|
window.console.log('条形码容器未找到')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 设置页面大小以适应小纸张(40mm x 30mm)
|
||||||
|
const widthInches = (40 * 0.0393701).toFixed(3) // 约1.575英寸
|
||||||
|
const heightInches = (30 * 0.0393701).toFixed(3) // 约1.181英寸
|
||||||
|
|
||||||
|
// 打印配置
|
||||||
|
const printOptions: printJS.Configuration = {
|
||||||
|
printable: 'barcodes-container',
|
||||||
|
type: 'html',
|
||||||
|
scanStyles: false,
|
||||||
|
honorMarginPadding: false,
|
||||||
|
targetStyles: ['*'],
|
||||||
|
style: `
|
||||||
|
@page {
|
||||||
|
size: ${widthInches}in ${heightInches}in;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 6px;
|
||||||
|
}
|
||||||
|
#barcodes-container canvas {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 2mm; /* 调整条形码之间的间距 */
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
onLoadingStart: () => console.log('开始加载'),
|
||||||
|
onLoadingEnd: () => console.log('加载完成'),
|
||||||
|
onError: (err) => console.error('打印出错:', err),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示条形码容器以便打印
|
||||||
|
container.style.display = 'block'
|
||||||
|
|
||||||
|
// 调用 printJS 进行打印
|
||||||
|
printJS(printOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义一个函数来从后端获取条形码字符串并打印
|
||||||
|
const fetchAndPrintBarcodes = async (count: number) => {
|
||||||
|
// 清空之前的条形码容器
|
||||||
|
const container = document.getElementById('barcodes-container')
|
||||||
|
if (!container) throw new Error('条形码容器未找到')
|
||||||
|
container.innerHTML = ''
|
||||||
|
|
||||||
|
// 从后端获取条形码字符串数组
|
||||||
|
api.materialApi.material.generateBarcodes(props.materialId, { count: count }, (res: Array<string>) => {
|
||||||
|
res.forEach((barcodeString: string, index: number) => {
|
||||||
|
const canvasId = `barcode-${index}`
|
||||||
|
const canvasElement = document.createElement('canvas')
|
||||||
|
// 设置画布大小
|
||||||
|
canvasElement.width = 472 // 宽度接近 40mm
|
||||||
|
canvasElement.height = 354 // 高度接近 30mm
|
||||||
|
|
||||||
|
canvasElement.id = canvasId
|
||||||
|
container.appendChild(canvasElement)
|
||||||
|
// 使用JsBarcode生成条形码
|
||||||
|
JsBarcode(`#${canvasId}`, barcodeString, {
|
||||||
|
// format: "EAN13", // 或者根据需要选择其他格式
|
||||||
|
width: 1, // 条形码线条宽度
|
||||||
|
height: 70, // 条形码高度
|
||||||
|
displayValue: true, // 显示条形码下方的文本
|
||||||
|
// fontOptions: "italic", // 文本样式
|
||||||
|
fontSize: 10, // 文本大小
|
||||||
|
textMargin: 5, // 文本与条形码之间的间距
|
||||||
|
margin: 10, // 条形码周围的空白边距
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果需要在组件挂载时自动执行打印,请取消注释以下代码
|
||||||
|
// onMounted(fetchAndPrintBarcodes);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 针对打印样式的样式 */
|
||||||
|
@media print {
|
||||||
|
#barcodes-container {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
x
Reference in New Issue
Block a user