xuhaifeng 2 mēneši atpakaļ
vecāks
revīzija
c93fb7a822

+ 176 - 92
admin-ui/src/views/systemSet/purchaseGoods/index.vue

@@ -107,10 +107,22 @@
                                     </template>
                                 </el-table-column>
                                 <el-table-column label="价格" align="center" prop="purchasePrice" />
-                                <el-table-column label="库存" align="center" prop="stock" />
+                                <el-table-column label="库存" align="center" prop="stock">
+                                    <template slot-scope="scope">
+                                        <span :class="{'low-stock': scope.row.stock <= 5}">{{ scope.row.stock }}</span>
+                                        <el-tag v-if="scope.row.stock <= 5" size="mini" type="warning">库存不足</el-tag>
+                                    </template>
+                                </el-table-column>
                                 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
                                     <template slot-scope="scope">
-                                        <el-button type="text" icon="el-icon-s-shop" @click="addGoods(scope.row)">添加</el-button>
+                                        <el-button 
+                                            type="text" 
+                                            icon="el-icon-s-shop" 
+                                            @click="addGoods(scope.row)"
+                                            :disabled="scope.row.stock <= 0"
+                                        >
+                                            添加
+                                        </el-button>
                                     </template>
                                 </el-table-column>
                             </el-table>
@@ -127,9 +139,6 @@
                     </el-col>
                     <el-col :span="18">
                         <el-form label-width="135px" style="height: 100px; padding-top: 40px; text-align: right" :inline="true" size="small">
-                            <el-form-item label="当前余额(元):" v-if="goodsType == '1'">
-                                <span style="color: #ff4949">{{ getNowBalanceValue }}</span>
-                            </el-form-item>
                             <el-form-item label-width="100px" label="总件数:" prop="totalClothNum">
                                 <span style="color: #ff4949">{{ calculateTotalCount }}</span>
                             </el-form-item>
@@ -273,7 +282,8 @@ export default {
             costTotalPrice: null,
             userInfoVO: null,
             isUserBalance: false,
-            orgName: ''
+            orgName: '',
+            stockWarningThreshold: 5, // 库存预警阈值
         }
     },
     created() {
@@ -312,6 +322,9 @@ export default {
             }
             // 当订单金额 小于等于 余额
             return (parseFloat(this.getNowBalance) * 10000 - parseFloat(this.totalPrice) * 10000) / 10000
+        },
+        lowStockItems() {
+            return this.goodsList.filter(item => item.stock <= this.stockWarningThreshold);
         }
     },
     methods: {
@@ -345,52 +358,53 @@ export default {
             if (this.userInfoVO.userType != '00') {
                 // 判断上级库存
                 if (row.stock <= 0) {
-                    this.$message.error('库存不足,无法添加')
-                    return
+                    this.$message.warning('库存不足,无法添加');
+                    return;
                 }
-                // 如果已添加集合数量大于0, 需要判断当前添加的是否在已添加集合中
-                // 在已添加集合中,直接添加数量+1
+                
+                // 如果已添加集合数量大于0,需要判断当前添加的是否在已添加集合中
                 if (this.addGoodsList.length > 0) {
-                    let match = this.addGoodsList.findIndex((item) => item.goodsSkuStoreId == row.goodsSkuStoreId)
-                    if (match != '-1') {
-                        let purchaseVo = this.purchaseCountVOList.find((item) => item.goodsSkuStoreId == row.goodsSkuStoreId)
+                    let match = this.addGoodsList.findIndex(item => item.goodsSkuStoreId == row.goodsSkuStoreId);
+                    if (match !== -1) {
+                        let purchaseVo = this.purchaseCountVOList.find(item => item.goodsSkuStoreId == row.goodsSkuStoreId);
                         if (purchaseVo.count >= row.stock) {
-                            this.$message.error('数量已超出')
-                            return
+                            this.$message.warning('数量已超出库存限制');
+                            return;
                         }
-                        this.purchaseCountVOList.find((item) => item.goodsSkuStoreId == row.goodsSkuStoreId).count++
-                        this.$forceUpdate()
-                        return
+                        purchaseVo.count++;
+                        this.$forceUpdate();
+                        return;
                     }
                 }
+                
                 // 不在已添加集合中,直接加入集合中
-                this.addGoodsList.push(row)
+                this.addGoodsList.push(row);
                 this.purchaseCountVOList.push({
-                    goodsSkuStoreId: row.goodsSkuStoreId,
-                    goodsCategoryId: this.goodsCategoryId,
-                    goodsCategoryName: this.categoryList.find((item) => item.id == this.goodsCategoryId).categoryName,
-                    count: 1
-                })
-                this.$forceUpdate()
+                    'goodsSkuStoreId': row.goodsSkuStoreId,
+                    'goodsCategoryId': this.goodsCategoryId,
+                    'goodsCategoryName': this.categoryList.find(item => item.id == this.goodsCategoryId).categoryName,
+                    'count': 1
+                });
+                this.$forceUpdate();
             } else {
-                // 总部进货, 无需判断上级库存
+                // 总部进货逻辑保持不变
                 if (this.addGoodsList.length > 0) {
-                    let match = this.addGoodsList.findIndex((item) => item.goodsSkuStoreId == row.goodsSkuStoreId)
-                    if (match != '-1') {
-                        this.purchaseCountVOList.find((item) => item.goodsSkuStoreId == row.goodsSkuStoreId).count++
-                        this.$forceUpdate()
-                        return
+                    let match = this.addGoodsList.findIndex(item => item.goodsSkuStoreId == row.goodsSkuStoreId);
+                    if (match !== -1) {
+                        this.purchaseCountVOList.find(item => item.goodsSkuStoreId == row.goodsSkuStoreId).count++;
+                        this.$forceUpdate();
+                        return;
                     }
                 }
-                // 不在已添加集合中,直接加入集合中
-                this.addGoodsList.push(row)
+                
+                this.addGoodsList.push(row);
                 this.purchaseCountVOList.push({
-                    goodsSkuStoreId: row.goodsSkuStoreId,
-                    goodsCategoryId: this.goodsCategoryId,
-                    goodsCategoryName: this.categoryList.find((item) => item.id == this.goodsCategoryId).categoryName,
-                    count: 1
-                })
-                this.$forceUpdate()
+                    'goodsSkuStoreId': row.goodsSkuStoreId,
+                    'goodsCategoryId': this.goodsCategoryId,
+                    'goodsCategoryName': this.categoryList.find(item => item.id == this.goodsCategoryId).categoryName,
+                    'count': 1
+                });
+                this.$forceUpdate();
             }
         },
         getMaxCount(row) {
@@ -510,68 +524,138 @@ export default {
                 .catch(() => {})
         },
         submitForm() {
-            this.$confirm('是否确认下单?')
-                .then(() => {
-                    if (this.totalCount == 0) {
-                        this.$message.error('商品数量为空,无法操作提交')
+            this.$confirm('是否确认下单?').then(() => {
+                if (this.totalCount == 0) {
+                    this.$message.error('商品数量为空,无法操作提交');
+                    return;
+                }
+
+                // 检查库存
+                for (let item of this.addGoodsList) {
+                    let purchaseVo = this.purchaseCountVOList.find(item => item.goodsSkuStoreId == item.goodsSkuStoreId);
+                    if (purchaseVo.count > item.stock) {
+                        this.$message.error(`商品 ${item.goodsName} 数量超出库存限制`);
+                        return;
                     }
-                    this.submitGoodsOrderVO.costTotalPrice = this.totalPrice
-                    this.submitGoodsOrderVO.goodsType = this.goodsType
-                    this.submitGoodsOrderVO.purchaseGoodsVOList = []
-                    if (this.userInfoVO.userType != '00' && this.isUserBalance == true) {
-                        this.submitGoodsOrderVO.isUserBalance = true
-                    } else {
-                        this.submitGoodsOrderVO.isUserBalance = false
+                }
+
+                this.submitGoodsOrderVO = {
+                    costTotalPrice: this.totalPrice,
+                    goodsType: this.goodsType,
+                    purchaseGoodsVOList: [],
+                    isUserBalance: this.userInfoVO.userType != '00' && this.isUserBalance
+                };
+
+                // 构建商品列表
+                this.addGoodsList.forEach(vo => {
+                    let purchaseVO = this.purchaseCountVOList.find(item => item.goodsSkuStoreId == vo.goodsSkuStoreId);
+                    let purchaseGoodsVO = {
+                        skuId: vo.id,
+                        goodsId: vo.goodsId,
+                        goodsCategoryId: purchaseVO.goodsCategoryId,
+                        goodsCategoryName: purchaseVO.goodsCategoryName,
+                        costPrice: vo.purchasePrice,
+                        buyNum: purchaseVO.count,
+                        skuName: ''
+                    };
+
+                    if (vo.specVoList != null) {
+                        vo.specVoList.forEach(spec => {
+                            purchaseGoodsVO.skuName = purchaseGoodsVO.skuName + spec.specName + ':' + spec.specValue + ' ';
+                        });
                     }
-                    this.addGoodsList.forEach((vo) => {
-                        let purchaseVO = this.purchaseCountVOList.find((item) => item.goodsSkuStoreId == vo.goodsSkuStoreId)
-                        let purchaseGoodsVO = {}
-                        purchaseGoodsVO.skuId = vo.id
-                        purchaseGoodsVO.goodsId = vo.goodsId
-                        purchaseGoodsVO.goodsCategoryId = purchaseVO.goodsCategoryId
-                        purchaseGoodsVO.goodsCategoryName = purchaseVO.goodsCategoryName
-                        purchaseGoodsVO.costPrice = vo.purchasePrice
-                        purchaseGoodsVO.buyNum = purchaseVO.count
-                        purchaseGoodsVO.skuName = ''
-                        if (vo.specVoList != null) {
-                            vo.specVoList.forEach((spec) => {
-                                purchaseGoodsVO.skuName = purchaseGoodsVO.skuName + spec.specName + ':' + spec.specValue + ' '
-                            })
-                        }
-                        this.submitGoodsOrderVO.purchaseGoodsVOList.push(purchaseGoodsVO)
-                    })
-                    addPurchaseGoods(this.submitGoodsOrderVO).then((response) => {
-                        this.$modal.msgSuccess('提交成功')
-                        this.open = false
-                        this.getList()
-                    })
-                })
-                .catch(() => {})
+
+                    this.submitGoodsOrderVO.purchaseGoodsVOList.push(purchaseGoodsVO);
+                });
+
+                // 提交订单
+                addPurchaseGoods(this.submitGoodsOrderVO).then(response => {
+                    this.$modal.msgSuccess('提交成功');
+                    this.open = false;
+                    this.getList();
+                }).catch(error => {
+                    this.$modal.msgError(error.message || '提交失败');
+                });
+            }).catch(() => {});
         }
     }
 }
 </script>
-<style>
-.list_title {
-    text-align: center;
-    line-height: 40px;
+<style lang="scss" scoped>
+.low-stock {
+  color: #e6a23c;
+  font-weight: bold;
+}
+
+.el-table {
+  .el-button--text {
+    &.is-disabled {
+      color: #c0c4cc;
+      cursor: not-allowed;
+    }
+  }
 }
-.head-container-two {
-    height: 500px;
-    display: block;
-    overflow-y: scroll;
+
+.stock-warning {
+  background-color: #fdf6ec;
+  color: #e6a23c;
+  padding: 5px 10px;
+  border-radius: 4px;
+  margin-top: 10px;
+  
+  .warning-title {
+    font-weight: bold;
+    margin-bottom: 5px;
+  }
+  
+  .warning-list {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 10px;
+    
+    .warning-item {
+      background: #fff;
+      padding: 5px 10px;
+      border-radius: 4px;
+      border: 1px solid #e6a23c;
+    }
+  }
 }
-.head-column1 {
-    height: 300px;
-    display: block;
-    overflow-y: scroll;
+
+// 优化表格样式
+.el-table {
+  th {
+    background-color: #f5f7fa;
+    color: #606266;
+    font-weight: 500;
+  }
+  
+  td {
+    padding: 8px 0;
+  }
 }
-.head-column2 {
-    height: 600px;
-    display: block;
-    overflow-y: scroll;
+
+// 优化按钮样式
+.el-button--text {
+  padding: 0 5px;
+  
+  &:hover {
+    color: #409EFF;
+  }
+  
+  &.is-disabled {
+    color: #c0c4cc;
+    cursor: not-allowed;
+    
+    &:hover {
+      color: #c0c4cc;
+    }
+  }
 }
-.box-shadow .el-button--medium {
-    font-size: 18px;
+
+// 优化标签样式
+.el-tag {
+  margin-left: 5px;
+  vertical-align: middle;
 }
 </style>

+ 59 - 9
admin-ui/src/views/workbench/workRetail/index.vue

@@ -174,7 +174,8 @@
                     :key="goods.goodsCode"
                     shadow="hover"
                     class="goods-item"
-                    @click.native="selectSpec(goods)"
+                    :class="{'out-of-stock': goods.stock <= 0}"
+                    @click.native="goods.stock > 0 && selectSpec(goods)"
                   >
                     <img
                       :src="goods.goodsImg || defaultImage"
@@ -185,6 +186,13 @@
                     <div class="goods-info">
                       <div class="goods-name" :title="goods.goodsName">{{goods.goodsName}}</div>
                       <div class="goods-price">¥{{formatMoney(goods.salePrice)}}</div>
+                      <div class="goods-stock" :class="{'low-stock': goods.stock <= 5 && goods.stock > 0}">
+                        库存: {{goods.stock}}
+                      </div>
+                    </div>
+                    <div class="stock-overlay" v-if="goods.stock <= 0">
+                      <i class="el-icon-warning"></i>
+                      <span>无库存</span>
                     </div>
                   </el-card>
                 </div>
@@ -583,16 +591,16 @@ export default {
     // 未选列表中,添加按钮
     addGoods(row) {
       if (row.stock <= 0) {
-        this.$message.error("库存不足,无法添加");
+        this.$message.warning("该商品已售罄");
         return;
       }
+      
       if (this.addGoodsList.length > 0) {
         let match = this.addGoodsList.findIndex(item => item.goodsSkuStoreId == row.goodsSkuStoreId)
-        // -1 : findIndex没找到
-        if (match != '-1') {
+        if (match !== -1) {
           let purchaseVo = this.purchaseCountVOList.find(item => item.goodsSkuStoreId == row.goodsSkuStoreId);
           if (purchaseVo.count >= row.stock) {
-            this.$message.error("库存不足");
+            this.$message.warning("库存不足");
             return;
           }
           purchaseVo.count++;
@@ -601,6 +609,7 @@ export default {
           return;
         }
       }
+      
       this.addGoodsList.push(row);
       this.purchaseCountVOList.push({
         'goodsSkuStoreId': row.goodsSkuStoreId,
@@ -646,6 +655,11 @@ export default {
     },
     // 选择商品规格
     selectSpec(row) {
+      if (row.stock <= 0) {
+        this.$message.warning("该商品已售罄");
+        return;
+      }
+      
       this.skuLoading = true;
       getGoodsSkuListToGoodsRetail(row.id).then(response => {
         this.goodsSkuList = response.data;
@@ -837,12 +851,18 @@ export default {
   padding: 10px;
 
   .goods-item {
+    position: relative;
     cursor: pointer;
     transition: all 0.3s;
 
-    &:hover {
-      transform: translateY(-2px);
-      box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
+    &.out-of-stock {
+      cursor: not-allowed;
+      opacity: 0.7;
+      
+      &:hover {
+        transform: none;
+        box-shadow: none;
+      }
     }
 
     .el-card__body {
@@ -861,7 +881,7 @@ export default {
       padding: 5px 0;
 
       .goods-name {
-        font-size: 12px; // 减小字体大小
+        font-size: 12px;
         margin-bottom: 3px;
         overflow: hidden;
         text-overflow: ellipsis;
@@ -873,6 +893,36 @@ export default {
         color: #f56c6c;
         font-size: 14px;
         font-weight: bold;
+        margin-bottom: 3px;
+      }
+
+      .goods-stock {
+        font-size: 12px;
+        color: #67c23a;
+        
+        &.low-stock {
+          color: #e6a23c;
+        }
+      }
+    }
+
+    .stock-overlay {
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      background: rgba(0, 0, 0, 0.5);
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      color: white;
+      font-size: 14px;
+
+      i {
+        font-size: 24px;
+        margin-bottom: 5px;
       }
     }
   }

+ 5 - 1
yiqi-common/src/main/java/com/yiqi/core/domain/GoodsInfo.java

@@ -167,9 +167,13 @@ public class GoodsInfo extends BaseEntity {
     @TableField(exist = false)
     private BigDecimal salePrice;
 
+    @ApiModelProperty("库存")
+    @TableField(exist = false)
+    private Integer stock;
+
     /**
      * 价格属性是否支持自主定价
      */
-    private Integer priceScope;
+//    private Integer priceScope;
 
 }

+ 2 - 0
yiqi-core/src/main/java/com/yiqi/core/service/impl/GoodsSkuServiceImpl.java

@@ -384,8 +384,10 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
         goodsInfoList.forEach(goodsInfo -> {
             if (CollUtil.isNotEmpty(resultMap) && resultMap.containsKey(goodsInfo.getId())) {
                 goodsInfo.setSalePrice((BigDecimal)resultMap.get(goodsInfo.getId()).get("salePrice"));
+                goodsInfo.setStock((Integer)resultMap.get(goodsInfo.getId()).get("stock"));
             } else {
                 goodsInfo.setSalePrice(BigDecimal.ZERO);
+                goodsInfo.setStock(0);
             }
         });
         return goodsInfoList;

+ 1 - 1
yiqi-core/src/main/resources/mapper/core/GoodsSkuMapper.xml

@@ -301,7 +301,7 @@
 
     <!--查询门店指定的商品集合里面,每个商品的最小值-->
     <select id="selectStoreSkuMinSalePriceToGoodsRetail" resultType="java.util.Map">
-        select goods_id, min(sale_price) as sale_price from goods_sku_store where
+        select goods_id, min(sale_price) as sale_price, sum(stock) as stock from goods_sku_store where
              target_id = #{storeId} and source_type='02' and sale_price is not null and status = '0'
              <if test="goodsIds != null">
                 and goods_id in