|
|
@@ -0,0 +1,450 @@
|
|
|
+<template>
|
|
|
+ <view class="page">
|
|
|
+ <!-- 顶部标题栏 -->
|
|
|
+ <uni-nav-bar
|
|
|
+ fixed
|
|
|
+ statusBar
|
|
|
+ left-icon="back"
|
|
|
+ title="新建退料单"
|
|
|
+ background-color="#157A2C"
|
|
|
+ color="#fff"
|
|
|
+ @clickLeft="back"
|
|
|
+ />
|
|
|
+
|
|
|
+ <view class="fixed-form">
|
|
|
+ <view class="form-section">
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">退料单编号</text>
|
|
|
+ <uni-easyinput v-model="returnForm.code" disabled />
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">退料单名称</text>
|
|
|
+ <uni-easyinput
|
|
|
+ v-model="returnForm.name"
|
|
|
+ placeholder="请输入领料单名称"
|
|
|
+ />
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">退料单场景</text>
|
|
|
+ <zxz-uni-data-select
|
|
|
+ :localdata="sceneList"
|
|
|
+ v-model="returnForm.scene"
|
|
|
+ dataValue="value"
|
|
|
+ format="{label}"
|
|
|
+ dataKey="label"
|
|
|
+ filterable
|
|
|
+ />
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">退料描述</text>
|
|
|
+ <uni-easyinput
|
|
|
+ v-model="returnForm.remark"
|
|
|
+ placeholder="请输入退料描述"
|
|
|
+ />
|
|
|
+ </view>
|
|
|
+ <view class="btn-add">
|
|
|
+ <button type="primary" size="mini" @click="choosePick">
|
|
|
+ 选择领料单
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 页面主体滚动区域 -->
|
|
|
+ <scroll-view class="material-scroll" scroll-y v-if="returnList.length != 0">
|
|
|
+ <view v-for="(item, idx) in returnList" :key="item.id">
|
|
|
+ <view class="form-section">
|
|
|
+ <view class="form-item">
|
|
|
+ <text
|
|
|
+ style="
|
|
|
+ width: 32%;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+ margin-bottom: 4rpx;
|
|
|
+ "
|
|
|
+ >领料单编号:</text
|
|
|
+ >
|
|
|
+ <text style="font-size: 28rpx; color: #666">{{ item.code }}</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="form-item">
|
|
|
+ <text
|
|
|
+ style="
|
|
|
+ width: 32%;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+ margin-bottom: 4rpx;
|
|
|
+ "
|
|
|
+ >领料单创建时间:</text
|
|
|
+ >
|
|
|
+ <text style="font-size: 28rpx; color: #666">{{
|
|
|
+ item.createTime
|
|
|
+ }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 物料列表 -->
|
|
|
+ <view class="material-list">
|
|
|
+ <view
|
|
|
+ class="material-card"
|
|
|
+ v-for="(mate, index) in item.pickOutInList"
|
|
|
+ :key="mate.id"
|
|
|
+ >
|
|
|
+ <!-- 删除按钮 -->
|
|
|
+ <view class="delete-btn" @click.stop="removeItem(idx, index)">
|
|
|
+ <uni-icons
|
|
|
+ custom-prefix="iconfont"
|
|
|
+ type="icon-shanchu"
|
|
|
+ size="28"
|
|
|
+ color="#fa3534"
|
|
|
+ />
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 卡片内容 -->
|
|
|
+ <view class="card-content">
|
|
|
+ <view class="card-row">
|
|
|
+ <text class="label">编码:</text>
|
|
|
+ <text class="value">{{ mate.code }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="card-row">
|
|
|
+ <text class="label">名称:</text>
|
|
|
+ <text class="value">{{ mate.name }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="card-row">
|
|
|
+ <text class="label">类型:</text>
|
|
|
+ <text class="value">{{
|
|
|
+ typeName[Number(mate.rootCategoryLevelId)]
|
|
|
+ }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="card-row">
|
|
|
+ <text class="label">型号:</text>
|
|
|
+ <text class="value">{{ mate.modelType }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="card-row">
|
|
|
+ <text class="label">规格:</text>
|
|
|
+ <text class="value">{{ mate.specification }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="card-row">
|
|
|
+ <text class="label">型号:</text>
|
|
|
+ <text class="value">{{ mate.modelType }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="card-row" v-if="clientEnvironmentId == 3">
|
|
|
+ <text class="label">刻码:</text>
|
|
|
+ <text class="value">{{ mate.extInfo.engrave }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="card-row" v-if="clientEnvironmentId == 3">
|
|
|
+ <text class="label">物料代号:</text>
|
|
|
+ <text class="value">{{ mate.extInfo.materielCode }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="card-row">
|
|
|
+ <text class="label">关联工单编码:</text>
|
|
|
+ <text class="value">{{ mate.workOrderCode }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="card-row">
|
|
|
+ <text class="label">工序:</text>
|
|
|
+ <text class="value">{{ mate.taskName }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="card-row">
|
|
|
+ <text class="label">退还数量:</text>
|
|
|
+ <text class="value">{{ mate.quantity }}{{ mate.unit }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+
|
|
|
+ <!-- 底部操作按钮 -->
|
|
|
+ <view class="footer-btn">
|
|
|
+ <button @click="close" size="mini">取消</button>
|
|
|
+ <button type="primary" @click="save" size="mini">提交</button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getCode } from "@/api/pda/selfBuiltPickOrder.js";
|
|
|
+import { typeName } from "@/pages/pda/feeding/common.js";
|
|
|
+import { getByCode } from "@/api/pda/common.js";
|
|
|
+import { refundable, save } from "@/api/pda/material.js";
|
|
|
+
|
|
|
+export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ returnForm: {
|
|
|
+ code: "",
|
|
|
+ name: "",
|
|
|
+ scene: "",
|
|
|
+ remark: "",
|
|
|
+ type: 1,
|
|
|
+ },
|
|
|
+ returnList: [],
|
|
|
+ selectionData: [],
|
|
|
+ typeName,
|
|
|
+ sceneList: [],
|
|
|
+ clientEnvironmentId:
|
|
|
+ uni.getStorageSync("userInfo") &&
|
|
|
+ uni.getStorageSync("userInfo").clientEnvironmentId,
|
|
|
+ };
|
|
|
+ },
|
|
|
+
|
|
|
+ onLoad() {
|
|
|
+ this.getByCodeFn();
|
|
|
+ this.getOrderCode();
|
|
|
+ },
|
|
|
+
|
|
|
+ onShow() {
|
|
|
+ uni.$off("setSelectList");
|
|
|
+
|
|
|
+ uni.$on("setSelectList", (selectList, id) => {
|
|
|
+ let ids = [];
|
|
|
+ selectList.forEach((it) => {
|
|
|
+ ids.push(it.id);
|
|
|
+ });
|
|
|
+
|
|
|
+ refundable(ids).then((res) => {
|
|
|
+ this.returnList = res;
|
|
|
+ console.log(res, "返回的数据");
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ methods: {
|
|
|
+ async getByCodeFn() {
|
|
|
+ await getByCode("returnScenario").then((res) => {
|
|
|
+ let _arr = [];
|
|
|
+ res.map((item) => {
|
|
|
+ const key = Object.keys(item)[0];
|
|
|
+ const value = item[key];
|
|
|
+ _arr.push({ label: value, value: key });
|
|
|
+ });
|
|
|
+
|
|
|
+ this.sceneList = _arr;
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ async getOrderCode() {
|
|
|
+ this.returnForm.code = await getCode("pick_order_code");
|
|
|
+ },
|
|
|
+
|
|
|
+ deepCopy(obj, hash = new WeakMap()) {
|
|
|
+ if (obj === null) return null;
|
|
|
+ if (obj instanceof Date) return new Date(obj);
|
|
|
+ if (obj instanceof RegExp) return new RegExp(obj);
|
|
|
+ if (typeof obj !== "object" && typeof obj !== "function") return obj;
|
|
|
+ if (hash.has(obj)) return hash.get(obj);
|
|
|
+
|
|
|
+ const result = Array.isArray(obj) ? [] : {};
|
|
|
+ hash.set(obj, result);
|
|
|
+
|
|
|
+ return Object.keys(obj).reduce((acc, key) => {
|
|
|
+ acc[key] = this.deepCopy(obj[key], hash);
|
|
|
+ return acc;
|
|
|
+ }, result);
|
|
|
+ },
|
|
|
+
|
|
|
+ checkItem(row) {
|
|
|
+ row.checked = !row.checked;
|
|
|
+ },
|
|
|
+
|
|
|
+ limitNum(row) {
|
|
|
+ if (row.demandQuantity > row.measureQuantity) {
|
|
|
+ row.demandQuantity = row.measureQuantity;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ removeItem(idx, index) {
|
|
|
+ this.returnList[idx].pickOutInList.splice(index, 1);
|
|
|
+ },
|
|
|
+
|
|
|
+ choosePick() {
|
|
|
+ const storageKey = Date.now() + "";
|
|
|
+ uni.setStorageSync(storageKey, this.returnList || []);
|
|
|
+ uni.navigateTo({
|
|
|
+ url: `/pages/pda/material_return/components/choosePickOrder?storageKey=${storageKey}`,
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ save() {
|
|
|
+ if (!this.returnForm.name) {
|
|
|
+ return uni.showToast({ title: "请输入退料单名称", icon: "none" });
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.returnList.length == 0) {
|
|
|
+ return uni.showToast({ title: "请选择领料单", icon: "none" });
|
|
|
+ }
|
|
|
+
|
|
|
+ let param = {
|
|
|
+ ...this.returnForm,
|
|
|
+ pickOrderList: this.returnList,
|
|
|
+ };
|
|
|
+
|
|
|
+ save(param).then((res) => {
|
|
|
+ uni.showToast({ title: "提交成功" });
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.navigateBack();
|
|
|
+ }, 500);
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ close(refresh) {
|
|
|
+ uni.$emit("closePick", refresh);
|
|
|
+ uni.navigateBack();
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.page {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ height: 100vh;
|
|
|
+ background-color: #f7f7f7;
|
|
|
+}
|
|
|
+
|
|
|
+.scroll-container {
|
|
|
+ flex: 1;
|
|
|
+ padding: 10rpx 16rpx;
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
+
|
|
|
+/* 固定表单区域 */
|
|
|
+.fixed-form {
|
|
|
+ position: sticky;
|
|
|
+ top: var(--status-bar-height, 0) + 88rpx; // 兼容有状态栏高度
|
|
|
+ z-index: 10;
|
|
|
+ background: #f7f7f7;
|
|
|
+ padding: 0 16rpx;
|
|
|
+}
|
|
|
+
|
|
|
+/* 可滚动物料列表 */
|
|
|
+.material-scroll {
|
|
|
+ flex: 1;
|
|
|
+ overflow-y: auto;
|
|
|
+ padding: 10rpx 16rpx;
|
|
|
+ margin-top: 16rpx;
|
|
|
+ padding-bottom: 115rpx;
|
|
|
+}
|
|
|
+
|
|
|
+/* 顶部表单 */
|
|
|
+.form-section {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ padding: 16rpx;
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+
|
|
|
+ .form-item {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 12rpx;
|
|
|
+
|
|
|
+ .label {
|
|
|
+ width: 22%;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+ margin-bottom: 4rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ uni-easyinput {
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn-add {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 物料列表卡片 */
|
|
|
+.material-list {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 16rpx;
|
|
|
+
|
|
|
+ .material-card {
|
|
|
+ position: relative;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ padding: 16rpx;
|
|
|
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
|
|
+ transition: background 0.2s;
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ background: #f5f5f5;
|
|
|
+ }
|
|
|
+
|
|
|
+ .delete-btn {
|
|
|
+ position: absolute;
|
|
|
+ top: 8rpx;
|
|
|
+ right: 8rpx;
|
|
|
+ width: 40rpx;
|
|
|
+ height: 40rpx;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ z-index: 10;
|
|
|
+ background: rgba(255, 255, 255, 0.8);
|
|
|
+ border-radius: 50%;
|
|
|
+ box-shadow: 0 1rpx 3rpx rgba(0, 0, 0, 0.2);
|
|
|
+ }
|
|
|
+
|
|
|
+ .card-content {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 8rpx;
|
|
|
+
|
|
|
+ .card-row {
|
|
|
+ display: flex;
|
|
|
+ // flex-wrap: wrap;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .label {
|
|
|
+ width: 22%;
|
|
|
+ flex-shrink: 0;
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #666;
|
|
|
+ margin-bottom: 4rpx;
|
|
|
+ }
|
|
|
+ .input-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8rpx;
|
|
|
+
|
|
|
+ uni-easyinput {
|
|
|
+ flex: 1; // 占满剩余空间
|
|
|
+ min-width: 0; // ✅允许收缩,防止换行
|
|
|
+ }
|
|
|
+
|
|
|
+ .unit {
|
|
|
+ flex-shrink: 0; // 单位宽度固定
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 底部固定按钮 */
|
|
|
+.footer-btn {
|
|
|
+ position: fixed;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ background: #fff;
|
|
|
+ padding: 16rpx;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ box-shadow: 0 -2rpx 6rpx rgba(0, 0, 0, 0.05);
|
|
|
+ z-index: 20;
|
|
|
+}
|
|
|
+
|
|
|
+/deep/ .uni-easyinput__content-input {
|
|
|
+ padding-left: 0;
|
|
|
+}
|
|
|
+</style>
|