出库对接

This commit is contained in:
zx
2026-04-14 08:46:29 +08:00
parent b16dd22d70
commit 6f1db0f92e
30 changed files with 1366 additions and 458 deletions

View File

@@ -1,6 +1,8 @@
<!-- 仓库/存储区选择 -->
<template>
<view class="content">
<navigation :title="isWarehousing.value ? '仓库选择' : '存储区选择'" :back-url="backUrl"></navigation>
<view class="contentBox">
<view class="topSearch">
<uni-easyinput type="text" v-model="queryParams.keyword" prefixIcon="search" :inputBorder="false"
@iconClick="getList" placeholder="请输入搜索内容" />
@@ -56,11 +58,13 @@
</view>
</template>
<script setup>
import { ref, toRefs } from 'vue';
import { computed, ref, toRefs } from 'vue';
import { onShow } from "@dcloudio/uni-app";
import { getWarehousingInfo } from '../../api/system';
import { getWarehousingInfo } from '@/api/system';
import getRepository from "@/api/getRepository";
import { objectToQuery } from '../until';
import Navigation from '../components/Navigation.vue';
import { watch } from 'vue';
const props = defineProps({
// 是否为仓库查询
@@ -69,12 +73,6 @@ const props = defineProps({
default: true,
required: true
},
// 返回出库开单/入库开单
backStr: {
type: String,
default: true,
required: true
},
pathParams: {
type: Object,
default: null,
@@ -82,11 +80,14 @@ const props = defineProps({
}
})
const { isWarehousing, backStr, pathParams } = toRefs(props)
const { isWarehousing, pathParams } = toRefs(props)
// 数据:查询关键字
const queryParams = ref({
keyword: ''
})
const backUrl = ref('')
// stockIn 入库单开单 stockIn_Detail入库单编辑 issueUniqueCode唯一码 issueUniqueCode_inbound入库生成唯一码
const keyType = computed(() => pathParams.value.type || pathParams.value.back)
// 绑定:加载屏
const pagingRef = ref(null)
// 数据:仓库/存储区
@@ -132,25 +133,27 @@ const getRepositoryInfo = async () => {
}
// 返回路径
const toBack = (back) => {
const toBack = (keyType) => {
console.log('监听', keyType);
let url = ''
switch (back) {
switch (keyType) {
case 'stockIn':
// 入库单开单
url = '/pages/warehousing/stockIn/create'
break;
case 'stockOut':
// 出库单开单
url = ''
url = '/pages/warehousing/stockOut/create'
break;
case 'stockOut-outbound':
// 出库单出库
url = '/pages/warehousing/stockOut/components/outAway'
break;
}
let params = pathParams.value
delete params.backStr
delete params.flag
const query = objectToQuery(params)
uni.navigateTo({
url: `${url}${query}`
})
const query = objectToQuery(pathParams.value)
backUrl.value = `${url}${query}`
}
// 选择:仓库/存储区
const onChecked = (val) => {
@@ -166,9 +169,25 @@ const onChecked = (val) => {
}
// 返回list
toBack(backStr.value)
uni.navigateTo({
url: backUrl.value
})
}
// 监听:确保 pathParams 变化时一定执行 toBack()
watch(
() => pathParams.value,
(d) => {
console.log('pathParams 变化:', d);
if (!d) return
const type = d.type || d.back;
console.log(type, 'eeeeeee');
toBack(type)
},
{ deep: true, immediate: true }
)
onShow(() => {
pagingRef.value?.reload?.()
})
@@ -177,7 +196,7 @@ onShow(() => {
<style scoped lang="scss">
.topSearch {
position: fixed;
top: 0;
top: 65rpx;
left: 0;
right: 0;
z-index: 999;
@@ -188,7 +207,7 @@ onShow(() => {
}
.containerBox {
padding-top: 44px;
padding-top: 120rpx !important;
width: 100%;
height: 100%;
box-sizing: border-box;
@@ -199,12 +218,10 @@ onShow(() => {
}
::v-deep.listBox {
.uni-list {
background-color: #F8F8FF;
}
background-color: #F8F8FF;
.uni-list-item {
margin-bottom: 1rpx;
margin-bottom: 8rpx;
}
.uni-list-item__container {

View File

@@ -5,7 +5,7 @@
<view class="line title">
<p> {{ typeName + '单号' }}{{ detailInfo?.billNo }}</p>
<span :style="getColor(detailInfo?.billType)">
{{ getBillType(detailInfo?.billType,detailInfo?.status) }}
{{ getBillType(detailInfo?.billType, detailInfo?.status, flag) }}
</span>
</view>
@@ -44,7 +44,7 @@
import { getBillType, formatDate, getColor } from '../until'
import { computed, toRefs } from 'vue';
import MaterialList from './MaterialList.vue'
import { includes } from 'lodash';
const props = defineProps({
// 查询列表类型 stockIn:入库 stockOut出库
type: {
@@ -60,10 +60,8 @@ const props = defineProps({
})
const { type, detailInfo } = toRefs(props)
const typeName = computed(() => type.value == 'stockIn' ? '入库单' : '出库单')
console.log(detailInfo, 'detailInfo');
const typeName = computed(() => includes(type.value, 'stockIn') ? '入库单' : '出库单')
const flag = computed(() => includes(type.value, 'stockIn') ? 0 : 1)
</script>
<style scoped lang="scss">

View File

@@ -1,12 +1,12 @@
<template>
<!-- 物料列表 - 添加物料 -->
<view class="materialList">
<view class="remarkLine">
<text>物料列表</text>
<uv-button type="primary" v-if="isAddMaterial" :plain="true"
size="small" text="添加物料" @click="toMaterial"></uv-button>
<view v-if="isEdit == 5" class="flex align-center justify-between">
<uv-button type="primary" v-if="isAddMaterial" :plain="true" size="small" text="添加物料"
@click="toMaterial"></uv-button>
<view v-if="isShowRqCode" class="flex align-center justify-between">
<span class="f-12 mr-16 grey" style="font-size: 12px;" v-if="num > 0">
剩余<span style="color: red;">
{{ num }}
@@ -15,7 +15,7 @@
<uv-button type="primary" :plain="true" size="small" text="快速生成唯一码"
@click="toGenerateUniqueCodeQuickly"></uv-button>
</view>
<!-- <p class="btn-link" v-if="isEdit == 2" @click="toEdit">修改</p> -->
</view>
<!-- 物料列表-->
@@ -52,7 +52,7 @@
</view>
</view>
<!-- 库存状态 -->
<view class="flex justify-between mb-2 " v-if="isEdit == 3">
<view class="flex justify-between mb-2 " v-if="isEdit == 3 && isStockIn">
<p style="font-size: 13px;">
已入库
<span style="color:green">{{ getStockQuantity(item, 'complete') }}</span>
@@ -62,6 +62,16 @@
<span style="color:red">{{ getStockQuantity(item, 'remaining') }}</span>
</p>
</view>
<view class="flex justify-between mb-2 " v-if="isEdit == 3 && !isStockIn">
<p style="font-size: 13px;">
已出库
<span style="color:green">{{ getStockQuantity(item, 'complete') }}</span>
</p>
<p style="font-size: 13px;">
剩余
<span style="color:red">{{ getStockQuantity(item, 'remaining') }}</span>
</p>
</view>
<!-- 备注 -->
<view class="remark-row">
<uni-forms-item :name="`material[${idx}].remark`" label="备注:">
@@ -98,29 +108,39 @@
</template>
<script setup>
import { computed, onMounted, ref, toRefs } from 'vue';
import { assign, findIndex ,includes} from 'lodash';
import { computed, ref, toRefs } from 'vue';
import { assign, findIndex, includes } from 'lodash';
import { getStockQuantity, objectToQuery } from '../until';
import { getTypeParentNames } from '../warehousing/uniqueCode/until';
import { onLoad, onShow } from "@dcloudio/uni-app";
const OPERATE_CONFIG = {
// 唯一码创建 /唯一码编辑 /唯一码详情 /入库单开单
issueUniqueCode: {
toMaterialUrl: '/pages/warehousing/uniqueCode/issueUniqueCode/materialSelection',
title: '入库单开单'
},
// 入库单入库
stockIn: {
toMaterialUrl: '/pages/warehousing/uniqueCode/issueUniqueCode/index',
title: '入库单开单'
},
}
const props = defineProps({
formData: { type: Object, default: () => ({ material: [], remark: '' }), required: true },//物料信息
isEdit: { type: Boolean, default: true, required: true }, //编辑1 / 物料只读2 / 入库单只读3 /入库生成唯一码编辑4 /5数量不可编辑 备注可编辑
backStr: { type: String, default: '' }, //选择物料返回页面的标识
pathParams: { type: Object, default: {} }, //只读时传入对应的code、id
extendData: { type: Object, default: {} }, //其他额外参数
})
const { formData, isEdit, backStr, pathParams, extendData } = toRefs(props)
const { formData, isEdit, pathParams, extendData } = toRefs(props)
const keyType = computed(() => pathParams.value.type)
//是否为编辑状态
const edit = computed(() => {
if (`${isEdit.value}` === '1') return '1';
else if (`${isEdit.value}` === '4') return '4';
else return false;
})
const edit = computed(() => includes(['1', '4', '5'], `${isEdit.value}`))
// 显示添加物料按钮 isEdit编辑、
const isAddMaterial = computed(() => isEdit == 1 && pathParams.back != 'issueUniqueCode_inbound' && !includes(backStr.value,'stockOut'))
const isAddMaterial = computed(() => `${isEdit.value}` === '1' && keyType != 'issueUniqueCode_inbound' && !includes(keyType.value, 'stockOut'))
// 显示快速生成唯一码 isShowRqCode
const isShowRqCode = computed(() => `${isEdit.value}` === '5' && !includes(keyType.value, 'stockOut'))
const isStockIn = computed(() => includes(keyType.value, 'stockIn'))
// 删除:数据
const delItem = ref(null)
// 删除:开关
@@ -134,16 +154,15 @@ const modalRef = ref()
// 按钮:添加物料
const toMaterial = () => {
if (backStr.value == 'stockIn') { // 入库单开单 - 添加物料可选择手输入/无线液位计
if (keyType.value == 'stockIn') { // 入库单开单 - 添加物料可选择手输入/无线液位计
modalRef.value.open()
} else {
const path = objectToQuery({ ...pathParams.value, back: backStr?.value })
const path = objectToQuery(pathParams.value)
// 唯一码 - 编辑/新增
let url = '/pages/warehousing/uniqueCode/issueUniqueCode/materialSelection';
const value = uni.getStorageSync('app_material');
uni.setStorageSync('app_material', [{ ...value[0], uniqueCodeRemark: formData.value?.remark }]); // 将最新的唯一码备注写入缓存
uni.navigateTo({
url: `${url}${path}`
url: `${OPERATE_CONFIG.issueUniqueCode.toMaterialUrl}${path}`
})
}
}
@@ -151,9 +170,9 @@ const toMaterial = () => {
const toMaterialSelection = (type) => {
// 0无线液 1手动输入
let url = ''
const path = objectToQuery({ ...pathParams.value, back: backStr.value })
const path = objectToQuery(pathParams.value)
if (type === '1') {
url = '/pages/warehousing/uniqueCode/issueUniqueCode/materialSelection'
url = `${OPERATE_CONFIG.issueUniqueCode.toMaterialUrl}`
}
uni.navigateTo({
url: `${url}${path}`
@@ -161,9 +180,11 @@ const toMaterialSelection = (type) => {
}
// 快速生成唯一码 -
const toGenerateUniqueCodeQuickly = () => {
const path = objectToQuery({ ...pathParams.value, back: 'inbound' })
const path = objectToQuery(pathParams.value)
console.log(path, 'path==>');
uni.navigateTo({
url: `/pages/warehousing/uniqueCode/issueUniqueCode/index${path}`
url: `${OPERATE_CONFIG.stockIn.toMaterialUrl}${path}`
})
}
@@ -188,7 +209,8 @@ const dialogConfirm = () => {
const getMaterialList = () => {
const params = formData.value?.material?.map((i) => ({
const material = formData.value?.material || []
const params = material?.map((i) => ({
...i,
material: {
//? 这里的判断是为了区分 =详情带出的物料以及新增的物料 详情带出的物料有id以及materialId 新增物料id为物料id materialId无值

View File

@@ -1,10 +1,10 @@
<template>
<!-- 状态栏占位 -->
<view class="nav-placeholder" :style="{ height: navHeight + 'px' }"></view>
<!-- <view class="nav-placeholder" :style="{ height: 35 + 'px' }"></view> -->
<view class="navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="navbar" :style="{ height: navHeight + 'rpx' }">
<view class="left" @click="goBack">
<uni-icons type="left" size="18" />
<uni-icons type="left" size="18" v-if="showBack" />
</view>
<!-- 标题 -->
@@ -16,14 +16,14 @@
</view>
</view>
<view class="content"></view>
<!-- <view class="contentBox"></view> -->
</template>
<script setup>
import { ref, onMounted, toRefs } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getTabBarList } from '../until'
import { find, findIndex } from 'lodash'
import { findIndex } from 'lodash'
const props = defineProps({
title: {
@@ -54,9 +54,11 @@ const isTabBar = ref('')
onMounted(() => {
try {
const res = uni.getSystemInfoSync()
statusBarHeight.value = res.statusBarHeight || 0
console.log(statusBarHeight, 'statusBarHeight==>');
// 标准导航栏高度 44px + 状态栏 = 总高度
navHeight.value = statusBarHeight.value + 44
navHeight.value = statusBarHeight.value + 60
} catch (e) {
console.warn('获取系统信息失败', e)
}
@@ -66,6 +68,7 @@ onMounted(() => {
onLoad(() => {
const tabList = getTabBarList()
const isTabBarNav = findIndex(tabList, (i) => i.pagePath == backUrl.value) != -1
console.log(tabList, backUrl, isTabBarNav);
isTabBar.value = isTabBarNav
if (backUrl.value) {
@@ -101,7 +104,6 @@ const goBack = () => {
</script>
<style scoped lang="scss">
/* 导航栏占位:撑开页面内容,不被遮挡 */
.nav-placeholder {
width: 100%;
}
@@ -112,8 +114,6 @@ const goBack = () => {
top: 0;
left: 0;
width: 100%;
// 高度由 状态栏 + 44px 决定,不要写死 70px
height: 44px;
background: #fff;
display: flex;
align-items: center;
@@ -132,8 +132,9 @@ const goBack = () => {
}
.title {
font-size: 16rpx;
font-weight: bold;
font-size: 16px;
font-weight: 600;
text-align: center;
color: #333;
max-width: 400rpx;
overflow: hidden;

View File

@@ -2,7 +2,7 @@
<!-- 我的入库单/我的出库单/入库单入库/出库单出库-->
<navigation :title="title" back-url="pages/warehousing/index"></navigation>
<view class="content">
<view class="contentBox">
<!-- 搜索框 -->
<view class="topSearch">
<uni-easyinput type="text" v-model="queryParams.keyword" prefixIcon="search" :input-border="false"
@@ -18,14 +18,15 @@
<view class="line title">
<p> {{ typeName }}编号{{ item.billNo }}</p>
<span :style="getColor(item?.billType)">
{{ getBillType(item?.billType, item?.status) }}
{{ getBillType(item?.billType, item?.status, flag) }}
</span>
</view>
<p class="line content">{{ typeName }}类型
<span>{{ getOrderType(item.status) }}</span>
</p>
<p class="line content">库位
<span>{{ item.areaName }}</span>
<span v-if="item.warehouseName">{{ item.warehouseName }}/</span>
<span v-if="item.areaName"> {{ item.areaName }}</span>
</p>
<p class="line content">开单时间
<span>{{ item.createTime }}</span>
@@ -39,10 +40,11 @@
</template>
<script setup>
import _, { includes } from 'lodash';
import _ from 'lodash';
import { computed, toRefs, ref } from 'vue';
import { onShow } from "@dcloudio/uni-app";
import { stockList } from '../../api/stockIn';
import { stockList } from '@/api/stockIn';
import { stockOutList } from '@/api/stockOut';
import { getBillType, getColor } from '../until';
import Navigation from '../components/Navigation.vue';
@@ -65,7 +67,8 @@ const { type, query } = toRefs(props)
const pagingRef = ref(null)
const list = ref([])
const typeName = computed(() => includes(type.value, 'stockIn') ? '入库单' : '出库单')
const flag = computed(() => _.includes(type.value, 'stockIn') ? 0 : 1)
const typeName = computed(() => _.includes(type.value, 'stockIn') ? '入库单' : '出库单')
const title = computed(() => {
if (type.value == 'stockIn') return '我的入库单'
else if (type.value == 'stockIn-putAway') return '入库单入库'
@@ -73,7 +76,7 @@ const title = computed(() => {
else return '出库单出库'
})
const getOrderType = () => {
return includes(type.value, 'stockIn') ? '入库单入库' : '出库单出库'
return _.includes(type.value, 'stockIn') ? '入库单入库' : '出库单出库'
}
const queryParams = ref({
@@ -85,11 +88,9 @@ onShow(() => {
})
const onDetail = (val) => {
if (_.includes(type.value, 'stockIn')) {
uni.navigateTo({
url: `/pages/warehousing/stockIn/components/detail?billNo=${val.billNo}&type=${type.value}`,
});
}
uni.navigateTo({
url: `/pages/warehousing/stockIn/components/detail?billNo=${val.billNo}&type=${type.value}`,
});
}
const getList = (pageNo, pageSize) => {
@@ -103,8 +104,15 @@ const getList = (pageNo, pageSize) => {
}).catch(() => {
pagingRef.value.complete(false)
})
}else{
} else {
stockOutList({ ...queryParams.value, ...query.value }).then(res => {
res.rows.forEach(e => {
e.showMore = false;
});
pagingRef.value.complete(res.rows)
}).catch(() => {
pagingRef.value.complete(false)
})
}
}
</script>
@@ -113,21 +121,19 @@ const getList = (pageNo, pageSize) => {
/* 搜索框:放在导航栏下面,不覆盖 */
.topSearch {
position: fixed;
top: var(--nav-height);
/* 关键:自动在导航栏下方 */
top: 65rpx;
left: 0;
right: 0;
z-index: 99;
/* 比导航栏小 */
padding: 8rpx 16rpx;
background-color: #fff;
border-bottom: 1px solid #eee;
box-sizing: border-box;
}
.containerBox {
padding-top: 90px !important;
/* 撑开:导航栏+搜索框高度 */
padding-top: 125rpx !important;
width: 100%;
height: 100%;
box-sizing: border-box;
@@ -143,6 +149,10 @@ const getList = (pageNo, pageSize) => {
font-size: 12px;
}
.uni-list--border-bottom {
padding: 8px 12px 8px 15px;
}
.uni-list {
background-color: #F8F8FF;
}
@@ -154,7 +164,7 @@ const getList = (pageNo, pageSize) => {
.line {
display: flex;
align-items: center;
padding: 12rpx 20rpx;
padding: 8px 0;
}
.title {

View File

@@ -1,6 +1,6 @@
<!-- 获取仓库数据 -->
<template>
<view class="content">
<view>
<uv-form ref="formRef" class="form" :model="formData" label-width="150rpx">
<!-- 仓库 -->
<uv-form-item label="仓库" prop="warehouse">
@@ -70,8 +70,7 @@ onShow(() => {
// 点击事件:选择仓库/选择存储区
const onClick = (type) => {
uni.setStorageSync('app_billRemark', formData.value.remark)
let query = { ...pathParams.value, backStr: 'stockIn' }
let query = { ...pathParams.value }
if (type == 'warehouse') {
query = objectToQuery({ ...query, flag: 'warehousing' })
} else if (type == 'storageArea') {