diff --git a/pages.json b/pages.json index 84545d0..9e862fd 100644 --- a/pages.json +++ b/pages.json @@ -96,11 +96,23 @@ "navigationBarTitleText": "设置" } }, + { + "path": "pages/printer-test/printer-test", + "style": { + "navigationBarTitleText": "打印机测试" + } + }, { "path": "pages/message/message", "style": { "navigationBarTitleText": "消息" } + }, + { + "path": "pages/search/search", + "style": { + "navigationBarTitleText": "搜索" + } } ], "globalStyle": { diff --git a/pages/index/index.vue b/pages/index/index.vue index 82ca69b..5ea3033 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -2,7 +2,10 @@ - {{ welcomeText }} + + {{ welcomeText }} + 🔍 + {{ todayDisplay }} @@ -188,6 +191,10 @@ function switchToTab(url) { uni.switchTab({ url }) } +function goSearch() { + uni.navigateTo({ url: '/pages/search/search' }) +} + // 定时刷新 let refreshTimer = null const REFRESH_INTERVAL = 5000 // 5秒 @@ -247,12 +254,24 @@ onHide(() => { padding: 30rpx 0; } +.welcome-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10rpx; +} + .welcome-title { - display: block; font-size: 44rpx; font-weight: bold; color: #333; - margin-bottom: 10rpx; +} + +.search-icon { + font-size: 40rpx; + padding: 10rpx 20rpx; + background-color: #f0f0f0; + border-radius: 50%; } .welcome-date { diff --git a/pages/printer-test/printer-test.vue b/pages/printer-test/printer-test.vue new file mode 100644 index 0000000..79cfd77 --- /dev/null +++ b/pages/printer-test/printer-test.vue @@ -0,0 +1,338 @@ + + + + + diff --git a/pages/search/search.vue b/pages/search/search.vue new file mode 100644 index 0000000..25b956d --- /dev/null +++ b/pages/search/search.vue @@ -0,0 +1,454 @@ + + + + + diff --git a/pages/settings/settings.vue b/pages/settings/settings.vue index 0813ddb..edd3e77 100644 --- a/pages/settings/settings.vue +++ b/pages/settings/settings.vue @@ -22,10 +22,16 @@ - - - - + + + 打印机 + + + 打印机测试 + + + + @@ -113,6 +119,11 @@ function onEditApiUrl() { }) } +// 跳转打印机测试页 +function goPrinterTest() { + uni.navigateTo({ url: '/pages/printer-test/printer-test' }) +} + onMounted(() => { // 真机/打包环境:通过 plus.runtime 获取 diff --git a/pages/warehouse/item-detail.vue b/pages/warehouse/item-detail.vue index 7c27726..27f271c 100644 --- a/pages/warehouse/item-detail.vue +++ b/pages/warehouse/item-detail.vue @@ -3,6 +3,9 @@ ‹ 返回 物品详情 + + 打印 + @@ -159,6 +162,16 @@ import { ref, onMounted } from 'vue' import { warehouseApi } from '@/api/warehouse.js' import { useConfigStore } from '@/stores/config.js' +// 仅在 App 环境下加载原生插件 +let printer = null +try { + if (uni.requireNativePlugin) { + printer = uni.requireNativePlugin('LcPrinter') + } +} catch (e) { + console.error('打印机插件加载失败:', e.message) +} + const configStore = useConfigStore() const itemId = ref(0) const loading = ref(false) @@ -318,6 +331,73 @@ function goBack() { uni.navigateBack({ delta: 1 }) } +// 打印物品标签 +function printItem() { + if (!printer) { + uni.showToast({ title: '打印机插件未加载(仅在 App 环境可用)', icon: 'none' }) + return + } + + if (!item.value) { + uni.showToast({ title: '物品信息未加载', icon: 'none' }) + return + } + + // 标签打印,使用黑标 + printer.printEnableMark({ + enable: true + }) + + // 第一行:标题(名称) + printer.setFontSize({ fontSize: 0 }) + printer.setTextBold({ bold: true }) + printer.printText({ + content: (item.value.Name || '物品')+'\n' + }) + printer.setTextBold({ bold: false }) + //printer.printLine({ line_length: 1 }) + + // 第二行:编号 + if (item.value.SerialNumber) { + printer.setFontSize({ fontSize: 1 }) + printer.printText({ + content: '序列号:' + item.value.SerialNumber +'\n' + }) + //printer.printLine({ line_length: 1 }) + } + + // 第三行:备注 + if (item.value.Remark) { + printer.setFontSize({ fontSize: 1 }) + printer.printText({ + content: '备注:' + item.value.Remark+'\n' + }) + //printer.printLine({ line_length: 1 }) + } + + // 第四行:创建日期 + if (item.value.CreatedAt) { + printer.setFontSize({ fontSize: 1 }) + printer.printText({ + content: '创建日期:' + formatDate(item.value.CreatedAt) + }) + //printer.printLine({ line_length: 1 }) + } + + // 条形码(高度4) + printer.printBarcode({ + text: 'item:' + itemId.value, + height: 40, + barcodeType: 73 + }) + printer.printLine({ line_length: 2 }) + + // 提交打印 + printer.start() + + uni.showToast({ title: '打印成功', icon: 'success' }) +} + async function onRefresh() { refreshing.value = true await fetchDetail() @@ -372,13 +452,16 @@ onShow(() => { color: #333; flex: 1; text-align: center; - padding-right: 60rpx; } -.title { - font-size: 36rpx; - font-weight: bold; - color: #333; +.header-right { + display: flex; + align-items: center; +} + +.print-btn { + font-size: 28rpx; + color: #007AFF; } .content { diff --git a/pages/warehouse/warehouse.vue b/pages/warehouse/warehouse.vue index 42efecf..a5a17d8 100644 --- a/pages/warehouse/warehouse.vue +++ b/pages/warehouse/warehouse.vue @@ -40,6 +40,7 @@ / + 打印 ✎ 编辑 @@ -236,6 +237,16 @@ import { onShow } from '@dcloudio/uni-app' import { warehouseApi } from '@/api/warehouse.js' import { useConfigStore } from '@/stores/config.js' +// 仅在 App 环境下加载原生插件 +let printer = null +try { + if (uni.requireNativePlugin) { + printer = uni.requireNativePlugin('LcPrinter') + } +} catch (e) { + console.error('打印机插件加载失败:', e.message) +} + const configStore = useConfigStore() function getPhotoUrl(sha256) { @@ -569,12 +580,110 @@ function goItemDetail(id) { }) } +// 打印容器标签 +async function printContainer() { + if (!printer) { + uni.showToast({ title: '打印机插件未加载(仅在 App 环境可用)', icon: 'none' }) + return + } + + if (!currentContainerId.value || currentContainerId.value === 0) { + uni.showToast({ title: '容器信息未加载', icon: 'none' }) + return + } + + uni.showLoading({ title: '获取容器信息...' }) + + try { + // 获取完整容器详情(包含 Remark, CreatedAt 等字段) + const res = await warehouseApi.getContainer(currentContainerId.value) + uni.hideLoading() + + if (res.errCode !== 0 || !res.data || !res.data.container) { + uni.showToast({ title: '获取容器信息失败', icon: 'none' }) + return + } + + const container = res.data.container + + // 标签打印,使用黑标 + printer.printEnableMark({ + enable: true + }) + + // 第一行:容器名(加粗) + printer.setFontSize({ fontSize: 0 }) + printer.setTextBold({ bold: true }) + printer.printText({ + content: (container.Title || '容器') + '\n' + }) + printer.setTextBold({ bold: false }) + + // 第二行:完整面包屑 + const breadcrumbText = breadcrumbs.value.map(b => b.title).join(' / ') + if (breadcrumbText) { + printer.setFontSize({ fontSize: 1 }) + printer.printText({ + content: breadcrumbText + '\n' + }) + } + + // 第三行:备注 + if (container.Remark) { + printer.setFontSize({ fontSize: 1 }) + printer.printText({ + content: container.Remark + '\n' + }) + } + + // 第四行:创建日期 + if (container.CreatedAt) { + printer.setFontSize({ fontSize: 1 }) + printer.printText({ + content: formatDate(container.CreatedAt) + }) + } + + // 条形码(高度40) + printer.printBarcode({ + text: 'warehouse:' + container.ID, + height: 40, + barcodeType: 73 + }) + printer.printLine({ line_length: 2 }) + + // 提交打印 + printer.start() + + uni.showToast({ title: '打印成功', icon: 'success' }) + } catch (e) { + uni.hideLoading() + console.error('打印失败', e) + uni.showToast({ title: '打印失败', icon: 'none' }) + } +} + +// 格式化日期 +function formatDate(dateStr) { + if (!dateStr) return '' + const date = new Date(dateStr) + return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}` +} + onMounted(() => { fetchContainers() }) // 每次页面显示时刷新数据(如从新增物品页面返回时) onShow(() => { + // 检查是否有条码导航事件 + uni.$once('barcode-navigate-container', (data) => { + if (data && data.id) { + currentContainerId.value = parseInt(data.id) + // 清空搜索,确保显示容器内容 + searchText.value = '' + } + }) fetchContainers() }) @@ -696,6 +805,14 @@ onShow(() => { font-size: 28rpx; color: #007AFF; white-space: nowrap; + margin-left: 20rpx; +} + +.print-btn { + font-size: 28rpx; + color: #007AFF; + white-space: nowrap; + margin-left: 20rpx; } .item-card { diff --git a/pages/workorder/show-workorder.vue b/pages/workorder/show-workorder.vue index 0728d36..fdd072b 100644 --- a/pages/workorder/show-workorder.vue +++ b/pages/workorder/show-workorder.vue @@ -3,8 +3,10 @@ ‹ 返回 工单详情 - 编辑 - + + 编辑 + 打印 + @@ -258,6 +260,16 @@ import { workOrderApi } from '@/api/work_order.js' import api from '@/api/index.js' import { useConfigStore } from '@/stores/config.js' +// 仅在 App 环境下加载原生插件 +let printer = null +try { + if (uni.requireNativePlugin) { + printer = uni.requireNativePlugin('LcPrinter') + } +} catch (e) { + console.error('打印机插件加载失败:', e.message) +} + const configStore = useConfigStore() const goBack = () => uni.navigateBack() @@ -342,6 +354,59 @@ async function fetchOrderDetail() { } } +// 打印工单标签 +function printWorkOrder() { + if (!printer) { + uni.showToast({ title: '打印机插件未加载(仅在 App 环境可用)', icon: 'none' }) + return + } + + // 标签打印,使用黑标 + printer.printEnableMark({ + enable: true + }) + + // 第一行:标题 + printer.setFontSize({ fontSize: 0 }) + printer.setTextBold({ bold: true }) + printer.printText({ + content: (order.value.Title || '工单')+'\n' + }) + printer.setTextBold({ bold: false }) + //printer.printLine({ line_length: 1 }) + + // 第二行:描述 + if (order.value.Description) { + //printer.setFontSize({ fontSize: 1 }) + printer.printText({ + content: order.value.Description+'\n' + }) + //printer.printLine({ line_length: 1 }) + } + + // 第三行:创建时间 + if (order.value.CreatedAt) { + printer.setFontSize({ fontSize: 1 }) + printer.printText({ + content: formatDate(order.value.CreatedAt) + }) + //printer.printLine({ line_length: 1 }) + } + + // 条形码(高40) + printer.printBarcode({ + text: 'wo:' + orderId.value, + height: 40, + barcodeType: 73 + }) + //printer.printLine({ line_length: 2 }) + + // 提交打印 + printer.start() + + uni.showToast({ title: '打印成功', icon: 'success' }) +} + // 新增进度 const selectedStatus = ref({}) const commitComment = ref('') @@ -621,7 +686,14 @@ async function onRefresh() { } .header-right { - width: 60rpx; + display: flex; + align-items: center; + gap: 40rpx; +} + +.print-btn { + font-size: 28rpx; + color: #007AFF; } .content {