| | |
| | | data: ids |
| | | }) |
| | | } |
| | | |
| | | // 编辑入库(用于库存台账编辑) |
| | | export const editStockInStock = (data) => { |
| | | return request({ |
| | | url: '/stockInRecord/editStockInStock', |
| | | method: 'POST', |
| | | data |
| | | }) |
| | | } |
| | |
| | | data: ids |
| | | }) |
| | | } |
| | | |
| | | // 编辑出库(库存台账编辑) |
| | | export const editStockOut = (data) => { |
| | | return request({ |
| | | url: '/stockOutRecord/editStockOut', |
| | | method: 'POST', |
| | | data |
| | | }) |
| | | } |
| | |
| | | <view class="row"><text class="l">规格型号</text><text class="r">{{ item.model }}</text></view> |
| | | <view class="row"><text class="l">单位</text><text class="r">{{ item.unit }}</text></view> |
| | | <view class="row"><text class="l">出库数量</text><text class="r highlight">{{ item.stockOutNum }}</text></view> |
| | | <!-- <view class="row"><text class="l">采购员</text><text class="r">{{ item.purchaser || '-' }}</text></view> --> |
| | | <view class="row"><text class="l">出库人</text><text class="r">{{ item.createBy }}</text></view> |
| | | <view class="row" v-if="item.recordType !== undefined"><text class="l">来源</text><text class="r">{{ getRecordType(item.recordType) || item.recordType }}</text></view> |
| | | <view class="row"><text class="l">毛重(吨)</text><text class="r">{{ item.grossWeight ?? '-' }}</text></view> |
| | | <view class="row"><text class="l">皮重(吨)</text><text class="r">{{ item.tareWeight ?? '-' }}</text></view> |
| | | <view class="row"><text class="l">净重(吨)</text><text class="r">{{ item.netWeight ?? '-' }}</text></view> |
| | | <view class="row"><text class="l">过磅日期</text><text class="r">{{ item.weighingDate || '-' }}</text></view> |
| | | <view class="row"><text class="l">过磅员</text><text class="r">{{ item.weighingOperator || '-' }}</text></view> |
| | | </view> |
| | | </view> |
| | | <view class="card-actions"> |
| | |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="section-card"> |
| | | <view class="section-head"> |
| | | <view class="section-dot"></view> |
| | | <text class="section-title">出库信息</text> |
| | | </view> |
| | | <view class="section-body"> |
| | | <view class="detail-row"> |
| | | <text class="label">车牌号</text> |
| | | <text class="value">{{ detail.licensePlateNo || '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">毛重(吨)</text> |
| | | <text class="value">{{ detail.grossWeight ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">皮重(吨)</text> |
| | | <text class="value">{{ detail.tareWeight ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">净重(吨)</text> |
| | | <text class="value">{{ detail.netWeight ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">过磅日期</text> |
| | | <text class="value">{{ detail.weighingDate || '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">过磅员</text> |
| | | <text class="value">{{ detail.weighingOperator || '-' }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view v-else class="empty"> |
| | | <text class="empty-text">暂无详情数据</text> |
| | |
| | | stockOutNum: d.stockOutNum, |
| | | createBy: d.createBy, |
| | | recordType: d.recordType, |
| | | licensePlateNo: d.licensePlateNo, |
| | | grossWeight: d.grossWeight, |
| | | tareWeight: d.tareWeight, |
| | | netWeight: d.netWeight, |
| | | weighingDate: d.weighingDate, |
| | | weighingOperator: d.weighingOperator, |
| | | purchaser: d.purchaser, |
| | | }; |
| | | } |
| | | |
| | |
| | | <view class="row"><text class="l">规格型号</text><text class="r">{{ item.model }}</text></view> |
| | | <view class="row"><text class="l">单位</text><text class="r">{{ item.unit }}</text></view> |
| | | <view class="row"><text class="l">入库数量</text><text class="r highlight">{{ item.stockInNum }}</text></view> |
| | | <view class="row"><text class="l">采购员</text><text class="r">{{ item.purchaser || '-' }}</text></view> |
| | | <view class="row"><text class="l">入库人</text><text class="r">{{ item.createBy }}</text></view> |
| | | <view class="row" v-if="item.recordType !== undefined"><text class="l">来源</text><text class="r">{{ getRecordType(item.recordType) || item.recordType }}</text></view> |
| | | </view> |
| | |
| | | </view> |
| | | <view class="section-body"> |
| | | <view class="detail-row"> |
| | | <text class="label">车牌号</text> |
| | | <text class="value">{{ detail.licensePlateNo || '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">毛重(吨)</text> |
| | | <text class="value">{{ detail.grossWeight ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">皮重(吨)</text> |
| | | <text class="value">{{ detail.tareWeight ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">净重(吨)</text> |
| | | <text class="value">{{ detail.netWeight ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">过磅日期</text> |
| | | <text class="value">{{ detail.weighingDate || '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">过磅员</text> |
| | | <text class="value">{{ detail.weighingOperator || '-' }}</text> |
| | | <text class="label">采购员</text> |
| | | <text class="value">{{ detail.purchaser || '-' }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | stockInNum: d.stockInNum, |
| | | createBy: d.createBy, |
| | | recordType: d.recordType, |
| | | licensePlateNo: d.licensePlateNo, |
| | | grossWeight: d.grossWeight, |
| | | tareWeight: d.tareWeight, |
| | | netWeight: d.netWeight, |
| | | weighingDate: d.weighingDate, |
| | | weighingOperator: d.weighingOperator, |
| | | purchaser: d.purchaser, |
| | | }; |
| | | } |
| | | |
| | |
| | | </view> |
| | | |
| | | <view class="form-section"> |
| | | <view class="section-title">过磅信息</view> |
| | | <view class="section-title">入库信息</view> |
| | | <view class="form-row"> |
| | | <text class="form-label required">车牌号</text> |
| | | <up-input v-model="form.licensePlateNo" placeholder="请输入车牌号" /> |
| | | <text class="form-label required">数量</text> |
| | | <up-input v-model="form.qualitity" type="number" placeholder="请输入数量" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label required">毛重(吨)</text> |
| | | <up-input v-model="form.grossWeight" type="digit" placeholder="请输入毛重" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label required">皮重(吨)</text> |
| | | <up-input v-model="form.tareWeight" type="digit" placeholder="请输入皮重" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">净重(吨)</text> |
| | | <up-input v-model="form.netWeight" type="digit" disabled placeholder="自动计算" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label required">过磅日期</text> |
| | | <view class="selector-trigger" @click="openWeighingDatePicker"> |
| | | <text class="selector-text" :class="{ placeholder: !form.weighingDate }"> |
| | | {{ form.weighingDate || "请选择过磅日期" }} |
| | | </text> |
| | | <up-icon name="calendar" size="16" color="#999"></up-icon> |
| | | </view> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label required">过磅员</text> |
| | | <up-input v-model="form.weighingOperator" placeholder="请输入过磅员" /> |
| | | <text class="form-label required">采购员</text> |
| | | <up-input v-model="form.purchaser" placeholder="请输入采购员" /> |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | </view> |
| | | </up-popup> |
| | | |
| | | <up-popup :show="showWeighingDatePicker" mode="bottom" @close="showWeighingDatePicker = false"> |
| | | <up-datetime-picker |
| | | :show="true" |
| | | v-model="weighingDateValue" |
| | | mode="datetime" |
| | | @confirm="onWeighingDateConfirm" |
| | | @cancel="showWeighingDatePicker = false" |
| | | /> |
| | | </up-popup> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, reactive, ref, watch } from "vue"; |
| | | import { computed, reactive, ref } from "vue"; |
| | | import { onLoad } from "@dcloudio/uni-app"; |
| | | import dayjs from "dayjs"; |
| | | import PageHeader from "@/components/PageHeader.vue"; |
| | | import { createConsumablesIn } from "@/api/consumablesLogistics/consumablesIn.js"; |
| | | import { productModelList } from "@/api/basicData/productModel.js"; |
| | |
| | | productModelName: "", |
| | | unit: "", |
| | | productType: undefined, |
| | | licensePlateNo: "", |
| | | grossWeight: "", |
| | | tareWeight: "", |
| | | netWeight: "", |
| | | weighingDate: "", |
| | | weighingOperator: "", |
| | | qualitity: "", |
| | | purchaser: "", |
| | | remark: "", |
| | | }); |
| | | |
| | |
| | | }); |
| | | const productList = ref([]); |
| | | const productLoading = ref(false); |
| | | |
| | | const showWeighingDatePicker = ref(false); |
| | | const weighingDateValue = ref(Date.now()); |
| | | |
| | | onLoad((options) => { |
| | | type.value = "0"; |
| | |
| | | showProductPopup.value = false; |
| | | }; |
| | | |
| | | const computeNetWeight = () => { |
| | | const gross = Number(form.grossWeight); |
| | | const tare = Number(form.tareWeight); |
| | | if (!isNaN(gross) && !isNaN(tare)) { |
| | | const net = Number((gross - tare).toFixed(2)); |
| | | form.netWeight = net > 0 ? net : 0; |
| | | } else { |
| | | form.netWeight = ""; |
| | | } |
| | | }; |
| | | |
| | | watch( |
| | | () => [form.grossWeight, form.tareWeight], |
| | | () => { |
| | | computeNetWeight(); |
| | | } |
| | | ); |
| | | |
| | | const openWeighingDatePicker = () => { |
| | | weighingDateValue.value = form.weighingDate |
| | | ? dayjs(form.weighingDate, "YYYY-MM-DD HH:mm:ss").valueOf() |
| | | : Date.now(); |
| | | showWeighingDatePicker.value = true; |
| | | }; |
| | | |
| | | const onWeighingDateConfirm = (e) => { |
| | | const ts = e?.value ?? weighingDateValue.value; |
| | | form.weighingDate = dayjs(ts).format("YYYY-MM-DD HH:mm:ss"); |
| | | showWeighingDatePicker.value = false; |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | if (!form.productName || !form.productModelId) { |
| | | uni.showToast({ title: "请选择产品", icon: "none" }); |
| | | return; |
| | | } |
| | | if (!form.licensePlateNo) { |
| | | uni.showToast({ title: "请输入车牌号", icon: "none" }); |
| | | if (!form.qualitity || Number(form.qualitity) <= 0) { |
| | | uni.showToast({ title: "请输入数量", icon: "none" }); |
| | | return; |
| | | } |
| | | if (!form.grossWeight || Number(form.grossWeight) <= 0) { |
| | | uni.showToast({ title: "请输入毛重", icon: "none" }); |
| | | return; |
| | | } |
| | | if (!form.tareWeight || Number(form.tareWeight) <= 0) { |
| | | uni.showToast({ title: "请输入皮重", icon: "none" }); |
| | | return; |
| | | } |
| | | if (!form.weighingDate) { |
| | | uni.showToast({ title: "请选择过磅日期", icon: "none" }); |
| | | return; |
| | | } |
| | | if (!form.weighingOperator) { |
| | | uni.showToast({ title: "请输入过磅员", icon: "none" }); |
| | | if (!form.purchaser) { |
| | | uni.showToast({ title: "请输入采购员", icon: "none" }); |
| | | return; |
| | | } |
| | | const payload = { |
| | |
| | | productModelName: form.productModelName, |
| | | unit: form.unit, |
| | | productType: form.productType, |
| | | licensePlateNo: form.licensePlateNo, |
| | | grossWeight: form.grossWeight, |
| | | tareWeight: form.tareWeight, |
| | | netWeight: form.netWeight, |
| | | weighingDate: form.weighingDate, |
| | | weighingOperator: form.weighingOperator, |
| | | qualitity: Number(form.qualitity), |
| | | purchaser: form.purchaser, |
| | | remark: form.remark, |
| | | }; |
| | | createConsumablesIn(payload) |
| | |
| | | <up-input v-model="form.stockOutNum" type="number" :placeholder="'最大' + stockRecord.unLockedQuantity" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">车牌号</text> |
| | | <up-input v-model="form.licensePlateNo" placeholder="请输入车牌号" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">毛重(吨)</text> |
| | | <up-input v-model="form.grossWeight" type="digit" placeholder="请输入毛重" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">皮重(吨)</text> |
| | | <up-input v-model="form.tareWeight" type="digit" placeholder="请输入皮重" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">净重(吨)</text> |
| | | <up-input v-model="form.netWeight" type="digit" disabled placeholder="自动计算" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">过磅日期</text> |
| | | <view class="selector-trigger" @click="openWeighingDatePicker"> |
| | | <text class="selector-text" :class="{ placeholder: !form.weighingDate }"> |
| | | {{ form.weighingDate || "请选择过磅日期" }} |
| | | </text> |
| | | <up-icon name="calendar" size="16" color="#999"></up-icon> |
| | | </view> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">过磅员</text> |
| | | <up-input v-model="form.weighingOperator" placeholder="请输入过磅员" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">备注</text> |
| | | <up-input v-model="form.remark" type="textarea" placeholder="选填" /> |
| | | </view> |
| | |
| | | <view class="bottom-bar"> |
| | | <view class="btn-submit" @click="handleSubmit">提交</view> |
| | | </view> |
| | | |
| | | <up-popup :show="showWeighingDatePicker" mode="bottom" @close="showWeighingDatePicker = false"> |
| | | <up-datetime-picker |
| | | :show="true" |
| | | v-model="weighingDateValue" |
| | | mode="datetime" |
| | | @confirm="onWeighingDateConfirm" |
| | | @cancel="showWeighingDatePicker = false" |
| | | /> |
| | | </up-popup> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, reactive, ref, watch } from "vue"; |
| | | import { computed, reactive, ref } from "vue"; |
| | | import { onLoad } from "@dcloudio/uni-app"; |
| | | import dayjs from "dayjs"; |
| | | import PageHeader from "@/components/PageHeader.vue"; |
| | | import { subtractConsumablesIn } from "@/api/consumablesLogistics/consumablesIn.js"; |
| | | |
| | | const type = ref("0"); |
| | | const isQualified = computed(() => true); |
| | | |
| | | const stockRecord = reactive({ |
| | | id: "", |
| | | productName: "", |
| | | model: "", |
| | | unLockedQuantity: 0, |
| | | }); |
| | | const stockRecord = reactive({}); |
| | | |
| | | const form = reactive({ |
| | | stockOutNum: "", |
| | | licensePlateNo: "", |
| | | grossWeight: "", |
| | | tareWeight: "", |
| | | netWeight: "", |
| | | weighingDate: "", |
| | | weighingOperator: "", |
| | | remark: "", |
| | | }); |
| | | |
| | | const showWeighingDatePicker = ref(false); |
| | | const weighingDateValue = ref(Date.now()); |
| | | |
| | | onLoad((options) => { |
| | | type.value = "0"; |
| | |
| | | try { |
| | | const payload = typeof cached === "string" ? JSON.parse(cached) : cached; |
| | | const item = payload && payload.item != null ? payload.item : payload; |
| | | stockRecord.id = item.id; |
| | | stockRecord.productName = item.productName; |
| | | stockRecord.model = item.model; |
| | | stockRecord.unLockedQuantity = item.unLockedQuantity || 0; |
| | | Object.assign(stockRecord, item || {}); |
| | | uni.removeStorageSync("stockSubtractRecord"); |
| | | } catch (e) { |
| | | uni.removeStorageSync("stockSubtractRecord"); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | const computeNetWeight = () => { |
| | | const gross = Number(form.grossWeight); |
| | | const tare = Number(form.tareWeight); |
| | | if (!isNaN(gross) && !isNaN(tare)) { |
| | | const net = Number((gross - tare).toFixed(2)); |
| | | form.netWeight = net > 0 ? net : 0; |
| | | } else { |
| | | form.netWeight = ""; |
| | | } |
| | | }; |
| | | |
| | | watch( |
| | | () => [form.grossWeight, form.tareWeight], |
| | | () => computeNetWeight() |
| | | ); |
| | | |
| | | const openWeighingDatePicker = () => { |
| | | weighingDateValue.value = form.weighingDate |
| | | ? dayjs(form.weighingDate, "YYYY-MM-DD HH:mm:ss").valueOf() |
| | | : Date.now(); |
| | | showWeighingDatePicker.value = true; |
| | | }; |
| | | |
| | | const onWeighingDateConfirm = (e) => { |
| | | const ts = e?.value ?? weighingDateValue.value; |
| | | form.weighingDate = dayjs(ts).format("YYYY-MM-DD HH:mm:ss"); |
| | | showWeighingDatePicker.value = false; |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | const outNum = Number(form.stockOutNum); |
| | |
| | | return; |
| | | } |
| | | subtractConsumablesIn({ |
| | | ...stockRecord, |
| | | id: stockRecord.id, |
| | | stockOutNum: outNum, |
| | | licensePlateNo: form.licensePlateNo, |
| | | grossWeight: form.grossWeight, |
| | | tareWeight: form.tareWeight, |
| | | netWeight: form.netWeight, |
| | | weighingDate: form.weighingDate, |
| | | weighingOperator: form.weighingOperator, |
| | | qualitity: outNum, |
| | | remark: form.remark, |
| | | }) |
| | | .then(() => { |
| | |
| | | url: "/pages/qualityManagement/finalInspection/index", |
| | | }); |
| | | break; |
| | | case "检测项维护": |
| | | case "化验项目管理": |
| | | uni.navigateTo({ |
| | | url: "/pages/qualityManagement/InspectItem/index", |
| | | }); |
| | |
| | | url: "/pages/qualityManagement/metricBinding/index", |
| | | }); |
| | | break; |
| | | case "不合格品管理": |
| | | case "不合格管理": |
| | | uni.navigateTo({ |
| | | url: "/pages/qualityManagement/nonconformingManagement/index", |
| | | }); |
| | | break; |
| | | case "原料检": |
| | | case "检测化验": |
| | | uni.navigateTo({ |
| | | url: "/pages/qualityManagement/rawMaterial/index", |
| | | }); |
| | |
| | | }); |
| | | purchaseItems.splice(0, purchaseItems.length, ...filteredPurchase); |
| | | |
| | | // 质量管理菜单:固定只展示 3 个入口 |
| | | // 过滤质量管理菜单(保留 3 个入口,但受权限控制) |
| | | const originalQuality = [ |
| | | { icon: "/static/images/icon/shengchanhesuan@2x.png", label: "检测项维护" }, |
| | | { icon: "/static/images/icon/caigoutaizhang@2x.png", label: "原料检" }, |
| | | { icon: "/static/images/icon/shengchandingdan@2x.png", label: "不合格品管理" }, |
| | | { icon: "/static/images/icon/shengchanhesuan@2x.png", label: "化验项目管理" }, |
| | | { icon: "/static/images/icon/caigoutaizhang@2x.png", label: "检测化验" }, |
| | | { icon: "/static/images/icon/shengchandingdan@2x.png", label: "不合格管理" }, |
| | | ]; |
| | | qualityItems.splice(0, qualityItems.length, ...originalQuality); |
| | | const filteredQuality = originalQuality.filter(item => { |
| | | return allowedMenuTitles.has(item.label); |
| | | }); |
| | | qualityItems.splice(0, qualityItems.length, ...filteredQuality); |
| | | |
| | | // 过滤安全生产菜单 |
| | | const originalSafety = [ |
| | |
| | | <view class="card-body"> |
| | | <view class="row"><text class="l">规格型号</text><text class="r">{{ item.model }}</text></view> |
| | | <view class="row"><text class="l">单位</text><text class="r">{{ item.unit }}</text></view> |
| | | <view class="row"><text class="l">出库数量</text><text class="r highlight">{{ item.stockOutNum }}</text></view> |
| | | <view class="row"><text class="l">出库人</text><text class="r">{{ item.createBy }}</text></view> |
| | | <view class="row"><text class="l">出库数量</text><text class="r highlight">{{ item.netWeight }}</text></view> |
| | | <view class="row"><text class="l">采购员</text><text class="r">{{ item.purchaser || item.createBy }}</text></view> |
| | | <view class="row" v-if="item.recordType !== undefined"><text class="l">来源</text><text class="r">{{ getRecordType(item.recordType) || item.recordType }}</text></view> |
| | | <view class="row"><text class="l">毛重(吨)</text><text class="r">{{ item.grossWeight ?? '-' }}</text></view> |
| | | <view class="row"><text class="l">皮重(吨)</text><text class="r">{{ item.tareWeight ?? '-' }}</text></view> |
| | | <view class="row"><text class="l">净重(吨)</text><text class="r">{{ item.netWeight ?? '-' }}</text></view> |
| | | <view class="row"><text class="l">过磅日期</text><text class="r">{{ item.weighingDate || '-' }}</text></view> |
| | | <view class="row"><text class="l">过磅员</text><text class="r">{{ item.weighingOperator || '-' }}</text></view> |
| | | </view> |
| | | </view> |
| | | <view class="card-actions"> |
| | | <view class="btn-delete" @click.stop="handleDeleteSingle(item)">删除</view> |
| | | <view |
| | | v-if="isQualifiedRow(item) && hasDispatchEdit" |
| | | class="btn-edit" |
| | | @click.stop="handleEdit(item)" |
| | | > |
| | | 编辑 |
| | | </view> |
| | | <view |
| | | v-if="hasDispatchCancel" |
| | | class="btn-delete" |
| | | @click.stop="handleDeleteSingle(item)" |
| | | > |
| | | 删除 |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | <view class="load-more-wrap" v-if="tableData.length > 0"> |
| | | <u-loadmore :status="loadStatus" @loadmore="loadMore" /> |
| | | </view> |
| | | |
| | | <!-- 编辑弹窗(参照 PC) --> |
| | | <up-popup :show="showEditModal" mode="bottom" @close="showEditModal = false"> |
| | | <view class="edit-popup"> |
| | | <view class="popup-header"> |
| | | <text class="popup-title">编辑出库</text> |
| | | </view> |
| | | <scroll-view scroll-y class="popup-body"> |
| | | <view class="form-row"> |
| | | <text class="form-label required">车牌号</text> |
| | | <up-input v-model="editForm.licensePlateNo" placeholder="请输入车牌号" /> |
| | | </view> |
| | | |
| | | <view class="form-row"> |
| | | <text class="form-label required">毛重(吨)</text> |
| | | <up-input |
| | | v-model="editForm.grossWeight" |
| | | type="digit" |
| | | placeholder="请输入毛重" |
| | | @blur="computeNetWeightEdit" |
| | | /> |
| | | </view> |
| | | |
| | | <view class="form-row"> |
| | | <text class="form-label required">皮重(吨)</text> |
| | | <up-input |
| | | v-model="editForm.tareWeight" |
| | | type="digit" |
| | | placeholder="请输入皮重" |
| | | @blur="computeNetWeightEdit" |
| | | /> |
| | | </view> |
| | | |
| | | <view class="form-row"> |
| | | <text class="form-label required">净重(吨)</text> |
| | | <up-input v-model="editForm.netWeight" type="digit" placeholder="自动计算" disabled /> |
| | | </view> |
| | | |
| | | <view class="form-row"> |
| | | <text class="form-label required">过磅日期</text> |
| | | <view class="selector-trigger" @click="openWeighingDatePicker"> |
| | | <text class="selector-text" :class="{ placeholder: !editForm.weighingDate }"> |
| | | {{ editForm.weighingDate || '请选择过磅日期' }} |
| | | </text> |
| | | <up-icon name="calendar" size="16" color="#999" /> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="form-row"> |
| | | <text class="form-label required">过磅员</text> |
| | | <up-input v-model="editForm.weighingOperator" placeholder="请输入过磅员" /> |
| | | </view> |
| | | |
| | | <view class="form-row"> |
| | | <text class="form-label">备注</text> |
| | | <up-input v-model="editForm.remark" type="textarea" placeholder="选填" /> |
| | | </view> |
| | | </scroll-view> |
| | | |
| | | <view class="popup-footer"> |
| | | <view class="btn-cancel" @click="showEditModal = false">取消</view> |
| | | <view class="btn-ok" @click="handleEditSubmit">确认</view> |
| | | </view> |
| | | |
| | | <up-popup :show="showWeighingDatePicker" mode="bottom" @close="showWeighingDatePicker = false"> |
| | | <up-datetime-picker |
| | | :show="true" |
| | | v-model="weighingDateValue" |
| | | mode="datetime" |
| | | @confirm="onWeighingDateConfirm" |
| | | @cancel="showWeighingDatePicker = false" |
| | | /> |
| | | </up-popup> |
| | | </view> |
| | | </up-popup> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, toRefs } from 'vue' |
| | | import { computed, ref, reactive, toRefs, watch } from 'vue' |
| | | import { onShow, onReachBottom } from '@dcloudio/uni-app' |
| | | import PageHeader from '@/components/PageHeader.vue' |
| | | import { getStockOutPage, delStockOut } from '@/api/inventoryManagement/stockOutRecord.js' |
| | | import dayjs from 'dayjs' |
| | | import { checkPermi } from '@/utils/permission' |
| | | import { getStockOutPage, delStockOut, editStockOut } from '@/api/inventoryManagement/stockOutRecord.js' |
| | | import { |
| | | findAllQualifiedStockOutRecordTypeOptions |
| | | } from '@/api/basicData/enum.js' |
| | |
| | | }) |
| | | const { searchForm } = toRefs(data) |
| | | |
| | | // 权限控制(参照 PC) |
| | | const hasDispatchEdit = computed(() => checkPermi(['dispatch_edit'])) |
| | | const hasDispatchCancel = computed(() => checkPermi(['dispatch_cancel'])) |
| | | |
| | | function getRecordType(recordType) { |
| | | if (recordType == null || recordType === '') return '' |
| | | return stockRecordTypeOptions.value.find(item => item.value === recordType)?.label || '' |
| | |
| | | .catch(() => { |
| | | stockRecordTypeOptions.value = [] |
| | | }) |
| | | } |
| | | |
| | | function isQualifiedRow(row) { |
| | | return row?.recordType === 0 || row?.recordType === '0' |
| | | } |
| | | |
| | | const getList = () => { |
| | |
| | | } |
| | | |
| | | const handleDeleteSingle = (item) => { |
| | | if (!hasDispatchCancel.value) return |
| | | uni.showModal({ |
| | | title: '删除', |
| | | content: '确认删除该条出库记录?', |
| | |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // ---------------- 编辑 ---------------- |
| | | const showEditModal = ref(false) |
| | | const showWeighingDatePicker = ref(false) |
| | | const weighingDateValue = ref(Date.now()) |
| | | |
| | | const editForm = reactive({ |
| | | id: null, |
| | | licensePlateNo: '', |
| | | grossWeight: '', |
| | | tareWeight: '', |
| | | netWeight: '', |
| | | weighingDate: '', |
| | | weighingOperator: '', |
| | | remark: '' |
| | | }) |
| | | |
| | | const computeNetWeightEdit = () => { |
| | | const gross = Number(editForm.grossWeight) |
| | | const tare = Number(editForm.tareWeight) |
| | | if (Number.isFinite(gross) && Number.isFinite(tare)) { |
| | | const net = gross - tare |
| | | const safeNet = Number(net.toFixed(2)) |
| | | editForm.netWeight = safeNet > 0 ? safeNet : 0 |
| | | } |
| | | } |
| | | |
| | | watch( |
| | | () => [showEditModal.value, editForm.grossWeight, editForm.tareWeight], |
| | | () => { |
| | | if (showEditModal.value) computeNetWeightEdit() |
| | | } |
| | | ) |
| | | |
| | | const openWeighingDatePicker = () => { |
| | | weighingDateValue.value = editForm.weighingDate |
| | | ? dayjs(editForm.weighingDate).valueOf() |
| | | : Date.now() |
| | | showWeighingDatePicker.value = true |
| | | } |
| | | |
| | | const onWeighingDateConfirm = (e) => { |
| | | editForm.weighingDate = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss') |
| | | showWeighingDatePicker.value = false |
| | | } |
| | | |
| | | const handleEdit = (row) => { |
| | | Object.assign(editForm, row || {}) |
| | | // 以当前毛重/皮重为准计算净重 |
| | | computeNetWeightEdit() |
| | | showEditModal.value = true |
| | | } |
| | | |
| | | const handleEditSubmit = () => { |
| | | if (!hasDispatchEdit.value) return |
| | | if (!editForm.licensePlateNo) return uni.showToast({ title: '请输入车牌号', icon: 'none' }) |
| | | if (!editForm.grossWeight && editForm.grossWeight !== 0) return uni.showToast({ title: '请输入毛重', icon: 'none' }) |
| | | if (!editForm.tareWeight && editForm.tareWeight !== 0) return uni.showToast({ title: '请输入皮重', icon: 'none' }) |
| | | if (!editForm.weighingDate) return uni.showToast({ title: '请选择过磅日期', icon: 'none' }) |
| | | if (!editForm.weighingOperator) return uni.showToast({ title: '请输入过磅员', icon: 'none' }) |
| | | |
| | | uni.showLoading({ title: '保存中...', mask: true }) |
| | | const { stockOutNum, ...payload } = editForm |
| | | editStockOut(payload) |
| | | .then(() => { |
| | | uni.showToast({ title: '编辑成功', icon: 'success' }) |
| | | showEditModal.value = false |
| | | getList() |
| | | }) |
| | | .catch(() => { |
| | | uni.showToast({ title: '编辑失败', icon: 'none' }) |
| | | }) |
| | | .finally(() => { |
| | | uni.hideLoading() |
| | | }) |
| | | } |
| | | |
| | | const goBack = () => uni.navigateBack() |
| | |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | width: 100%; |
| | | text-align: center; |
| | | } |
| | | .btn-delete { |
| | | font-size: 28rpx; |
| | | color: #f56c6c; |
| | | padding: 12rpx 32rpx; |
| | | margin: 0 auto; |
| | | display: inline-flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | .btn-edit { |
| | | font-size: 28rpx; |
| | | color: #2979ff; |
| | | padding: 12rpx 32rpx; |
| | | margin: 0 auto; |
| | | display: inline-flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | .no-data { |
| | | text-align: center; |
| | |
| | | font-size: 28rpx; |
| | | } |
| | | .load-more-wrap { padding: 24rpx 0 40rpx; } |
| | | |
| | | /* 编辑弹窗样式 */ |
| | | .edit-popup { |
| | | background: #fff; |
| | | border-radius: 24rpx 24rpx 0 0; |
| | | padding-bottom: env(safe-area-inset-bottom); |
| | | } |
| | | .popup-header { |
| | | padding: 24rpx; |
| | | border-bottom: 1rpx solid #eee; |
| | | text-align: center; |
| | | } |
| | | .popup-title { |
| | | font-size: 30rpx; |
| | | font-weight: 500; |
| | | color: #333; |
| | | } |
| | | .popup-body { |
| | | padding: 24rpx 24rpx 0; |
| | | max-height: 60vh; |
| | | } |
| | | .popup-footer { |
| | | display: flex; |
| | | gap: 24rpx; |
| | | padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom)); |
| | | border-top: 1rpx solid #eee; |
| | | } |
| | | .btn-cancel, |
| | | .btn-ok { |
| | | flex: 1; |
| | | height: 88rpx; |
| | | border-radius: 999rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-size: 30rpx; |
| | | } |
| | | .btn-cancel { |
| | | background: #f0f0f0; |
| | | color: #666; |
| | | } |
| | | .btn-ok { |
| | | background: #2979ff; |
| | | color: #fff; |
| | | } |
| | | .form-row { |
| | | margin-bottom: 24rpx; |
| | | } |
| | | .form-label { |
| | | display: block; |
| | | font-size: 26rpx; |
| | | color: #666; |
| | | margin-bottom: 12rpx; |
| | | } |
| | | .form-label.required:before { |
| | | content: '*'; |
| | | color: #f56c6c; |
| | | margin-right: 6rpx; |
| | | } |
| | | .selector-trigger { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding: 20rpx 24rpx; |
| | | background: #f5f5f5; |
| | | border-radius: 12rpx; |
| | | } |
| | | .selector-text { |
| | | font-size: 28rpx; |
| | | color: #333; |
| | | } |
| | | .selector-text.placeholder { |
| | | color: #999; |
| | | } |
| | | </style> |
| | |
| | | <text class="value value-num">{{ detail.stockOutNum ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">出库人</text> |
| | | <text class="value">{{ detail.createBy || '-' }}</text> |
| | | <text class="label">采购员</text> |
| | | <text class="value">{{ detail.purchaser || detail.createBy || '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">来源</text> |
| | | <text class="value">{{ getRecordType(detail.recordType) || '-' }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <!-- 出库信息 --> |
| | | <view class="section-card"> |
| | | <view class="section-head"> |
| | | <view class="section-dot"></view> |
| | | <text class="section-title">出库信息</text> |
| | | </view> |
| | | <view class="section-body"> |
| | | <view class="detail-row"> |
| | | <text class="label">车牌号</text> |
| | | <text class="value">{{ detail.licensePlateNo || '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">毛重(吨)</text> |
| | | <text class="value">{{ detail.grossWeight ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">皮重(吨)</text> |
| | | <text class="value">{{ detail.tareWeight ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">净重(吨)</text> |
| | | <text class="value">{{ detail.netWeight ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">过磅日期</text> |
| | | <text class="value">{{ detail.weighingDate || '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="label">过磅员</text> |
| | | <text class="value">{{ detail.weighingOperator || '-' }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | stockOutNum: d.stockOutNum, |
| | | createBy: d.createBy, |
| | | recordType: d.recordType, |
| | | licensePlateNo: d.licensePlateNo, |
| | | grossWeight: d.grossWeight, |
| | | tareWeight: d.tareWeight, |
| | | netWeight: d.netWeight, |
| | | weighingDate: d.weighingDate, |
| | | weighingOperator: d.weighingOperator |
| | | purchaser: d.purchaser |
| | | } |
| | | } |
| | | |
| | |
| | | <template> |
| | | <template> |
| | | <up-popup :show="dialogFormVisible" mode="bottom" :round="10" closeable @close="closeDia"> |
| | | <view class="form-popup"> |
| | | <view class="popup-header"> |
| | |
| | | supplierName: form.value.supplierName || '', |
| | | itemType: '', |
| | | inboundNum: 0, |
| | | inboundDate: '', |
| | | inboundDate: getCurrentDate(), |
| | | taxRate: null, |
| | | taxInclusiveUnitPrice: 0, |
| | | taxInclusiveTotalPrice: 0, |
| | |
| | | |
| | | const openDatePicker = (index) => { |
| | | currentEditIndex.value = index |
| | | const currentDate = productList.value[index]?.inboundDate |
| | | dateValue.value = currentDate ? new Date(currentDate).getTime() : Date.now() |
| | | showDatePicker.value = true |
| | | } |
| | | |
| | |
| | | v-model="form.inboundDate" |
| | | readonly |
| | | placeholder="请选择入库日期" |
| | | @click="showDatePicker = true" |
| | | @click="openInboundDatePicker" |
| | | /> |
| | | <template #right> |
| | | <up-icon name="calendar" @click="showDatePicker = true"></up-icon> |
| | | <up-icon name="calendar" @click="openInboundDatePicker"></up-icon> |
| | | </template> |
| | | </u-form-item> |
| | | </view> |
| | |
| | | showDatePicker.value = false |
| | | } |
| | | |
| | | const openInboundDatePicker = () => { |
| | | dateValue.value = form.value.inboundDate ? new Date(form.value.inboundDate).getTime() : Date.now() |
| | | showDatePicker.value = true |
| | | } |
| | | |
| | | // 计算含税总价 |
| | | const calculateTotalPrice = () => { |
| | | const num = parseFloat(form.value.inboundNum) || 0 |
| | |
| | | </view> |
| | | </view> |
| | | <view class="card-actions"> |
| | | <view class="btn-delete" @click.stop="handleDeleteSingle(item)">删除</view> |
| | | <view |
| | | v-if="isQualifiedRow(item) && hasReceiptEdit" |
| | | class="btn-edit" |
| | | @click.stop="handleEdit(item)" |
| | | > |
| | | 编辑 |
| | | </view> |
| | | <view |
| | | v-if="hasReceiptCancel" |
| | | class="btn-delete" |
| | | @click.stop="handleDeleteSingle(item)" |
| | | > |
| | | 删除 |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | <view class="load-more-wrap" v-if="tableData.length > 0"> |
| | | <u-loadmore :status="loadStatus" @loadmore="loadMore" /> |
| | | </view> |
| | | |
| | | <!-- 编辑弹窗 --> |
| | | <up-popup :show="showEditModal" mode="bottom" @close="showEditModal = false"> |
| | | <view class="edit-popup"> |
| | | <view class="popup-header"> |
| | | <text class="popup-title">编辑入库</text> |
| | | </view> |
| | | <scroll-view scroll-y class="popup-body"> |
| | | <view class="form-row"> |
| | | <text class="form-label required">车牌号</text> |
| | | <up-input v-model="editForm.licensePlateNo" placeholder="请输入车牌号" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label required">毛重(吨)</text> |
| | | <up-input v-model="editForm.grossWeight" type="digit" placeholder="请输入毛重" @blur="computeNetWeightEdit" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label required">皮重(吨)</text> |
| | | <up-input v-model="editForm.tareWeight" type="digit" placeholder="请输入皮重" @blur="computeNetWeightEdit" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label required">净重(吨)</text> |
| | | <up-input v-model="editForm.netWeight" type="digit" placeholder="自动计算" disabled /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label required">过磅日期</text> |
| | | <view class="selector-trigger" @click="openWeighingDatePicker"> |
| | | <text class="selector-text" :class="{ placeholder: !editForm.weighingDate }"> |
| | | {{ editForm.weighingDate || '请选择过磅日期' }} |
| | | </text> |
| | | <up-icon name="calendar" size="16" color="#999" /> |
| | | </view> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label required">过磅员</text> |
| | | <up-input v-model="editForm.weighingOperator" placeholder="请输入过磅员" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">备注</text> |
| | | <up-input v-model="editForm.remark" type="textarea" placeholder="选填" /> |
| | | </view> |
| | | </scroll-view> |
| | | <view class="popup-footer"> |
| | | <view class="btn-cancel" @click="showEditModal = false">取消</view> |
| | | <view class="btn-ok" @click="handleEditSubmit">确认</view> |
| | | </view> |
| | | |
| | | <!-- 过磅日期选择 --> |
| | | <up-popup :show="showWeighingDatePicker" mode="bottom" @close="showWeighingDatePicker = false"> |
| | | <up-datetime-picker |
| | | :show="true" |
| | | v-model="weighingDateValue" |
| | | mode="datetime" |
| | | @confirm="onWeighingDateConfirm" |
| | | @cancel="showWeighingDatePicker = false" |
| | | /> |
| | | </up-popup> |
| | | </view> |
| | | </up-popup> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, toRefs } from 'vue' |
| | | import { computed, ref, reactive, toRefs, watch } from 'vue' |
| | | import { onShow, onReachBottom } from '@dcloudio/uni-app' |
| | | import dayjs from 'dayjs' |
| | | import PageHeader from '@/components/PageHeader.vue' |
| | | import { |
| | | getStockInRecordListPage, |
| | | batchDeleteStockInRecords |
| | | batchDeleteStockInRecords, |
| | | editStockInStock |
| | | } from '@/api/inventoryManagement/stockInRecord.js' |
| | | import { |
| | | findAllQualifiedStockInRecordTypeOptions |
| | | } from '@/api/basicData/enum.js' |
| | | import { checkPermi } from '@/utils/permission' |
| | | |
| | | const stockRecordTypeOptions = ref([]) |
| | | const currentType = () => '0' |
| | |
| | | const tableData = ref([]) |
| | | const total = ref(0) |
| | | const loadStatus = ref('loadmore') // loadmore | loading | nomore | error |
| | | |
| | | // 权限控制 |
| | | const hasReceiptEdit = computed(() => checkPermi(['receipt_edit'])) |
| | | const hasReceiptCancel = computed(() => checkPermi(['receipt_cancel'])) |
| | | |
| | | const page = reactive({ current: 1, size: 4 }) |
| | | const data = reactive({ |
| | |
| | | function getRecordType(recordType) { |
| | | if (recordType == null || recordType === '') return '' |
| | | return stockRecordTypeOptions.value.find(item => item.value === recordType)?.label || '' |
| | | } |
| | | |
| | | function isQualifiedRow(row) { |
| | | return row?.recordType === 0 || row?.recordType === '0' |
| | | } |
| | | |
| | | function fetchRecordTypeOptions() { |
| | |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // ---------------- 编辑入库 ---------------- |
| | | const showEditModal = ref(false) |
| | | const showWeighingDatePicker = ref(false) |
| | | const weighingDateValue = ref(Date.now()) |
| | | |
| | | const editForm = reactive({ |
| | | id: null, |
| | | licensePlateNo: '', |
| | | grossWeight: '', |
| | | tareWeight: '', |
| | | netWeight: '', |
| | | weighingDate: '', |
| | | weighingOperator: '', |
| | | remark: '' |
| | | }) |
| | | |
| | | const computeNetWeightEdit = () => { |
| | | const gross = Number(editForm.grossWeight) |
| | | const tare = Number(editForm.tareWeight) |
| | | if (Number.isFinite(gross) && Number.isFinite(tare)) { |
| | | const net = gross - tare |
| | | const safeNet = Number(net.toFixed(2)) |
| | | editForm.netWeight = safeNet > 0 ? safeNet : 0 |
| | | } |
| | | } |
| | | |
| | | watch( |
| | | () => [editForm.grossWeight, editForm.tareWeight], |
| | | () => { |
| | | if (showEditModal.value) computeNetWeightEdit() |
| | | } |
| | | ) |
| | | |
| | | const openWeighingDatePicker = () => { |
| | | weighingDateValue.value = editForm.weighingDate ? dayjs(editForm.weighingDate).valueOf() : Date.now() |
| | | showWeighingDatePicker.value = true |
| | | } |
| | | |
| | | const onWeighingDateConfirm = (e) => { |
| | | editForm.weighingDate = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss') |
| | | showWeighingDatePicker.value = false |
| | | } |
| | | |
| | | const handleEdit = (row) => { |
| | | Object.assign(editForm, row || {}) |
| | | computeNetWeightEdit() |
| | | showEditModal.value = true |
| | | } |
| | | |
| | | const handleEditSubmit = () => { |
| | | if (!editForm.licensePlateNo) return uni.showToast({ title: '请输入车牌号', icon: 'none' }) |
| | | if (editForm.grossWeight === '' || Number(editForm.grossWeight) < 0) return uni.showToast({ title: '请输入毛重', icon: 'none' }) |
| | | if (editForm.tareWeight === '' || Number(editForm.tareWeight) < 0) return uni.showToast({ title: '请输入皮重', icon: 'none' }) |
| | | if (!editForm.weighingDate) return uni.showToast({ title: '请选择过磅日期', icon: 'none' }) |
| | | if (!editForm.weighingOperator) return uni.showToast({ title: '请输入过磅员', icon: 'none' }) |
| | | |
| | | uni.showLoading({ title: '保存中...', mask: true }) |
| | | editStockInStock({ ...editForm }) |
| | | .then(() => { |
| | | uni.showToast({ title: '编辑成功', icon: 'success' }) |
| | | showEditModal.value = false |
| | | getList() |
| | | }) |
| | | .catch(() => { |
| | | uni.showToast({ title: '编辑失败', icon: 'none' }) |
| | | }) |
| | | .finally(() => { |
| | | uni.hideLoading() |
| | | }) |
| | | } |
| | | |
| | | const goBack = () => uni.navigateBack() |
| | |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .btn-edit { |
| | | font-size: 28rpx; |
| | | color: #2979ff; |
| | | padding: 12rpx 32rpx; |
| | | margin: 0 auto; |
| | | display: inline-flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | .no-data { |
| | | text-align: center; |
| | | padding: 80rpx 0; |
| | |
| | | .load-more-wrap { |
| | | padding: 24rpx 0 40rpx; |
| | | } |
| | | |
| | | /* 编辑弹窗样式 */ |
| | | .edit-popup { |
| | | background: #fff; |
| | | border-radius: 24rpx 24rpx 0 0; |
| | | padding-bottom: env(safe-area-inset-bottom); |
| | | } |
| | | .popup-header { |
| | | padding: 24rpx; |
| | | border-bottom: 1rpx solid #eee; |
| | | text-align: center; |
| | | } |
| | | .popup-title { |
| | | font-size: 30rpx; |
| | | font-weight: 500; |
| | | color: #333; |
| | | } |
| | | .popup-body { |
| | | padding: 24rpx 24rpx 0; |
| | | max-height: 60vh; |
| | | } |
| | | .popup-footer { |
| | | display: flex; |
| | | gap: 24rpx; |
| | | padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom)); |
| | | border-top: 1rpx solid #eee; |
| | | } |
| | | .btn-cancel, |
| | | .btn-ok { |
| | | flex: 1; |
| | | height: 88rpx; |
| | | border-radius: 999rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-size: 30rpx; |
| | | } |
| | | .btn-cancel { |
| | | background: #f0f0f0; |
| | | color: #666; |
| | | } |
| | | .btn-ok { |
| | | background: #2979ff; |
| | | color: #fff; |
| | | } |
| | | .form-row { |
| | | margin-bottom: 24rpx; |
| | | } |
| | | .form-label { |
| | | display: block; |
| | | font-size: 26rpx; |
| | | color: #666; |
| | | margin-bottom: 12rpx; |
| | | } |
| | | .form-label.required:before { |
| | | content: '*'; |
| | | color: #f56c6c; |
| | | margin-right: 6rpx; |
| | | } |
| | | .selector-trigger { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding: 20rpx 24rpx; |
| | | background: #f5f5f5; |
| | | border-radius: 12rpx; |
| | | } |
| | | .selector-text { |
| | | font-size: 28rpx; |
| | | color: #333; |
| | | } |
| | | .selector-text.placeholder { |
| | | color: #999; |
| | | } |
| | | </style> |
| | |
| | | grossWeight: '', |
| | | tareWeight: '', |
| | | netWeight: '', |
| | | weighingDate: '', |
| | | weighingDate: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
| | | weighingOperator: '', |
| | | qualitity: '', |
| | | remark: '' |
| | |
| | | </view> |
| | | |
| | | <view class="form-section"> |
| | | <view class="section-title">出库/过磅信息</view> |
| | | <view class="section-title">出库信息</view> |
| | | <view class="form-row"> |
| | | <text class="form-label">车牌号</text> |
| | | <up-input v-model="form.licensePlateNo" placeholder="请输入车牌号" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">毛重(吨)</text> |
| | | <up-input |
| | | v-model="form.grossWeight" |
| | | type="digit" |
| | | placeholder="请输入毛重" |
| | | /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">皮重(吨)</text> |
| | | <up-input |
| | | v-model="form.tareWeight" |
| | | type="digit" |
| | | placeholder="请输入皮重" |
| | | /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">净重(吨)</text> |
| | | <up-input |
| | | v-model="form.netWeight" |
| | | type="digit" |
| | | disabled |
| | | placeholder="自动计算" |
| | | /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">过磅日期</text> |
| | | <view class="selector-trigger" @click="openWeighingDatePicker"> |
| | | <text class="selector-text" :class="{ placeholder: !form.weighingDate }"> |
| | | {{ form.weighingDate || '请选择过磅日期' }} |
| | | </text> |
| | | <up-icon name="calendar" size="16" color="#999"></up-icon> |
| | | </view> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">过磅员</text> |
| | | <up-input v-model="form.weighingOperator" placeholder="请输入过磅员" /> |
| | | <text class="form-label">出库数量</text> |
| | | <up-input v-model="form.stockOutNum" type="number" :placeholder="'最大' + (form.unLockedQuantity ?? 0)" /> |
| | | </view> |
| | | <view class="form-row"> |
| | | <text class="form-label">备注</text> |
| | |
| | | <view class="bottom-bar"> |
| | | <view class="btn-submit" @click="handleSubmit">出库</view> |
| | | </view> |
| | | |
| | | <!-- 过磅日期选择器 --> |
| | | <up-popup :show="showWeighingDatePicker" mode="bottom" @close="showWeighingDatePicker = false"> |
| | | <up-datetime-picker |
| | | :show="true" |
| | | v-model="weighingDateValue" |
| | | mode="datetime" |
| | | @confirm="onWeighingDateConfirm" |
| | | @cancel="showWeighingDatePicker = false" |
| | | /> |
| | | </up-popup> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, watch, computed } from 'vue' |
| | | import { ref, reactive, computed } from 'vue' |
| | | import { onLoad } from '@dcloudio/uni-app' |
| | | import dayjs from 'dayjs' |
| | | import PageHeader from '@/components/PageHeader.vue' |
| | | import { subtractStockInventory } from '@/api/inventoryManagement/stockInventory.js' |
| | | |
| | |
| | | createTime: '', |
| | | updateTime: '', |
| | | version: undefined, |
| | | // 出库/过磅信息 |
| | | licensePlateNo: '', |
| | | grossWeight: '', |
| | | tareWeight: '', |
| | | netWeight: '', |
| | | weighingDate: '', |
| | | weighingOperator: '', |
| | | // 出库信息 |
| | | stockOutNum: '', |
| | | remark: '' |
| | | }) |
| | | |
| | | const type = ref('0') // 固定合格库存 |
| | | const showWeighingDatePicker = ref(false) |
| | | const weighingDateValue = ref(Date.now()) |
| | | |
| | | onLoad((options) => { |
| | | type.value = '0' |
| | |
| | | } |
| | | }) |
| | | |
| | | // 净重 = 毛重 - 皮重 |
| | | const computeNetWeight = () => { |
| | | const gross = Number(form.grossWeight) |
| | | const tare = Number(form.tareWeight) |
| | | if (!isNaN(gross) && !isNaN(tare)) { |
| | | const net = Number((gross - tare).toFixed(2)) |
| | | form.netWeight = net > 0 ? net : 0 |
| | | } else { |
| | | form.netWeight = '' |
| | | } |
| | | } |
| | | |
| | | watch( |
| | | () => [form.grossWeight, form.tareWeight], |
| | | () => { |
| | | computeNetWeight() |
| | | } |
| | | ) |
| | | |
| | | const openWeighingDatePicker = () => { |
| | | weighingDateValue.value = form.weighingDate |
| | | ? dayjs(form.weighingDate, 'YYYY-MM-DD HH:mm:ss').valueOf() |
| | | : Date.now() |
| | | showWeighingDatePicker.value = true |
| | | } |
| | | |
| | | const onWeighingDateConfirm = (e) => { |
| | | const ts = e?.value ?? weighingDateValue.value |
| | | form.weighingDate = dayjs(ts).format('YYYY-MM-DD HH:mm:ss') |
| | | showWeighingDatePicker.value = false |
| | | } |
| | | |
| | | const handleSubmit = () => { |
| | | if (!form.id) { |
| | | uni.showToast({ title: '记录信息缺失,无法出库', icon: 'none' }) |
| | | return |
| | | } |
| | | const payload = { ...form } |
| | | const outNum = Number(form.stockOutNum) |
| | | const max = Number(form.unLockedQuantity ?? 0) |
| | | if (!outNum || outNum <= 0 || outNum > max) { |
| | | uni.showToast({ title: `请输入 1~${max} 之间的数量`, icon: 'none' }) |
| | | return |
| | | } |
| | | const payload = { |
| | | id: form.id, |
| | | stockOutNum: outNum, |
| | | remark: form.remark |
| | | } |
| | | subtractStockInventory(payload) |
| | | .then(() => { |
| | | uni.showToast({ title: '出库成功', icon: 'success' }) |
| | |
| | | checkType: '', |
| | | checkResult: '', |
| | | checkUserName: userStore?.nickName || '', |
| | | checkTime: '' |
| | | checkTime: dayjs().format('YYYY-MM-DD') |
| | | }) |
| | | |
| | | const inspectItems = ref([]) // qualityInspectItem |