| | |
| | | :disabled="!canEditProducts" |
| | | @click="openSpecificationPicker(idx)" /> |
| | | <template #right> |
| | | <view v-if="canEditProducts" |
| | | class="scan-entry" |
| | | @click.stop="scanBarcode(idx)"> |
| | | <up-icon name="scan" |
| | | size="18" |
| | | color="#3c9cff"></up-icon> |
| | | <text class="scan-entry-text">扫码</text> |
| | | </view> |
| | | <up-icon name="arrow-right" |
| | | v-if="canEditProducts" |
| | | @click="openSpecificationPicker(idx)"></up-icon> |
| | |
| | | |
| | | <script setup> |
| | | import { onMounted, ref, computed } from "vue"; |
| | | import { modelList, productTreeList } from "@/api/basicData/product.js"; |
| | | import { |
| | | modelList, |
| | | productTreeList, |
| | | modelByBarcode, |
| | | } from "@/api/basicData/product.js"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { calculateTaxExclusiveTotalPrice } from "@/utils/summarizeTable"; |
| | | import { formatDateToYMD } from "@/utils/ruoyi"; |
| | |
| | | name: model.text, |
| | | value: model.value, |
| | | unit: model.unit, |
| | | subname: model.barcode ? `条码:${model.barcode}` : "", |
| | | })); |
| | | }); |
| | | |
| | |
| | | showCategoryPicker.value = false; |
| | | }; |
| | | |
| | | // 获取规格型号 |
| | | // 获取规格型号(返回 Promise,便于扫码后顺序回填) |
| | | const getModels = value => { |
| | | modelList({ id: value }).then(res => { |
| | | modelOptions.value = res.map(user => ({ |
| | | return modelList({ id: value }).then(res => { |
| | | const list = res?.data || res || []; |
| | | modelOptions.value = list.map(user => ({ |
| | | text: user.model, |
| | | value: user.id, |
| | | unit: user.unit, |
| | | barcode: user.barcode, |
| | | })); |
| | | }); |
| | | }; |
| | | |
| | | // 扫码按条码精确回填产品大类+规格型号 |
| | | const scanBarcode = idx => { |
| | | if (!canEditProducts.value) return; |
| | | uni.scanCode({ |
| | | scanType: ["barCode", "qrCode"], |
| | | success: async res => { |
| | | const barcode = (res.result || "").trim(); |
| | | if (!barcode) return; |
| | | uni.showLoading({ title: "匹配中...", mask: true }); |
| | | try { |
| | | const resp = await modelByBarcode({ barcode }); |
| | | const info = resp?.data || resp; |
| | | if (info && info.productId) { |
| | | currentProductIndex.value = idx; |
| | | // 先加载该产品下的规格列表,保证与手动选择时的 UI 状态一致 |
| | | await getModels(info.productId); |
| | | const row = productData.value[idx]; |
| | | row.productCategory = info.productName || row.productCategory; |
| | | row.specificationModel = info.model || ""; |
| | | row.productModelId = info.id || ""; |
| | | row.unit = info.unit || ""; |
| | | } |
| | | uni.hideLoading(); |
| | | uni.showToast({ title: "已匹配规格", icon: "success" }); |
| | | } catch (e) { |
| | | // 未匹配等错误已有全局 toast,这里只恢复 loading |
| | | uni.hideLoading(); |
| | | } |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | |
| | | <style scoped lang="scss"> |
| | | @import "@/static/scss/form-common.scss"; |
| | | |
| | | // 规格行扫码入口 |
| | | .scan-entry { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-right: 8px; |
| | | |
| | | .scan-entry-text { |
| | | font-size: 13px; |
| | | color: #3c9cff; |
| | | margin-left: 2px; |
| | | } |
| | | } |
| | | |
| | | .approval-process { |
| | | background: #fff; |
| | | margin: 16px; |