diff --git a/src/apis/material/materialInfo.ts b/src/apis/material/materialInfo.ts index 7ba84f5..1a5c0dc 100644 --- a/src/apis/material/materialInfo.ts +++ b/src/apis/material/materialInfo.ts @@ -14,12 +14,16 @@ export interface MaterialInfoResp { createUserString: string updateUserString: string lightLevel: number + batch: string + mark: string disabled: boolean photoLoadError: boolean } export interface MaterialInfoQuery { materialName: string | undefined encoding: string | undefined + batch: string | undefined + mark: string | undefined sort: Array } diff --git a/src/apis/weightManage/weightManage.ts b/src/apis/weightManage/weightManage.ts index f78aa46..295e518 100644 --- a/src/apis/weightManage/weightManage.ts +++ b/src/apis/weightManage/weightManage.ts @@ -10,6 +10,7 @@ export interface WeighManageResp { unitWeight: number photoUrl: string batch: string + mark: string materialProcess: string matchResult: string downFloatRatio: string diff --git a/src/apis/workOrder/workOrder.ts b/src/apis/workOrder/workOrder.ts index 64be349..d2c6d1b 100644 --- a/src/apis/workOrder/workOrder.ts +++ b/src/apis/workOrder/workOrder.ts @@ -11,6 +11,7 @@ export interface WorkOrderResp { unitWeight: string materialSpec: string photoUrl: string + batch: string totalWeight: string totalCalculatedWeight: string totalCount: string @@ -19,6 +20,7 @@ export interface WorkOrderResp { matchResult: string workOrderInfos: Array qrCodeData: string + mark: string } export interface WorkOrderInfoResp { @@ -26,15 +28,19 @@ export interface WorkOrderInfoResp { workOrderId: string materialId: string weightTime: string + batch: string quantity: string weight: string imgUrl: string calculatedWeight: string + weightQuantity: string + mark: string } export interface WorkOrderQuery { orderNo: string | undefined materialName: string | undefined + batch: string | undefined encoding: string | undefined userName: string | undefined carNo: string | undefined diff --git a/src/types/components.d.ts b/src/types/components.d.ts index e69de29..5ce01c9 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -0,0 +1,145 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// Generated by unplugin-vue-components +// Read more: https://github.com/vuejs/core/pull/3399 +export {} + +declare module 'vue' { + export interface GlobalComponents { + AAlert: typeof import('@arco-design/web-vue')['Alert'] + AAvatar: typeof import('@arco-design/web-vue')['Avatar'] + ABadge: typeof import('@arco-design/web-vue')['Badge'] + ABreadcrumb: typeof import('@arco-design/web-vue')['Breadcrumb'] + ABreadcrumbItem: typeof import('@arco-design/web-vue')['BreadcrumbItem'] + AButton: typeof import('@arco-design/web-vue')['Button'] + AButtonGroup: typeof import('@arco-design/web-vue')['ButtonGroup'] + ACard: typeof import('@arco-design/web-vue')['Card'] + ACardMeta: typeof import('@arco-design/web-vue')['CardMeta'] + ACarousel: typeof import('@arco-design/web-vue')['Carousel'] + ACarouselItem: typeof import('@arco-design/web-vue')['CarouselItem'] + ACheckbox: typeof import('@arco-design/web-vue')['Checkbox'] + ACheckboxGroup: typeof import('@arco-design/web-vue')['CheckboxGroup'] + ACol: typeof import('@arco-design/web-vue')['Col'] + AColorPicker: typeof import('@arco-design/web-vue')['ColorPicker'] + AConfigProvider: typeof import('@arco-design/web-vue')['ConfigProvider'] + ADatePicker: typeof import('@arco-design/web-vue')['DatePicker'] + ADescriptions: typeof import('@arco-design/web-vue')['Descriptions'] + ADescriptionsItem: typeof import('@arco-design/web-vue')['DescriptionsItem'] + ADivider: typeof import('@arco-design/web-vue')['Divider'] + ADoption: typeof import('@arco-design/web-vue')['Doption'] + ADrawer: typeof import('@arco-design/web-vue')['Drawer'] + ADropdown: typeof import('@arco-design/web-vue')['Dropdown'] + AEmpty: typeof import('@arco-design/web-vue')['Empty'] + AForm: typeof import('@arco-design/web-vue')['Form'] + AFormItem: typeof import('@arco-design/web-vue')['FormItem'] + AGrid: typeof import('@arco-design/web-vue')['Grid'] + AGridItem: typeof import('@arco-design/web-vue')['GridItem'] + AImage: typeof import('@arco-design/web-vue')['Image'] + AInput: typeof import('@arco-design/web-vue')['Input'] + AInputGroup: typeof import('@arco-design/web-vue')['InputGroup'] + AInputNumber: typeof import('@arco-design/web-vue')['InputNumber'] + AInputPassword: typeof import('@arco-design/web-vue')['InputPassword'] + AInputSearch: typeof import('@arco-design/web-vue')['InputSearch'] + ALayout: typeof import('@arco-design/web-vue')['Layout'] + ALayoutContent: typeof import('@arco-design/web-vue')['LayoutContent'] + ALayoutHeader: typeof import('@arco-design/web-vue')['LayoutHeader'] + ALayoutSider: typeof import('@arco-design/web-vue')['LayoutSider'] + ALink: typeof import('@arco-design/web-vue')['Link'] + AMenu: typeof import('@arco-design/web-vue')['Menu'] + AMenuItem: typeof import('@arco-design/web-vue')['MenuItem'] + AModal: typeof import('@arco-design/web-vue')['Modal'] + AOption: typeof import('@arco-design/web-vue')['Option'] + AOverflowList: typeof import('@arco-design/web-vue')['OverflowList'] + APagination: typeof import('@arco-design/web-vue')['Pagination'] + APopconfirm: typeof import('@arco-design/web-vue')['Popconfirm'] + APopover: typeof import('@arco-design/web-vue')['Popover'] + AProgress: typeof import('@arco-design/web-vue')['Progress'] + ARadio: typeof import('@arco-design/web-vue')['Radio'] + ARadioGroup: typeof import('@arco-design/web-vue')['RadioGroup'] + ARangePicker: typeof import('@arco-design/web-vue')['RangePicker'] + ARow: typeof import('@arco-design/web-vue')['Row'] + AScrollbar: typeof import('@arco-design/web-vue')['Scrollbar'] + ASelect: typeof import('@arco-design/web-vue')['Select'] + ASkeleton: typeof import('@arco-design/web-vue')['Skeleton'] + ASkeletonLine: typeof import('@arco-design/web-vue')['SkeletonLine'] + ASpace: typeof import('@arco-design/web-vue')['Space'] + ASpin: typeof import('@arco-design/web-vue')['Spin'] + AStatistic: typeof import('@arco-design/web-vue')['Statistic'] + ASubMenu: typeof import('@arco-design/web-vue')['SubMenu'] + ASwitch: typeof import('@arco-design/web-vue')['Switch'] + ATable: typeof import('@arco-design/web-vue')['Table'] + ATableColumn: typeof import('@arco-design/web-vue')['TableColumn'] + ATabPane: typeof import('@arco-design/web-vue')['TabPane'] + ATabs: typeof import('@arco-design/web-vue')['Tabs'] + ATag: typeof import('@arco-design/web-vue')['Tag'] + ATextarea: typeof import('@arco-design/web-vue')['Textarea'] + ATooltip: typeof import('@arco-design/web-vue')['Tooltip'] + ATree: typeof import('@arco-design/web-vue')['Tree'] + ATreeSelect: typeof import('@arco-design/web-vue')['TreeSelect'] + ATrigger: typeof import('@arco-design/web-vue')['Trigger'] + ATypographyParagraph: typeof import('@arco-design/web-vue')['TypographyParagraph'] + ATypographyText: typeof import('@arco-design/web-vue')['TypographyText'] + ATypographyTitle: typeof import('@arco-design/web-vue')['TypographyTitle'] + AUpload: typeof import('@arco-design/web-vue')['Upload'] + Avatar: typeof import('./../components/Avatar/index.vue')['default'] + AWatermark: typeof import('@arco-design/web-vue')['Watermark'] + Breadcrumb: typeof import('./../components/Breadcrumb/index.vue')['default'] + CellCopy: typeof import('./../components/CellCopy/index.vue')['default'] + Chart: typeof import('./../components/Chart/index.vue')['default'] + CronForm: typeof import('./../components/GenCron/CronForm/index.vue')['default'] + CronModal: typeof import('./../components/GenCron/CronModal/index.vue')['default'] + DateRangePicker: typeof import('./../components/DateRangePicker/index.vue')['default'] + DayForm: typeof import('./../components/GenCron/CronForm/component/day-form.vue')['default'] + FilePreview: typeof import('./../components/FilePreview/index.vue')['default'] + GiCellAvatar: typeof import('./../components/GiCell/GiCellAvatar.vue')['default'] + GiCellGender: typeof import('./../components/GiCell/GiCellGender.vue')['default'] + GiCellStatus: typeof import('./../components/GiCell/GiCellStatus.vue')['default'] + GiCellTag: typeof import('./../components/GiCell/GiCellTag.vue')['default'] + GiCellTags: typeof import('./../components/GiCell/GiCellTags.vue')['default'] + GiCodeView: typeof import('./../components/GiCodeView/index.vue')['default'] + GiDot: typeof import('./../components/GiDot/index.tsx')['default'] + GiEditTable: typeof import('./../components/GiEditTable/GiEditTable.vue')['default'] + GiFlexibleBox: typeof import('./../components/GiFlexibleBox/index.vue')['default'] + GiFooter: typeof import('./../components/GiFooter/index.vue')['default'] + GiForm: typeof import('./../components/GiForm/src/GiForm.vue')['default'] + GiIconSelector: typeof import('./../components/GiIconSelector/index.vue')['default'] + GiIframe: typeof import('./../components/GiIframe/index.vue')['default'] + GiLeftRightPane: typeof import('./../components/GiLeftRightPane/index.vue')['default'] + GiOption: typeof import('./../components/GiOption/index.vue')['default'] + GiOptionItem: typeof import('./../components/GiOptionItem/index.vue')['default'] + GiOverFlowTags: typeof import('./../components/GiOverFlowTags/index.vue')['default'] + GiSpace: typeof import('./../components/GiSpace/index.vue')['default'] + GiSplitButton: typeof import('./../components/GiSplitButton/index.vue')['default'] + GiSplitPane: typeof import('./../components/GiSplitPane/index.vue')['default'] + GiSplitPaneFlexibleBox: typeof import('./../components/GiSplitPane/components/GiSplitPaneFlexibleBox.vue')['default'] + GiSvgIcon: typeof import('./../components/GiSvgIcon/index.vue')['default'] + GiTable: typeof import('./../components/GiTable/index.vue')['default'] + GiTag: typeof import('./../components/GiTag/index.tsx')['default'] + GiThemeBtn: typeof import('./../components/GiThemeBtn/index.vue')['default'] + HourForm: typeof import('./../components/GenCron/CronForm/component/hour-form.vue')['default'] + Icon403: typeof import('./../components/icons/Icon403.vue')['default'] + Icon404: typeof import('./../components/icons/Icon404.vue')['default'] + Icon500: typeof import('./../components/icons/Icon500.vue')['default'] + IconBorders: typeof import('./../components/icons/IconBorders.vue')['default'] + IconTableSize: typeof import('./../components/icons/IconTableSize.vue')['default'] + IconTreeAdd: typeof import('./../components/icons/IconTreeAdd.vue')['default'] + IconTreeReduce: typeof import('./../components/icons/IconTreeReduce.vue')['default'] + JsonPretty: typeof import('./../components/JsonPretty/index.vue')['default'] + MinuteForm: typeof import('./../components/GenCron/CronForm/component/minute-form.vue')['default'] + MonthForm: typeof import('./../components/GenCron/CronForm/component/month-form.vue')['default'] + ParentView: typeof import('./../components/ParentView/index.vue')['default'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + SecondForm: typeof import('./../components/GenCron/CronForm/component/second-form.vue')['default'] + SplitPanel: typeof import('./../components/SplitPanel/index.vue')['default'] + TextCopy: typeof import('./../components/TextCopy/index.vue')['default'] + ToggleDark: typeof import('./../components/ToggleDark/index.vue')['default'] + UserSelect: typeof import('./../components/UserSelect/index.vue')['default'] + Verify: typeof import('./../components/Verify/index.vue')['default'] + VerifyPoints: typeof import('./../components/Verify/Verify/VerifyPoints.vue')['default'] + VerifySlide: typeof import('./../components/Verify/Verify/VerifySlide.vue')['default'] + WeekForm: typeof import('./../components/GenCron/CronForm/component/week-form.vue')['default'] + YearForm: typeof import('./../components/GenCron/CronForm/component/year-form.vue')['default'] + } +} diff --git a/src/views/barcodePrint/index.vue b/src/views/barcodePrint/index.vue index 457421c..976bfd4 100644 --- a/src/views/barcodePrint/index.vue +++ b/src/views/barcodePrint/index.vue @@ -23,88 +23,160 @@
- - + +
-
- 生成标签 -
+
+ 明细标签 + 整体标签 +
-
- +

标签预览

-
- - - - - - - - - - - - - - - - - - -
-
-
零件名称
-
{{ labelData.partName }}
-
-
-
-
生产日期
-
{{ labelData.productionDate }}
-
-
-
- QR Code -
生成二维码中...
-
-
-
-
零件号
-
{{ labelData.partNumber }}
-
-
-
-
数量
-
{{ labelData.totalCount }}
-
-
-
-
标重(g)
-
{{ labelData.totalCalculatedWeight }}
-
-
-
-
包装签字
-
{{ labelData.packingSignature || '' }}
-
-
-
-
实重(g)
-
{{ labelData.totalWeight || '' }}
-
-
-
-
检验签字
-
{{ labelData.inspectionSignature || '' }}
-
-
-
+ + + +
打印标签 @@ -118,7 +190,7 @@ import { ref, reactive, nextTick, onMounted } from 'vue' import { Message } from '@arco-design/web-vue' import { useRoute } from 'vue-router' -import {getWorkOrder} from "@/apis/workOrder/workOrder" +import {getWorkOrder, type WorkOrderInfoResp} from "@/apis/workOrder/workOrder" import QRCode from 'qrcode'; const route = useRoute() @@ -132,11 +204,28 @@ const formData = reactive({ totalCalculatedWeight: '', totalWeight: '', totalCount: '', - productionBatch: '', + batch: '', + mark: '', qrCodeData: '', + workOrderInfos: Array(), }) -// 标签数据 +// 标签数据数组 +const labelDataList = reactive>([]) + +// 标签数据(用于整体标签) const labelData = reactive({ partName: '', partNumber: '', @@ -148,6 +237,7 @@ const labelData = reactive({ inspectionSignature: '', qrCodeData: '', qrCodeImage: '', + mark: '', }) // 标签容器引用 @@ -170,10 +260,16 @@ const generateQRCode = async (data: string) => { } } -// 生成标签 -const generateLabel = async () => { - if (!formData.productionBatch) { - Message.error('请输入生产批次') +// 生成明细标签 +const generateDetailLabel = async () => { + if (!formData.workOrderInfos || formData.workOrderInfos.length === 0) { + Message.error('未获取到工单明细信息') + return + } + + if (!formData.batch) { + console.log("11111", formData.batch); + Message.error('未获取到批次信息') return } if (!formData.materialName) { @@ -182,6 +278,9 @@ const generateLabel = async () => { } try { + // 清空之前的标签数据 + labelDataList.length = 0 + // 格式化生产日期为 yyyyMMddHHmm 格式 const now = new Date() const formattedDate = now.getFullYear().toString() + @@ -192,10 +291,69 @@ const generateLabel = async () => { const formattedDate2 = now.getFullYear().toString() + String(now.getMonth() + 1).padStart(2, '0') + - String(now.getDate()).padStart(2, '0'); + String(now.getDate()).padStart(2, '0') + + // 为每个工单明细生成一个标签 + for (const workOrderInfo of formData.workOrderInfos) { + // 计算二维码数据 + const orderNo = formData.orderNo + workOrderInfo.id; + const qrCodeData = `10#${formData.materialName}$11#9DP$12#${formData.batch}$17#${workOrderInfo.quantity}$20#${formattedDate2}$31#${orderNo}$DY` + + // 生成二维码图片 + const qrCodeImage = await generateQRCode(qrCodeData) + + // 添加标签数据 + labelDataList.push({ + partName: formData.materialName || '', + partNumber: formData.encoding || '', + totalCalculatedWeight: workOrderInfo.calculatedWeight || '', + totalWeight: workOrderInfo.weight || '', + productionDate: formattedDate, + totalCount: workOrderInfo.quantity || '', + packingSignature: '', + inspectionSignature: '', + qrCodeData: qrCodeData, + qrCodeImage: qrCodeImage, + mark: formData.mark || '', + }) + } + + Message.success(`成功生成 ${labelDataList.length} 个明细标签`) + } catch (error) { + console.error('生成明细标签失败:', error) + Message.error('生成明细标签失败') + } +} + +// 生成整体标签 +const generateOverallLabel = async () => { + if (!formData.batch) { + Message.error('未获取到批次信息') + return + } + if (!formData.materialName) { + Message.error('未获取到物料信息') + return + } + + try { + // 清空明细标签数据 + labelDataList.length = 0 + + // 格式化生产日期为 yyyyMMddHHmm 格式 + const now = new Date() + const formattedDate = now.getFullYear().toString() + + String(now.getMonth() + 1).padStart(2, '0') + + String(now.getDate()).padStart(2, '0') + + String(now.getHours()).padStart(2, '0') + + String(now.getMinutes()).padStart(2, '0') + + const formattedDate2 = now.getFullYear().toString() + + String(now.getMonth() + 1).padStart(2, '0') + + String(now.getDate()).padStart(2, '0') // 计算二维码数据 - const qrCodeData = `10#${formData.materialName}$11#9DP$12#${formData.productionBatch}$17#${formData.totalCount}$20#${formattedDate2}$31#${formData.orderNo}$DY` + const qrCodeData = `10#${formData.materialName}$11#9DP$12#${formData.batch}$17#${formData.totalCount}$20#${formattedDate2}$31#${formData.orderNo}$DY` // 生成二维码图片 const qrCodeImage = await generateQRCode(qrCodeData) @@ -211,7 +369,8 @@ const generateLabel = async () => { packingSignature: '', inspectionSignature: '', qrCodeData: qrCodeData, - qrCodeImage: qrCodeImage + qrCodeImage: qrCodeImage, + mark: formData.mark || '', }) Message.success('标签生成成功') @@ -233,16 +392,16 @@ onMounted(() => { formData.encoding = res.data.encoding formData.materialName = res.data.materialName formData.orderNo = res.data.orderNo + formData.batch = res.data.batch formData.totalCalculatedWeight = res.data.totalCalculatedWeight formData.totalWeight = res.data.totalWeight formData.totalCount = res.data.totalCount + formData.workOrderInfos = res.data.workOrderInfos + formData.mark = res.data.mark } else { Message.error('获取详情失败') } }); - - // 自动生成标签 - generateLabel() } }) @@ -253,7 +412,81 @@ const printLabel = async () => { // 创建打印窗口 const printWindow = window.open('', '_blank') if (printWindow) { - // 直接构建打印内容,确保二维码图片正确生成 + // 判断是打印明细标签还是整体标签 + const isDetailLabels = labelDataList.length > 0 + const labelsToPrint = isDetailLabels ? labelDataList : [labelData] + + // 生成标签HTML + const labelsHTML = labelsToPrint.map(item => ` +
+ + + + + + + + + + + + + + + + + + +
+
+
零件名称
+
${item.partName}
+
+
+
+
生产日期
+
${item.productionDate}
+
+
+
+ QR Code +
${item.mark || ''}
+
+
+
+
零件号
+
${item.partNumber}
+
+
+
+
数量
+
${item.totalCount}
+
+
+
+
标重(g)
+
${item.totalCalculatedWeight}
+
+
+
+
包装签字
+
${item.packingSignature || ''}
+
+
+
+
实重(g)
+
${item.totalWeight || ''}
+
+
+
+
检验签字
+
${item.inspectionSignature || ''}
+
+
+
+ `).join('') + + // 构建打印内容 const printHTML = ` @@ -269,76 +502,13 @@ const printLabel = async () => { .label-field { font-size: 7pt; font-weight: bold; margin-right: 2mm; min-width: 25pt; } .label-value { font-size: 7pt; flex: 1; } .qr-code img { width: 20mm; height: 20mm; margin: 1mm 0; } + .mark-number { font-size: 7pt; margin-top: 1mm; text-align: center; } .serial-number { font-size: 7pt; margin-top: 1mm; }
-
- - - - - - - - - - - - - - - - - - -
-
-
零件名称
-
${labelData.partName}
-
-
-
-
生产日期
-
${labelData.productionDate}
-
-
-
- QR Code -
-
-
-
零件号
-
${labelData.partNumber}
-
-
-
-
数量
-
${labelData.totalCount}
-
-
-
-
标重(g)
-
${labelData.totalCalculatedWeight}
-
-
-
-
包装签字
-
${labelData.packingSignature || ''}
-
-
-
-
实重(g)
-
${labelData.totalWeight || ''}
-
-
-
-
检验签字
-
${labelData.inspectionSignature || ''}
-
-
-
+ ${labelsHTML}
@@ -399,6 +569,7 @@ defineOptions({ name: 'print' }) margin-top: 20px; display: flex; justify-content: center; + gap: 20px; } /* 标签预览 */ @@ -418,9 +589,9 @@ defineOptions({ name: 'print' }) .label-container { display: flex; - flex-wrap: wrap; + flex-direction: column; gap: 20px; - justify-content: center; + align-items: center; margin-bottom: 20px; } @@ -465,6 +636,7 @@ defineOptions({ name: 'print' }) .label-value { font-size: 12px; + font-weight: bold; flex: 1; } @@ -484,6 +656,13 @@ defineOptions({ name: 'print' }) color: #666; } +.mark-number { + font-size: 10px; + margin-top: 5px; + text-align: center; + font-weight: bold; +} + .serial-number { font-size: 12px; margin-top: 5px; diff --git a/src/views/material/MaterialInfoAddModal.vue b/src/views/material/MaterialInfoAddModal.vue index 849068a..1c277d9 100644 --- a/src/views/material/MaterialInfoAddModal.vue +++ b/src/views/material/MaterialInfoAddModal.vue @@ -91,6 +91,15 @@ const columns: ColumnItem[] = reactive([ type: 'input', span: 24, }, + { + label: '标记号', + field: 'mark', + type: 'input', + span: 24, + props: { + maxLength: 25, + }, + }, { label: '灯光等级', field: 'lightLevel', diff --git a/src/views/material/index.vue b/src/views/material/index.vue index c9dc496..24957d1 100644 --- a/src/views/material/index.vue +++ b/src/views/material/index.vue @@ -20,6 +20,8 @@