This commit is contained in:
zc
2026-03-09 15:24:02 +08:00
parent 630a98af65
commit d8273464c5
5 changed files with 104 additions and 83 deletions

View File

@@ -12,10 +12,12 @@ export interface WorkOrderResp {
materialSpec: string materialSpec: string
photoUrl: string photoUrl: string
totalWeight: string totalWeight: string
totalCalculatedWeight: string
totalCount: string totalCount: string
createUserString: string createUserString: string
updateUserString: string updateUserString: string
matchResult: string matchResult: string
workOrderInfos: Array<WorkOrderInfoResp>
} }
export interface WorkOrderInfoResp { export interface WorkOrderInfoResp {
@@ -46,9 +48,14 @@ export function listWorkOrder(query: WorkOrderPageQuery) {
return http.get<PageRes<WorkOrderResp[]>>(`${BASE_URL}`, query) return http.get<PageRes<WorkOrderResp[]>>(`${BASE_URL}`, query)
} }
/** @desc 查询工作订单详情 */
export function getWorkOrderInfos(id: string) {
return http.get<Array<WorkOrderInfoResp>>(`${BASE_URL}/info/${id}`)
}
/** @desc 查询工作订单详情 */ /** @desc 查询工作订单详情 */
export function getWorkOrder(id: string) { export function getWorkOrder(id: string) {
return http.get<Array<WorkOrderInfoResp>>(`${BASE_URL}/${id}`) return http.get<WorkOrderResp>(`${BASE_URL}/${id}`)
} }
/** @desc 新增工作订单 */ /** @desc 新增工作订单 */

View File

@@ -9,17 +9,17 @@
<div class="form-grid"> <div class="form-grid">
<div class="form-grid-item"> <div class="form-grid-item">
<a-form-item label="物料名称"> <a-form-item label="物料名称">
<a-input v-model="formData.materialName" placeholder="请输入物料名称" :disabled="isFromWorkOrder" /> <a-input v-model="formData.materialName" placeholder="未获取到物料名称" :disabled="true" />
</a-form-item> </a-form-item>
</div> </div>
<div class="form-grid-item"> <div class="form-grid-item">
<a-form-item label="物料编码"> <a-form-item label="物料编码">
<a-input v-model="formData.encoding" placeholder="请输入物料编码" :disabled="isFromWorkOrder" /> <a-input v-model="formData.encoding" placeholder="未获取到物料编码" :disabled="true" />
</a-form-item> </a-form-item>
</div> </div>
<div class="form-grid-item"> <div class="form-grid-item">
<a-form-item label="工单编号"> <a-form-item label="工单编号">
<a-input v-model="formData.orderNo" placeholder="请输入工单编号" :disabled="isFromWorkOrder" /> <a-input v-model="formData.orderNo" placeholder="未获取到工单编号" :disabled="true" />
</a-form-item> </a-form-item>
</div> </div>
<div class="form-grid-item"> <div class="form-grid-item">
@@ -62,13 +62,13 @@
</td> </td>
<td class="label-cell"> <td class="label-cell">
<div class="label-field">数量</div> <div class="label-field">数量</div>
<div class="label-value">{{ labelData.quantity }}</div> <div class="label-value">{{ labelData.totalCount }}</div>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="label-cell"> <td class="label-cell">
<div class="label-field">标重(kg)</div> <div class="label-field">标重(kg)</div>
<div class="label-value">{{ labelData.standardWeight }}</div> <div class="label-value">{{ labelData.totalCalculatedWeight }}</div>
</td> </td>
<td class="label-cell"> <td class="label-cell">
<div class="label-field">包装签字</div> <div class="label-field">包装签字</div>
@@ -78,19 +78,13 @@
<tr> <tr>
<td class="label-cell"> <td class="label-cell">
<div class="label-field">实重(kg)</div> <div class="label-field">实重(kg)</div>
<div class="label-value">{{ labelData.actualWeight || '' }}</div> <div class="label-value">{{ labelData.totalWeight || '' }}</div>
</td> </td>
<td class="label-cell"> <td class="label-cell">
<div class="label-field">检验签字</div> <div class="label-field">检验签字</div>
<div class="label-value">{{ labelData.inspectionSignature || '' }}</div> <div class="label-value">{{ labelData.inspectionSignature || '' }}</div>
</td> </td>
</tr> </tr>
<!-- <tr>-->
<!-- <td class="label-cell" colspan="2"></td>-->
<!-- <td class="label-cell qr-cell">-->
<!-- <div class="serial-number">序号: {{ labelData.serialNumber }}</div>-->
<!-- </td>-->
<!-- </tr>-->
</table> </table>
</div> </div>
</div> </div>
@@ -106,80 +100,71 @@
import { ref, reactive, nextTick, onMounted } from 'vue' import { ref, reactive, nextTick, onMounted } from 'vue'
import { Message } from '@arco-design/web-vue' import { Message } from '@arco-design/web-vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import {getWorkOrder} from "@/apis/workOrder/workOrder";
const route = useRoute() const route = useRoute()
// //
const formData = reactive({ const formData = reactive({
workerOrderId: '',
encoding: '', encoding: '',
materialName: '', materialName: '',
orderNo: '', orderNo: '',
totalCalculatedWeight: '',
totalWeight: '',
totalCount: '',
productionBatch: '' productionBatch: ''
}) })
//
const isFromWorkOrder = ref(false)
// //
const labelData = reactive({ const labelData = reactive({
partName: '', partName: '',
partNumber: '', partNumber: '',
standardWeight: '', totalCalculatedWeight: '',
actualWeight: '', totalWeight: '',
productionDate: '', productionDate: '',
quantity: '', totalCount: '',
packingSignature: '', packingSignature: '',
inspectionSignature: '', inspectionSignature: '',
serialNumber: '',
qrCodeData: '', qrCodeData: '',
}) })
// //
const labelContainer = ref<HTMLElement | null>(null) const labelContainer = ref<HTMLElement | null>(null)
//
const fetchLabelData = async (params: any) => {
//
return new Promise((resolve) => {
setTimeout(() => {
// 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 mockData = {
partName: params.materialName || 'PP0449002护套',
partNumber: params.encoding || 'PP0449002',
standardWeight: '0.39500',
actualWeight: '',
productionDate: formattedDate,
quantity: '200',
packingSignature: '',
inspectionSignature: '',
serialNumber: '4',
qrCodeData: `PART:${params.encoding || 'PP0449002'},NAME:${params.materialName || 'PP0449002护套'},DATE:${formattedDate},QTY:200`,
}
resolve(mockData)
}, 500)
})
}
// //
const generateLabel = async () => { const generateLabel = async () => {
if (!formData.productionBatch) { if (!formData.productionBatch) {
Message.error('请输入生产批次') Message.error('请输入生产批次')
return return
} }
if (!formData.materialName) {
Message.error('未获取到物料信息')
return
}
try { try {
// // yyyyMMddHHmm
const result = await fetchLabelData(formData) const now = new Date()
Object.assign(labelData, result) 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')
// formData
Object.assign(labelData, {
partName: formData.materialName || '',
partNumber: formData.encoding || '',
totalCalculatedWeight: formData.totalCalculatedWeight || '',
totalWeight: formData.totalWeight || '',
productionDate: formattedDate,
totalCount: formData.totalCount || '',
packingSignature: '',
inspectionSignature: '',
qrCodeData: `PART:${formData.encoding || 'PP0449002'},NAME:${formData.materialName || 'PP0449002护套'},DATE:${formattedDate},QTY:200`,
})
Message.success('标签生成成功') Message.success('标签生成成功')
} catch (error) { } catch (error) {
console.error('生成标签失败:', error) console.error('生成标签失败:', error)
@@ -190,16 +175,23 @@ const generateLabel = async () => {
// //
onMounted(() => { onMounted(() => {
// //
const materialName = route.query.materialName as string const workerOrderId = route.query.workerOrderId as string
const encoding = route.query.encoding as string
const orderNo = route.query.orderNo as string
// //
if (materialName && encoding && orderNo) { if (workerOrderId) {
formData.materialName = materialName formData.workerOrderId = workerOrderId
formData.encoding = encoding getWorkOrder(workerOrderId).then(res => {
formData.orderNo = orderNo if (res.code == '0') {
isFromWorkOrder.value = true formData.encoding = res.data.encoding
formData.materialName = res.data.materialName
formData.orderNo = res.data.orderNo
formData.totalCalculatedWeight = res.data.totalCalculatedWeight
formData.totalWeight = res.data.totalWeight
formData.totalCount = res.data.totalCount
} else {
Message.error('获取详情失败')
}
});
// //
generateLabel() generateLabel()

View File

@@ -20,7 +20,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted } from 'vue' import { ref, reactive, onMounted, onUnmounted } from 'vue'
import { type FormInstance, Message } from '@arco-design/web-vue' import { type FormInstance, Message } from '@arco-design/web-vue'
import { useTabsStore, useUserStore } from '@/stores' import { useTabsStore, useUserStore } from '@/stores'
@@ -42,12 +42,24 @@ const loading = ref(false)
// 登录 // 登录
const handleLogin = async () => { const handleLogin = async () => {
// 检查用户是否已经登录
if (userStore.token) {
return
}
const isInvalid = await formRef.value?.validate() const isInvalid = await formRef.value?.validate()
if (isInvalid) return if (isInvalid) return
try { try {
loading.value = true loading.value = true
// 调用后端接口校验卡号 // 调用后端接口校验卡号
await userStore.cardLogin(form) await userStore.cardLogin(form)
// 登录成功后移除事件监听器
if (keyDownListener) {
document.removeEventListener('keydown', keyDownListener)
keyDownListener = null
}
tabsStore.reset() tabsStore.reset()
const { redirect, ...othersQuery } = router.currentRoute.value.query const { redirect, ...othersQuery } = router.currentRoute.value.query
await router.push({ await router.push({
@@ -64,24 +76,30 @@ const handleLogin = async () => {
} }
} }
// 键盘事件监听器引用
let keyDownListener: ((e: KeyboardEvent) => void) | null = null
// 监听键盘输入,实现自动识别卡号 // 监听键盘输入,实现自动识别卡号
onMounted(() => { onMounted(() => {
// 监听全局键盘事件,用于识别刷卡输入 // 监听Enter键用于自动登录
document.addEventListener('keydown', (e) => { keyDownListener = (e) => {
// 刷卡器通常会快速输入卡号并以Enter键结束 // 刷卡器通常会快速输入卡号并以Enter键结束
if (e.key === 'Enter') { if (e.key === 'Enter') {
// 遇到Enter键尝试登录 // 遇到Enter键尝试登录
if (form.cardNumber.trim()) { if (form.cardNumber.trim()) {
handleLogin() handleLogin()
} }
} else if (e.key.length === 1 && !e.ctrlKey && !e.altKey && !e.metaKey) {
// 只捕获单个字符的按键,忽略控制键和功能键
form.cardNumber += e.key
} else if (e.key === 'Backspace') {
// 处理退格键
form.cardNumber = form.cardNumber.slice(0, -1)
} }
}) }
document.addEventListener('keydown', keyDownListener)
})
// 组件卸载时移除事件监听器
onUnmounted(() => {
if (keyDownListener) {
document.removeEventListener('keydown', keyDownListener)
}
}) })
</script> </script>

View File

@@ -792,7 +792,7 @@ const calculateWeight = () => {
// 处理确定 // 处理确定
const handleConfirm = () => { const handleConfirm = () => {
// 校验输入数量是否为空 // 校验输入数量是否为空
if (!inputQuantity.value || inputQuantity.value.trim() === '') { if (!inputQuantity.value || inputQuantity.value.trim() === '') {
Message.error('请输入数量') Message.error('请输入数量')
@@ -803,6 +803,12 @@ const handleConfirm = () => {
return return
} }
// 2. 抓拍当前画面
let captureUrl = ''
if (cameraVideo.value && cameraStatus.value === 'connected') {
captureUrl = capturePhoto();
}
// 生成新的列表数据 // 生成新的列表数据
const newItem = { const newItem = {
key: (weighingList.value.length + 1).toString(), key: (weighingList.value.length + 1).toString(),
@@ -825,7 +831,7 @@ const handleConfirm = () => {
} }
// 抓拍功能 - 内部方法,不暴露按钮 // 抓拍功能 - 内部方法,不暴露按钮
const capturePhoto = async (): Promise<string> => { const capturePhoto = (): Promise<string> => {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
try { try {
const video = cameraVideo.value const video = cameraVideo.value
@@ -852,7 +858,7 @@ const capturePhoto = async (): Promise<string> => {
// 调用后端接口 // 调用后端接口
const response = await catchPhoto(formData) const response = await catchPhoto(formData)
if (!response.code === '200') { if (response.code !== '200') {
reject(new Error('上传失败')) reject(new Error('上传失败'))
return return
} }

View File

@@ -117,7 +117,7 @@ import {Message} from "@arco-design/web-vue";
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { import {
deleteWorkOrder, deleteWorkOrder,
exportWorkOrder, getWorkOrder, exportWorkOrder, getWorkOrderInfos,
listWorkOrder, listWorkOrder,
type WorkOrderQuery, type WorkOrderQuery,
type WorkOrderResp type WorkOrderResp
@@ -218,7 +218,7 @@ const onDetail = async (record: WorkOrderResp) => {
detailModalVisible.value = true detailModalVisible.value = true
detailData.value = [] detailData.value = []
getWorkOrder(record.id).then(res => { getWorkOrderInfos(record.id).then(res => {
if (res.code == '0') { if (res.code == '0') {
detailData.value = res.data; detailData.value = res.data;
detailLoading.value = false detailLoading.value = false
@@ -258,9 +258,7 @@ const onPrint = (record: WorkOrderResp) => {
router.push({ router.push({
path: '/print', path: '/print',
query: { query: {
materialName: record.materialName, workerOrderId: record.id,
encoding: record.encoding,
orderNo: record.orderNo
} }
}) })
} }