潘超林 6 mēneši atpakaļ
vecāks
revīzija
ab0319c923

+ 17 - 0
src/api/manage/product.js

@@ -84,4 +84,21 @@ export function updateGoods(query) {
         method: 'post',
         data: query
     })
+}
+
+
+export function setLowPrice(query) {
+    return request({
+        url: '/system/goods/setLowPrice',
+        method: 'post',
+        data: query
+    })
+}
+
+export function cancelLowPrice(query) {
+    return request({
+        url: '/system/goods/cancelLowPrice',
+        method: 'post',
+        data: query
+    })
 }

+ 3 - 3
src/components/Map/map.vue

@@ -136,11 +136,11 @@ export default {
     },
     initAMap() {
       window._AMapSecurityConfig = {
-        securityJsCode: "4990f840a53760ad4a153076bfd6c4dc",
+        securityJsCode: "aae243a4d33170d5331abec91fe2cd0c",
       };
       let that = this;
       AMapLoader.load({
-        key: "aeb9d882fa88154234bf135e75b7ef9d", // 申请好的Web端开发者Key,首次调用 load 时必填
+        key: "2e75f4c22217359628e22c2e170b4778", // 申请好的Web端开发者Key,首次调用 load 时必填
         version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
         plugins: [
           "AMap.Geocoder",
@@ -159,7 +159,7 @@ export default {
           that.map = new AMap.Map("container", {
             // 设置地图容器id
             viewMode: "2D", // 是否为3D地图模式
-            zoom: 11, // 初始化地图级别
+            zoom: 11, // 初始化地图级别.
             resizeEnable: true,
           });
           that.geocoder = new AMap.Geocoder();

+ 88 - 44
src/views/product/createProduct.vue

@@ -4,14 +4,17 @@
       <el-row style="padding-top: 20px">
         <el-col :span="24">
           <el-descriptions title="基本信息" column="1"> </el-descriptions>
-          <basicInfo @updateValue="updateValue"></basicInfo>
+          <basicInfo @updateValue="updateValue" ref="basicRefs"></basicInfo>
           <el-descriptions title="销售信息" column="1"> </el-descriptions>
-          <salesInfo @updateValue="updateValue"></salesInfo>
+          <salesInfo @updateValue="updateValue" ref="salesRefs"></salesInfo>
           <el-descriptions title="商品详情" column="1"> </el-descriptions>
-          <productInfo @updateValue="updateValue"></productInfo>
+          <productInfo @updateValue="updateValue" ref="productRefs"></productInfo>
 
           <div class="dialog-footer" style="text-align: center">
-            <el-button type="primary" @click="submitForm">保 存</el-button>
+            <el-button @click="submitCancel">取 消</el-button>
+            <el-button type="primary" @click="submitForm" :loading="btnLading"
+              >保 存</el-button
+            >
 
             <el-button type="primary" @click="submitFormDraft">存入草稿箱</el-button>
           </div>
@@ -232,6 +235,7 @@ export default {
     return {
       form: {},
       headerImg: [],
+      btnLading: false,
     };
   },
   methods: {
@@ -244,59 +248,99 @@ export default {
         }
       });
     },
-    submitForm() {
-      console.log(this.form);
-      if (this.form.scope === "") {
-        this.$message.error(`经营区域不能为空!`);
-        return;
-      } else if (this.form.saleType === "") {
-        this.$message.error(`销售方式不能为空`);
-        return;
-      } else if (this.form.saleType === "") {
-        this.$message.error(`销售方式不能为空`);
-        return;
-      } else if (this.form.categoryId === "") {
-        this.$message.error(`商品分类不能为空`);
-        return;
-      } else if (this.form.pic === "") {
-        this.$message.error(`商品封面图不能为空`);
-        return;
-      } else if (this.form.unit === "") {
-        this.$message.error(`商品封面图不能为空`);
+    submitCancel() {
+      this.$confirm("是否取消发布,所填写的信息将会消失?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
+          this.$router.replace({ path: "/product/product/index" });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    async submitForm() {
+      let basic = await this.$refs.basicRefs.formvalidate();
+      if (basic) {
+        let sales = await this.$refs.salesRefs.formvalidate();
+        if (sales) {
+          let product = await this.$refs.productRefs.formvalidate();
+          if (!product) {
+            return;
+          }
+        } else {
+          return;
+        }
+      } else {
         return;
-      } else if (this.form.skuList === "") {
+      }
+      if (this.form.skuList === "") {
         this.$message.error(`商品规格不能为空`);
         return;
-      } else if (this.form.packing === "") {
-        this.$message.error(`包装方式不能为空`);
-        return;
-      } else if (this.form.shippingTimeDesc === "") {
-        this.$message.error(`发货时间不能为空`);
-        return;
-      } else if (this.form.freeShipping === "") {
-        this.$message.error(`运费不能为空`);
-        return;
-      } else if (this.form.shippingAddr === "") {
-        this.$message.error(`发货地址不能为空`);
-        return;
-      } else if (this.form.spuDesc === "") {
-        this.$message.error(`商品介绍不能为空`);
-        return;
-      } else if (this.form.saleModel === "2") {
-        if (this.form.presaleStartTime === "" || this.form.presaleEndTime === "") {
-          this.$message.error(`预售时间不能为空`);
-          return;
-        }
       }
+      // console.log(this.form);
+      // if (this.form.scope === "") {
+      //   this.$message.error(`经营区域不能为空!`);
+      //   return;
+      // } else if (this.form.saleType === "") {
+      //   this.$message.error(`销售方式不能为空`);
+      //   return;
+      // } else if (this.form.saleType === "") {
+      //   this.$message.error(`销售方式不能为空`);
+      //   return;
+      // } else if (this.form.categoryId === "") {
+      //   this.$message.error(`商品分类不能为空`);
+      //   return;
+      // } else if (this.form.pic === "") {
+      //   this.$message.error(`商品封面图不能为空`);
+      //   return;
+      // } else if (this.form.unit === "") {
+      //   this.$message.error(`商品封面图不能为空`);
+      //   return;
+      // } else
+      // else if (this.form.packing === "") {
+      //   this.$message.error(`包装方式不能为空`);
+      //   return;
+      // } else if (this.form.shippingTimeDesc === "") {
+      //   this.$message.error(`发货时间不能为空`);
+      //   return;
+      // } else if (this.form.freeShipping === "") {
+      //   this.$message.error(`运费不能为空`);
+      //   return;
+      // } else if (this.form.shippingAddr === "") {
+      //   this.$message.error(`发货地址不能为空`);
+      //   return;
+      // } else if (this.form.spuDesc === "") {
+      //   this.$message.error(`商品介绍不能为空`);
+      //   return;
+      // } else if (this.form.saleModel === "2") {
+      //   if (this.form.presaleStartTime === "" || this.form.presaleEndTime === "") {
+      //     this.$message.error(`预售时间不能为空`);
+      //     return;
+      //   }
+      // } else if (this.form.skuList.length< 1) {
+      //     this.$message.error(`请输入规格`);
+      //     return;
+      // }
 
       if (this.form.bannerList?.length > 0) {
         this.form.bannerList.shift();
       }
+      this.btnLading = true;
       publishGoods(this.form).then((res) => {
         if (res.code == 200) {
+          this.btnLading = false;
           this.$message.success(`发布成功!`);
           this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
           this.$router.replace({ path: "/product/product/index" });
+        } else {
+          this.btnLading = false;
         }
       });
     },

+ 182 - 3
src/views/product/list/allProduct.vue

@@ -182,7 +182,7 @@
         label="操作"
         align="center"
         class-name="small-padding fixed-width"
-        width="200"
+        width="300"
       >
         <template slot-scope="scope">
           <el-button
@@ -193,6 +193,23 @@
             >预览</el-button
           >
           <el-button
+            v-if="scope.row.scope == 1"
+            size="mini"
+            type="text"
+            @click="handleBargain(scope.row)"
+            v-hasPermi="['manage:order:detail']"
+            >设置特价</el-button
+          >
+          <el-button
+            v-if="scope.row.scope == 2"
+            size="mini"
+            type="text"
+            style="color: green"
+            @click="handleCancal(scope.row)"
+            v-hasPermi="['manage:order:detail']"
+            >取消特价</el-button
+          >
+          <el-button
             size="mini"
             type="text"
             :style="scope.row.spuStatus == 1 ? 'color:green' : 'color:red'"
@@ -281,6 +298,92 @@
         <el-button type="primary" @click="eventsSubmit">确 定</el-button>
       </span>
     </el-dialog>
+
+    <el-dialog
+      title="设为特价商品"
+      :visible.sync="bargainVisible"
+      :before-close="bargainVisible == false"
+      width="60%"
+    >
+      <el-table
+        :data="speList.skuList"
+        row-key="id"
+        @current-change="eventsChange"
+        highlight-current-row
+      >
+        <el-table-column prop="title" label="规格名称">
+          <template slot-scope="scope">
+            {{ scope.row.skuSpecsList[0].specsName }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="title" label="规格内容">
+          <template slot-scope="scope">
+            {{ scope.row.skuSpecsList[0].specsValue }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="title" label="单价">
+          <template slot-scope="scope">
+            {{ scope.row.skuPriceList[0].originalPrice }}元/{{ speList.unit }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="title" label="优惠价">
+          <template slot-scope="scope">
+            <el-input
+              v-model="scope.row.skuPriceList[0].price"
+              placeholder="请输入优惠价"
+              clearable
+              style="width: 160px"
+              @input="passValue"
+            >
+              <template slot="suffix"> 元/{{ speList.unit }} </template>
+            </el-input>
+          </template>
+        </el-table-column>
+        <el-table-column prop="title" label="单次最多购买量">
+          <template slot-scope="scope">
+            <el-input
+              v-model="scope.row.limitationDto.oneCount"
+              placeholder="请输入单次最多购买量"
+              clearable
+              style="width: 160px"
+              @input="passValue"
+            >
+              <template slot="suffix"> {{ speList.unit }} </template>
+            </el-input>
+          </template>
+        </el-table-column>
+        <el-table-column prop="title" label="单日最多购买量">
+          <template slot-scope="scope">
+            <el-input
+              v-model="scope.row.limitationDto.dayCount"
+              placeholder="请输入单日最多购买量"
+              clearable
+              style="width: 160px"
+              @input="passValue"
+            >
+              <template slot="suffix"> {{ speList.unit }} </template>
+            </el-input>
+          </template>
+        </el-table-column>
+        <el-table-column prop="title" label="每人总购买量">
+          <template slot-scope="scope">
+            <el-input
+              v-model="scope.row.limitationDto.totalCount"
+              placeholder="请输入每人总购买量"
+              clearable
+              style="width: 160px"
+              @input="passValue"
+            >
+              <template slot="suffix"> {{ speList.unit }} </template>
+            </el-input>
+          </template>
+        </el-table-column>
+      </el-table>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="bargainVisible = false">取 消</el-button>
+        <el-button type="primary" @click="bargainSubmit">确 定</el-button>
+      </span>
+    </el-dialog>
   </div>
 </template>
 
@@ -291,6 +394,8 @@ import {
   GoodsUpOrDown,
   editGoods,
   goodsRemove,
+  setLowPrice,
+  cancelLowPrice,
 } from "@/api/manage/product";
 
 import { promotionList, promotionSku } from "@/api/active/index";
@@ -303,6 +408,7 @@ export default {
   data() {
     return {
       // 遮罩层
+      bargainVisible: false,
       loading: true,
       showSearch: true,
       total: 0,
@@ -337,12 +443,85 @@ export default {
       skuId: "",
       eventList: [],
       radioId: "",
+      shopInfo: {},
+      speList: {},
+      speRecord: {},
     };
   },
   mounted() {
     this.getList();
+    this.getInfo();
   },
   methods: {
+    bargainSubmit() {
+      console.log(this.speList.skuList);
+      let params = {
+        id: this.speRecord.id,
+        lowestSend: 0,
+        saleType: this.speRecord.saleType,
+        skuList: this.speList.skuList,
+      };
+      setLowPrice(params).then((res) => {
+        if (res.code == 200) {
+          this.$message.success("设置特价成功!");
+          this.bargainVisible = false;
+          this.getList();
+        }
+      });
+    },
+    handleCancal(record) {
+      this.$confirm("是否确定取消该商品的特价", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          cancelLowPrice({
+            id: record.id,
+          }).then((res) => {
+            if (res.code == 200) {
+              this.$message.success(`取消特价成功!`);
+              this.getList();
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消操作",
+          });
+        });
+    },
+
+    handleBargain(record) {
+      this.speRecord = record;
+      getGoodsInfo({ spuId: record.id }).then((res) => {
+        if (res.code == 200) {
+          let params = res.data;
+          this.speList = params;
+          
+          this.speList.skuList.forEach((e) => {
+            e.skuPriceList[0].price=undefined
+            if (!e.limitationDto) {
+              e.limitationDto = {
+                dayCount: undefined,
+                oneCount: undefined,
+                totalCount: undefined,
+              };
+            }
+          });
+          this.bargainVisible = true;
+        }
+      });
+    },
+    getInfo() {
+      getStoreInfo().then((res) => {
+        if (res.code == 200) {
+          this.shopInfo = res.data;
+          this.form.scope = res.data.scope;
+        }
+      });
+    },
     eventsSubmit() {
       let ids = [];
       this.multipleSelection.forEach((e) => {
@@ -390,7 +569,7 @@ export default {
     },
 
     handleDelete(record) {
-      this.$confirm("是否确认删除该商品?", "提示", {
+      this.$confirm("是否确认删除该商品,删除后无法恢复?", "提示", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
         type: "warning",
@@ -513,7 +692,7 @@ export default {
       this.multipleSelection.forEach((e) => {
         ids.push(e.id);
       });
-      this.$confirm("是否确认批量删除商品?", "提示", {
+      this.$confirm("是否确认批量删除商品,删除后无法恢复?", "提示", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
         type: "warning",

+ 3 - 2
src/views/product/list/draftProduct.vue

@@ -101,9 +101,9 @@
               : scope.row.goodsDto.saleType == 3
               ? "一件代发"
               : ""
-          }}
+          }}  
         </template>
-      </el-table-column> -->
+      </el-table-column> --> 
       <el-table-column
         label="操作"
         align="center"
@@ -227,6 +227,7 @@ export default {
       getGoodsDraftById({ id: record.id }).then((res) => {
         if (res.code == 200) {
           let params = res.data.goodsDto;
+          params.goodsDraftId=record.id
           this.$router.push({
             path: "/product/product/updateProduct",
             query: { params },

+ 79 - 22
src/views/product/module/basic-info.vue

@@ -19,14 +19,16 @@
           </el-form-item>
         </el-col> -->
       <el-col :span="24">
-        <el-form-item>
-          <span slot="label"><span class="required">*</span> 销售方式</span>
+        <el-form-item prop="saleType">
+          <span slot="label">销售方式</span>
           <el-radio-group v-model="form.saleType" @change="passValue">
             <el-radio
               :label="0"
               :value="0"
               v-if="shopInfo.scope == 0 || shopInfo.scope == 1"
-              >整车</el-radio
+              >{{
+                shopInfo.scope == 0 ? "整车" : shopInfo.scope == 1 ? "普通商品" : ""
+              }}</el-radio
             >
             <el-radio :label="2" :value="2" v-if="shopInfo.scope == 0">拼车</el-radio>
             <!-- <el-radio :label="3">预售</el-radio> -->
@@ -35,18 +37,18 @@
           </el-radio-group>
         </el-form-item>
       </el-col>
-      <el-col :span="24" v-if="form.saleType == 0">
-        <el-form-item>
-          <span slot="label"><span class="required">*</span> 销售模式</span>
+      <el-col :span="24" v-if="shopInfo.scope == 0 && form.saleType == 0">
+        <el-form-item prop="saleModel">
+          <span slot="label">销售模式</span>
           <el-radio-group v-model="form.saleModel" @change="passValue">
             <el-radio :label="1">现货</el-radio>
-            <el-radio :label="2">预售</el-radio>
+            <el-radio :label="2" v-if="shopInfo.scope == 0">预售</el-radio>
           </el-radio-group>
         </el-form-item>
       </el-col>
       <el-col :span="24" v-if="form.saleModel == 2">
-        <el-form-item>
-          <span slot="label"><span class="required">*</span> 预售时间</span>
+        <el-form-item prop="datePicker">
+          <span slot="label">预售时间</span>
           <el-date-picker
             v-model="datePicker"
             type="datetimerange"
@@ -61,8 +63,8 @@
       </el-col>
 
       <el-col :span="24">
-        <el-form-item>
-          <span slot="label"><span class="required">*</span> 商品分类</span>
+        <el-form-item prop="categoryId">
+          <span slot="label">商品分类</span>
           <el-cascader
             v-model="form.categoryId"
             ref="formCascader"
@@ -73,27 +75,46 @@
         </el-form-item>
       </el-col>
       <el-col :span="24">
-        <el-form-item>
-          <span slot="label"><span class="required">*</span> 商品名称</span>
+        <el-form-item prop="title">
+          <span slot="label">商品名称</span>
           <el-input
             v-model="form.title"
             placeholder="请输入商品名称"
             clearable
             style="width: 260px"
+            maxlength="20"
+            show-word-limit
             @input="passValue"
           />
         </el-form-item>
       </el-col>
+      <el-col :span="24" v-if="form.saleType == 2">
+        <el-form-item prop="carpoolSuccessTime">
+          <span slot="label">拼车成功时间</span>
+          <el-input
+            v-model="form.carpoolSuccessTime"
+            placeholder="请输入拼车成功时间"
+            clearable
+            style="width: 260px"
+            @input="passValue"
+          >
+            <template slot="suffix"> 天 </template>
+          </el-input>
+        </el-form-item>
+      </el-col>
       <el-col :span="24" v-if="form.saleType == 4">
-        <el-form-item>
-          <span slot="label"><span class="required">*</span> 礼包描述</span>
+        <el-form-item prop="giftDesc">
+          <span slot="label">礼包描述</span>
           <el-input
             @input="passValue"
             v-model="form.giftDesc"
+            maxlength="70"
+            show-word-limit
             placeholder="请输入礼包描述"
             clearable
             style="width: 600px"
-          />
+          >
+          </el-input>
         </el-form-item>
       </el-col>
       <el-col :span="24">
@@ -120,7 +141,7 @@
       </el-col>
       <el-col :span="24">
         <el-form-item prop="bannerList">
-          <span slot="label"><span class="required">*</span> 商品图</span>
+          <span slot="label">商品图</span>
           <span class="tips"
             >图片要求:大小3M内,至多可上传10张,第一张图默认为商品封面图</span
           >
@@ -147,6 +168,7 @@
               :before-remove="requestRemove"
               :http-request="(data) => requestUpload(data, 'banner')"
               :show-file-list="false"
+              :before-upload="beforeAvatarUpload"
               :limit="11"
               action="#"
               :multiple="true"
@@ -174,6 +196,7 @@ export default {
   data() {
     return {
       form: {
+        carpoolSuccessTime: "",
         scope: "",
         saleType: undefined,
         saleModel: undefined,
@@ -198,13 +221,15 @@ export default {
         value: "value",
       },
       rules: {
-        scope: [{ required: true, message: "经营区域不能为空", trigger: "blur" }],
         saleType: [{ required: true, message: "销售方式不能为空", trigger: "blur" }],
         saleModel: [{ required: true, message: "销售模式不能为空", trigger: "blur" }],
         categoryId: [{ required: true, message: "分类不能为空", trigger: "blur" }],
         title: [{ required: true, message: "商品名称不能为空", trigger: "blur" }],
         giftDesc: [{ required: true, message: "礼包描述不能为空", trigger: "blur" }],
-        pic: [{ required: true, message: "封面图不能为空", trigger: "blur" }],
+        bannerList: [{ required: true, message: "商品图不能为空", trigger: "blur" }],
+        carpoolSuccessTime: [
+          { required: true, message: "拼车成功时间不能为空", trigger: "blur" },
+        ],
       },
       index: 0,
       shopInfo: {},
@@ -250,6 +275,32 @@ export default {
   },
 
   methods: {
+    beforeAvatarUpload(file) {
+      const isJPG = file.type === "image/jpeg" || "image/png" || "image/jpg";
+      const isLt2M = file.size / 1024 / 1024 < 2;
+      if (!isJPG) {
+        this.$message.error("上传图片只能是 JPG或PNG或JPEG 格式!");
+      }
+      if (!isLt2M) {
+        this.$message.error("上传图片大小不能超过 2MB!");
+      }
+      return isJPG && isLt2M;
+    },
+
+    formvalidate() {
+      let that = this;
+      return new Promise((resolve) => {
+        that.$refs.queryForm.validate((valid) => {
+          console.log(valid);
+          if (valid) {
+            resolve(valid);
+          } else {
+            resolve(valid);
+          }
+        });
+      });
+    },
+
     removeImg(index) {
       this.bannerList.splice(index, 1);
       this.passValue();
@@ -280,8 +331,9 @@ export default {
           sort: this.bannerList[index].name,
         });
       }
-      this.form.pic = this.bannerList[0].url;
-
+      if (this.bannerList.length > 1) {
+        this.form.pic = this.bannerList[0].url;
+      }
       if (this.form.scope == 1) {
         this.form.saleType = 0;
         this.form.saleModel = 1;
@@ -301,7 +353,12 @@ export default {
     cascaderChange(val) {
       let nodes = this.$refs.formCascader.getCheckedNodes();
       this.form.categoryName = nodes[0].label;
-      this.form.categoryIds = val;
+      // this.form.categoryIds = val;
+      let list = [];
+      val.forEach((e) => {
+        list.push(parseInt(e));
+      });
+      this.form.categoryIds = JSON.stringify(list);
       if (val.length == 1) {
         this.form.categoryId = val[0];
       } else if (val.length == 2) {

+ 34 - 16
src/views/product/module/product-info.vue

@@ -1,9 +1,9 @@
 <template>
-  <el-form :model="form" ref="queryForm" size="small" :inline="true" label-width="120px">
+  <el-form :model="form" ref="queryForm" size="small"     :rules="rules" :inline="true" label-width="120px">
     <el-row>
       <el-col :span="24">
-        <el-form-item>
-          <span slot="label"><span class="required">*</span> 商品介绍</span>
+        <el-form-item prop="spuDesc">
+          <span slot="label">商品介绍</span>
           <el-input
             style="width: 700px"
             type="textarea"
@@ -53,16 +53,15 @@
           </el-upload>
         </el-form-item>
       </el-col>
-      <!-- <el-col :span="24">
-        <el-form-item>
-          <span slot="label"><span class="required">*</span> 发布状态</span>
-          <el-radio-group v-model="form.">
-    <el-radio :label="3">备选项</el-radio>
-    <el-radio :label="6">备选项</el-radio>
-    <el-radio :label="9">备选项</el-radio>
-  </el-radio-group>
+      <el-col :span="24">
+        <el-form-item prop="spuStatus">
+          <span slot="label"> 发布状态</span>
+          <el-radio-group v-model="form.spuStatus">
+            <el-radio :label="0" :value="0">上架</el-radio>
+            <el-radio :label="1" :value="1">下架</el-radio>
+          </el-radio-group>
         </el-form-item>
-      </el-col> -->
+      </el-col>
     </el-row>
   </el-form>
 </template>
@@ -78,12 +77,17 @@ export default {
         spuDetailList: [],
         specialList: [],
         spuDesc: "",
+        spuStatus: 0,
       },
       headers: { Auth: "Bearer " + getToken(), "Content-type": "multipart/form-data" },
       spuDetailList: [],
       specialList: [],
       index: 0,
       index1: 0,
+      rules: {
+        spuDesc: [{ required: true, message: "商品介绍不能为空", trigger: "blur" }],
+        spuStatus: [{ required: true, message: "发布状态不能为空", trigger: "blur" }],
+      },
     };
   },
   watch: {
@@ -93,7 +97,8 @@ export default {
         //监听info对象变化
         if (newVal) {
           this.form.spuDesc = newVal.spuDesc;
-
+          this.spuDetailList = [];
+          this.specialList = [];
           if (newVal.spuDetailList) {
             newVal.spuDetailList.forEach((e) => {
               this.spuDetailList.push({
@@ -103,9 +108,9 @@ export default {
               });
             });
           }
-          if (newVal.spuDetailList) {
-            newVal.spuDetailList.forEach((e) => {
-              this.spuDetailList.push({
+          if (newVal.specialList) {
+            newVal.specialList.forEach((e) => {
+              this.specialList.push({
                 url: e.fileUrl,
                 id: e.id,
                 sort: e.sort,
@@ -120,6 +125,19 @@ export default {
   },
 
   methods: {
+    formvalidate() {
+      let that=this
+      return new Promise((resolve) => {
+        that.$refs.queryForm.validate((valid) => {
+          console.log(valid);
+          if (valid) {
+            resolve(valid);
+          } else {
+            resolve(valid);
+          }
+        });
+      });
+    },
     passValue() {
       if (this.specialList) {
         this.form.specialList = [];

+ 96 - 36
src/views/product/module/sales-info.vue

@@ -9,8 +9,8 @@
   >
     <el-row>
       <el-col :span="24">
-        <el-form-item>
-          <span slot="label"><span class="required">*</span> 计量单位</span>
+        <el-form-item prop="unit">
+          <span slot="label">计量单位</span>
           <el-select v-model="form.unit" placeholder="请选择" @change="passValue">
             <el-option
               v-for="item in measure"
@@ -37,6 +37,8 @@
                   v-model="scope.row.skuSpecsList[0].specsName"
                   placeholder="请输入规格名称"
                   clearable
+                  maxlength="8"
+                  show-word-limit
                   @input="passValue"
                 />
               </template>
@@ -47,25 +49,29 @@
                   v-model="scope.row.skuSpecsList[0].specsValue"
                   placeholder="规格内容"
                   clearable
+                  maxlength="8"
+                  show-word-limit
                   @input="passValue"
                 />
               </template>
             </el-table-column>
             <el-table-column prop="name" label="库存" width="160">
               <template slot-scope="scope">
-                <el-input
+                  <el-input-number
+                :controls="false"
                   v-model="scope.row.stock"
                   placeholder="库存"
                   clearable
                   @input="passValue"
                 >
                   <template slot="suffix"> {{ form.unit }} </template>
-                </el-input>
+                </el-input-number>
               </template>
             </el-table-column>
             <el-table-column prop="address" label="起批量" width="160">
               <template slot-scope="scope">
-                <el-input
+                 <el-input-number
+                :controls="false"
                   v-model="scope.row.skuPriceList[0].minPurchase"
                   placeholder="起批量"
                   clearable
@@ -74,55 +80,59 @@
                   <template slot="suffix">
                     {{ form.unit }}
                   </template>
-                </el-input>
+                </el-input-number>
               </template>
             </el-table-column>
             <el-table-column prop="address" label="收购价" width="160">
               <template slot-scope="scope">
-                <el-input
+              <el-input-number
+                :controls="false"
                   v-model="scope.row.skuCost.purchaseFee"
                   placeholder="收购价"
                   clearable
                   @input="passValue"
                 >
                   <template slot="suffix"> {{ form.unit }}/元 </template>
-                </el-input>
+                </el-input-number>
               </template>
             </el-table-column>
             <el-table-column prop="address" label="人工费" width="160">
               <template slot-scope="scope">
-                <el-input
+                 <el-input-number
+                :controls="false"
                   v-model="scope.row.skuCost.laborFee"
                   placeholder="人工费"
                   clearable
                   @input="passValue"
                 >
                   <template slot="suffix"> {{ form.unit }}/元 </template>
-                </el-input>
+                </el-input-number>
               </template>
             </el-table-column>
             <el-table-column prop="address" label="代办费" width="160">
               <template slot-scope="scope">
-                <el-input
+              <el-input-number
+                :controls="false"
                   v-model="scope.row.skuCost.agencyFee"
                   placeholder="代办费"
                   clearable
                   @input="passValue"
                 >
                   <template slot="suffix"> {{ form.unit }}/元 </template>
-                </el-input>
+                </el-input-number>
               </template>
             </el-table-column>
             <el-table-column prop="address" label="材料费" width="160">
               <template slot-scope="scope">
-                <el-input
+                <el-input-number
+                :controls="false"
                   @input="passValue"
                   v-model="scope.row.skuCost.materialFee"
                   placeholder="材料费"
                   clearable
                 >
                   <template slot="suffix"> {{ form.unit }}/元 </template>
-                </el-input>
+                </el-input-number>
               </template>
             </el-table-column>
             <!-- <el-table-column prop="name" label="原价" width="180"> </el-table-column> -->
@@ -131,6 +141,19 @@
                 {{ computePrice(scope.row) }}元/{{ form.unit }}
               </template>
             </el-table-column>
+            <el-table-column label="规格重量" width="160">
+              <template slot-scope="scope">
+                 <el-input-number
+                :controls="false"
+                  v-model="scope.row.weight"
+                  placeholder="请输入单个规格重量"
+                  clearable
+                  @input="passValue"
+                >
+                  <template slot="suffix"> /Kg </template>
+                </el-input-number>
+              </template>
+              </el-table-column>
             <el-table-column prop="address" label="操作" width="160">
               <template slot-scope="scope">
                 <el-button
@@ -153,6 +176,8 @@
                   v-model="scope.row.skuSpecsList[0].specsName"
                   placeholder="请输入规格名称"
                   clearable
+                  maxlength="8"
+                  show-word-limit
                   @input="passValue"
                 />
               </template>
@@ -163,25 +188,29 @@
                   v-model="scope.row.skuSpecsList[0].specsValue"
                   placeholder="规格内容"
                   clearable
+                  maxlength="8"
+                  show-word-limit
                   @input="passValue"
                 />
               </template>
             </el-table-column>
             <el-table-column prop="name" label="库存" width="160">
               <template slot-scope="scope">
-                <el-input
+                <el-input-number
+                :controls="false"
                   v-model="scope.row.stock"
                   placeholder="库存"
                   clearable
                   @input="passValue"
                 >
                   <template slot="suffix"> {{ form.unit }} </template>
-                </el-input>
+                </el-input-number>
               </template>
             </el-table-column>
             <el-table-column label="起批量" width="160">
               <template slot-scope="scope">
-                <el-input
+                <el-input-number
+                :controls="false"
                   v-model="scope.row.skuPriceList[0].minPurchase"
                   placeholder="起批量"
                   clearable
@@ -190,19 +219,20 @@
                   <template slot="suffix">
                     {{ form.unit }}
                   </template>
-                </el-input>
+                </el-input-number>
               </template>
             </el-table-column>
             <el-table-column label="批发价" width="160">
               <template slot-scope="scope">
-                <el-input
+                 <el-input-number
+                :controls="false"
                   v-model="scope.row.skuPriceList[0].originalPrice"
                   placeholder="收购价"
                   clearable
                   @input="passValue"
                 >
                   <template slot="suffix"> {{ form.unit }}/元 </template>
-                </el-input>
+                </el-input-number>
               </template>
             </el-table-column>
             <el-table-column prop="address" label="商品单价" width="80">
@@ -215,6 +245,20 @@
                 元/{{ form.unit }}
               </template>
             </el-table-column>
+
+            <el-table-column label="规格重量" width="160">
+              <template slot-scope="scope">
+                 <el-input-number
+                :controls="false"
+                  v-model="scope.row.weight"
+                  placeholder="请输入单个规格重量"
+                  clearable
+                  @input="passValue"
+                >
+                <template slot="suffix"> /Kg </template>
+                </el-input-number>
+              </template>
+              </el-table-column>
             <el-table-column prop="address" label="操作" width="160">
               <template slot-scope="scope">
                 <el-button
@@ -248,8 +292,8 @@
                   </el-option>
                 </el-select>
               </el-form-item>
-              <el-form-item>
-                <span slot="label"><span class="required">*</span> 发货时间</span>
+              <el-form-item prop="shippingTimeDesc">
+                <span slot="label">发货时间</span>
                 <el-select
                   v-model="form.shippingTimeDesc"
                   placeholder="请选择包装方式"
@@ -313,8 +357,8 @@
         </el-form-item>
       </el-col>
       <el-col :span="24" style="margin-top: 20px" v-if="shopInfo.scope == 0">
-        <el-form-item>
-          <span slot="label"><span class="required">*</span> 运费</span>
+        <el-form-item prop="freeShipping">
+          <span slot="label">运费</span>
           <div class="main1">
             <el-radio-group
               v-model="form.freeShipping"
@@ -328,8 +372,8 @@
         </el-form-item>
       </el-col>
       <el-col :span="24" style="margin-top: 20px">
-        <el-form-item>
-          <span slot="label"><span class="required">*</span> 发货地址</span>
+        <el-form-item prop="shippingAddrBean.addrDetail">
+          <span slot="label"> 发货地址</span>
           <div style="display: flex; flex-direction: row; align-items: center">
             <el-button
               @click="selectAddr"
@@ -394,9 +438,11 @@ export default {
       rules: {
         freeShipping: [{ required: true, message: "请选择运费方式", trigger: "blur" }],
         props: [{ required: true, message: "商品属性不能为空", trigger: "blur" }],
-        unit: [{ required: true, message: "请选择计量单位", trigger: "blur" }],
+        unit: [{ required: true, message: "计量单位", trigger: "blur" }],
+        shippingTimeDesc: [{ required: true, message: "发货时间不能为空", trigger: "blur" }],
         skuList: [{ required: true, message: "规格不能为空", trigger: "blur" }],
         packing: [{ required: true, message: "包装方式不能为空", trigger: "blur" }],
+        "shippingAddrBean.addrDetail": [{ required: true, message: "详细地址不能为空", trigger: "blur" }],
       },
       shopInfo: {},
     };
@@ -440,6 +486,19 @@ export default {
     },
   },
   methods: {
+    formvalidate() {
+      let that=this
+      return new Promise((resolve) => {
+        that.$refs.queryForm.validate((valid) => {
+          console.log(valid);
+          if (valid) {
+            resolve(valid);
+          } else {
+            resolve(valid);
+          }
+        });
+      });
+    },
     getInfo() {
       getStoreInfo().then((res) => {
         if (res.code == 200) {
@@ -532,12 +591,13 @@ export default {
     },
     addSpecification() {
       this.form.skuList.push({
-        stock: "",
+        stock: undefined,
+        weight:undefined,
         skuCost: {
-          purchaseFee: "",
-          laborFee: "",
-          agencyFee: "",
-          materialFee: "",
+          purchaseFee: undefined,
+          laborFee: undefined,
+          agencyFee: undefined,
+          materialFee: undefined,
         },
         skuSpecsList: [
           {
@@ -548,10 +608,10 @@ export default {
         ],
         skuPriceList: [
           {
-            minPurchase: "",
-            maxPurchase: "",
-            price: "",
-            originalPrice: "",
+            minPurchase: undefined,
+            maxPurchase: undefined,
+            price: undefined,
+            originalPrice: undefined,
             lowestPrice: 1,
           },
         ],

+ 100 - 43
src/views/product/updateProduct.vue

@@ -4,14 +4,15 @@
       <el-row style="padding-top: 20px">
         <el-col :span="24">
           <el-descriptions title="基本信息" column="1"> </el-descriptions>
-          <basicInfo @updateValue="updateValue" :data="form"></basicInfo>
+          <basicInfo ref="basicRefs" @updateValue="updateValue" :data="form"></basicInfo>
           <el-descriptions title="销售信息" column="1"> </el-descriptions>
-          <salesInfo @updateValue="updateValue" :data="form"></salesInfo>
+          <salesInfo ref="salesRefs" @updateValue="updateValue" :data="form"></salesInfo>
 
           <el-descriptions title="商品详情" column="1"> </el-descriptions>
-          <productInfo @updateValue="updateValue" :data="form"></productInfo>
+          <productInfo  ref="productRefs" @updateValue="updateValue" :data="form"></productInfo>
           <div class="dialog-footer" style="text-align: center">
-            <el-button type="primary" @click="submitForm">保 存</el-button>
+            <el-button @click="submitCancel">取 消</el-button>
+            <el-button type="primary" @click="submitForm"  :loading="btnLading">保 存</el-button>
 
             <el-button type="primary" @click="submitFormDraft">存入草稿箱</el-button>
           </div>
@@ -232,6 +233,7 @@ export default {
     return {
       form: {},
       headerImg: [],
+      btnLading:false,
     };
   },
   mounted() {
@@ -268,6 +270,24 @@ export default {
     }
   },
   methods: {
+    submitCancel() {
+      this.$confirm("是否取消发布,所填写的信息将会消失?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
+          this.$router.replace({ path: "/product/product/index" });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+
     submitFormDraft() {
       saveGoodsDraft(this.form).then((res) => {
         if (res.code == 200) {
@@ -277,54 +297,91 @@ export default {
         }
       });
     },
-    submitForm() {
-      if (this.form.scope === "") {
-        this.$message.error(`经营区域不能为空!`);
-        return;
-      } else if (this.form.saleType === "") {
-        this.$message.error(`销售方式不能为空`);
-        return;
-      } else if (this.form.saleType === "") {
-        this.$message.error(`销售方式不能为空`);
-        return;
-      } else if (this.form.categoryId === "") {
-        this.$message.error(`商品分类不能为空`);
-        return;
-      } else if (this.form.pic === "") {
-        this.$message.error(`商品封面图不能为空`);
-        return;
-      } else if (this.form.unit === "") {
-        this.$message.error(`商品封面图不能为空`);
+    async submitForm() {
+      let basic = await this.$refs.basicRefs.formvalidate();
+      if (basic) {
+        let sales = await this.$refs.salesRefs.formvalidate();
+        if (sales) {
+          let product = await this.$refs.productRefs.formvalidate();
+          if (!product) {
+            return;
+          }
+        } else {
+          return;
+        }
+      } else {
         return;
-      } else if (this.form.skuList === "") {
+      }
+      if (this.form.skuList === "") {
         this.$message.error(`商品规格不能为空`);
         return;
-      } else if (this.form.packing === "") {
-        this.$message.error(`包装方式不能为空`);
-        return;
-      } else if (this.form.shippingTimeDesc === "") {
-        this.$message.error(`发货时间不能为空`);
-        return;
-      } else if (this.form.freeShipping === "") {
-        this.$message.error(`运费不能为空`);
-        return;
-      } else if (this.form.shippingAddr === "") {
-        this.$message.error(`发货地址不能为空`);
-        return;
-      } else if (this.form.spuDesc === "") {
-        this.$message.error(`商品介绍不能为空`);
-        return;
-      } else if (this.form.saleModel === "2") {
-        if (this.form.presaleStartTime === "" || this.form.presaleEndTime === "") {
-          this.$message.error(`预售时间不能为空`);
-          return;
-        }
       }
+
+      // if (this.form.scope === "") {
+      //   this.$message.error(`经营区域不能为空!`);
+      //   return;
+      // } else if (this.form.saleType === "") {
+      //   this.$message.error(`销售方式不能为空`);
+      //   return;
+      // } else if (this.form.saleType === "") {
+      //   this.$message.error(`销售方式不能为空`);
+      //   return;
+      // } else if (this.form.categoryId === "") {
+      //   this.$message.error(`商品分类不能为空`);
+      //   return;
+      // } else if (this.form.pic === "") {
+      //   this.$message.error(`商品封面图不能为空`);
+      //   return;
+      // } else if (this.form.unit === "") {
+      //   this.$message.error(`商品封面图不能为空`);
+      //   return;
+      // } else if (this.form.skuList === "") {
+      //   this.$message.error(`商品规格不能为空`);
+      //   return;
+      // } else if (this.form.packing === "") {
+      //   this.$message.error(`包装方式不能为空`);
+      //   return;
+      // } else if (this.form.shippingTimeDesc === "") {
+      //   this.$message.error(`发货时间不能为空`);
+      //   return;
+      // } else if (this.form.freeShipping === "") {
+      //   this.$message.error(`运费不能为空`);
+      //   return;
+      // } else if (this.form.shippingAddr === "") {
+      //   this.$message.error(`发货地址不能为空`);
+      //   return;
+      // } else if (this.form.spuDesc === "") {
+      //   this.$message.error(`商品介绍不能为空`);
+      //   return;
+      // } else if (this.form.saleModel === "2") {
+      //   if (this.form.presaleStartTime === "" || this.form.presaleEndTime === "") {
+      //     this.$message.error(`预售时间不能为空`);
+      //     return;
+      //   }
+      // }
+      if (this.form.bannerList?.length > 0) {
+        this.form.bannerList.shift();
+      }
+      this.btnLading = true;
+      publishGoods(this.form).then((res) => {
+        if (res.code == 200) {
+          this.btnLading = false;
+          this.$message.success(`发布成功!`);
+          this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
+          this.$router.replace({ path: "/product/product/index" });
+        }else{
+          this.btnLading = false;
+        }
+      });
+      this.btnLading=true
       updateGoods(this.form).then((res) => {
         if (res.code == 200) {
+          this.btnLading=false
           this.$message.success(`编辑成功!`);
           this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
           this.$router.replace({ path: "/product/product/index" });
+        }else{
+          this.btnLading=false
         }
       });
     },