周宾
10 小时以前 5392dc649209ff372ec276aa6cbf86b16b12a375
天津双奇点-仓储物流板块开发
已添加2个文件
已修改11个文件
1119 ■■■■■ 文件已修改
src/api/inventoryManagement/receiptManagement.js 95 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/config.js 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/manifest.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages.json 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/components/GoodsDetailPopup.vue 290 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/index.vue 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/inventoryManagement/dispatchLog/index.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/inventoryManagement/issueManagement/edit.vue 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/inventoryManagement/issueManagement/index.vue 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/inventoryManagement/receiptManagement/edit.vue 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/inventoryManagement/receiptManagement/index.vue 99 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/inventoryManagement/receiptManagement/procurement-edit.vue 274 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/inventoryManagement/stockManagement/index.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/inventoryManagement/receiptManagement.js
@@ -1,37 +1,92 @@
// å·¡æ£€ä¸Šä¼ 
import request from '@/utils/request'
import request from "@/utils/request";
// é‡‡è´­å…¥åº“列表
export function listPage(query) {
    return request({
        url: '/stockin/listPage',
        method: 'get',
        params: query
    })
  return request({
    url: "/stockin/listPage",
    method: "get",
    params: query,
  });
}
//自定义入库列表
export function listPageByCustom(query) {
    return request({
        url: '/stockin/listPageByCustom',
        method: 'get',
        params: query
    })
  return request({
    url: "/stockin/listPageByCustom",
    method: "get",
    params: query,
  });
}
//新增自定义入库
// èŽ·å–ç”¨æˆ·ä¿¡æ¯
export function addCustom(query) {
  return request({
    url: '/stockin/addCustom',
    method: 'post',
    data: query
  })
    url: "/stockin/addCustom",
    method: "post",
    data: query,
  });
}
// åˆ é™¤è‡ªå®šä¹‰å…¥åº“
 export function deleteCustom(query) {
export function deleteCustom(query) {
  return request({
    url: '/stockin/deleteCustom',
    method: 'delete',
    data: query
  })
    url: "/stockin/deleteCustom",
    method: "delete",
    data: query,
  });
}
//删除采购入库
export function stockinDel(query) {
  return request({
    url: "/stockin/del",
    method: "post",
    data: query,
  });
}
export function detailManagementByCustom(query) {
  return request({
    url: "/stockin/detailManagementByCustom",
    method: "get",
    params: query,
  });
}
// é‡‡è´­å…¥åº“-详情
export function stockinDetail(query) {
  return request({
    url: "/stockin/detail",
    method: "get",
    params: query,
  });
}
export function ledgerListPage(query) {
  return request({
    url: "/purchase/ledger/listPage",
    method: "get",
    params: query,
  });
}
export function productlist(query) {
  return request({
    url: "/stockin/productlist",
    method: "get",
    params: query,
  });
}
export function stockinAdd(query) {
  return request({
    url: "/stockin/add",
    method: "post",
    data: query,
  });
}
export function stockinUpdate(query) {
  return request({
    url: "/stockin/update",
    method: "post",
    data: query,
  });
}
src/config.js
@@ -2,7 +2,9 @@
const config = {
  //  baseUrl: 'https://vue.ruoyi.vip/prod-api',
  // baseUrl: 'http://localhost/prod-api',
    baseUrl: 'http://192.168.1.147:7003', // å¤©æ´¥åŒå¥‡ç‚¹
    // baseUrl: 'http://192.168.1.147:7003', // å¤©æ´¥åŒå¥‡ç‚¹
    baseUrl: 'http://114.132.189.42:9042', // å¤©æ´¥åŒå¥‡ç‚¹
  imgUrl: 'http://114.132.189.42:9044',
  // baseUrl: 'http://114.132.189.42:9066', // å®å¤æ¶¦æ³°
  // baseUrl: 'http://114.132.189.42:9068', // æ–°ç–†æµ·å·å¼€å¿ƒ
  // baseUrl: 'http://192.168.1.147:9036',
src/manifest.json
@@ -1,6 +1,6 @@
{
    "name" : "润泰生物",
    "appid" : "__UNI__115F1B1",
    "name" : "双奇点",
    "appid" : "__UNI__E1C100D",
    "description" : "",
    "versionName" : "1.0.0",
    "versionCode" : "100",
src/pages.json
@@ -631,6 +631,13 @@
                    }
                },
        {
                    "path": "receiptManagement/procurement-edit",
                    "style": {
                        "navigationBarTitleText": "采购入库",
            "navigationStyle": "custom"
                    }
                },
        {
                    "path": "issueManagement/index",
                    "style": {
                        "navigationBarTitleText": "出库管理",
src/pages/components/GoodsDetailPopup.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,290 @@
<template>
    <uni-popup
        ref="popupRef"
        type="center"
        :round="20"
        @close="handleClose"
        @open="handleOpen"
    >
        <view class="dispatch-modal">
            <!-- å¤´éƒ¨ -->
            <view class="modal-header">
                <text class="modal-title">产品详情</text>
                <view class="close-btn" @click="handleClose">
                    <up-icon name="close" size="20" color="#999"></up-icon>
                </view>
            </view>
            <!-- è¡¨å•内容 -->
            <view class="modal-content">
                <up-form
                    :model="detailData"
                    ref="formRef"
                    :rules="rules"
                    labelWidth="120"
                >
                    <!-- é¡¹ç›®åŸºæœ¬ä¿¡æ¯ -->
                    <view class="form-section">
                        <text class="section-title">产品信息</text>
                        <up-form-item v-if="detailType == 2" label="产品图片" prop="url">
                            <image :src="baseUrl+detailData.url" class="detail-img"></image>
                        </up-form-item>
                        <up-form-item label="产品名称" prop="productCategory">
                            <up-input
                                v-model="detailData.productCategory"
                                disabled
                                placeholder=""
                            />
                        </up-form-item>
                        <up-form-item label="产品高度" prop="specificationModel">
                            <up-input
                                v-model="detailData.specificationModelUnit"
                                disabled
                                placeholder=""
                            />
                        </up-form-item>
                        <up-form-item label="单价(元)/ä»¶" prop="taxInclusiveUnitPrice">
                            <up-input
                                v-model="detailData.taxInclusiveUnitPrice"
                                disabled
                                placeholder=""
                            />
                        </up-form-item>
                        <up-form-item label="单价(美元)/ä»¶" prop="dollarPrice">
                            <up-input
                                v-model="detailData.dollarPrice"
                                disabled
                                placeholder=""
                            />
                        </up-form-item>
                    </view>
                    <!-- æ•°é‡ä¿¡æ¯ -->
                    <view class="form-section">
                        <text class="section-title">数量信息</text>
                        <up-form-item label="入库数量/ä»¶" prop="inboundNum">
                            <up-input
                                v-model="detailData.inboundNum"
                                disabled
                                placeholder=""
                            />
                        </up-form-item>
                        <!-- <up-form-item label="出库数量/ä»¶" prop="totalInboundNum">
                            <up-input
                                v-model="detailData.totalInboundNum"
                                disabled
                                placeholder=""
                            />
                        </up-form-item>
                        <up-form-item label="库存数量/ä»¶" prop="inboundNum0" required>
                             <up-input
                                v-model="detailData.inboundNum0"
                                disabled
                                placeholder=""
                            />
                        </up-form-item> -->
                        <up-form-item label="每件数量/支" prop="boxNum" required>
                             <up-input
                                v-model="detailData.boxNum"
                                disabled
                                placeholder=""
                            />
                        </up-form-item>
                    </view>
                    <!-- å…¶ä»–信息 -->
                    <view class="form-section">
                        <text class="section-title">其他信息</text>
                        <up-form-item label="纸箱规格" prop="cartonSpecifications">
                            <up-input
                                v-model="detailData.cartonSpecifications"
                                disabled
                                placeholder=""
                            />
                        </up-form-item>
                        <up-form-item label="入库人" prop="createBy">
                            <up-input
                                v-model="detailData.createBy"
                                disabled
                                placeholder=""
                            />
                        </up-form-item>
                        <up-form-item label="入库时间" prop="inboundDate">
                            <up-input
                                v-model="detailData.inboundDate"
                                disabled
                                placeholder=""
                            />
                        </up-form-item>
                    </view>
                </up-form>
            </view>
        </view>
    </uni-popup>
</template>
<script setup>
import { ref, reactive } from 'vue';
import config from '@/config'
const baseUrl = config.baseUrl
const emit = defineEmits(['confirm']);
// å¼¹çª—显示状态
const popupRef = ref();
// è¡¨å•数据
const detailData = reactive({});
// è¡¨å•验证规则
const rules = reactive({});
const detailType = ref(0)
// æ‰“开弹窗
const open = async (rowData) => {
    try {
        // å¡«å……表单数据
        Object.assign(detailData, {
            ...rowData,
            specificationModelUnit: rowData.specificationModel + rowData.unit,
            totalInboundNum: rowData.totalInboundNum||0
        });
        popupRef.value.open()
        detailType.value = rowData.type
    } catch (error) {
        console.log(error)
        uni.showToast({
            title: '加载用户列表失败',
            icon: 'error'
        });
    }
};
// å¼¹çª—打开事件
const handleOpen = () => {
    // å¼¹çª—打开时的处理
};
// å…³é—­å¼¹çª—
const handleClose = () => {
    popupRef.value.close()
    // é‡ç½®è¡¨å•
    for (const key in detailData) {
        detailData[key] = undefined;
    }
};
// æš´éœ²æ–¹æ³•
defineExpose({
    open
});
</script>
<style scoped lang="scss">
.dispatch-modal {
    background: #ffffff;
    border-radius: 20px;
    max-height: 80vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    padding-bottom: 20rpx;
}
.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px 20px 0 20px;
    border-bottom: 1px solid #f0f0f0;
    padding-bottom: 16px;
    margin-bottom: 20px;
}
.modal-title {
    font-size: 18px;
    font-weight: 600;
    color: #333;
}
.close-btn {
    padding: 4px;
    &:active {
        opacity: 0.7;
    }
}
.modal-content {
    flex: 1;
    padding: 0 20px;
    overflow-y: auto;
    .datetime-picker-value{
        font-size: 14px;
        border: 1px solid #e5e5e5;
        box-sizing: border-box;
        border-radius: 4px;
        padding: 0 5px;
        padding-left: 10px;
        position: relative;
        display: flex;
        -webkit-user-select: none;
        -moz-user-select: none;
        user-select: none;
        flex-direction: row;
        align-items: center;
        width: 100%;
        flex: 1;
        height: 35px;
    }
}
.form-section {
    margin-bottom: 24px;
}
.section-title {
    display: block;
    font-size: 16px;
    font-weight: 600;
    color: #333;
    margin-bottom: 16px;
    padding-left: 8px;
    border-left: 3px solid #2979ff;
}
.modal-footer {
    display: flex;
    gap: 12px;
    padding: 20px;
    border-top: 1px solid #f0f0f0;
    background: #fafafa;
}
.detail-img {
    width: 200rpx;
    height: 200rpx;
    border-radius: 8rpx;
    background-color: #f5f5f5;
}
// uView ç»„件样式调整
:deep(.up-form-item) {
    margin-bottom: 20px;
}
:deep(.up-input) {
    background: #f8f9fa;
    border-radius: 8px;
}
:deep(.up-input--disabled) {
    background: #f0f0f0;
    color: #999;
}
:deep(.up-number-box) {
    background: #f8f9fa;
    border-radius: 8px;
}
</style>
src/pages/index.vue
@@ -209,14 +209,17 @@
                </up-grid>
            </view>
        </view>
        <GoodsDetailPopup ref="refGoodsDetailPopup"></GoodsDetailPopup>
    </view>
</template>
<script setup>
import {ref, onMounted, nextTick, reactive} from 'vue';
import {userLoginFacotryList} from "@/api/login";
import { stockinDetail, detailManagementByCustom } from '@/api/inventoryManagement/receiptManagement'
import modal from "@/plugins/modal";
import useUserStore from "@/store/modules/user";
import GoodsDetailPopup from './components/GoodsDetailPopup.vue';
const userStore = useUserStore()
const factoryId = ref('');
@@ -259,6 +262,10 @@
    {
        icon: '/static/images/icon/huikuandengji@2x.png',
        label: '库存管理',
    },
    {
        icon: '/static/images/icon/huikuandengji@2x.png',
        label: '产品扫码',
    }
]);
@@ -558,6 +565,9 @@
                url: '/pages/inventoryManagement/stockManagement/index'
            });
            break
        case '产品扫码':
            scanQRCode()
            break
        default:
            uni.showToast({
                title: `点击了${item.label}`,
@@ -612,6 +622,73 @@
    });
}
//开始扫码
const scanQRCode = ()=>{
    uni.scanCode({
        onlyFromCamera:true,
        scanType:['barCode','qrCode'],
        success(res) {
            searchDetail(res.result||'')
        },
        fail(res) {
            uni.showToast({
                title: res.errMsg||'扫码失败',
                icon: 'none',
                duration: 1500
            })
        }
    })
}
//谈框相关
const refGoodsDetailPopup = ref(null)
//查看详情
const searchDetail = (barcode)=>{
    if(!barcode||barcode.indexOf(',')==-1){
        uni.showToast({
            title:"请扫描正确的二维码",
            icon: 'none',
            duration: 1500
        })
        return
    }
    let barcodeList = barcode.split(",")
    let barcodeId = barcodeList[0]
    let type = barcodeList[1]
    let detailApi = null
    if(type==1){
        detailApi = stockinDetail
    }else if(type==2){
        detailApi = detailManagementByCustom
    }
    if(!detailApi){
        uni.showToast({
            title:"请扫描正确的二维码",
            icon: 'none',
            duration: 1500
        })
        return
    }
    detailApi({id:barcodeId}).then((resp) => {
        if(resp.code!=200||!resp.data)return
        // barcodeDetail.value = resp.data
        refGoodsDetailPopup.value.open({
            type: type,
            ...resp.data
        })
    }).catch(() => {
        uni.showToast({
            title: "获取数据失败",
            icon: 'none',
            duration: 1500
        });
    })
}
// å®šä¹‰æ–¹æ³•
const click = (name) => {
    if (uToastRef.value) {
src/pages/inventoryManagement/dispatchLog/index.vue
@@ -8,7 +8,43 @@
        <view v-if="contentList?.length !== 0" class="content">
            <view v-if="tabCurrent === 0">
                <block v-for="item in contentList" :key="item.id">
                    <view class="item-box item-box0"></view>
                    <view class="item-box item-box0">
                        <view class="item">
                            <view class="label">出库日期</view>
                            <view class="value">{{ item.createTime }}</view>
                        </view>
                        <view class="item">
                            <view class="label">产品名称</view>
                            <view class="value">{{ item.productCategory }}</view>
                        </view>
                        <view class="item">
                            <view class="label">产品高度</view>
                            <view class="value">{{ item.specificationModel }}{{ item.unit }}</view>
                        </view>
                        <view class="item">
                            <view class="label">出库数量/ä»¶</view>
                            <view class="value">{{ item.inboundNum }}</view>
                        </view>
                        <view class="item">
                            <view class="label">每件数量/支</view>
                            <view class="value">{{ item.boxNum }}</view>
                        </view>
                        <view class="item">
                            <view class="label">单价(元)/支</view>
                            <view class="value">{{ item.taxInclusiveUnitPrice }}</view>
                        </view>
                        <view class="item">
                            <view class="label">纸箱规格</view>
                            <view class="value">{{ item.cartonSpecifications }}cm</view>
                        </view>
                        <view class="item">
                            <view class="label">出库人</view>
                            <view class="value">{{ item.createBy }}</view>
                        </view>
                        <view class="item" style="justify-content: flex-end;">
                            <button class="mini-btn" type="warn" size="mini" style="margin-left: 0;margin-right: 0;" @click="deleteGoods(item)">删除</button>
                        </view>
                    </view>
                </block>
                <uni-load-more :status="loadMoreStatus"></uni-load-more>
            </view>
@@ -130,7 +166,7 @@
                uni.showLoading({
                    title: '删除中...'
                })
                let params = [goods.id]
                let params = {ids:[goods.id]}
                stockmanagementDel(params).then(res => {
                    uni.hideLoading()
                    reloadPage()
src/pages/inventoryManagement/issueManagement/edit.vue
@@ -9,14 +9,16 @@
                        <uni-easyinput v-model="productCategory" placeholder="" disabled />
                    </uni-forms-item>
                    <uni-forms-item label="出库数量/ä»¶" required>
                        <uni-number-box v-model="goods.quantity" :min="0"></uni-number-box>
                        <uni-number-box v-model="goods.quantity" :min="0" :max="inboundNum0"></uni-number-box>
                    </uni-forms-item>
                    <uni-forms-item label="出库日期" required>
                        <uni-datetime-picker type="date" :clear-icon="false" v-model="goods.time" />
                    </uni-forms-item>
                    <uni-forms-item label="出库人" required>
                        <picker :range="userList" @change="swichUser" range-key="nickName">
                            <text>{{ userName||'请选择' }}</text>
                            <view  style="border: 1px solid #f5f5f5;border-radius: 4rpx;padding: 20rpx;">
                                <text>{{ userName||'请选择' }}</text>
                            </view>
                        </picker>
                    </uni-forms-item>
                </uni-forms>
@@ -38,6 +40,7 @@
const pageTitle = ref('领用产品')
const userList = ref([])
const userName = ref('')
const inboundNum0 = ref(0)
const goods = ref({
    id: 0,
    quantity: 0,
@@ -52,6 +55,30 @@
    uni.navigateBack()
}
const submitForm = async () => {
    if(!goods.value.quantity){
        uni.showToast({
            title:'请添加出库数量',
            icon: 'none',
            duration: 1500
        })
        return
    }
    if(!goods.value.time){
        uni.showToast({
            title:'请选择出库日期',
            icon: 'none',
            duration: 1500
        })
        return
    }
    if(!goods.value.userId){
        uni.showToast({
            title:'请选择出库人',
            icon: 'none',
            duration: 1500
        })
        return
    }
    let res = await stockout(goods.value)
    if (res.code !== 200) {
        uni.showToast({
@@ -83,6 +110,8 @@
    let _goods = JSON.parse(props.goods)
    goods.value.id = _goods.id
    productCategory.value = _goods.productCategory
    inboundNum0.value = _goods.inboundNum0
    goods.value.type = _goods.purchaseContractNumber?1:3
    initContacts()
})
</script>
@@ -99,7 +128,7 @@
    box-sizing: border-box;
    margin-bottom: 20rpx;
    padding: 20rpx;
    background-color: #f5f5f5;
    border-radius: 20rpx;
}
src/pages/inventoryManagement/issueManagement/index.vue
@@ -7,7 +7,52 @@
        <view v-if="contentList?.length !== 0" class="content">
            <view v-if="tabCurrent === 0">
                <block v-for="item in contentList" :key="item.id">
                    <view class="item-box item-box0"></view>
                    <view class="item-box item-box0">
                        <view class="item">
                            <view class="label">入库时间</view>
                            <view class="value">{{ item.inboundDate }}</view>
                        </view>
                        <view class="item">
                            <view class="label">产品名称</view>
                            <view class="value">{{ item.productCategory }}</view>
                        </view>
                        <view class="item">
                            <view class="label">产品高度</view>
                            <view class="value">{{ item.specificationModel }}{{ item.unit }}</view>
                        </view>
                        <view class="item">
                            <view class="label">入库数量/ä»¶</view>
                            <view class="value">{{ item.inboundNum }}</view>
                        </view>
                        <view class="item">
                            <view class="label">库存数量/ä»¶</view>
                            <view class="value">{{ item.inboundNum0 }}</view>
                        </view>
                        <view class="item">
                            <view class="label">每件数量/支</view>
                            <view class="value">{{ item.boxNum }}</view>
                        </view>
                        <view class="item">
                            <view class="label">单价(元)/ä»¶</view>
                            <view class="value">{{ item.taxInclusiveUnitPrice }}</view>
                        </view>
                        <view class="item">
                            <view class="label">单价(美元)/ä»¶</view>
                            <view class="value">{{ item.dollarPrice }}</view>
                        </view>
                        <view class="item">
                            <view class="label">纸箱规格</view>
                            <view class="value">{{ item.cartonSpecifications }}cm</view>
                        </view>
                        <view class="item">
                            <view class="label">入库人</view>
                            <view class="value">{{ item.createBy }}</view>
                        </view>
                        <view class="item" style="justify-content: flex-end;">
                            <button class="mini-btn" type="primary" size="mini" style="margin-left: 0;margin-right: 0;"
                                @click="openForm(item, 'edit')">领用</button>
                        </view>
                    </view>
                </block>
                <uni-load-more :status="loadMoreStatus"></uni-load-more>
            </view>
@@ -45,10 +90,14 @@
                            <view class="value">{{ item.boxNum }}</view>
                        </view>
                        <view class="item">
                            <view class="label">单价(元)/支</view>
                            <view class="label">单价(元)/ä»¶</view>
                            <view class="value">{{ item.taxInclusiveUnitPrice }}</view>
                        </view>
                        <view class="item">
                            <view class="label">单价(美元)/ä»¶</view>
                            <view class="value">{{ item.dollarPrice }}</view>
                        </view>
                        <view class="item">
                            <view class="label">纸箱规格</view>
                            <view class="value">{{ item.cartonSpecifications }}cm</view>
                        </view>
src/pages/inventoryManagement/receiptManagement/edit.vue
@@ -2,15 +2,18 @@
    <PageHeader :title="pageTitle" @back="goBack" />
    <view class="account-detail">
        <view class="box">
            <view v-if="type == 'add'">
            <view v-if="type == 'add'" style="margin-bottom: 20rpx;">
                <button class="mini-btn" type="primary" size="mini" style="margin-left: 0;margin-right: 0;"
                    @click="addItem">新增</button>
            </view>
            <view v-for="(item, index) in goodsList" class="form-box">
                <button v-if="type == 'add'" class="mini-btn del-btn" type="warn" size="mini" style="margin-left: 0;margin-right: 0;"
                    @click="delItem(index)">删除</button>
                <uni-forms :key="index" label-position="top" label-width="400rpx">
                    <uni-forms-item label="产品图片" required>
                        <view class="add-img">
                            <image v-if="item.url" class="img" :src="baseUrl + item.url" mode="aspectFill" />
                            <image v-if="item.url" class="img" :src="baseUrl + item.url" mode="aspectFill"
                                @click="addImg(index)" />
                            <uni-icons v-else type="camera-filled" size="56" style="color: #8a8a8a"
                                @click="addImg(index)"></uni-icons>
                        </view>
@@ -33,8 +36,11 @@
                    <uni-forms-item label="每件数量/支" required>
                        <uni-number-box v-model="item.boxNum" :min="0"></uni-number-box>
                    </uni-forms-item>
                    <uni-forms-item label="单价(元)/支" required>
                    <uni-forms-item label="单价(元)/ä»¶" required>
                        <uni-number-box v-model="item.taxInclusiveUnitPrice" :min="0" :step="0.01"></uni-number-box>
                    </uni-forms-item>
                    <uni-forms-item label="单价(美元)/ä»¶" required>
                        <uni-number-box v-model="item.dollarPrice" :min="0" :step="0.01"></uni-number-box>
                    </uni-forms-item>
                    <uni-forms-item label="入库日期" required>
                        <uni-datetime-picker type="date" :clear-icon="false" v-model="item.inboundDate" />
@@ -55,7 +61,7 @@
import { getToken } from "@/utils/auth";
import { addCustom } from '@/api/inventoryManagement/receiptManagement.js'
import config from '@/config'
const baseUrl = config.baseUrl
const baseUrl = config.imgUrl
const pageTitle = ref('新增自定义入库')
const goodsList = ref([])
const type = ref('add')
@@ -73,6 +79,7 @@
    taxExclusiveTotalPrice: 0,
    taxInclusiveTotalPrice: 0,
    taxInclusiveUnitPrice: 0,
    dollarPrice: 0,
    taxRate: 0,
    unit: "",
    url: "",
@@ -81,7 +88,64 @@
const goBack = () => {
    uni.navigateBack()
}
const showToast = (msg)=>{
    uni.showToast({
        title: msg,
        icon: 'none',
        duration: 1500
    })
}
const submitForm = async() => {
    if (!goodsList.value.length) {
      showToast('请至少添加一条产品数据')
      return
    }
    // éªŒè¯è‡ªå®šä¹‰æ·»åŠ çš„æ•°æ®å¿…å¡«å­—æ®µ
    for (let i = 0; i < goodsList.value.length; i++) {
      const product = goodsList.value[i];
      if (!product.productCategory || !product.specificationModel || !product.unit) {
        showToast(`第${i + 1}行产品数据未填写完整(产品、产品高度、高度单位为必填)`)
        return
      }
      if (!product.url) {
        showToast(`第${i + 1}行产品未上传产品图片`)
        return
      }
      if (!product.cartonSpecifications) {
        showToast(`第${i + 1}行产品未填写纸箱规格`)
        return
      }
      // if (!product.itemType) {
      //   proxy.$modal.msgError(`第${i + 1}行请选择物品类型`)
      //   return
      // }
      const stock = Number(product?.inboundNum ?? 0);
      if (!Number.isFinite(stock) || stock <= 0) {
        showToast(`第${i + 1}行本次入库数量需大于0`)
        return
      }
      const boxNum = Number(product?.boxNum ?? 0);
      if (!Number.isFinite(boxNum) || boxNum <= 0) {
        showToast(`第${i + 1}行每件数量/支需大于0`)
        return
      }
      const taxInclusiveUnitPrice = Number(product?.taxInclusiveUnitPrice ?? 0);
      if (!Number.isFinite(taxInclusiveUnitPrice) || taxInclusiveUnitPrice <= 0) {
        showToast(`第${i + 1}行单价(元)需大于0`)
        return
      }
      const dollarPrice = Number(product?.dollarPrice ?? 0);
      if (!Number.isFinite(dollarPrice) || dollarPrice <= 0) {
        showToast(`第${i + 1}行单价(美元)需大于0`)
        return
      }
      if (!product.inboundDate) {
        showToast(`第${i + 1}行请选择入库日期`)
        return
      }
    }
    let res = await addCustom(goodsList.value)
    if(res.code !== 200){
        uni.showToast({
@@ -128,6 +192,9 @@
            if (e.errMsg == 'chooseMedia:fail cancel') {
                return
            }
            if (e.errMsg == 'user cancel') {
                return
            }
            uni.showToast({
                title: "上传失败",
                icon: 'none',
@@ -135,6 +202,10 @@
            })
        }
    })
}
const delItem = (index)=>{
    console.log('xxxx')
    goodsList.value.splice(index,1)
}
const UploadImage = (url, index) => {
    uni.uploadFile({
@@ -194,8 +265,21 @@
    box-sizing: border-box;
    margin-bottom: 20rpx;
    padding: 20rpx;
    background-color: #f5f5f5;
    // background-color: #f5f5f5;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
    transition: box-shadow 0.3s ease;
    border-radius: 20rpx;
    position: relative;
    .del-btn{
        position: absolute;
        right: 20rpx;
        top: 40rpx;
        z-index: 40;
    }
}
.form-box:hover {
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.add-img {
src/pages/inventoryManagement/receiptManagement/index.vue
@@ -8,7 +8,50 @@
        <view v-if="contentList?.length !== 0" class="content">
            <view v-if="tabCurrent === 0">
                <block v-for="item in contentList" :key="item.id">
                    <view class="item-box item-box0"></view>
                    <view class="item-box item-box0">
                        <view class="item">
                            <view class="label">入库时间</view>
                            <view class="value">{{ item.createTime }}</view>
                        </view>
                        <view class="item">
                            <view class="label">产品名称</view>
                            <view class="value">{{ item.productCategory }}</view>
                        </view>
                        <view class="item">
                            <view class="label">产品高度</view>
                            <view class="value">{{ item.specificationModel }}{{ item.unit }}</view>
                        </view>
                        <view class="item">
                            <view class="label">入库数量/ä»¶</view>
                            <view class="value">{{ item.inboundNum }}</view>
                        </view>
                        <view class="item">
                            <view class="label">每件数量/支</view>
                            <view class="value">{{ item.boxNum }}</view>
                        </view>
                        <view class="item">
                            <view class="label">单价(元)/ä»¶</view>
                            <view class="value">{{ item.taxInclusiveUnitPrice }}</view>
                        </view>
                        <view class="item">
                            <view class="label">单价(美元)/ä»¶</view>
                            <view class="value">{{ item.dollarPrice }}</view>
                        </view>
                        <view class="item">
                            <view class="label">纸箱规格</view>
                            <view class="value">{{ item.cartonSpecifications }}cm</view>
                        </view>
                        <view class="item">
                            <view class="label">入库人</view>
                            <view class="value">{{ item.createBy }}</view>
                        </view>
                        <view class="item" style="justify-content: flex-end;">
                            <button class="mini-btn" type="warn" size="mini" style="margin-left: 0;margin-right: 20rpx;"
                                @click="deleteGoods(item)">删除</button>
                            <button class="mini-btn" type="primary" size="mini" style="margin-left: 0;margin-right: 0;"
                                @click="openForm(item, 'edit')">编辑</button>
                        </view>
                    </view>
                </block>
                <uni-load-more :status="loadMoreStatus"></uni-load-more>
            </view>
@@ -42,8 +85,12 @@
                            <view class="value">{{ item.boxNum }}</view>
                        </view>
                        <view class="item">
                            <view class="label">单价(元)/支</view>
                            <view class="label">单价(元)/ä»¶</view>
                            <view class="value">{{ item.taxInclusiveUnitPrice }}</view>
                        </view>
                        <view class="item">
                            <view class="label">单价(美元)/ä»¶</view>
                            <view class="value">{{ item.dollarPrice }}</view>
                        </view>
                        <view class="item">
                            <view class="label">纸箱规格</view>
@@ -54,15 +101,17 @@
                            <view class="value">{{ item.createBy }}</view>
                        </view>
                        <view class="item" style="justify-content: flex-end;">
                            <button class="mini-btn" type="warn" size="mini" style="margin-left: 0;margin-right: 20rpx;" @click="deleteGoods(item)">删除</button>
                            <button class="mini-btn" type="primary" size="mini" style="margin-left: 0;margin-right: 0;" @click="openForm(item,'edit')">编辑</button>
                            <button class="mini-btn" type="warn" size="mini" style="margin-left: 0;margin-right: 20rpx;"
                                @click="deleteGoods(item)">删除</button>
                            <button class="mini-btn" type="primary" size="mini" style="margin-left: 0;margin-right: 0;"
                                @click="openForm(item, 'edit')">编辑</button>
                        </view>
                    </view>
                </block>
                <uni-load-more :status="loadMoreStatus"></uni-load-more>
            </view>
        </view>
        <view class="fab-button" @click="openForm({},'add')">
        <view class="fab-button" @click="openForm({}, 'add')">
            <up-icon name="plus" size="24" color="#ffffff"></up-icon>
        </view>
        <view v-if="contentList?.length === 0" class="no-data">
@@ -73,10 +122,10 @@
<script setup>
import { ref, reactive, computed } from 'vue'
import { listPage, listPageByCustom,deleteCustom } from '@/api/inventoryManagement/receiptManagement.js'
import { listPage, listPageByCustom, deleteCustom,stockinDel } from '@/api/inventoryManagement/receiptManagement.js'
import { onShow, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app'
import config from '@/config'
const baseUrl = config.baseUrl
const baseUrl = config.imgUrl
// tab相关
const tabItems = reactive(['采购入库', '成品入库'])
const tabCurrent = ref(0)
@@ -94,10 +143,16 @@
}
// æ‰“开编辑/新增
const openForm = (goods,type) => {
    uni.navigateTo({
        url: '/pages/inventoryManagement/receiptManagement/edit?goods=' + JSON.stringify(goods)
    })
const openForm = (goods) => {
    if (tabCurrent.value === 0) {
        uni.navigateTo({
            url: '/pages/inventoryManagement/receiptManagement/procurement-edit?goods=' + JSON.stringify(goods)
        })
    } else {
        uni.navigateTo({
            url: '/pages/inventoryManagement/receiptManagement/edit?goods=' + JSON.stringify(goods)
        })
    }
}
// åˆ†é¡µç›¸å…³
@@ -132,7 +187,7 @@
    contentList.value = []
    getList()
}
const deleteGoods = async (goods) => {
const deleteGoods = async (goods) => {
    uni.showModal({
        title: '提示',
        content: '确定要删除该商品的入库吗?',
@@ -141,8 +196,20 @@
                uni.showLoading({
                    title: '删除中...'
                })
                let params = [goods.id]
                deleteCustom(params).then(res => {
                let params = {}
                let deleteApi = ''
                if(tabCurrent.value == 0){
                    deleteApi = stockinDel
                    params = {
                        ids:[goods.id],
                        type: 1
                    }
                }else{
                    deleteApi = deleteCustom
                    params = [goods.id]
                }
                deleteApi(params).then(res => {
                    uni.hideLoading()
                    reloadPage()
                })
@@ -195,7 +262,8 @@
    color: #999;
    font-size: 14px;
}
.item-box{
.item-box {
    box-sizing: border-box;
    margin: 20rpx;
    padding: 20rpx;
@@ -219,6 +287,7 @@
        }
    }
}
// æµ®åŠ¨æŒ‰é’®æ ·å¼
.fab-button {
    position: fixed;
src/pages/inventoryManagement/receiptManagement/procurement-edit.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,274 @@
<template>
    <PageHeader :title="pageTitle" @back="goBack" />
    <view class="account-detail">
        <view class="box">
            <view style="margin-bottom: 20rpx;">
                <uni-data-select v-model="ledgerVlaue" :localdata="ledgerList" placeholder="请选择采购订单号"
                    :disabled="type == 'edit'" @change="switchLedger"></uni-data-select>
            </view>
            <view v-for="(item, index) in goodsList" class="form-box" :key="index">
                <checkbox-group v-if="type == 'add'" @change="switchCheck(index)">
                    <checkbox value="cb" style="transform:scale(0.7)" />
                </checkbox-group>
                <uni-forms :key="index" label-position="top" label-width="400rpx">
                    <!-- <uni-forms-item label="产品图片" required>
                        <view class="add-img">
                            <image v-if="item.url" class="img" :src="baseUrl + item.url" mode="aspectFill"
                                @click="addImg(index)" />
                            <uni-icons v-else type="camera-filled" size="56" style="color: #8a8a8a"
                                @click="addImg(index)"></uni-icons>
                        </view>
                    </uni-forms-item> -->
                    <uni-forms-item label="名称" required>
                        <uni-easyinput v-model="item.productCategory" placeholder="请输入名称" disabled />
                    </uni-forms-item>
                    <uni-forms-item label="高度" required>
                        <uni-easyinput v-model="item.specificationModel" type="number" placeholder="请输入高度" disabled />
                    </uni-forms-item>
                    <uni-forms-item label="高度单位" required>
                        <uni-easyinput v-model="item.unit" placeholder="请输入高度单位" disabled />
                    </uni-forms-item>
                    <uni-forms-item label="纸箱规格" required>
                        <uni-easyinput v-model="item.cartonSpecifications" placeholder="请输入纸箱规格"
                            :disabled="type == 'edit'" />
                    </uni-forms-item>
                    <uni-forms-item label="待入库数量/ä»¶" required>
                        <uni-number-box v-model="item.quantity0" :min="0" disabled></uni-number-box>
                    </uni-forms-item>
                    <uni-forms-item label="入库数量/ä»¶" required>
                        <uni-number-box v-model="item.quantityStock" :min="0" :max="item.quantity0"></uni-number-box>
                    </uni-forms-item>
                    <uni-forms-item label="每件数量/支" required>
                        <uni-number-box v-model="item.boxNum" :min="0" :disabled="type == 'edit'"></uni-number-box>
                    </uni-forms-item>
                    <uni-forms-item label="单价(元)/ä»¶" required>
                        <uni-number-box v-model="item.taxInclusiveUnitPrice" :min="0" :step="0.01"
                            disabled></uni-number-box>
                    </uni-forms-item>
                    <uni-forms-item label="单价(美元)/ä»¶" required>
                        <uni-number-box v-model="item.dollarPrice" :min="0" :step="0.01"
                            :disabled="type == 'edit'"></uni-number-box>
                    </uni-forms-item>
                </uni-forms>
            </view>
            <view style="display: flex;justify-content: flex-end;">
                <button class="mini-btn" type="primary" size="mini"
                    style="margin-left: 0;margin-right: 0;margin-right: 20rpx;" @click="submitForm">确定</button>
                <button class="mini-btn" size="mini" style="margin-left: 0;margin-right: 0;" @click="goBack">取消</button>
            </view>
        </view>
    </view>
</template>
<script setup>
import { onMounted, ref } from 'vue'
import { ledgerListPage, productlist, stockinAdd, stockinUpdate } from '@/api/inventoryManagement/receiptManagement.js'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore()
const pageTitle = ref('新增自定义入库')
const goodsList = ref([])
const type = ref('add')
const props = defineProps(['goods'])
const defaultGoods = {
    boxNum: 0,
    cartonSpecifications: "",
    id: null,
    inboundDate: "",
    quantityStock: 0,
    itemType: "",
    productCategory: "",
    specificationModel: "",
    supplierName: "",
    taxExclusiveTotalPrice: 0,
    taxInclusiveTotalPrice: 0,
    taxInclusiveUnitPrice: 0,
    dollarPrice: 0,
    taxRate: 0,
    unit: "",
    url: "",
}
const switchCheck = (index) => {
    goodsList.value[index].checked = !goodsList.value[index].checked
}
const goBack = () => {
    uni.navigateBack()
}
const submitForm = async () => {
    let _list = []
    goodsList.value.map(item => {
        if (item.checked && type.value == 'add') {
            item.inboundQuantity = item.quantityStock
            item.unitPrice = item.taxInclusiveUnitPrice
            _list.push(item)
        }
        if (type.value == 'edit') {
            _list.push({ ...item, quantityStock: item.inboundNum })
        }
    })
    if (_list.length === 0) {
        uni.showToast({
            title: '请选择要入库的产品',
            icon: 'none'
        })
        return
    }
    let pamaes = {
    }
    let supplierName = ''
    ledgerList.value.map((item) => {
        if (ledgerVlaue.value == item.value) {
            supplierName = item.supplierName
        }
    })
    if (type.value == 'add') {
        pamaes = {
            entryDate: getCurrentDate(),
            purchaseContractNumber: ledgerVlaue.value,
            inboundBatch: '',
            inboundTime: formatDateTime(),
            nickName: userStore.nickName,
            remark: '',
            supplierId: null,
            supplierName: supplierName,
            recorderName: userStore.name,
            id: null,
            details: _list
        }
    } else {
        pamaes = {
            id: _list[0].id,
            quantityStock: _list[0].quantityStock
        }
    }
    console.log('pamaes', pamaes)
    let requiredApi = ''
    if (type.value == 'add') {
        requiredApi = stockinAdd
    } else {
        requiredApi = stockinUpdate
    }
    let res = await requiredApi(pamaes)
    if (res.code !== 200) {
        uni.showToast({
            title: res.msg,
            icon: 'none'
        })
        return
    }
    uni.showToast({
        title: '新增成功',
        icon: 'none'
    })
    goBack()
}
function getCurrentDate() {
    return formatDateTime(new Date(), false);
}
function formatDateTime(date = new Date(), includeTime = true) {
    const d = new Date(date);
    const year = d.getFullYear();
    const month = String(d.getMonth() + 1).padStart(2, '0');
    const day = String(d.getDate()).padStart(2, '0');
    if (!includeTime) {
        return `${year}-${month}-${day}`;
    }
    const hours = String(d.getHours()).padStart(2, '0');
    const minutes = String(d.getMinutes()).padStart(2, '0');
    const seconds = String(d.getSeconds()).padStart(2, '0');
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
//采购订单号相关
const ledgerList = ref([])
const ledgerVlaue = ref(0)
const getLedgerList = async (_goods) => {
    let res = await ledgerListPage({ current: -1, size: -1 })
    if (res.code !== 200) return
    ledgerList.value = res.data?.records || []
    ledgerList.value = ledgerList.value.map(item => {
        return {
            text: item.purchaseContractNumber + '·' + item.supplierName,
            value: item.purchaseContractNumber,
            supplierName: item.supplierName
        }
    })
    if (_goods.id) {
        ledgerList.value.map(item => {
            if (item.value == _goods.purchaseContractNumber) {
                ledgerVlaue.value = _goods.purchaseContractNumber
                switchLedger(_goods.purchaseContractNumber)
            }
        })
    }
}
const switchLedger = (purchaseContractNumber) => {
    getGoodsList(purchaseContractNumber)
}
const getGoodsList = async (purchaseContractNumber) => {
    let res = await productlist({ purchaseContractNumber })
    if (res.code !== 200) return
    if (type.value == 'edit') {
        goodsList.value.map((el) => {
            res.data.map(item => {
                if (el.id == item.recordId) {
                    el.quantity0 = item.quantity0
                }
            })
        })
    } else {
        goodsList.value = res.data.map(item => {
            return { ...defaultGoods, ...item }
        })
    }
}
onMounted(() => {
    let _goods = JSON.parse(props.goods)
    if (_goods.id) {
        pageTitle.value = '编辑自定义入库'
        type.value = 'edit'
        goodsList.value.push({ ...defaultGoods, ..._goods })
    }
    getLedgerList(_goods)
    userStore.getInfo()
})
</script>
<style lang="scss" scoped>
.box {
    background-color: #fff;
    box-sizing: border-box;
    padding: 20rpx;
    min-height: 80rpx;
    padding-bottom: calc(30rpx + env(safe-area-inset-bottom));
}
.form-box {
    box-sizing: border-box;
    margin-bottom: 20rpx;
    padding: 20rpx;
    // background-color: #f5f5f5;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
    transition: box-shadow 0.3s ease;
    border-radius: 20rpx;
}
.form-box:hover {
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.add-img {
    .img {
        background-color: #efefef;
        border-radius: 10rpx;
        width: 200rpx;
        height: 200rpx;
    }
}
</style>
src/pages/inventoryManagement/stockManagement/index.vue
@@ -7,7 +7,48 @@
        <view v-if="contentList?.length !== 0" class="content">
            <view v-if="tabCurrent === 0">
                <block v-for="item in contentList" :key="item.id">
                    <view class="item-box item-box0"></view>
                    <view class="item-box item-box0">
                        <view class="item">
                            <view class="label">入库时间</view>
                            <view class="value">{{ item.inboundDate }}</view>
                        </view>
                        <view class="item">
                            <view class="label">产品名称</view>
                            <view class="value">{{ item.productCategory }}</view>
                        </view>
                        <view class="item">
                            <view class="label">产品高度</view>
                            <view class="value">{{ item.specificationModel }}{{ item.unit }}</view>
                        </view>
                        <view class="item">
                            <view class="label">入库数量/ä»¶</view>
                            <view class="value">{{ item.inboundNum }}</view>
                        </view>
                        <view class="item">
                            <view class="label">库存数量/ä»¶</view>
                            <view class="value">{{ item.inboundNum0 }}</view>
                        </view>
                        <view class="item">
                            <view class="label">每件数量/支</view>
                            <view class="value">{{ item.boxNum }}</view>
                        </view>
                        <view class="item">
                            <view class="label">单价(元)/支</view>
                            <view class="value">{{ item.taxInclusiveUnitPrice }}</view>
                        </view>
                        <view class="item">
                            <view class="label">纸箱规格</view>
                            <view class="value">{{ item.cartonSpecifications }}cm</view>
                        </view>
                        <view class="item">
                            <view class="label">入库人</view>
                            <view class="value">{{ item.createBy }}</view>
                        </view>
                        <!-- <view class="item" style="justify-content: flex-end;">
                            <button class="mini-btn" type="primary" size="mini" style="margin-left: 0;margin-right: 0;"
                                @click="openForm(item, 'edit')">编辑</button>
                        </view> -->
                    </view>
                </block>
                <uni-load-more :status="loadMoreStatus"></uni-load-more>
            </view>
@@ -56,10 +97,10 @@
                            <view class="label">入库人</view>
                            <view class="value">{{ item.createBy }}</view>
                        </view>
                        <view class="item" style="justify-content: flex-end;">
                        <!-- <view class="item" style="justify-content: flex-end;">
                            <button class="mini-btn" type="primary" size="mini" style="margin-left: 0;margin-right: 0;"
                                @click="openForm(item, 'edit')">编辑</button>
                        </view>
                        </view> -->
                    </view>
                </block>
                <uni-load-more :status="loadMoreStatus"></uni-load-more>