소스 검색

景聚庭-点餐代码提交

huangguoce 1 주 전
부모
커밋
260729fe96

+ 12 - 0
api/psi/DishOrderService.js

@@ -0,0 +1,12 @@
+import request from "../../common/request"
+import { PSI_MANAGEMANT as prefix } from "@/api/AppPath";
+
+export default class DishOrderService {
+  findOrderById(id) {
+    return request({
+      url: prefix + "/psi/dishOrder/findOrderById",
+      method: "get",
+      params: { id: id },
+    });
+  }
+}

+ 8 - 0
api/psi/MaterialTypeService.js

@@ -26,6 +26,14 @@ export default class MaterialTypeService {
     })
   }
 
+  summaryTreeData(param) {
+    return request({
+      url: prefix + '/psi/materialType/summaryTreeData',
+      method: 'get',
+      params: param
+    })
+  }
+
   save(param) {
     return request({
       url: prefix + '/psi/materialType/save',

+ 18 - 0
pages.json

@@ -248,6 +248,24 @@
 		{
 			"path" : "pages/generateForm/InvoiceUpdateGenerateForm",
 			"style" : {}
+		},
+		{
+			"path" : "pages/psiManagement/dishManage/DishOrderApproval",
+			"style" : {
+				"navigationBarTitleText": "点菜订单审批"
+			}
+		},
+		{
+			"path" : "pages/psiManagement/wareHouse/WareHouseAddForm",
+			"style" : {
+				"navigationBarTitleText": "入库"
+			}
+		},
+		{
+			"path" : "pages/psiManagement/wareHouseSummary/WareHouseSummaryList",
+			"style" : {
+				"navigationBarTitleText": "库存列表"
+			}
 		}
     ],
 	"subPackages": [{

+ 502 - 0
pages/psiManagement/dishManage/DishOrderApproval.vue

@@ -0,0 +1,502 @@
+<template>
+	<view class="dish-order-approval">
+		<view v-if="loading" class="loading-wrap">
+			<u-loading-icon text="加载中" textSize="14"></u-loading-icon>
+		</view>
+
+		<view v-else-if="currentOrder" class="page-body">
+			<view class="summary-card">
+				<view class="summary-head">
+					<view class="summary-title">订单信息</view>
+					<view class="status-tag" :class="orderStatusClass(currentOrder.orderStatus)">{{ orderStatusName(currentOrder.orderStatus) }}</view>
+				</view>
+				<view class="summary-main">
+					<view class="room-name">{{ currentOrder.roomName || '-' }}</view>
+					<view class="order-no">{{ currentOrder.orderNo || '-' }}</view>
+				</view>
+				<view class="summary-grid">
+					<view class="summary-item">
+						<text>结账方式</text>
+						<text>{{ settleTypeName(currentOrder.settleType) }}</text>
+					</view>
+					<view class="summary-item">
+						<text>账单原金额</text>
+						<text>¥{{ formatMoney(currentOrder.totalAmount) }}</text>
+					</view>
+					<view class="summary-item">
+						<text>折扣比例</text>
+						<text>{{ discountRateText(currentOrder) }}</text>
+					</view>
+					<view class="summary-item">
+						<text>优惠金额</text>
+						<text>¥{{ formatMoney(currentOrder.discountAmount) }}</text>
+					</view>
+					<view class="summary-item">
+						<text>实收金额</text>
+						<text>¥{{ formatMoney(currentOrder.payableAmount) }}</text>
+					</view>
+					<view class="summary-item summary-wide">
+						<text>结账/取消时间</text>
+						<text>{{ currentOrder.settleTime || '-' }}</text>
+					</view>
+				</view>
+			</view>
+
+			<view class="tab-bar">
+				<view
+					v-for="tab in tabs"
+					:key="tab.name"
+					class="tab-item"
+					:class="{ active: activeTab === tab.name }"
+					@click="activeTab = tab.name"
+				>
+					<text>{{ tab.label }}</text>
+					<text class="tab-count">{{ tab.count }}</text>
+				</view>
+			</view>
+
+			<view class="dish-list">
+				<view v-if="currentDetailList.length === 0" class="empty-wrap">
+					<u-empty mode="data" text="暂无菜品"></u-empty>
+				</view>
+				<view v-for="(item, index) in currentDetailList" :key="item.id || index" class="dish-card">
+					<view class="dish-row dish-title-row">
+						<view class="dish-name">{{ item.dishName || '-' }}</view>
+						<view class="dish-amount">¥{{ formatMoney(getDisplayAmount(item)) }}</view>
+					</view>
+					<view class="dish-meta">
+						<text>{{ item.typeName || '未分类' }}</text>
+						<text v-if="item.spec">规格:{{ item.spec }}</text>
+					</view>
+					<view class="dish-row">
+						<view class="dish-price">单价 ¥{{ formatMoney(item.salePrice) }}</view>
+						<view class="dish-qty">x {{ getDisplayQuantity(item) }}</view>
+					</view>
+					<view v-if="item.createTime && activeTab !== 'actual'" class="dish-time">
+						{{ activeTab === 'add' ? '加菜时间' : '减菜时间' }}:{{ item.createTime }}
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<view v-else class="empty-page">
+			<u-empty mode="data" text="暂无订单信息"></u-empty>
+		</view>
+	</view>
+</template>
+
+<script>
+import DishOrderService from '@/api/psi/DishOrderService'
+
+export default {
+	name: 'DishOrderApproval',
+	props: {
+		businessId: {
+			type: String,
+			default: ''
+		},
+		formReadOnly: {
+			type: Boolean,
+			default: true
+		},
+		status: {
+			type: String,
+			default: ''
+		}
+	},
+	data() {
+		return {
+			loading: false,
+			activeTab: 'actual',
+			currentOrder: null,
+			routeBusinessId: '',
+			dishOrderService: null
+		}
+	},
+	computed: {
+		tabs() {
+			const order = this.currentOrder || {}
+			return [
+				{ name: 'actual', label: '实际菜单', count: this.getList(order.detailList).length },
+				{ name: 'add', label: '加菜', count: this.getList(order.addDishList).length },
+				{ name: 'reduce', label: '减菜', count: this.getList(order.reduceDishList).length }
+			]
+		},
+		currentDetailList() {
+			const order = this.currentOrder || {}
+			if (this.activeTab === 'add') {
+				return this.getList(order.addDishList)
+			}
+			if (this.activeTab === 'reduce') {
+				return this.getList(order.reduceDishList)
+			}
+			return this.getList(order.detailList)
+		}
+	},
+	watch: {
+		businessId() {
+			this.init()
+		}
+	},
+	onLoad(option) {
+		this.routeBusinessId = (option && (option.businessId || option.id)) || ''
+		uni.setNavigationBarTitle({ title: '点菜订单审批' })
+		this.init()
+	},
+	created() {
+		this.dishOrderService = new DishOrderService()
+	},
+	mounted() {
+		this.init()
+	},
+	methods: {
+		init() {
+			const id = this.getBusinessId()
+			this.activeTab = 'actual'
+			if (!id || id === 'false') {
+				this.currentOrder = null
+				return
+			}
+			if (!this.dishOrderService) {
+				this.dishOrderService = new DishOrderService()
+			}
+			this.loading = true
+			this.$emit('changeLoading', true)
+			this.dishOrderService.findOrderById(id).then((data) => {
+				this.currentOrder = data || {}
+			}).catch(() => {
+				this.currentOrder = null
+				uni.showToast({ title: '订单信息加载失败', icon: 'none' })
+			}).finally(() => {
+				this.loading = false
+				this.$emit('changeLoading', false)
+			})
+		},
+		getBusinessId() {
+			return this.businessId || this.routeBusinessId || ''
+		},
+		getKeyWatch() {
+			this.init()
+		},
+		close() {
+			this.currentOrder = null
+		},
+		saveForm(callback) {
+			this.callFlowCallback(callback)
+		},
+		agreeForm(callback) {
+			this.callFlowCallback(callback)
+		},
+		startForm(callback) {
+			this.callFlowCallback(callback)
+		},
+		reapplyForm(callback) {
+			this.callFlowCallback(callback)
+		},
+		updateStatusById(type, callback) {
+			this.callFlowCallback(callback)
+		},
+		callFlowCallback(callback) {
+			const order = this.currentOrder || {}
+			if (callback) {
+				callback('psi_dish_order', order.id || this.getBusinessId(), order)
+			}
+		},
+		getList(list) {
+			return Array.isArray(list) ? list : []
+		},
+		getDisplayQuantity(item) {
+			return Math.abs(Number(item.quantity || 0))
+		},
+		getDisplayAmount(item) {
+			return Math.abs(Number(item.amount || 0))
+		},
+		orderStatusName(value) {
+			if (value === '0') {
+				return '用餐中'
+			}
+			if (value === '1') {
+				return '已结账'
+			}
+			if (value === '2') {
+				return '已取消'
+			}
+			return '-'
+		},
+		orderStatusClass(value) {
+			if (value === '1') {
+				return 'success'
+			}
+			if (value === '2') {
+				return 'danger'
+			}
+			return 'primary'
+		},
+		settleTypeName(value) {
+			if (value === '0') {
+				return '结账'
+			}
+			if (value === '1') {
+				return '折扣结账'
+			}
+			if (value === '2') {
+				return '优惠结账'
+			}
+			return '-'
+		},
+		discountRateText(order) {
+			if (!order || order.settleType !== '1') {
+				return '-'
+			}
+			return this.formatMoney(order.discountRate) + '%'
+		},
+		formatMoney(value) {
+			return Number(value || 0).toFixed(2)
+		}
+	}
+}
+</script>
+
+<style scoped>
+.dish-order-approval {
+	min-height: 100vh;
+	background: #f5f6fa;
+	padding: 20rpx 20rpx 40rpx;
+	box-sizing: border-box;
+}
+
+.loading-wrap,
+.empty-page {
+	min-height: 360rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	background: #fff;
+	border-radius: 16rpx;
+}
+
+.summary-card,
+.dish-card {
+	background: #fff;
+	border-radius: 16rpx;
+	box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.04);
+}
+
+.summary-card {
+	padding: 28rpx;
+}
+
+.summary-head,
+.summary-main,
+.dish-row,
+.tab-bar {
+	display: flex;
+	align-items: center;
+}
+
+.summary-head,
+.summary-main,
+.dish-row {
+	justify-content: space-between;
+}
+
+.summary-title {
+	font-size: 32rpx;
+	font-weight: 600;
+	color: #303133;
+}
+
+.status-tag {
+	padding: 8rpx 18rpx;
+	border-radius: 999rpx;
+	font-size: 24rpx;
+	line-height: 32rpx;
+	color: #2979ff;
+	background: #ecf5ff;
+}
+
+.status-tag.success {
+	color: #19be6b;
+	background: #e8f7ef;
+}
+
+.status-tag.danger {
+	color: #fa3534;
+	background: #fff1f0;
+}
+
+.summary-main {
+	margin-top: 24rpx;
+	gap: 24rpx;
+}
+
+.room-name {
+	font-size: 40rpx;
+	font-weight: 700;
+	color: #1f2d3d;
+	min-width: 0;
+	flex: 1;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+
+.order-no {
+	font-size: 24rpx;
+	color: #909399;
+	max-width: 320rpx;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+
+.summary-grid {
+	display: grid;
+	grid-template-columns: repeat(2, minmax(0, 1fr));
+	gap: 22rpx;
+	margin-top: 28rpx;
+}
+
+.summary-item {
+	min-width: 0;
+	padding: 18rpx;
+	border-radius: 12rpx;
+	background: #f7f8fa;
+}
+
+.summary-wide {
+	grid-column: span 2;
+}
+
+.summary-item text:first-child {
+	display: block;
+	font-size: 24rpx;
+	color: #909399;
+	line-height: 34rpx;
+}
+
+.summary-item text:last-child {
+	display: block;
+	margin-top: 8rpx;
+	font-size: 28rpx;
+	font-weight: 600;
+	color: #303133;
+	line-height: 38rpx;
+	word-break: break-all;
+}
+
+.tab-bar {
+	margin: 24rpx 0;
+	padding: 8rpx;
+	background: #fff;
+	border-radius: 14rpx;
+	gap: 8rpx;
+}
+
+.tab-item {
+	flex: 1;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	gap: 8rpx;
+	height: 72rpx;
+	border-radius: 10rpx;
+	font-size: 28rpx;
+	color: #606266;
+}
+
+.tab-item.active {
+	background: #2979ff;
+	color: #fff;
+	font-weight: 600;
+}
+
+.tab-count {
+	font-size: 22rpx;
+	min-width: 32rpx;
+	height: 32rpx;
+	line-height: 32rpx;
+	text-align: center;
+	border-radius: 999rpx;
+	background: rgba(144, 147, 153, 0.15);
+}
+
+.tab-item.active .tab-count {
+	background: rgba(255, 255, 255, 0.24);
+}
+
+.dish-list {
+	display: flex;
+	flex-direction: column;
+	gap: 18rpx;
+}
+
+.empty-wrap {
+	padding: 60rpx 0;
+	background: #fff;
+	border-radius: 16rpx;
+}
+
+.dish-card {
+	padding: 24rpx;
+}
+
+.dish-title-row {
+	gap: 16rpx;
+}
+
+.dish-name {
+	min-width: 0;
+	flex: 1;
+	font-size: 32rpx;
+	font-weight: 600;
+	color: #303133;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+
+.dish-amount {
+	font-size: 30rpx;
+	font-weight: 700;
+	color: #fa3534;
+}
+
+.dish-meta {
+	display: flex;
+	flex-wrap: wrap;
+	gap: 12rpx;
+	margin-top: 14rpx;
+}
+
+.dish-meta text {
+	padding: 6rpx 12rpx;
+	border-radius: 8rpx;
+	font-size: 24rpx;
+	line-height: 32rpx;
+	color: #606266;
+	background: #f4f4f5;
+}
+
+.dish-price,
+.dish-qty,
+.dish-time {
+	font-size: 26rpx;
+	color: #606266;
+}
+
+.dish-row:not(.dish-title-row) {
+	margin-top: 18rpx;
+}
+
+.dish-qty {
+	font-weight: 600;
+	color: #303133;
+}
+
+.dish-time {
+	margin-top: 14rpx;
+	line-height: 36rpx;
+	color: #909399;
+}
+</style>

+ 14 - 4
pages/psiManagement/wareHouse/PurchaseSelector.vue

@@ -1,8 +1,10 @@
 <template>
     <view>
-        <u-form-item label="采购编号" prop="purchaseNo" :required="true">
-            <u--input :value="currentValue" placeholder="请选择采购编号" readonly :disabled="disabled"
-                @focus="openPicker"></u--input>
+        <u-form-item label="采购编号" prop="purchaseNo" :required="required">
+            <view class="selector-trigger" @tap.stop="openPicker">
+                <u--input :value="currentValue" placeholder="请选择采购编号"  :disabled="disabled"
+                    @focus="openPicker" @click="openPicker" @tap="openPicker"></u--input>
+            </view>
         </u-form-item>
 
         <view class="selector-mask" :class="{ show: visible }" @tap="closePicker"></view>
@@ -41,7 +43,11 @@ export default {
     name: 'PurchaseSelector',
     props: {
         inputForm: Object,
-        disabled: Boolean
+        disabled: Boolean,
+        required: {
+            type: Boolean,
+            default: true
+        }
     },
     data() {
         return {
@@ -114,6 +120,10 @@ export default {
 </script>
 
 <style scoped>
+.selector-trigger {
+    width: 100%;
+}
+
 .selector-mask {
     position: fixed;
     inset: 0;

+ 915 - 0
pages/psiManagement/wareHouse/WareHouseAddForm.vue

@@ -0,0 +1,915 @@
+<template>
+    <view class="page-wrap">
+        <u--form :model="inputForm" labelWidth="100px" class="u-form" labelPosition="left" :rules="rules"
+            ref="inputForm">
+            <u-form-item label="入库编号" borderBottom prop="wareHouseNumber">
+                <u--input placeholder="自动生成" v-model="inputForm.wareHouseNumber" disabled></u--input>
+            </u-form-item>
+            <u-form-item label="入库名称" borderBottom prop="wareHouseName" :required="true">
+                <u--input placeholder="请填写入库名称" v-model="inputForm.wareHouseName" :disabled="nodeFlag"></u--input>
+            </u-form-item>
+            <u-form-item label="经办人" borderBottom prop="handledBy">
+                <u--input v-model="inputForm.handledBy" disabled></u--input>
+            </u-form-item>
+            <u-form-item label="经办部门" borderBottom prop="handledByOfficeName">
+                <u--input v-model="inputForm.handledByOfficeName" disabled></u--input>
+            </u-form-item>
+            <u-form-item label="入库时间" borderBottom prop="wareHouseDate" :required="true">
+                <el-date-picker v-model="inputForm.wareHouseDate" type="date" value-format="yyyy-MM-dd"
+                    placeholder="请选择入库时间" style="width:100%" placement="bottom-start" clearable
+                    :disabled="nodeFlag">
+                </el-date-picker>
+            </u-form-item>
+
+            <purchase-selector :inputForm="inputForm" :disabled="nodeFlag" :required="false"
+                @selected="handlePurchaseSelected">
+            </purchase-selector>
+
+            <u-form-item label="备注" borderBottom prop="remarks">
+                <u--textarea placeholder="请填写备注信息" :rows="4" :maxlength="500" v-model="inputForm.remarks"
+                    :disabled="nodeFlag"></u--textarea>
+            </u-form-item>
+
+            <view v-if="inputForm.purchaseNo" class="section-wrap">
+                <view class="section-title">采购详情</view>
+                <view v-for="(item, index) in inputForm.detailInfos" :key="item.id || index" class="detail-card">
+                    <view class="detail-card-title">采购明细 {{ index + 1 }}</view>
+                    <view class="detail-grid">
+                        <view class="detail-item">
+                            <text class="detail-label">采购人</text>
+                            <text class="detail-value">{{ item.purchaserAgent || '-' }}</text>
+                        </view>
+                        <view class="detail-item">
+                            <text class="detail-label">采购部门</text>
+                            <text class="detail-value">{{ item.procurementOffice || '-' }}</text>
+                        </view>
+                        <view class="detail-item">
+                            <text class="detail-label">采购类型</text>
+                            <text class="detail-value">{{ item.procurementType || '-' }}</text>
+                        </view>
+                        <view class="detail-item">
+                            <text class="detail-label">供应商</text>
+                            <text class="detail-value">{{ item.supplierName || '-' }}</text>
+                        </view>
+                        <view class="detail-item">
+                            <text class="detail-label">商品名称</text>
+                            <text class="detail-value">{{ item.tradeName || '-' }}</text>
+                        </view>
+                        <view class="detail-item">
+                            <text class="detail-label">商品数量</text>
+                            <text class="detail-value">{{ item.tradeNumber || '-' }}</text>
+                        </view>
+                        <view class="detail-item">
+                            <text class="detail-label">商品单价</text>
+                            <text class="detail-value">{{ item.tradePrice || '-' }}</text>
+                        </view>
+                        <view class="detail-item">
+                            <text class="detail-label">商品总价</text>
+                            <text class="detail-value">{{ item.priceSum || '-' }}</text>
+                        </view>
+                        <view class="detail-item">
+                            <text class="detail-label">单位</text>
+                            <text class="detail-value">{{ item.company || '-' }}</text>
+                        </view>
+                        <view class="detail-item">
+                            <text class="detail-label">备注</text>
+                            <text class="detail-value">{{ item.remarks || '-' }}</text>
+                        </view>
+                    </view>
+                    <el-button v-if="!nodeFlag" style="width: 100%; margin-top: 16rpx;" type="primary" plain
+                        @click="wareHouseAdd(index)">
+                        入库
+                    </el-button>
+                </view>
+            </view>
+
+            <view class="section-wrap">
+                <view class="section-title">入库详情</view>
+                <view v-for="(item, index) in inputForm.wareHouse" :key="item.id || index"
+                    class="detail-card warehouse-card">
+                    <view class="detail-card-title">入库明细 {{ index + 1 }}</view>
+
+                    <u-form-item label="入库人" :prop="'wareHouse[' + index + '].wareHouseMan'" :required="true">
+                        <u--input v-model="inputForm.wareHouse[index].wareHouseMan" placeholder="请选择入库人"
+                            :disabled="nodeFlag" @focus="openUserPullForm(index)" clearable></u--input>
+                    </u-form-item>
+                    <u-form-item label="入库部门" :prop="'wareHouse[' + index + '].wareHouseManOffice'">
+                        <u--input v-model="inputForm.wareHouse[index].wareHouseManOffice" disabled></u--input>
+                    </u-form-item>
+                    <u-form-item label="入库类型" :prop="'wareHouse[' + index + '].wareHouseType'" :required="true">
+                        <u--input v-model="inputForm.wareHouse[index].wareHouseType" placeholder="请选择入库类型"
+                            :disabled="nodeFlag" @focus="openTypePicker(index)" clearable></u--input>
+                    </u-form-item>
+
+                    <ware-house-goods-selector :rowIndex="index" :inputForm="inputForm" :disabled="nodeFlag"
+                        @selected="handleGoodsSelected"></ware-house-goods-selector>
+                    <ware-house-supplier-selector :rowIndex="index" :inputForm="inputForm" :disabled="nodeFlag"
+                        @selected="handleSupplierSelected"></ware-house-supplier-selector>
+
+                    <u-form-item label="商品数量" :prop="'wareHouse[' + index + '].tradeNumber'" :required="true">
+                        <u--input v-model="inputForm.wareHouse[index].tradeNumber" placeholder="请输入商品数量"
+                            :disabled="nodeFlag" @blur="onRowInputBlur(index, 'tradeNumber')"></u--input>
+                    </u-form-item>
+                    <u-form-item label="单位" :prop="'wareHouse[' + index + '].company'">
+                        <u--input v-model="inputForm.wareHouse[index].company" placeholder="请输入单位" :disabled="nodeFlag"
+                            @blur="calculateWareHouseTotals"></u--input>
+                    </u-form-item>
+                    <u-form-item label="包装规格" :prop="'wareHouse[' + index + '].spec'" :required="true">
+                        <u--input v-model="inputForm.wareHouse[index].spec" placeholder="请输入包装规格" :disabled="nodeFlag"
+                            @blur="onRowInputBlur(index, 'spec')"></u--input>
+                    </u-form-item>
+                    <u-form-item label="商品单价(元)" :prop="'wareHouse[' + index + '].tradePrice'">
+                        <u--input v-model="inputForm.wareHouse[index].tradePrice" placeholder="请输入商品单价"
+                            :disabled="nodeFlag" @blur="onRowInputBlur(index, 'tradePrice')"></u--input>
+                    </u-form-item>
+                    <u-form-item label="商品总价" :prop="'wareHouse[' + index + '].priceSum'">
+                        <u--input v-model="inputForm.wareHouse[index].priceSum" placeholder="自动计算" disabled></u--input>
+                    </u-form-item>
+                    <u-form-item label="生产日期" :prop="'wareHouse[' + index + '].produceDate'">
+                        <el-date-picker v-model="inputForm.wareHouse[index].produceDate" type="date"
+                            placeholder="请选择生产日期" style="width:100%" placement="bottom-start" clearable
+                            :disabled="nodeFlag">
+                        </el-date-picker>
+                    </u-form-item>
+                    <u-form-item label="保质期" :prop="'wareHouse[' + index + '].shelfLife'">
+                        <view class="shelf-life-wrap">
+                            <u--input class="shelf-life-input"  v-model="inputForm.wareHouse[index].shelfLife"
+                                placeholder="请输入保质期" :disabled="nodeFlag">
+                            </u--input>
+                            <jp-picker class="shelf-life-unit" placeholder="单位"
+                                v-model="inputForm.wareHouse[index].shelfLifeUnit" :disabled="nodeFlag" rangeKey="label"
+                                rangeValue="value" :range="shelfLifeUnitOptions">
+                            </jp-picker>
+                        </view>
+                    </u-form-item>
+                    <u-form-item label="实际价格" :prop="'wareHouse[' + index + '].actualPrice'">
+                        <u--input v-model="inputForm.wareHouse[index].actualPrice" placeholder="请输入实际价格"
+                            :disabled="nodeFlag" @blur="onRowInputBlur(index, 'actualPrice')"></u--input>
+                    </u-form-item>
+                    <u-form-item label="备注" :prop="'wareHouse[' + index + '].remarks'">
+                        <u--input v-model="inputForm.wareHouse[index].remarks" placeholder="请输入备注" :disabled="nodeFlag">
+                        </u--input>
+                    </u-form-item>
+                    <u-form-item label="附件上传">
+                        <UploadComponent :uploadUrl="`${uploadUrl}/public-modules-server/oss/file/webUpload/upload`"
+                            @onRemove="(file, fileList, fileIndex) => handleRemove(file, fileList, index, fileIndex, 'detail')"
+                            @onSuccess="(file, fileList) => handleUploadSuccess(file, fileList, index, 'detail')"
+                            :fileList="inputForm.wareHouse[index].fileInfoLost" :limit="3" :isDelete="nodeFlag"
+                            :isUpload="nodeFlag">
+                        </UploadComponent>
+                    </u-form-item>
+
+                    <u-form-item label="" v-if="!nodeFlag">
+                        <el-button style="width: 100%" type="danger" plain @click="removeWareHouseRow(index)">
+                            删除入库明细 {{ index + 1 }}
+                        </el-button>
+                    </u-form-item>
+                </view>
+
+                <u-form-item label="" v-if="!nodeFlag">
+                    <el-button style="width: 100%" type="primary" @click="addWareHouseRow()" plain>新增入库明细</el-button>
+                </u-form-item>
+            </view>
+
+            <u-form-item label="附件">
+                <UploadComponent :uploadUrl="`${uploadUrl}/public-modules-server/oss/file/webUpload/upload`"
+                    @onRemove="(file, fileList, fileIndex) => handleRemove(file, fileList, '', fileIndex, '')"
+                    @onSuccess="(file, fileList) => handleUploadSuccess(file, fileList, '', '')"
+                    :fileList="inputForm.files" :limit="3" :isDelete="nodeFlag" :isUpload="nodeFlag">
+                </UploadComponent>
+            </u-form-item>
+        </u--form>
+
+        <view v-if="!nodeFlag" class="submit-bar">
+            <el-button class="submit-button" type="primary" :loading="loading" @click="handlePageSubmit">
+                提交
+            </el-button>
+        </view>
+
+        <user-select ref="userPicker" @input="handleUserSelected"></user-select>
+        <ba-tree-picker ref="treePicker" :multiple="false" @select-change="selectTypeChange" title="类型选择"
+            :localdata="listData" valueKey="value" textKey="label" childrenKey="children" />
+    </view>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+import userSelect from '@/components/user-select/user-select-radio.vue'
+import baTreePicker from '@/components/ba-tree-picker/ba-tree-picker.vue'
+import UploadComponent from '@/pages/common/UploadComponent.vue'
+import upload from '@/utils/upload.js'
+import MaterialTypeService from '@/api/psi/MaterialTypeService'
+import MaterialManagementService from '@/api/psi/MaterialManagementService'
+import WareHouseService from '@/api/psi/WareHouseService'
+import PurchaseSelector from './PurchaseSelector.vue'
+import WareHouseGoodsSelector from './WareHouseGoodsSelector.vue'
+import WareHouseSupplierSelector from './WareHouseSupplierSelector.vue'
+
+export default {
+    name: 'PsiWareHouseAddForm',
+    components: {
+        userSelect,
+        baTreePicker,
+        UploadComponent,
+        PurchaseSelector,
+        WareHouseGoodsSelector,
+        WareHouseSupplierSelector
+    },
+    computed: mapState({
+        userInfo: (state) => state.user.userInfo
+    }),
+    props: {
+        businessId: {
+            type: String,
+            default: ''
+        },
+        formReadOnly: {
+            type: Boolean,
+            default: false
+        },
+        status: {
+            type: String,
+            default: ''
+        },
+        isCc: {
+            type: Boolean,
+            default: false
+        }
+    },
+    data() {
+        return {
+            uploadUrl: upload.UPLOAD_URL,
+            nodeFlag: false,
+            loading: false,
+            listData: [],
+            materialList: [],
+            currentTypeIndex: -1,
+            inputForm: this.createInputForm(),
+            rules: {
+                wareHouseName: [
+                    {
+                        required: true,
+                        message: '入库名称不能为空',
+                        trigger: ['blur', 'change']
+                    }
+                ]
+            },
+            shelfLifeUnitOptions: [
+                { label: '年', value: '年' },
+                { label: '月', value: '月' },
+                { label: '天', value: '天' }
+            ]
+        }
+    },
+    materialTypeService: null,
+    materialManagementService: null,
+    wareHouseService: null,
+    created() {
+        this.ensureServices()
+        this.loadMaterialTypes()
+        this.resetForm()
+    },
+    watch: {
+        userInfo: {
+            handler() {
+                this.fillUserInfo()
+            },
+            immediate: true,
+            deep: true
+        }
+    },
+    onLoad(options = {}) {
+        this.ensureServices()
+        this.resetForm()
+        if (options.purchaseId) {
+            this.loadPurchaseById(options.purchaseId)
+        } else if (options.id) {
+            this.init('purchaseAdd', options.id)
+        }
+    },
+    methods: {
+        createInputForm() {
+            return {
+                id: '',
+                procInsId: '',
+                processDefinitionId: '',
+                status: '',
+                wareHouseTotalPrice: '',
+                wareHouseActualPrice: '',
+                tradeTotalPrice: '',
+                fileInfoLost: [],
+                purchaseNo: '',
+                purchaseId: '',
+                contractNo: '',
+                handledBy: '',
+                handledById: '',
+                handledByOffice: '',
+                handledByOfficeName: '',
+                wareHouseName: '',
+                wareHouseNumber: '',
+                userId: '',
+                wareHouseDate: '',
+                remarks: '',
+                detailInfos: [],
+                wareHouse: [],
+                files: [],
+                functionFlag: ''
+            }
+        },
+        ensureServices() {
+            if (!this.materialTypeService) {
+                this.materialTypeService = new MaterialTypeService()
+            }
+            if (!this.materialManagementService) {
+                this.materialManagementService = new MaterialManagementService()
+            }
+            if (!this.wareHouseService) {
+                this.wareHouseService = new WareHouseService()
+            }
+        },
+        async loadMaterialTypes() {
+            try {
+                const data = await this.materialTypeService.cgList()
+                this.materialList = data || []
+                this.listData = this.buildTree(this.materialList)
+            } catch (e) {
+                this.materialList = []
+                this.listData = []
+            }
+        },
+        fillUserInfo() {
+            if (!this.userInfo) {
+                return
+            }
+            const office = this.userInfo.officeDTO || this.userInfo.office || {}
+            this.inputForm.handledBy = this.inputForm.handledBy || this.userInfo.name || this.userInfo.realname || ''
+            this.inputForm.handledById = this.inputForm.handledById || this.userInfo.id || this.userInfo.userId || ''
+            this.inputForm.userId = this.inputForm.userId || this.userInfo.id || this.userInfo.userId || ''
+            this.inputForm.handledByOffice = this.inputForm.handledByOffice || office.id || this.userInfo.officeId || ''
+            this.inputForm.handledByOfficeName = this.inputForm.handledByOfficeName || office.name || this.userInfo.officeName || ''
+        },
+        resetForm() {
+            this.inputForm = this.createInputForm()
+            this.fillUserInfo()
+            this.nodeFlag = !!this.formReadOnly
+        },
+        init(method, id) {
+            this.resetForm()
+            if (method === 'purchaseAdd' && id) {
+                this.loadPurchaseById(id)
+            }
+        },
+        async loadPurchaseById(id) {
+            try {
+                const data = await this.materialManagementService.findById(id)
+                this.applyPurchaseData(data, id)
+            } catch (e) {
+                uni.showToast({
+                    title: '采购详情加载失败',
+                    icon: 'none'
+                })
+            }
+        },
+        applyPurchaseData(data, id) {
+            const purchase = data || {}
+            this.inputForm.purchaseNo = purchase.purchaseNo || ''
+            this.inputForm.purchaseId = id || purchase.id || ''
+            this.inputForm.detailInfos = (purchase.detailInfos || []).map(item => ({
+                ...item,
+                fileInfoLost: item.fileInfoLost || [],
+                priceSum: this.computePriceSum(item.tradePrice, item.tradeNumber)
+            }))
+            this.calculateDetailTotalPrice()
+            this.calculateWareHouseTotals()
+        },
+        buildTree(nodes, parentId = '0') {
+            const tree = []
+            for (const node of nodes || []) {
+                if (node.parentId === parentId) {
+                    const treeNode = {
+                        ...node
+                    }
+                    const children = this.buildTree(nodes, node.id)
+                    if (children.length) {
+                        treeNode.children = children
+                    }
+                    tree.push(treeNode)
+                }
+            }
+            return tree
+        },
+        isEmpty(value) {
+            if (value === null || value === undefined) {
+                return true
+            }
+            if (typeof value === 'string' && value.trim() === '') {
+                return true
+            }
+            if (Array.isArray(value) && value.length === 0) {
+                return true
+            }
+            return false
+        },
+        isNotEmpty(value) {
+            return !this.isEmpty(value)
+        },
+        computePriceSum(price, number) {
+            if (this.isEmpty(price) || this.isEmpty(number)) {
+                return ''
+            }
+            const amount = parseFloat(price || 0) * parseFloat(number || 0)
+            if (Number.isNaN(amount)) {
+                return ''
+            }
+            return amount.toFixed(2)
+        },
+        calculateDetailTotalPrice() {
+            const total = (this.inputForm.detailInfos || []).reduce((sum, item) => {
+                return sum + parseFloat(item.priceSum || 0)
+            }, 0)
+            this.inputForm.tradeTotalPrice = total ? total.toFixed(2) : ''
+        },
+        calculateWareHouseTotals() {
+            const totalPrice = (this.inputForm.wareHouse || []).reduce((sum, item) => {
+                return sum + parseFloat(item.priceSum || 0)
+            }, 0)
+            const totalActual = (this.inputForm.wareHouse || []).reduce((sum, item) => {
+                return sum + parseFloat(item.actualPrice || 0)
+            }, 0)
+            this.inputForm.wareHouseTotalPrice = totalPrice ? totalPrice.toFixed(2) : ''
+            this.inputForm.wareHouseActualPrice = totalActual ? totalActual.toFixed(2) : ''
+        },
+        openUserPullForm(index) {
+            if (this.nodeFlag) {
+                return
+            }
+            this.$refs.userPicker.open(index, 'wareHouse')
+        },
+        handleUserSelected(data, index, type) {
+            if (type !== 'wareHouse') {
+                return
+            }
+            this.patchWareHouseRow(index, {
+                wareHouseManId: data.id,
+                wareHouseMan: data.label,
+                wareHouseManOffice: data.parentLabel,
+                deptId: data.parentId
+            })
+        },
+        openTypePicker(index) {
+            if (this.nodeFlag) {
+                return
+            }
+            this.currentTypeIndex = index
+            this.$refs.treePicker._show(index)
+        },
+        selectTypeChange(ids, names, index) {
+            this.patchWareHouseRow(index, {
+                wareHouseType: names,
+                wareHouseTypeId: ids[0],
+                tradeName: '',
+                supplierName: '',
+                supplierId: '',
+                isSupplier: '',
+                tradePrice: '',
+                tradeNumber: '',
+                priceSum: '',
+                company: '',
+                spec: '',
+                actualPrice: '',
+                surplusNumber: ''
+            })
+        },
+        async handlePurchaseSelected(row) {
+            try {
+                const data = await this.materialManagementService.findById(row.id)
+                if (this.isNotEmpty(this.inputForm.purchaseNo) && this.inputForm.purchaseNo !== data.purchaseNo) {
+                    this.inputForm.wareHouse = []
+                }
+                this.applyPurchaseData(data, row.id)
+            } catch (e) {
+                uni.showToast({
+                    title: '采购详情加载失败',
+                    icon: 'none'
+                })
+            }
+        },
+        handleGoodsSelected({ index, item }) {
+            this.patchWareHouseRow(index, {
+                tradeName: item.tradeName || ''
+            })
+        },
+        handleSupplierSelected({ index, item }) {
+            this.patchWareHouseRow(index, {
+                supplierName: item.name || '',
+                supplierId: item.id || '',
+                isSupplier: '2'
+            })
+        },
+        createWareHouseRow(row = {}) {
+            const office = (this.userInfo && (this.userInfo.officeDTO || this.userInfo.office)) || {}
+            return {
+                id: '',
+                wareHouseManId: this.userInfo && (this.userInfo.id || this.userInfo.userId),
+                wareHouseMan: this.userInfo && (this.userInfo.name || this.userInfo.realname),
+                wareHouseManOffice: office.name || (this.userInfo && this.userInfo.officeName),
+                deptId: office.id || (this.userInfo && this.userInfo.officeId),
+                wareHouseType: '',
+                wareHouseTypeId: '',
+                tradeName: '',
+                supplierName: '',
+                supplierId: '',
+                isSupplier: '',
+                tradeNumber: '',
+                company: '',
+                spec: '',
+                tradePrice: '',
+                priceSum: '',
+                produceDate: '',
+                shelfLife: '',
+                shelfLifeUnit: '月',
+                actualPrice: '',
+                remarks: '',
+                fileInfoLost: [],
+                ...row
+            }
+        },
+        addWareHouseRow(row) {
+            this.inputForm.wareHouse.push(this.createWareHouseRow(row))
+            this.calculateWareHouseTotals()
+        },
+        wareHouseAdd(index) {
+            const detail = (this.inputForm.detailInfos || [])[index]
+            if (!detail) {
+                return
+            }
+            const row = {
+                wareHouseTypeId: detail.procurementTypeId || '',
+                wareHouseType: detail.procurementType || '',
+                tradeName: detail.tradeName || '',
+                tradeNumber: detail.tradeNumber || '',
+                tradePrice: detail.tradePrice || '',
+                company: detail.company || '',
+                priceSum: this.computePriceSum(detail.tradePrice, detail.tradeNumber),
+                supplierId: '',
+                supplierName: '',
+                isSupplier: '',
+                spec: '',
+                produceDate: '',
+                shelfLife: '',
+                shelfLifeUnit: '月'
+            }
+            if (this.isNotEmpty(detail.supplierId) && this.isNotEmpty(detail.isSupplier) && detail.isSupplier === '2') {
+                row.supplierId = detail.supplierId
+                row.supplierName = detail.supplierName
+                row.isSupplier = detail.isSupplier
+            }
+            this.addWareHouseRow(row)
+        },
+        patchWareHouseRow(index, patch) {
+            const row = (this.inputForm.wareHouse || [])[index] || {}
+            const nextRow = {
+                ...row,
+                ...patch
+            }
+            if (Object.prototype.hasOwnProperty.call(patch, 'tradePrice') || Object.prototype.hasOwnProperty.call(patch, 'tradeNumber')) {
+                nextRow.priceSum = this.computePriceSum(nextRow.tradePrice, nextRow.tradeNumber)
+            }
+            this.$set(this.inputForm.wareHouse, index, nextRow)
+            this.calculateWareHouseTotals()
+        },
+        removeWareHouseRow(index) {
+            this.inputForm.wareHouse.splice(index, 1)
+            this.calculateWareHouseTotals()
+        },
+        onRowInputBlur(index, field) {
+            const row = (this.inputForm.wareHouse || [])[index]
+            if (!row) {
+                return
+            }
+            let value = row[field]
+            if (['tradeNumber', 'tradePrice', 'actualPrice'].includes(field)) {
+                value = this.formatNumberInput(value)
+            }
+            if (field === 'spec') {
+                value = this.formatIntegerInput(value)
+                if (this.isNotEmpty(value) && parseInt(value, 10) <= 0) {
+                    value = ''
+                    this.$message.warning('请输入除0以外的正整数')
+                }
+            }
+            this.patchWareHouseRow(index, {
+                [field]: value
+            })
+        },
+        formatNumberInput(inputValue, decimalLimit = 2) {
+            if (this.isEmpty(inputValue)) {
+                return ''
+            }
+            const valueText = String(inputValue)
+            if (!/^\d*\.?\d*$/.test(valueText)) {
+                return ''
+            }
+            let value = valueText.replace(/[^\d.]/g, '')
+            const dotIndex = value.indexOf('.')
+            if (dotIndex !== -1) {
+                const substr = value.substr(dotIndex + 1)
+                if (substr.indexOf('.') !== -1) {
+                    value = value.substr(0, dotIndex + 1) + substr.replace(/\./g, '')
+                }
+                const integerPart = value.substring(0, dotIndex)
+                const decimalPart = value.substring(dotIndex + 1, dotIndex + 1 + decimalLimit)
+                value = integerPart + '.' + decimalPart
+            }
+            return value
+        },
+        formatIntegerInput(inputValue) {
+            if (this.isEmpty(inputValue)) {
+                return ''
+            }
+            return String(inputValue).replace(/[^\d]/g, '')
+        },
+        handleUploadSuccess(file, fileList, index, type) {
+            if (type === 'detail') {
+                this.inputForm.wareHouse[index].fileInfoLost = fileList
+            } else {
+                this.inputForm.files = fileList
+            }
+        },
+        handleRemove(file, fileList, lineIndex, fileIndex, type) {
+            if (type === 'detail') {
+                this.inputForm.wareHouse[lineIndex].fileInfoLost.splice(fileIndex, 1)
+            } else {
+                this.inputForm.files.splice(fileIndex, 1)
+            }
+        },
+        formatDate(date) {
+            if (this.isEmpty(date)) {
+                return ''
+            }
+            const dateNew = new Date(date)
+            if (Number.isNaN(dateNew.getTime())) {
+                return ''
+            }
+            const year = dateNew.getFullYear()
+            const month = `${dateNew.getMonth() + 1}`.padStart(2, '0')
+            const day = `${dateNew.getDate()}`.padStart(2, '0')
+            return `${year}-${month}-${day}`
+        },
+        toSubmitData() {
+            const data = JSON.parse(JSON.stringify(this.inputForm))
+            data.wareHouseDate = this.formatDate(this.inputForm.wareHouseDate)
+            data.wareHouse = (this.inputForm.wareHouse || []).map(item => ({
+                ...JSON.parse(JSON.stringify(item)),
+                produceDate: this.formatDate(item.produceDate),
+                actualPrice: this.normalizeOptionalNumber(item.actualPrice)
+            }))
+            return data
+        },
+        normalizeOptionalNumber(value) {
+            if (this.isEmpty(value)) {
+                return null
+            }
+            return value
+        },
+        validateBaseForm() {
+            if (this.isEmpty(this.inputForm.wareHouseDate)) {
+                this.$message.error('入库时间不能为空')
+                return false
+            }
+            return true
+        },
+        validateWareHouseRows() {
+            if (this.isEmpty(this.inputForm.wareHouse)) {
+                this.$message.error('至少填写一条入库详情信息')
+                return false
+            }
+            const rows = this.inputForm.wareHouse
+            for (let i = 0; i < rows.length; i++) {
+                const row = rows[i]
+                const lineNo = i + 1
+                if (this.isEmpty(row.wareHouseMan)) {
+                    this.$message.error(`入库详情第${lineNo}行请选择入库人`)
+                    return false
+                }
+                if (this.isEmpty(row.wareHouseType)) {
+                    this.$message.error(`入库详情第${lineNo}行请选择入库类型`)
+                    return false
+                }
+                if (this.isEmpty(row.supplierName) || this.isEmpty(row.supplierId)) {
+                    this.$message.error(`入库详情第${lineNo}行请选择供应商`)
+                    return false
+                }
+                if (this.isEmpty(row.tradeName)) {
+                    this.$message.error(`入库详情第${lineNo}行请填写商品名称`)
+                    return false
+                }
+                if (this.isEmpty(row.tradeNumber)) {
+                    this.$message.error(`入库详情第${lineNo}行请填写商品数量`)
+                    return false
+                }
+                if (this.isEmpty(row.spec)) {
+                    this.$message.error(`入库详情第${lineNo}行请填写包装规格`)
+                    return false
+                }
+            }
+            for (let i = 0; i < rows.length; i++) {
+                for (let j = i + 1; j < rows.length; j++) {
+                    if (rows[i].wareHouseTypeId === rows[j].wareHouseTypeId &&
+                        rows[i].tradeName === rows[j].tradeName &&
+                        rows[i].supplierId === rows[j].supplierId) {
+                        this.$message.warning('入库详情中,同种入库类型、同一供应商的商品名称只能输入一条')
+                        return false
+                    }
+                }
+            }
+            return true
+        },
+        confirmShelfLifeRows() {
+            const rows = this.inputForm.wareHouse || []
+            const index = rows.findIndex(row => {
+                return (this.isEmpty(row.produceDate) && this.isNotEmpty(row.shelfLife)) ||
+                    (this.isNotEmpty(row.produceDate) && this.isEmpty(row.shelfLife))
+            })
+            if (index === -1) {
+                return Promise.resolve(true)
+            }
+            const row = rows[index]
+            return new Promise(resolve => {
+                uni.showModal({
+                    title: '提示',
+                    content: `入库详情第${index + 1}行的${row.tradeName || '商品'}的生产日期或保质期未填写,是否继续提交?`,
+                    success: res => {
+                        resolve(!!res.confirm)
+                    },
+                    fail: () => {
+                        resolve(false)
+                    }
+                })
+            })
+        },
+        async submitWithStatus(status, functionFlag, callback) {
+            this.fillUserInfo()
+            await this.$refs.inputForm.validate()
+            if (!this.validateBaseForm()) {
+                return
+            }
+            if (!this.validateWareHouseRows()) {
+                return
+            }
+            const confirmed = await this.confirmShelfLifeRows()
+            if (!confirmed) {
+                return
+            }
+            this.loading = true
+            try {
+                this.calculateDetailTotalPrice()
+                this.calculateWareHouseTotals()
+                const submitData = this.toSubmitData()
+                submitData.status = status
+                submitData.functionFlag = functionFlag
+                this.inputForm.status = status
+                this.inputForm.functionFlag = functionFlag
+                const data = await this.wareHouseService.save(submitData)
+                this.inputForm.id = data.businessId
+                if (callback) {
+                    callback(data.businessTable, data.businessId, submitData)
+                }
+                return data
+            } finally {
+                this.loading = false
+            }
+        },
+        saveForm(callback) {
+            return this.submitWithStatus('1', '', callback)
+        },
+        async handlePageSubmit() {
+            const data = await this.submitWithStatus('0', '')
+            if (!data) {
+                return
+            }
+            uni.showToast({
+                title: '提交成功',
+                icon: 'success'
+            })
+            setTimeout(() => {
+                uni.navigateBack()
+            }, 800)
+        },
+        startForm(callback) {
+            return this.startFormTrue(callback)
+        },
+        startFormTrue(callback) {
+            return this.submitWithStatus('2', 'start', callback)
+        },
+        reapplyForm(callback) {
+            return this.startFormTrue(callback)
+        },
+        agreeForm(callback) {
+            return this.submitWithStatus('5', 'agree', callback)
+        }
+    }
+}
+</script>
+
+<style scoped>
+.page-wrap {
+    padding-bottom: 120rpx;
+}
+
+.section-wrap {
+    margin-top: 24rpx;
+}
+
+.section-title {
+    margin-bottom: 16rpx;
+    padding-left: 8rpx;
+    font-size: 30rpx;
+    font-weight: 700;
+    color: #1f2937;
+    border-left: 6rpx solid #2979ff;
+}
+
+.detail-card {
+    margin-bottom: 20rpx;
+    padding: 24rpx;
+    background: #fff;
+    border-radius: 20rpx;
+    box-shadow: 0 10rpx 30rpx rgba(15, 23, 42, 0.05);
+}
+
+.warehouse-card {
+    padding-bottom: 16rpx;
+}
+
+.detail-card-title {
+    margin-bottom: 12rpx;
+    font-size: 28rpx;
+    font-weight: 600;
+    color: #0f172a;
+}
+
+.detail-grid {
+    display: grid;
+    grid-template-columns: repeat(2, minmax(0, 1fr));
+    gap: 16rpx;
+}
+
+.detail-item {
+    display: flex;
+    flex-direction: column;
+    padding: 18rpx 20rpx;
+    background: #f8fafc;
+    border-radius: 16rpx;
+}
+
+.detail-label {
+    font-size: 22rpx;
+    color: #64748b;
+}
+
+.detail-value {
+    margin-top: 8rpx;
+    font-size: 26rpx;
+    line-height: 1.5;
+    color: #0f172a;
+    word-break: break-all;
+}
+
+.shelf-life-wrap {
+    display: flex;
+    width: 100%;
+    gap: 16rpx;
+}
+
+.shelf-life-input {
+    flex: 1;
+    min-width: 0;
+}
+
+.shelf-life-unit {
+    flex: 0 0 128rpx;
+    width: 128rpx;
+}
+
+.submit-bar {
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 20;
+    padding: 18rpx 28rpx calc(18rpx + env(safe-area-inset-bottom));
+    background: #fff;
+    box-shadow: 0 -8rpx 24rpx rgba(15, 23, 42, 0.08);
+}
+
+.submit-button {
+    width: 100%;
+}
+
+@media (max-width: 768px) {
+    .detail-grid {
+        grid-template-columns: repeat(1, minmax(0, 1fr));
+    }
+}
+</style>

+ 35 - 2
pages/psiManagement/wareHouse/WareHouseGoodsSelector.vue

@@ -1,8 +1,13 @@
 <template>
     <view>
         <u-form-item label="商品名称" :prop="'wareHouse[' + rowIndex + '].tradeName'" :required="true">
-            <u--input :value="currentValue" placeholder="请选择商品名称" readonly :disabled="disabled"
-                @focus="openPicker"></u--input>
+            <view class="goods-input-wrap">
+                <u--input class="goods-input" :value="currentValue" placeholder="请输入或选择商品名称" :disabled="disabled"
+                    @input="handleManualInput"></u--input>
+                <el-button class="goods-select-btn" type="primary" plain :disabled="disabled" @click="openPicker">
+                    选择
+                </el-button>
+            </view>
         </u-form-item>
 
         <view class="selector-mask" :class="{ show: visible }" @tap="closePicker"></view>
@@ -79,6 +84,17 @@ export default {
             }
             return false
         },
+        handleManualInput(value) {
+            if (this.disabled) {
+                return
+            }
+            const rows = (this.inputForm && this.inputForm.wareHouse) || []
+            const row = rows[this.rowIndex]
+            if (!row) {
+                return
+            }
+            this.$set(row, 'tradeName', value)
+        },
         async openPicker() {
             if (this.disabled) {
                 return
@@ -127,6 +143,23 @@ export default {
 </script>
 
 <style scoped>
+.goods-input-wrap {
+    display: flex;
+    align-items: center;
+    width: 100%;
+    gap: 16rpx;
+}
+
+.goods-input {
+    flex: 1;
+    min-width: 0;
+}
+
+.goods-select-btn {
+    flex: 0 0 132rpx;
+    width: 132rpx;
+}
+
 .selector-mask {
     position: fixed;
     inset: 0;

+ 24 - 2
pages/psiManagement/wareHouse/WareHouseSupplierSelector.vue

@@ -1,8 +1,13 @@
 <template>
     <view>
         <u-form-item label="供应商" :prop="'wareHouse[' + rowIndex + '].supplierName'" :required="true">
-            <u--input :value="currentValue" placeholder="请选择供应商" readonly :disabled="disabled"
-                @focus="openPicker"></u--input>
+            <view class="supplier-input-wrap" @tap.stop="openPicker">
+                <u--input class="supplier-input" :value="currentValue" placeholder="请选择供应商" readonly
+                    :disabled="disabled" @focus="openPicker" @click="openPicker" @tap="openPicker"></u--input>
+                <el-button class="supplier-select-btn" type="primary" plain :disabled="disabled" @click="openPicker">
+                    选择
+                </el-button>
+            </view>
         </u-form-item>
 
         <view class="selector-mask" :class="{ show: visible }" @tap="closePicker"></view>
@@ -113,6 +118,23 @@ export default {
 </script>
 
 <style scoped>
+.supplier-input-wrap {
+    display: flex;
+    align-items: center;
+    width: 100%;
+    gap: 16rpx;
+}
+
+.supplier-input {
+    flex: 1;
+    min-width: 0;
+}
+
+.supplier-select-btn {
+    flex: 0 0 132rpx;
+    width: 132rpx;
+}
+
 .selector-mask {
     position: fixed;
     inset: 0;

+ 68 - 0
pages/psiManagement/wareHouseSummary/EditTradeNameDialog.vue

@@ -0,0 +1,68 @@
+<template>
+    <el-dialog title="修改商品名称" :visible.sync="visible" width="86%" append-to-body>
+        <u--input v-model="inputForm.tradeName" placeholder="请输入商品名称"></u--input>
+        <span slot="footer">
+            <el-button @click="visible = false">取消</el-button>
+            <el-button type="primary" @click="submit">确定</el-button>
+        </span>
+    </el-dialog>
+</template>
+
+<script>
+import WareHouseService from '@/api/psi/WareHouseService'
+
+export default {
+    name: 'EditTradeNameDialog',
+    data() {
+        return {
+            visible: false,
+            inputForm: {
+                oldTradeName: '',
+                tradeName: '',
+                wareHouseType: '',
+                wareHouseTypeName: ''
+            }
+        }
+    },
+    wareHouseService: null,
+    created() {
+        this.wareHouseService = new WareHouseService()
+    },
+    methods: {
+        open(row) {
+            this.inputForm = {
+                oldTradeName: (row && row.tradeName) || '',
+                tradeName: (row && row.tradeName) || '',
+                wareHouseType: (row && row.wareHouseType) || '',
+                wareHouseTypeName: (row && row.wareHouseTypeName) || ''
+            }
+            this.visible = true
+        },
+        submit() {
+            if (!this.inputForm.tradeName) {
+                uni.showToast({
+                    title: '商品名称不能为空',
+                    icon: 'none'
+                })
+                return
+            }
+            uni.showModal({
+                title: '提示',
+                content: `确定将 [${this.inputForm.wareHouseTypeName}] 商品 "${this.inputForm.oldTradeName}" 全部改为 "${this.inputForm.tradeName}" 吗?`,
+                success: async res => {
+                    if (!res.confirm) {
+                        return
+                    }
+                    await this.wareHouseService.saveTradeName(this.inputForm.oldTradeName, this.inputForm.tradeName, this.inputForm.wareHouseType)
+                    this.visible = false
+                    uni.showToast({
+                        title: '修改成功',
+                        icon: 'success'
+                    })
+                    this.$emit('success')
+                }
+            })
+        }
+    }
+}
+</script>

+ 278 - 0
pages/psiManagement/wareHouseSummary/WareHouseHistoryPanel.vue

@@ -0,0 +1,278 @@
+<template>
+    <view>
+        <view class="panel-mask" :class="{ show: visible }" @tap="close"></view>
+        <view class="history-panel" :class="{ show: visible }">
+            <view class="panel-header">
+                <view class="panel-action" @tap="close">关闭</view>
+                <view class="panel-title">{{ tradeName || '库存记录' }}</view>
+                <view class="panel-action panel-action-placeholder">关闭</view>
+            </view>
+            <view class="history-tabs">
+                <view class="history-tab" :class="{ active: activeTab === 'wareHouse' }" @tap="activeTab = 'wareHouse'">
+                    入库
+                </view>
+                <view class="history-tab" :class="{ active: activeTab === 'collect' }" @tap="activeTab = 'collect'">
+                    领用
+                </view>
+                <view class="history-tab" :class="{ active: activeTab === 'loss' }" @tap="activeTab = 'loss'">
+                    报损
+                </view>
+            </view>
+            <scroll-view scroll-y class="history-list">
+                <view v-if="loading" class="panel-state">加载中...</view>
+                <view v-else-if="activeHistoryList.length === 0" class="panel-state">暂无记录</view>
+                <view v-else class="history-list-inner">
+                    <view v-for="(record, index) in activeHistoryList" :key="record.id || index" class="history-card">
+                        <template v-if="activeTab === 'wareHouse'">
+                            <view class="history-title">{{ record.wareHouseName || record.wareHouseNumber || '-' }}</view>
+                            <view class="history-grid">
+                                <text>入库编号:{{ record.wareHouseNumber || '-' }}</text>
+                                <text>入库数量:{{ record.tradeNumber || '-' }}</text>
+                                <text>当前库存:{{ record.currentInventory || '-' }}</text>
+                                <text>生产日期:{{ record.produceDate || '-' }}</text>
+                                <text>保质期:{{ formatShelfLife(record) }}</text>
+                                <text>经办人:{{ record.wareHouseHandledBy || '-' }}</text>
+                                <text>入库时间:{{ record.wareHouseDate || '-' }}</text>
+                            </view>
+                        </template>
+                        <template v-else-if="activeTab === 'collect'">
+                            <view class="history-title">{{ record.collectNo || record.goodsName || '-' }}</view>
+                            <view class="history-grid">
+                                <text>领用数量:{{ calcCollectRecordNumber(record) }}</text>
+                                <text>当前库存:{{ record.currentInventory || '-' }}</text>
+                                <text>经办人:{{ record.collectHandleBy || '-' }}</text>
+                                <text>领用时间:{{ record.collectDate || '-' }}</text>
+                            </view>
+                        </template>
+                        <template v-else>
+                            <view class="history-title">{{ record.lossNo || record.goodsName || '-' }}</view>
+                            <view class="history-grid">
+                                <text>报损数量:{{ record.lossNumber || '-' }}</text>
+                                <text>经办人:{{ record.handledByName || '-' }}</text>
+                                <text>经办部门:{{ record.handledByOfficeName || '-' }}</text>
+                                <text>报损时间:{{ record.createTime || '-' }}</text>
+                            </view>
+                        </template>
+                    </view>
+                </view>
+            </scroll-view>
+        </view>
+    </view>
+</template>
+
+<script>
+import WareHouseService from '@/api/psi/WareHouseService'
+import LossService from '@/api/psi/LossService'
+
+export default {
+    name: 'WareHouseHistoryPanel',
+    data() {
+        return {
+            visible: false,
+            loading: false,
+            activeTab: 'wareHouse',
+            tradeName: '',
+            wareHouseHistoryList: [],
+            collectHistoryList: [],
+            lossHistoryList: []
+        }
+    },
+    wareHouseService: null,
+    lossService: null,
+    computed: {
+        activeHistoryList() {
+            if (this.activeTab === 'wareHouse') {
+                return this.wareHouseHistoryList
+            }
+            if (this.activeTab === 'collect') {
+                return this.collectHistoryList
+            }
+            return this.lossHistoryList
+        }
+    },
+    created() {
+        this.wareHouseService = new WareHouseService()
+        this.lossService = new LossService()
+    },
+    methods: {
+        async open(row, supplierId) {
+            this.tradeName = (row && row.tradeName) || ''
+            this.activeTab = 'wareHouse'
+            this.visible = true
+            this.loading = true
+            try {
+                const params = {
+                    current: 1,
+                    size: 20,
+                    tradeName: this.tradeName
+                }
+                const [wareData, collectData, lossData] = await Promise.all([
+                    this.wareHouseService.wareHouseHistoryList({
+                        ...params,
+                        detailId: supplierId ? row.id || '' : ''
+                    }),
+                    this.wareHouseService.collectHistoryList(params),
+                    this.lossService.getLossByTradeName({
+                        current: 1,
+                        size: 20,
+                        goodsName: this.tradeName
+                    })
+                ])
+                this.wareHouseHistoryList = (wareData && wareData.records) || []
+                this.collectHistoryList = (collectData && collectData.records) || []
+                this.lossHistoryList = (lossData && lossData.records) || []
+            } finally {
+                this.loading = false
+            }
+        },
+        close() {
+            this.visible = false
+        },
+        formatShelfLife(row) {
+            if (row.shelfLife && row.shelfLifeUnit) {
+                return `${row.shelfLife}${row.shelfLifeUnit}`
+            }
+            return '-'
+        },
+        calcCollectRecordNumber(row) {
+            if (row.notSurplusStock && row.spec) {
+                const value = parseFloat(row.notSurplusStock) / parseFloat(row.spec)
+                if (Number.isNaN(value)) {
+                    return '-'
+                }
+                return Number.isInteger(value) ? String(value) : value.toFixed(2)
+            }
+            return '-'
+        }
+    }
+}
+</script>
+
+<style scoped>
+.panel-mask {
+    position: fixed;
+    inset: 0;
+    background: rgba(0, 0, 0, 0.35);
+    opacity: 0;
+    visibility: hidden;
+    transition: all 0.25s ease;
+    z-index: 1000;
+}
+
+.panel-mask.show {
+    opacity: 1;
+    visibility: visible;
+}
+
+.history-panel {
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    height: 78vh;
+    background: #f7f9fc;
+    border-radius: 28rpx 28rpx 0 0;
+    transform: translateY(100%);
+    transition: transform 0.25s ease;
+    z-index: 1001;
+    display: flex;
+    flex-direction: column;
+}
+
+.history-panel.show {
+    transform: translateY(0);
+}
+
+.panel-header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 28rpx 32rpx 16rpx;
+    background: #fff;
+    border-bottom: 1rpx solid #eef2f7;
+}
+
+.panel-title {
+    max-width: 460rpx;
+    font-size: 32rpx;
+    font-weight: 600;
+    color: #1f2937;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
+.panel-action {
+    min-width: 80rpx;
+    font-size: 28rpx;
+    color: #2979ff;
+}
+
+.panel-action-placeholder {
+    opacity: 0;
+}
+
+.history-tabs {
+    display: grid;
+    grid-template-columns: repeat(3, minmax(0, 1fr));
+    gap: 12rpx;
+    padding: 18rpx 24rpx;
+    background: #fff;
+}
+
+.history-tab {
+    padding: 16rpx 0;
+    text-align: center;
+    border-radius: 999rpx;
+    font-size: 26rpx;
+    color: #475569;
+    background: #f1f5f9;
+}
+
+.history-tab.active {
+    color: #fff;
+    background: #2979ff;
+}
+
+.history-list {
+    flex: 1;
+    padding: 18rpx 24rpx 32rpx;
+}
+
+.history-list-inner {
+    display: flex;
+    flex-direction: column;
+    gap: 16rpx;
+}
+
+.panel-state {
+    padding-top: 120rpx;
+    text-align: center;
+    font-size: 28rpx;
+    color: #94a3b8;
+}
+
+.history-card {
+    padding: 22rpx;
+    background: #fff;
+    border-radius: 18rpx;
+    box-shadow: 0 8rpx 24rpx rgba(15, 23, 42, 0.05);
+}
+
+.history-title {
+    margin-bottom: 12rpx;
+    font-size: 28rpx;
+    font-weight: 700;
+    color: #0f172a;
+    word-break: break-all;
+}
+
+.history-grid {
+    display: flex;
+    flex-direction: column;
+    gap: 8rpx;
+    font-size: 24rpx;
+    line-height: 1.5;
+    color: #475569;
+}
+</style>

+ 260 - 0
pages/psiManagement/wareHouseSummary/WareHouseSummaryList.vue

@@ -0,0 +1,260 @@
+<template>
+    <view class="page-wrap">
+<!--        <cu-custom :backUrl="'/pages/index/index'" :isBack="true" bgColor="bg-gradual-blue">
+            <block slot="content">库存列表</block>
+        </cu-custom> -->
+
+        <view class="search-panel">
+            <u-search :show-action="false" v-model="searchForm.tradeName" placeholder="搜索商品名称"
+                @search="refreshList" @clear="refreshList"></u-search>
+            <view class="filter-row">
+                <view class="filter-item" @tap="openSupplierPicker">
+                    <text class="filter-label">供应商</text>
+                    <text class="filter-value">{{ searchForm.supplierName || '全部' }}</text>
+                </view>
+            </view>
+            <view class="action-row">
+                <el-button class="action-button" type="primary" @click="refreshList">查询</el-button>
+                <el-button class="action-button" plain @click="resetSearch">重置</el-button>
+            </view>
+        </view>
+
+        <view class="summary-row">
+            <text>共 {{ tablePage.total }} 条库存,已全部展示</text>
+            <text v-if="loading">加载中...</text>
+        </view>
+
+        <view v-if="!loading && dataList.length === 0" class="empty-state">暂无库存数据</view>
+
+        <view v-else class="table-wrap">
+            <el-table class="stock-el-table" :data="dataList" border stripe height="calc(100vh - 260px)"
+                style="width: 100%">
+                <el-table-column type="index" label="序号" width="60" align="center"></el-table-column>
+                <el-table-column prop="tradeName" label="商品名称" min-width="150" show-overflow-tooltip>
+                    <template slot-scope="scope">
+                        <span class="text-strong">{{ scope.row.tradeName || '-' }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="总量" width="90" align="center">
+                    <template slot-scope="scope">{{ formatNumber(scope.row.allNumber) }}</template>
+                </el-table-column>
+                <el-table-column label="领用量" width="90" align="center">
+                    <template slot-scope="scope">{{ calcBorrowNumber(scope.row) }}</template>
+                </el-table-column>
+                <el-table-column label="报损量" width="90" align="center">
+                    <template slot-scope="scope">{{ calcLossNumber(scope.row) }}</template>
+                </el-table-column>
+                <el-table-column label="剩余量" width="90" align="center">
+                    <template slot-scope="scope">
+                        <span class="text-surplus">{{ formatNumber(scope.row.tradeNumber) }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column prop="company" label="单位" width="80" align="center">
+                    <template slot-scope="scope">{{ scope.row.company || '-' }}</template>
+                </el-table-column>
+            </el-table>
+        </view>
+
+        <ware-house-supplier-picker ref="supplierPicker" @selected="selectSupplier" @clear="clearSupplier">
+        </ware-house-supplier-picker>
+    </view>
+</template>
+
+<script>
+import WareHouseService from '@/api/psi/WareHouseService'
+import WareHouseSupplierPicker from './WareHouseSupplierPicker.vue'
+
+export default {
+    name: 'WareHouseSummaryList',
+    components: {
+        WareHouseSupplierPicker
+    },
+    data() {
+        return {
+            loading: false,
+            searchForm: {
+                tradeName: '',
+                supplierId: '',
+                supplierName: ''
+            },
+            dataList: [],
+            tablePage: {
+                total: 0,
+                currentPage: 1,
+                pageSize: 1000000,
+                orders: []
+            }
+        }
+    },
+    wareHouseService: null,
+    created() {
+        this.wareHouseService = new WareHouseService()
+        this.refreshList()
+    },
+    onPullDownRefresh() {
+        this.refreshList().finally(() => {
+            uni.stopPullDownRefresh()
+        })
+    },
+    methods: {
+        getSearchParams() {
+            return {
+                tradeName: this.searchForm.tradeName,
+                supplierId: this.searchForm.supplierId,
+                supplierName: this.searchForm.supplierName
+            }
+        },
+        async refreshList() {
+            this.tablePage.currentPage = 1
+            this.loading = true
+            try {
+                const data = await this.wareHouseService.wareHouseSummaryList({
+                    current: 1,
+                    size: this.tablePage.pageSize,
+                    orders: this.tablePage.orders,
+                    ...this.getSearchParams()
+                })
+                this.dataList = (data && data.records) || []
+                this.tablePage.total = (data && data.total) || this.dataList.length
+            } finally {
+                this.loading = false
+            }
+        },
+        resetSearch() {
+            this.searchForm = {
+                tradeName: '',
+                supplierId: '',
+                supplierName: ''
+            }
+            this.refreshList()
+        },
+        openSupplierPicker() {
+            this.$refs.supplierPicker.open()
+        },
+        selectSupplier(item) {
+            this.searchForm.supplierId = item.id || ''
+            this.searchForm.supplierName = item.name || ''
+            this.refreshList()
+        },
+        clearSupplier() {
+            this.searchForm.supplierId = ''
+            this.searchForm.supplierName = ''
+            this.refreshList()
+        },
+        formatNumber(value) {
+            if (value === null || value === undefined || value === '') {
+                return '0'
+            }
+            return value
+        },
+        calcBorrowNumber(row) {
+            if (row.notSurplusStock && row.spec) {
+                return this.trimNumber(parseFloat(row.notSurplusStock) / parseFloat(row.spec))
+            }
+            return '0'
+        },
+        calcLossNumber(row) {
+            if (row.lossNumber && row.spec) {
+                return this.trimNumber(parseFloat(row.lossNumber) / parseFloat(row.spec))
+            }
+            return '0'
+        },
+        trimNumber(value) {
+            if (Number.isNaN(value)) {
+                return '0'
+            }
+            return Number.isInteger(value) ? String(value) : value.toFixed(2)
+        }
+    }
+}
+</script>
+
+<style scoped>
+.page-wrap {
+    min-height: 100vh;
+    padding: 20rpx 24rpx 48rpx;
+    background: #f6f8fb;
+}
+
+.search-panel {
+    padding: 22rpx;
+    background: #fff;
+    border-radius: 18rpx;
+    box-shadow: 0 8rpx 24rpx rgba(15, 23, 42, 0.05);
+}
+
+.filter-row {
+    display: grid;
+    grid-template-columns: minmax(0, 1fr);
+    gap: 16rpx;
+    margin-top: 18rpx;
+}
+
+.filter-item {
+    min-width: 0;
+    padding: 18rpx 20rpx;
+    background: #f8fafc;
+    border-radius: 14rpx;
+}
+
+.filter-label {
+    display: block;
+    font-size: 22rpx;
+    color: #64748b;
+}
+
+.filter-value {
+    display: block;
+    margin-top: 8rpx;
+    font-size: 26rpx;
+    color: #0f172a;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
+.action-row {
+    display: flex;
+    gap: 16rpx;
+    margin-top: 18rpx;
+}
+
+.action-button {
+    flex: 1;
+}
+
+.summary-row {
+    display: flex;
+    justify-content: space-between;
+    padding: 22rpx 4rpx 12rpx;
+    font-size: 24rpx;
+    color: #64748b;
+}
+
+.empty-state {
+    padding: 120rpx 0;
+    text-align: center;
+    font-size: 28rpx;
+    color: #94a3b8;
+}
+
+.table-wrap {
+    background: #fff;
+    border-radius: 14rpx;
+    box-shadow: 0 8rpx 24rpx rgba(15, 23, 42, 0.05);
+    overflow: hidden;
+}
+
+.text-strong {
+    font-weight: 700;
+}
+
+.text-surplus {
+    font-weight: 800;
+    color: #0f766e;
+}
+
+.stock-el-table {
+    font-size: 24rpx;
+}
+</style>

+ 191 - 0
pages/psiManagement/wareHouseSummary/WareHouseSupplierPicker.vue

@@ -0,0 +1,191 @@
+<template>
+    <view>
+        <view class="selector-mask" :class="{ show: visible }" @tap="close"></view>
+        <view class="selector-panel" :class="{ show: visible }">
+            <view class="selector-header">
+                <view class="selector-action" @tap="close">取消</view>
+                <view class="selector-title">选择供应商</view>
+                <view class="selector-action" @tap="clear">清空</view>
+            </view>
+            <view class="selector-search">
+                <u-search :show-action="false" v-model="keyword" placeholder="搜索供应商名称"></u-search>
+            </view>
+            <scroll-view scroll-y class="selector-list">
+                <view v-if="loading" class="selector-state">加载中...</view>
+                <view v-else-if="filteredList.length === 0" class="selector-state">暂无可选供应商</view>
+                <view v-else class="selector-list-inner">
+                    <view class="selector-card" v-for="item in filteredList" :key="item.id" @tap="select(item)">
+                        <view class="selector-name">{{ item.name }}</view>
+                        <view class="selector-meta">
+                            <text v-if="item.address">地址:{{ item.address }}</text>
+                            <text v-if="item.telPhone">联系电话:{{ item.telPhone }}</text>
+                        </view>
+                    </view>
+                </view>
+            </scroll-view>
+        </view>
+    </view>
+</template>
+
+<script>
+import SupplierService from '@/api/psi/SupplierService'
+
+export default {
+    name: 'WareHouseSupplierPicker',
+    data() {
+        return {
+            visible: false,
+            loading: false,
+            keyword: '',
+            supplierList: []
+        }
+    },
+    supplierService: null,
+    computed: {
+        filteredList() {
+            const keyword = (this.keyword || '').trim().toLowerCase()
+            if (!keyword) {
+                return this.supplierList
+            }
+            return this.supplierList.filter(item => (item.name || '').toLowerCase().includes(keyword))
+        }
+    },
+    created() {
+        this.supplierService = new SupplierService()
+    },
+    methods: {
+        async open() {
+            this.visible = true
+            this.keyword = ''
+            if (!this.supplierList.length) {
+                await this.loadSuppliers()
+            }
+        },
+        close() {
+            this.visible = false
+        },
+        async loadSuppliers() {
+            this.loading = true
+            try {
+                const data = await this.supplierService.list({
+                    current: 1,
+                    size: -1
+                })
+                this.supplierList = (data && data.records) || []
+            } finally {
+                this.loading = false
+            }
+        },
+        select(item) {
+            this.$emit('selected', item)
+            this.close()
+        },
+        clear() {
+            this.$emit('clear')
+            this.close()
+        }
+    }
+}
+</script>
+
+<style scoped>
+.selector-mask {
+    position: fixed;
+    inset: 0;
+    background: rgba(0, 0, 0, 0.35);
+    opacity: 0;
+    visibility: hidden;
+    transition: all 0.25s ease;
+    z-index: 1000;
+}
+
+.selector-mask.show {
+    opacity: 1;
+    visibility: visible;
+}
+
+.selector-panel {
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    height: 68vh;
+    background: #f7f9fc;
+    border-radius: 28rpx 28rpx 0 0;
+    transform: translateY(100%);
+    transition: transform 0.25s ease;
+    z-index: 1001;
+    display: flex;
+    flex-direction: column;
+}
+
+.selector-panel.show {
+    transform: translateY(0);
+}
+
+.selector-header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 28rpx 32rpx 16rpx;
+    background: #fff;
+    border-bottom: 1rpx solid #eef2f7;
+}
+
+.selector-title {
+    font-size: 32rpx;
+    font-weight: 600;
+    color: #1f2937;
+}
+
+.selector-action {
+    min-width: 80rpx;
+    font-size: 28rpx;
+    color: #2979ff;
+}
+
+.selector-search {
+    padding: 20rpx 24rpx 8rpx;
+    background: #fff;
+}
+
+.selector-list {
+    flex: 1;
+    padding: 16rpx 24rpx 32rpx;
+}
+
+.selector-list-inner {
+    display: flex;
+    flex-direction: column;
+    gap: 16rpx;
+}
+
+.selector-state {
+    padding-top: 120rpx;
+    text-align: center;
+    font-size: 28rpx;
+    color: #94a3b8;
+}
+
+.selector-card {
+    background: #fff;
+    border-radius: 20rpx;
+    padding: 24rpx;
+    box-shadow: 0 8rpx 24rpx rgba(15, 23, 42, 0.06);
+}
+
+.selector-name {
+    font-size: 30rpx;
+    font-weight: 600;
+    color: #0f172a;
+}
+
+.selector-meta {
+    display: flex;
+    flex-direction: column;
+    gap: 8rpx;
+    margin-top: 12rpx;
+    font-size: 24rpx;
+    color: #64748b;
+}
+</style>

+ 517 - 0
pages/psiManagement/wareHouseSummary/bak.vue

@@ -0,0 +1,517 @@
+<template>
+    <view class="page-wrap">
+<!--        <cu-custom :backUrl="'/pages/index/index'" :isBack="true" bgColor="bg-gradual-blue">
+            <block slot="content">库存列表</block>
+        </cu-custom> -->
+
+        <view class="search-panel">
+            <u-search :show-action="false" v-model="searchForm.tradeName" placeholder="搜索商品名称"
+                @search="refreshList" @clear="refreshList"></u-search>
+            <view class="filter-row">
+                <view class="filter-item" @tap="openTypePicker">
+                    <text class="filter-label">入库类型</text>
+                    <text class="filter-value">{{ searchForm.wareHouseTypeName || '全部' }}</text>
+                </view>
+                <view class="filter-item" @tap="openSupplierPicker">
+                    <text class="filter-label">供应商</text>
+                    <text class="filter-value">{{ searchForm.supplierName || '全部' }}</text>
+                </view>
+            </view>
+            <view class="action-row">
+                <el-button class="action-button" type="primary" @click="refreshList">查询</el-button>
+                <el-button class="action-button" plain @click="resetSearch">重置</el-button>
+            </view>
+        </view>
+
+        <view class="summary-row">
+            <text>共 {{ tablePage.total }} 条库存</text>
+            <text v-if="loading">加载中...</text>
+        </view>
+
+        <view v-if="!loading && dataList.length === 0" class="empty-state">暂无库存数据</view>
+
+        <view v-for="(item, index) in dataList" :key="item.id || item.tradeName + item.wareHouseType + index"
+            class="stock-card">
+            <view class="card-head">
+                <view class="goods-name">{{ item.tradeName || '-' }}</view>
+                <view class="type-badge">{{ item.wareHouseTypeName || '-' }}</view>
+            </view>
+
+            <view class="stock-main">
+                <view class="stock-number">
+                    <text class="number-label">剩余量:</text>
+                    <text class="number-value">{{ formatNumber(item.tradeNumber) }}</text>
+                    <!-- <text class="number-unit">{{ item.company || '' }}</text> -->
+                </view>
+                <view class="stock-total">
+                    <text>总量: {{ formatNumber(item.allNumber) }}</text>
+                    <text>单位: {{ item.company || '-' }}</text>
+                </view>
+            </view>
+
+            <view class="metric-grid">
+                <view class="metric-item">
+                    <text class="metric-label">领用量</text>
+                    <text class="metric-value">{{ calcBorrowNumber(item) }}</text>
+                </view>
+                <view class="metric-item">
+                    <text class="metric-label">报损量</text>
+                    <text class="metric-value">{{ calcLossNumber(item) }}</text>
+                </view>
+                <view class="metric-item">
+                    <text class="metric-label">提醒数量</text>
+                    <u--input class="warn-input" v-model="item.warnNum" placeholder="0" @blur="changeWarnNum(item)">
+                    </u--input>
+                </view>
+                <view class="metric-item">
+                    <text class="metric-label">是否提醒</text>
+                    <el-switch :value="item.warnFlag === '1'" active-color="#13ce66" inactive-color="#ff4949"
+                        @change="updateWarnFlag(item)">
+                    </el-switch>
+                </view>
+            </view>
+
+            <view class="card-actions">
+                <el-button class="card-button" type="primary" plain @click="openHistory(item)">查看记录</el-button>
+            </view>
+        </view>
+
+        <view v-if="dataList.length" class="load-more">
+            <text v-if="loadingMore">加载中...</text>
+            <text v-else-if="dataList.length >= tablePage.total">没有更多了</text>
+            <text v-else @tap="loadMore">加载更多</text>
+        </view>
+
+        <ba-tree-picker ref="typePicker" :multiple="false" @select-change="selectTypeChange" title="类型选择"
+            :localdata="typeTree" valueKey="value" textKey="label" childrenKey="children" />
+        <ware-house-supplier-picker ref="supplierPicker" @selected="selectSupplier" @clear="clearSupplier">
+        </ware-house-supplier-picker>
+        <ware-house-history-panel ref="historyPanel"></ware-house-history-panel>
+        <edit-trade-name-dialog ref="editTradeNameDialog" @success="refreshList"></edit-trade-name-dialog>
+    </view>
+</template>
+
+<script>
+import baTreePicker from '@/components/ba-tree-picker/ba-tree-picker.vue'
+import WareHouseService from '@/api/psi/WareHouseService'
+import MaterialTypeService from '@/api/psi/MaterialTypeService'
+import WareHouseSupplierPicker from './WareHouseSupplierPicker.vue'
+import WareHouseHistoryPanel from './WareHouseHistoryPanel.vue'
+import EditTradeNameDialog from './EditTradeNameDialog.vue'
+
+export default {
+    name: 'WareHouseSummaryList',
+    components: {
+        baTreePicker,
+        WareHouseSupplierPicker,
+        WareHouseHistoryPanel,
+        EditTradeNameDialog
+    },
+    data() {
+        return {
+            loading: false,
+            loadingMore: false,
+            searchForm: {
+                wareHouseType: '',
+                wareHouseTypeName: '',
+                tradeName: '',
+                supplierId: '',
+                supplierName: ''
+            },
+            dataList: [],
+            tablePage: {
+                total: 0,
+                currentPage: 1,
+                pageSize: 10,
+                orders: []
+            },
+            typeTree: []
+        }
+    },
+    wareHouseService: null,
+    materialTypeService: null,
+    created() {
+        this.wareHouseService = new WareHouseService()
+        this.materialTypeService = new MaterialTypeService()
+        this.loadTypeTree()
+        this.refreshList()
+    },
+    onPullDownRefresh() {
+        this.refreshList().finally(() => {
+            uni.stopPullDownRefresh()
+        })
+    },
+    onReachBottom() {
+        this.loadMore()
+    },
+    methods: {
+        async loadTypeTree() {
+            try {
+                const data = await this.materialTypeService.summaryTreeData({
+                    type: 'last'
+                })
+                this.typeTree = this.normalizeTree(data || [])
+            } catch (e) {
+                try {
+                    const data = await this.materialTypeService.cgList()
+                    this.typeTree = this.buildTree(data || [])
+                } catch (error) {
+                    this.typeTree = []
+                }
+            }
+        },
+        normalizeTree(nodes) {
+            return (nodes || []).map(item => ({
+                ...item,
+                value: item.value || item.id,
+                label: item.label || item.name,
+                children: this.normalizeTree(item.children || [])
+            }))
+        },
+        buildTree(nodes, parentId = '0') {
+            const tree = []
+            for (const node of nodes || []) {
+                if (node.parentId === parentId) {
+                    const children = this.buildTree(nodes, node.id)
+                    const treeNode = {
+                        ...node,
+                        value: node.value || node.id,
+                        label: node.label || node.name
+                    }
+                    if (children.length) {
+                        treeNode.children = children
+                    }
+                    tree.push(treeNode)
+                }
+            }
+            return tree
+        },
+        getSearchParams() {
+            return {
+                wareHouseType: this.searchForm.wareHouseType,
+                tradeName: this.searchForm.tradeName,
+                supplierId: this.searchForm.supplierId,
+                supplierName: this.searchForm.supplierName
+            }
+        },
+        async refreshList() {
+            this.tablePage.currentPage = 1
+            this.loading = true
+            try {
+                const data = await this.wareHouseService.wareHouseSummaryList({
+                    current: this.tablePage.currentPage,
+                    size: this.tablePage.pageSize,
+                    orders: this.tablePage.orders,
+                    ...this.getSearchParams()
+                })
+                this.dataList = (data && data.records) || []
+                this.tablePage.total = (data && data.total) || 0
+            } finally {
+                this.loading = false
+            }
+        },
+        async loadMore() {
+            if (this.loading || this.loadingMore || this.dataList.length >= this.tablePage.total) {
+                return
+            }
+            this.loadingMore = true
+            try {
+                const nextPage = this.tablePage.currentPage + 1
+                const data = await this.wareHouseService.wareHouseSummaryList({
+                    current: nextPage,
+                    size: this.tablePage.pageSize,
+                    orders: this.tablePage.orders,
+                    ...this.getSearchParams()
+                })
+                this.dataList = this.dataList.concat((data && data.records) || [])
+                this.tablePage.currentPage = nextPage
+                this.tablePage.total = (data && data.total) || this.tablePage.total
+            } finally {
+                this.loadingMore = false
+            }
+        },
+        resetSearch() {
+            this.searchForm = {
+                wareHouseType: '',
+                wareHouseTypeName: '',
+                tradeName: '',
+                supplierId: '',
+                supplierName: ''
+            }
+            this.refreshList()
+        },
+        openTypePicker() {
+            this.$refs.typePicker._show()
+        },
+        selectTypeChange(ids, names) {
+            this.searchForm.wareHouseType = (ids && ids[0]) || ''
+            this.searchForm.wareHouseTypeName = Array.isArray(names) ? names.join('/') : names
+            this.refreshList()
+        },
+        openSupplierPicker() {
+            this.$refs.supplierPicker.open()
+        },
+        selectSupplier(item) {
+            this.searchForm.supplierId = item.id || ''
+            this.searchForm.supplierName = item.name || ''
+            this.refreshList()
+        },
+        clearSupplier() {
+            this.searchForm.supplierId = ''
+            this.searchForm.supplierName = ''
+            this.refreshList()
+        },
+        formatNumber(value) {
+            if (value === null || value === undefined || value === '') {
+                return '0'
+            }
+            return value
+        },
+        calcBorrowNumber(row) {
+            if (row.notSurplusStock && row.spec) {
+                return this.trimNumber(parseFloat(row.notSurplusStock) / parseFloat(row.spec))
+            }
+            return '0'
+        },
+        calcLossNumber(row) {
+            if (row.lossNumber && row.spec) {
+                return this.trimNumber(parseFloat(row.lossNumber) / parseFloat(row.spec))
+            }
+            return '0'
+        },
+        trimNumber(value) {
+            if (Number.isNaN(value)) {
+                return '0'
+            }
+            return Number.isInteger(value) ? String(value) : value.toFixed(2)
+        },
+        async updateWarnFlag(row) {
+            try {
+                await this.wareHouseService.updateWarnFlagByTradeNameAndType(row.tradeName, row.wareHouseType)
+                uni.showToast({
+                    title: '提醒状态已更新',
+                    icon: 'success'
+                })
+                this.refreshList()
+            } catch (e) {
+                this.refreshList()
+            }
+        },
+        async changeWarnNum(row) {
+            const warnNum = row.warnNum === '' || row.warnNum === null || row.warnNum === undefined ? 0 : row.warnNum
+            try {
+                await this.wareHouseService.updateWarnNumByTradeNameAndType(row.tradeName, row.wareHouseType, warnNum)
+                uni.showToast({
+                    title: '提醒数量已更新',
+                    icon: 'success'
+                })
+                this.refreshList()
+            } catch (e) {
+                this.refreshList()
+            }
+        },
+        openHistory(row) {
+            this.$refs.historyPanel.open(row, this.searchForm.supplierId)
+        },
+        openEditTradeName(row) {
+            this.$refs.editTradeNameDialog.open(row)
+        }
+    }
+}
+</script>
+
+<style scoped>
+.page-wrap {
+    min-height: 100vh;
+    padding: 20rpx 24rpx 48rpx;
+    background: #f6f8fb;
+}
+
+.search-panel {
+    padding: 22rpx;
+    background: #fff;
+    border-radius: 18rpx;
+    box-shadow: 0 8rpx 24rpx rgba(15, 23, 42, 0.05);
+}
+
+.filter-row {
+    display: grid;
+    grid-template-columns: repeat(2, minmax(0, 1fr));
+    gap: 16rpx;
+    margin-top: 18rpx;
+}
+
+.filter-item {
+    min-width: 0;
+    padding: 18rpx 20rpx;
+    background: #f8fafc;
+    border-radius: 14rpx;
+}
+
+.filter-label {
+    display: block;
+    font-size: 22rpx;
+    color: #64748b;
+}
+
+.filter-value {
+    display: block;
+    margin-top: 8rpx;
+    font-size: 26rpx;
+    color: #0f172a;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
+.action-row {
+    display: flex;
+    gap: 16rpx;
+    margin-top: 18rpx;
+}
+
+.action-button {
+    flex: 1;
+}
+
+.summary-row {
+    display: flex;
+    justify-content: space-between;
+    padding: 22rpx 4rpx 12rpx;
+    font-size: 24rpx;
+    color: #64748b;
+}
+
+.empty-state {
+    padding: 120rpx 0;
+    text-align: center;
+    font-size: 28rpx;
+    color: #94a3b8;
+}
+
+.stock-card {
+    margin-bottom: 20rpx;
+    padding: 24rpx;
+    background: #fff;
+    border-radius: 18rpx;
+    box-shadow: 0 8rpx 24rpx rgba(15, 23, 42, 0.05);
+}
+
+.card-head {
+    display: flex;
+    align-items: flex-start;
+    justify-content: space-between;
+    gap: 16rpx;
+}
+
+.goods-name {
+    flex: 1;
+    font-size: 31rpx;
+    font-weight: 700;
+    line-height: 1.4;
+    color: #0f172a;
+    word-break: break-all;
+}
+
+.type-badge {
+    max-width: 260rpx;
+    padding: 8rpx 14rpx;
+    border-radius: 999rpx;
+    font-size: 22rpx;
+    color: #1d4ed8;
+    background: #dbeafe;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
+.stock-main {
+    display: flex;
+    justify-content: space-between;
+    gap: 20rpx;
+    margin-top: 24rpx;
+    padding: 22rpx;
+    background: #f8fafc;
+    border-radius: 16rpx;
+}
+
+.stock-number {
+    display: flex;
+    align-items: baseline;
+    gap: 8rpx;
+}
+
+.number-label {
+    font-size: 22rpx;
+    color: #64748b;
+}
+
+.number-value {
+    font-size: 46rpx;
+    font-weight: 800;
+    color: #0f766e;
+}
+
+.number-unit {
+    font-size: 24rpx;
+    color: #475569;
+}
+
+.stock-total {
+    display: flex;
+    flex-direction: column;
+    gap: 8rpx;
+    text-align: right;
+    font-size: 24rpx;
+    color: #475569;
+}
+
+.metric-grid {
+    display: grid;
+    grid-template-columns: repeat(2, minmax(0, 1fr));
+    gap: 16rpx;
+    margin-top: 18rpx;
+}
+
+.metric-item {
+    min-width: 0;
+    padding: 18rpx;
+    background: #fbfdff;
+    border: 1rpx solid #eef2f7;
+    border-radius: 14rpx;
+}
+
+.metric-label {
+    display: block;
+    margin-bottom: 10rpx;
+    font-size: 22rpx;
+    color: #64748b;
+}
+
+.metric-value {
+    font-size: 28rpx;
+    font-weight: 600;
+    color: #0f172a;
+}
+
+.warn-input {
+    width: 100%;
+}
+
+.card-actions {
+    display: grid;
+    gap: 16rpx;
+    margin-top: 18rpx;
+}
+
+.card-button {
+    width: 100%;
+}
+
+.load-more {
+    padding: 24rpx 0;
+    text-align: center;
+    font-size: 26rpx;
+    color: #64748b;
+}
+</style>

+ 8 - 0
pages/workbench/task/TaskForm.vue

@@ -30,6 +30,10 @@
 						v-else-if="formUrl.includes('/psiManagement/collect/') && formUrl.endsWith('CollectForm')"
 						:formReadOnly="formReadOnly" :class="formReadOnly ? 'readonly' : ''" ref="form"
 						:businessId="businessId" :status="status"></PsiCollectForm>
+					<DishOrderApproval
+						v-else-if="formUrl.includes('/psiManagement/dishManage/') && formUrl.endsWith('DishOrderApproval')"
+						:formReadOnly="formReadOnly" :class="formReadOnly ? 'readonly' : ''" ref="form"
+						:businessId="businessId" :status="status"></DishOrderApproval>
 					<CollectForm v-else-if="formUrl.endsWith('CollectForm')" :formReadOnly="formReadOnly"
 						:class="formReadOnly ? 'readonly' : ''" ref="form" :businessId="businessId"></CollectForm>
 					<!-- 已完成 -->
@@ -185,6 +189,7 @@ import PsiPurchaseForm from '@/pages/psiManagement/purchase/PurchaseForm.vue'
 import PsiWareHouseUpdateForm from '@/pages/psiManagement/wareHouse/WareHouseUpdateForm.vue'
 import PsiLossForm from '@/pages/psiManagement/loss/LossForm.vue'
 import PsiCollectForm from '@/pages/psiManagement/collect/CollectForm.vue'
+import DishOrderApproval from '@/pages/psiManagement/dishManage/DishOrderApproval.vue'
 import EnrollmentRegistrationAddForm from '@/pages/human/enrollment/registration/EnrollmentRegistrationAddForm.vue'
 import moment from 'moment'
 import taskService from "@/api/flowable/taskService"
@@ -259,6 +264,8 @@ export default {
 					this.form = RegistrationAddForm
 				} else if (this.formUrl.includes('/psiManagement/collect/') && this.formUrl.endsWith('CollectForm')) {
 					this.form = PsiCollectForm
+				} else if (this.formUrl.includes('/psiManagement/dishManage/') && this.formUrl.endsWith('DishOrderApproval')) {
+					this.form = DishOrderApproval
 				} else if (this.formUrl.endsWith('CollectForm')) {
 					this.form = CollectForm
 				} else if (this.formUrl.includes('/psiManagement/purchase/') && this.formUrl.endsWith('PurchaseForm')) {
@@ -338,6 +345,7 @@ export default {
 		PsiWareHouseUpdateForm,
 		PsiLossForm,
 		PsiCollectForm,
+		DishOrderApproval,
 		HolidayForm,
 		DepartRegistrationAddForm,
 		HandoverAddForm,

+ 12 - 8
pages/workbench/task/TaskFormDetail.vue

@@ -16,7 +16,7 @@
 		</view>
 		<view v-show="1 === tabIndex">
 			<view class="padding">
-	
+
 				<view class="cu-timeline" :key="index" v-for="(act, index) in historicTaskList">
 					<view class="cu-time">{{act.histIns.startTime |formatDate('MM-DD')}}</view>
 					<view class="cu-item text-blue">
@@ -25,12 +25,12 @@
 								<view class="cu-tag bg-cyan">{{act.histIns.activityName}}</view>
 								<!-- <view class="cu-tag line-cyan">{{act.histIns.activityName}}</view> -->
 							</view>
-							
+
 							<view class="margin-top">
 								审批人 : {{act.assigneeName}}
 							</view>
 							<view class="margin-top">
-								办理状态 :<view class="cu-tag bg-blue">{{act.comment.status}}</view>  
+								办理状态 :<view class="cu-tag bg-blue">{{act.comment.status}}</view>
 							</view>
 							<view class="margin-top">
 								审批意见 : {{act.comment.message}}
@@ -68,11 +68,12 @@
 	import PsiWareHouseUpdateForm from '@/pages/psiManagement/wareHouse/WareHouseUpdateForm.vue'
 	import PsiLossForm from '@/pages/psiManagement/loss/LossForm.vue'
 	import PsiCollectForm from '@/pages/psiManagement/collect/CollectForm.vue'
+	import DishOrderApproval from '@/pages/psiManagement/dishManage/DishOrderApproval.vue'
 	import EnrollmentRegistrationAddForm from '@/pages/human/enrollment/registration/EnrollmentRegistrationAddForm.vue'
 	import taskService from "@/api/flowable/taskService"
 	import formService from "@/api/flowable/formService"
 	import MeetingRoomForm from '@/pages/dailyOfficeWork/daily/MeetingRoomForm.vue'
-	
+
 	export default {
 		onLoad: function (option) {
 		    this.flow = JSON.parse(decodeURIComponent(option.flow));
@@ -98,7 +99,7 @@
 				  uni.showToast({ title: '没有关联流程表单!', icon: "none" });
 				} else {
 					// uniapp 不支持动态组件,所以通过名称匹配决定调用的表单组件
-					if(this.formUrl.endsWith('TestActivitiLeaveForm')){ 
+					if(this.formUrl.endsWith('TestActivitiLeaveForm')){
 						this.form = TestActivitiLeaveForm
 					}else if(this.formUrl.endsWith('DepartRegistrationAddForm')){
 						this.form = DepartRegistrationAddForm
@@ -110,10 +111,12 @@
 						this.form = InvoiceFormTask
 					}else if(this.formUrl.endsWith('EnrollmentRegistrationAddForm')){
 						this.form = EnrollmentRegistrationAddForm
-					}else if(this.formUrl.endsWith('RegistrationAddForm')){ 
+					}else if(this.formUrl.endsWith('RegistrationAddForm')){
 						this.form = RegistrationAddForm
 					}else if(this.formUrl.includes('/psiManagement/collect/') && this.formUrl.endsWith('CollectForm')){
 						this.form = PsiCollectForm
+					}else if(this.formUrl.includes('/psiManagement/dishManage/') && this.formUrl.endsWith('DishOrderApproval')){
+						this.form = DishOrderApproval
 					}else if(this.formUrl.endsWith('CollectForm')){
 						this.form = CollectForm
 					}else if(this.formUrl.includes('/psiManagement/purchase/') && this.formUrl.endsWith('PurchaseForm')){
@@ -150,11 +153,11 @@
 					  let input = JSON.parse(JSON.stringify(item))
 					  this.formData.push(input)
 				  })
-			
+
 				    // 读取任务表单配置
 				let res = await formService.getHistoryTaskFormData({ processInstanceId: this.procInsId, procDefId: this.procDefId, taskDefKey: this.taskDefKey })
 				this.setData(res, 'audit')
-				  
+
 				}
 			  }
 			// 读取历史任务列表
@@ -174,6 +177,7 @@
 			PsiWareHouseUpdateForm,
 			PsiLossForm,
 			PsiCollectForm,
+			DishOrderApproval,
 			HolidayForm,
 			DepartRegistrationAddForm,
 			HandoverAddForm,

+ 37 - 12
pages/workbench/workbench.vue

@@ -134,6 +134,14 @@
 				if (item.category === '未设置') {
 					if (item.name === '进销存-领用申请') {
 						jjtTest.push(item)
+						jjtTest.push({
+							name : "入库",
+							notFlowable :true
+						})
+						jjtTest.push({
+							name : "库存",
+							notFlowable :true
+						})
 						// this.processMap.set('物资管理', [item])
 					}
 					if (item.name === '物资管理-领用申请') {
@@ -259,18 +267,35 @@
 				})
 			},
 			start (row) {
-				  // 读取流程表单
-				taskService.getTaskDef({
-				  procDefId: row.id,
-				  status: 'start'
-				}).then((data) => {
-					console.log('data',data)
-				  let processTitle = `${this.username} 在 ${moment(new Date()).format('YYYY-MM-DD HH:mm')} 发起了 [${row.name}]`
-				  let query = {procDefId: row.id, procDefKey: row.key, status: 'start', title: `发起流程【${row.name}】`, formType: data.formType, formUrl: data.formUrl, formTitle: processTitle}
-				  uni.navigateTo({
-					 url: '/pages/workbench/task/TaskForm?flow='+JSON.stringify(query)
-				  })
-				})
+				if(row.notFlowable){
+					switch(row.name){
+						case "入库":
+							uni.navigateTo({
+							    url: '/pages/psiManagement/wareHouse/WareHouseAddForm'
+							})
+							break;
+						case "库存":
+							uni.navigateTo({
+							    url: '/pages/psiManagement/wareHouseSummary/WareHouseSummaryList'
+							})
+							break;	
+							
+							
+					}
+				}else{
+					// 读取流程表单
+					taskService.getTaskDef({
+					  procDefId: row.id,
+					  status: 'start'
+					}).then((data) => {
+						console.log('data',data)
+					  let processTitle = `${this.username} 在 ${moment(new Date()).format('YYYY-MM-DD HH:mm')} 发起了 [${row.name}]`
+					  let query = {procDefId: row.id, procDefKey: row.key, status: 'start', title: `发起流程【${row.name}】`, formType: data.formType, formUrl: data.formUrl, formTitle: processTitle}
+					  uni.navigateTo({
+						 url: '/pages/workbench/task/TaskForm?flow='+JSON.stringify(query)
+					  })
+					})
+				}
 		  },
 			// 查询当前用户是否是管理员用户
 			checkIsAdmin () {