叶静 2 minggu lalu
induk
melakukan
53ac74e0b4

+ 4 - 2
src/app/shop/admin/finance/commission/index.vue

@@ -52,9 +52,11 @@
           </el-table-column>
           <el-table-column :label="t('modules.commission.orderNo')" min-width="150">
             <template #default="scope">
-              <el-link v-if="scope.row.orderNo" type="primary" :underline="true" @click="viewOrderDetail(scope.row)">
+              <el-link v-if="scope.row.orderNo && scope.row.orderNo.startsWith('BH')" type="primary" :underline="true"
+                @click="viewOrderDetail(scope.row)">
                 {{ scope.row.orderNo }}
               </el-link>
+              <span v-else-if="scope.row.orderNo">{{ scope.row.orderNo }}</span>
               <span v-else>--</span>
             </template>
           </el-table-column>
@@ -301,7 +303,7 @@ function viewUserDetail(row) {
 
 // 查看订单详情
 function viewOrderDetail(row) {
-  if (!row.orderNo) return;
+  if (!row.orderNo || !row.orderNo.startsWith('BH')) return;
   useModal(
     OrderDetail,
     {

+ 49 - 5
src/app/shop/admin/goods/goods/edit.vue

@@ -42,7 +42,7 @@
 
                 <el-form-item :label="t('modules.goods.goodsDescription')" prop="storeInfo">
                   <el-input v-model="formData.storeInfo" type="textarea" :rows="4"
-                    :placeholder="t('form.inputGoodsDescription')" maxlength="500" show-word-limit />
+                    :placeholder="t('form.inputGoodsDescription')" maxlength="256" show-word-limit />
                 </el-form-item>
 
                 <el-form-item :label="t('modules.goods.shippingTemplate')" prop="tempId">
@@ -104,7 +104,8 @@
                 </el-form-item>
 
                 <el-form-item :label="t('modules.goods.goodsSupplier')" prop="itemSupplier" required>
-                  <el-input v-model="formData.itemSupplier" :placeholder="t('form.inputGoodsSupplier')" />
+                  <el-input v-model="formData.itemSupplier" :placeholder="t('form.inputGoodsSupplier')" maxlength="20"
+                    show-word-limit />
                 </el-form-item>
               </el-col>
 
@@ -135,7 +136,7 @@
         <div v-show="currentStep === 1" class="" :key="forceUpdateKey">
           <el-form ref="attrFormRef" :model="formData" :rules="attrRules" :label-width="formLabelWidth">
             <!-- 多规格设置 -->
-            <el-card class="spec-card">
+            <el-card ref="specCardRef" class="spec-card">
               <template #header>
                 <div class="card-header">
                   <span>{{ t('modules.goods.specificationSettings') }}</span>
@@ -147,7 +148,8 @@
                 <div class="sku" v-for="(s, k) in formData.skus" :key="`sku-${k}-${forceUpdateKey}`">
                   <div class="sku-key sa-flex sa-row-between">
                     <div class="sa-flex">
-                      <div class="sa-m-r-16">{{ t('modules.goods.specificationName') }}</div>
+                      <div class="sa-m-r-16"><span class="required">*</span>{{ t('modules.goods.specificationName') }}
+                      </div>
                       <el-input v-model="s.name" :placeholder="t('form.inputSpecificationName')" class="sku-key-input"
                         @input="buildSkuPriceTable"></el-input>
                     </div>
@@ -156,7 +158,7 @@
                     </el-icon>
                   </div>
                   <div class="sku-value sa-flex sa-flex-wrap">
-                    <div class="sku-value-title sa-m-r-16 sa-m-b-16 sa-flex">{{
+                    <div class="sku-value-title sa-m-r-16 sa-m-b-16 sa-flex"><span class="required">*</span>{{
                       t('modules.goods.specificationValue')
                     }}</div>
                     <div v-for="(sc, c) in s.children" :key="c" class="sku-value-box sa-m-b-16">
@@ -375,6 +377,7 @@ const forceUpdateKey = ref(0);
 // 表单引用
 const basicFormRef = ref();
 const attrFormRef = ref();
+const specCardRef = ref();
 
 // 表单数据
 const formData = reactive({
@@ -913,6 +916,15 @@ const nextStep = async () => {
     }
     // 进入下一步(商品属性设置)
     currentStep.value++;
+
+    // 等待DOM更新后滚动到规格设置区域
+    await nextTick();
+    if (specCardRef.value) {
+      specCardRef.value.$el.scrollIntoView({
+        behavior: 'smooth',
+        block: 'start'
+      });
+    }
   } else if (currentStep.value === 1) {
     // 第二步:提交所有数据(基本信息 + 商品属性)
     await submitGoods();
@@ -1026,6 +1038,34 @@ const submitGoods = async () => {
       return;
     }
 
+    // 验证商品规格必填项
+    // 检查是否有有效的规格配置
+    const validSpecs = formData.skus.filter(sku =>
+      sku.name && sku.name.trim() && sku.children && sku.children.length > 0 &&
+      sku.children.some(child => child.name && child.name.trim())
+    );
+
+    if (validSpecs.length === 0) {
+      ElMessage.error(t('modules.goods.pleaseAddSpecification'));
+      return;
+    }
+
+    // 检查每个规格是否都有规格名称和至少一个规格值
+    for (let i = 0; i < formData.skus.length; i++) {
+      const sku = formData.skus[i];
+      // 跳过空的规格项(没有名称的)
+      if (!sku.name || !sku.name.trim()) {
+        continue;
+      }
+
+      // 如果有规格名称,必须有至少一个有效的规格值
+      const validChildren = sku.children.filter(child => child.name && child.name.trim());
+      if (validChildren.length === 0) {
+        ElMessage.error(t('modules.goods.specificationValueRequired', { name: sku.name }));
+        return;
+      }
+    }
+
     // 验证商品属性(如果有SKU)
     if (formData.sku_prices && formData.sku_prices.length > 0) {
       // 验证SKU数据
@@ -1044,6 +1084,10 @@ const submitGoods = async () => {
           return;
         }
       }
+    } else {
+      // 如果没有SKU价格数据,说明规格配置不完整
+      ElMessage.error(t('modules.goods.pleaseCompleteSpecification'));
+      return;
     }
 
     // 调用统一保存接口

+ 3 - 1
src/locales/en-US/index.json

@@ -379,7 +379,7 @@
     "inputSubtitle": "Please input subtitle (max 50 characters)",
     "categoryNameRequired": "Please input category name",
     "inputGoodsBrand": "Please input goods brand",
-    "inputGoodsDescription": "Please input goods description (max 500 characters)",
+    "inputGoodsDescription": "Please input goods description (max 256 characters)",
     "inputGoodsNumber": "Please input goods number",
     "inputGoodsSupplier": "Please input goods supplier",
     "selectShippingTemplate": "Please select shipping template",
@@ -1140,6 +1140,8 @@
       "specificationValueExists": "Specification value already exists",
       "batchSettingsSuccess": "Batch settings successful",
       "pleaseAddSpecification": "Please add goods specification first",
+      "pleaseCompleteSpecification": "Please complete goods specification information",
+      "specificationValueRequired": "Specification \"{name}\" must have at least one specification value",
       "specificationSalePriceError": "The sale price of specification {index} cannot be empty and must be greater than 0",
       "specificationMarketPriceError": "The market price of specification {index} cannot be empty and must be greater than 0",
       "specificationStockError": "The stock of specification {index} cannot be empty and cannot be less than 0",

+ 3 - 1
src/locales/zh-CN/index.json

@@ -378,7 +378,7 @@
     "inputSubtitle": "请输入副标题(限50字符)",
     "categoryNameRequired": "请填写商品分类名称",
     "inputGoodsBrand": "请输入商品品牌",
-    "inputGoodsDescription": "请输入商品介绍(限500字符)",
+    "inputGoodsDescription": "请输入商品介绍(限256字符)",
     "inputGoodsNumber": "请输入商品货号",
     "inputGoodsSupplier": "请输入商品供应商",
     "selectShippingTemplate": "请选择运费模板",
@@ -1142,6 +1142,8 @@
       "specificationValueExists": "子规格已存在",
       "batchSettingsSuccess": "批量设置成功",
       "pleaseAddSpecification": "请先添加商品规格",
+      "pleaseCompleteSpecification": "请完善商品规格信息",
+      "specificationValueRequired": "规格\"{name}\"必须添加至少一个规格值",
       "specificationSalePriceError": "第{index}个规格的销售价格不能为空且必须大于0",
       "specificationMarketPriceError": "第{index}个规格的市场价不能为空且必须大于0",
       "specificationStockError": "第{index}个规格的商品库存不能为空且不能小于0",