潘超林 hai 1 mes
pai
achega
8847890634

+ 1 - 1
src/views/member/list/allProduct.vue

@@ -521,7 +521,7 @@ export default {
         saleType: "",
         saleModel: "",
         scope: "",
-        spuType: 2,
+        spuType: 4,
         promotionTag: "",
       },
       // 表单参数

+ 1 - 1
src/views/member/list/draftProduct.vue

@@ -145,7 +145,7 @@ export default {
         pageNo: 1,
         pageSize: 10,
         title: "",
-        spuType: 2,
+        spuType: 4,
       },
       // 表单参数
       form: {},

+ 0 - 27
src/views/product/createProduct.vue

@@ -262,25 +262,7 @@ export default {
       btnLading: false,
     };
   },
-  mounted() {
-    this.getInfo();
-  },
   methods: {
-    getInfo() {
-      getStoreInfo().then((res) => {
-        if (res.code == 200) {
-          if (res.data.scope == 0) {
-            if (this.form.saleType == 2) {
-              this.$refs.salesRefs.setShowCom(true);
-            } else {
-              this.$refs.salesRefs.setShowCom(false);
-            }
-          } else {
-            this.$refs.salesRefs.setShowCom(true);
-          }
-        }
-      });
-    },
     submitFormDraft() {
       if (this.form.categoryId?.length > 0) {
         this.form.categoryId =
@@ -415,15 +397,6 @@ export default {
     },
     updateValue(val) {
       this.form = { ...this.form, ...val };
-      console.log(this.form);
-
-      if (this.form.saleType == 2) {
-        this.$refs.salesRefs.setShowCom(true);
-      } else if (this.form.scope == 0) {
-        this.$refs.salesRefs.setShowCom(false);
-      } else {
-        this.$refs.salesRefs.setShowCom(true);
-      }
       this.headerImg = [];
       if (val.vid || this.form.vid) {
         this.headerImg.push({

+ 88 - 53
src/views/product/list/allProduct.vue

@@ -66,10 +66,16 @@
       </el-form-item> -->
 
       <el-form-item>
-        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
           >搜索</el-button
         >
-        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+          >重置</el-button
+        >
       </el-form-item>
     </el-form>
     <el-row :gutter="10" class="mb8">
@@ -100,12 +106,20 @@
             更多批量操作<i class="el-icon-arrow-down el-icon--right"></i>
           </el-button>
           <el-dropdown-menu slot="dropdown">
-            <el-dropdown-item @click.native="BatchRemove">批量删除</el-dropdown-item>
-            <el-dropdown-item @click.native="handleEvents" v-if="shopInfo.scope == 1"
+            <el-dropdown-item @click.native="BatchRemove"
+              >批量删除</el-dropdown-item
+            >
+            <el-dropdown-item
+              @click.native="handleEvents"
+              v-if="shopInfo.scope == 1"
               >批量加入活动</el-dropdown-item
             >
-            <el-dropdown-item @click.native="handleExport">批量导出</el-dropdown-item>
-            <el-dropdown-item @click.native="handleDelist">批量下架</el-dropdown-item>
+            <el-dropdown-item @click.native="handleExport"
+              >批量导出</el-dropdown-item
+            >
+            <el-dropdown-item @click.native="handleDelist"
+              >批量下架</el-dropdown-item
+            >
             <el-dropdown-item @click.native="handleSort"
               >批量加入店铺分类</el-dropdown-item
             >
@@ -139,7 +153,11 @@
       />
       <el-table-column label="分类" align="center" prop="categoryName" />
 
-      <el-table-column label="店铺所属分类" align="center" prop="merchantClassifyName" />
+      <el-table-column
+        label="店铺所属分类"
+        align="center"
+        prop="merchantClassifyName"
+      />
 
       <el-table-column label="价格" align="center" width="120">
         <template slot-scope="scope">
@@ -168,7 +186,11 @@
       </el-table-column>
       <el-table-column label="展示销量" align="center" prop="lookSalesVolume">
       </el-table-column>
-      <el-table-column label="销售模式" align="center" v-if="shopInfo.scope == 0">
+      <el-table-column
+        label="销售模式"
+        align="center"
+        v-if="shopInfo.scope == 0"
+      >
         <template slot-scope="scope">
           <span v-if="scope.row.scope == 0">
             {{ scope.row.saleModel == 1 ? "现货" : "预售" }}
@@ -242,8 +264,12 @@
       <el-table-column label="商品属性" align="center" width="150">
         <template slot-scope="scope">
           <div v-for="(item, index) in scope.row.propNew" :key="index">
-            <div style="text-align: left">属性{{ index + 1 }}:{{ item.name }}</div>
-            <div style="text-align: left">属性值{{ index + 1 }}:{{ item.value }}</div>
+            <div style="text-align: left">
+              属性{{ index + 1 }}:{{ item.name }}
+            </div>
+            <div style="text-align: left">
+              属性值{{ index + 1 }}:{{ item.value }}
+            </div>
           </div>
         </template>
       </el-table-column>
@@ -286,7 +312,9 @@
           >
           <el-button
             v-if="
-              scope.row.scope == 1 && !scope.row.promotionTitle && scope.row.scope != 3
+              scope.row.scope == 1 &&
+              !scope.row.promotionTitle &&
+              scope.row.scope != 3
             "
             size="mini"
             type="text"
@@ -310,7 +338,11 @@
             @click="handleStatus(scope.row)"
             v-hasPermi="['manage:order:detail']"
             >{{
-              scope.row.spuStatus == 1 ? "上架" : scope.row.spuStatus == 0 ? "下架" : ""
+              scope.row.spuStatus == 1
+                ? "上架"
+                : scope.row.spuStatus == 0
+                ? "下架"
+                : ""
             }}</el-button
           >
 
@@ -366,7 +398,9 @@
       >
         <el-table-column label width="45">
           <template slot-scope="scope">
-            <el-radio :label="scope.row.id" v-model="radioId"><span></span></el-radio>
+            <el-radio :label="scope.row.id" v-model="radioId"
+              ><span></span
+            ></el-radio>
           </template>
         </el-table-column>
         <el-table-column prop="title" label="活动名称"> </el-table-column>
@@ -436,18 +470,24 @@
       >
         <el-table-column prop="title" label="规格名称">
           <template slot-scope="scope">
-            {{ scope.row.skuSpecsList ? scope.row.skuSpecsList[0].specsName : "" }}
+            {{
+              scope.row.skuSpecsList ? scope.row.skuSpecsList[0].specsName : ""
+            }}
           </template>
         </el-table-column>
         <el-table-column prop="title" label="规格内容">
           <template slot-scope="scope">
-            {{ scope.row.skuSpecsList ? scope.row.skuSpecsList[0].specsValue : "" }}
+            {{
+              scope.row.skuSpecsList ? scope.row.skuSpecsList[0].specsValue : ""
+            }}
           </template>
         </el-table-column>
         <el-table-column prop="title" label="单价">
           <template slot-scope="scope">
             {{
-              scope.row.skuPriceList ? scope.row.skuPriceList[0].originalPrice : ""
+              scope.row.skuPriceList
+                ? scope.row.skuPriceList[0].originalPrice
+                : ""
             }}元/{{ speList.unit }}
           </template>
         </el-table-column>
@@ -589,8 +629,7 @@ export default {
         categoryId: "",
         spuStatus: "",
         saleType: "",
-        scope: "",
-        spuType: 0,
+        spuType: 1,
       },
       // 表单参数
       form: {},
@@ -698,11 +737,6 @@ export default {
                 oneCount: "",
                 totalCount: "",
               });
-              // e.limitationDto = {
-              //   dayCount: "",
-              //   oneCount: "",
-              //   totalCount: "",
-              // };
             }
           });
           this.$forceUpdate();
@@ -756,7 +790,9 @@ export default {
 
       for (let index = 0; index < this.multipleSelection.length; index++) {
         if (this.multipleSelection[index].scope == 3) {
-          this.$message.error("所选商品包含同城秒送商品,无法批量加入活动,请重新选择");
+          this.$message.error(
+            "所选商品包含同城秒送商品,无法批量加入活动,请重新选择"
+          );
           return;
         }
       }
@@ -765,7 +801,9 @@ export default {
           this.multipleSelection[index].promotionTag ||
           this.multipleSelection[index].scope == 2
         ) {
-          this.$message.error("所选商品包含已参加活动商品,无法批量加入活动,请重新选择");
+          this.$message.error(
+            "所选商品包含已参加活动商品,无法批量加入活动,请重新选择"
+          );
           return;
         }
       }
@@ -850,7 +888,9 @@ export default {
             .then(() => {
               batchEditCategory({
                 ids: ids.toString(),
-                merchantClassifyId: JSON.stringify(this.sort.merchantClassifyId),
+                merchantClassifyId: JSON.stringify(
+                  this.sort.merchantClassifyId
+                ),
                 merchantClassifyName: this.sort.merchantClassifyName,
               }).then((res) => {
                 if (res.code == 200) {
@@ -892,7 +932,9 @@ export default {
       }
       for (let index = 0; index < this.multipleSelection.length; index++) {
         if (this.multipleSelection[index].spuStatus == 1) {
-          this.$message.error("所选商品包含已下架商品,无法批量下架,请重新选择");
+          this.$message.error(
+            "所选商品包含已下架商品,无法批量下架,请重新选择"
+          );
           return;
         }
       }
@@ -1031,7 +1073,8 @@ export default {
         .then(() => {
           GoodsUpOrDown({
             spuId: record.id,
-            spuStatus: record.spuStatus == 1 ? 0 : record.spuStatus == 0 ? 1 : "",
+            spuStatus:
+              record.spuStatus == 1 ? 0 : record.spuStatus == 0 ? 1 : "",
           }).then((res) => {
             if (res.code == 200) {
               this.$message.success(`操作成功!`);
@@ -1098,14 +1141,9 @@ export default {
       });
     },
     cascaderChange(val) {
-      if (val.length == 1) {
-        this.queryParams.categoryId = val[0];
-      } else if (val.length == 2) {
-        this.queryParams.categoryId = val[1];
-      } else if (val.length == 3) {
-        this.queryParams.categoryId = val[2];
+      if (val.length > 0) {
+        this.queryParams.categoryId = val[val.length - 1];
       }
-      // this.getList();
     },
     categoryLazyLoad(node, resolve) {
       let level = node.level;
@@ -1152,12 +1190,8 @@ export default {
     },
 
     cascadermerchantChange(val) {
-      if (val.length == 1) {
-        this.queryParams.merchantClassifyId = val[0];
-      } else if (val.length == 2) {
-        this.queryParams.merchantClassifyId = val[1];
-      } else if (val.length == 3) {
-        this.queryParams.merchantClassifyId = val[2];
+      if (val.length > 0) {
+        this.queryParams.merchantClassifyId = val[val.length - 1];
       }
     },
     categoryLazyLoadUpdate(node, resolve) {
@@ -1184,18 +1218,19 @@ export default {
           resolve(nodes);
         });
       } else if (level == 1) {
-        getMerchantClassifyList({ parentId: node.data.value, classifyType: 1 }).then(
-          (res) => {
-            const nodes = Array.from(res.data).map((item) => ({
-              value: item.id,
-              label: `${item.classifyName}`,
-              leaf: level >= 2,
-              // level: 2,
-            }));
-            // 通过调用resolve将子节点数据返回,通知组件数据加载完成
-            resolve(nodes);
-          }
-        );
+        getMerchantClassifyList({
+          parentId: node.data.value,
+          classifyType: 1,
+        }).then((res) => {
+          const nodes = Array.from(res.data).map((item) => ({
+            value: item.id,
+            label: `${item.classifyName}`,
+            leaf: level >= 2,
+            // level: 2,
+          }));
+          // 通过调用resolve将子节点数据返回,通知组件数据加载完成
+          resolve(nodes);
+        });
       } else {
         resolve({});
       }

+ 17 - 7
src/views/product/list/draftProduct.vue

@@ -18,10 +18,16 @@
       </el-form-item>
 
       <el-form-item>
-        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
           >搜索</el-button
         >
-        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+          >重置</el-button
+        >
       </el-form-item>
     </el-form>
     <el-col :span="1.5">
@@ -65,9 +71,7 @@
       <el-table-column label="价格" align="center">
         <template slot-scope="scope">
           {{
-            scope.row.skuList
-              ? scope.row.skuList[0].skuPriceList[0].price
-              : ""
+            scope.row.skuList ? scope.row.skuList[0].skuPriceList[0].price : ""
           }}/{{ scope.row.unit }}
         </template>
       </el-table-column>
@@ -92,7 +96,13 @@
       </el-table-column>
       <el-table-column label="经营区域" align="center">
         <template slot-scope="scope">
-          {{ scope.row.scope == 0 ? "全国" : scope.row.scope == 1 ? "同城" : "特价" }}
+          {{
+            scope.row.scope == 0
+              ? "全国"
+              : scope.row.scope == 1
+              ? "同城"
+              : "特价"
+          }}
         </template>
       </el-table-column>
       <el-table-column label="销售方式" align="center">
@@ -154,7 +164,7 @@ export default {
         pageNo: 1,
         pageSize: 10,
         title: "",
-        spuType: 0,
+        spuType: 1,
       },
       // 表单参数
       form: {},

+ 3 - 43
src/views/product/module/basic-info.vue

@@ -12,29 +12,14 @@
         <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"
-              >{{
-                shopInfo.scope == 0
-                  ? "整车"
-                  : shopInfo.scope == 1
-                  ? "普通商品"
-                  : ""
-              }}</el-radio
-            >
-            <el-radio :label="2" :value="2" v-if="shopInfo.scope == 0"
-              >拼车</el-radio
-            >
-            <el-radio :label="4" :value="4" v-if="shopInfo.scope == 1"
+            <el-radio :label="0" :value="0">普通商品</el-radio>
+            <el-radio :label="4" :value="4"
               >礼包</el-radio
             >
-            <!-- <el-radio :label="5" :value="5" v-if="shopInfo.scope == 1">同城秒送</el-radio> -->
           </el-radio-group>
         </el-form-item>
       </el-col>
-      <el-col :span="24" v-if="form.saleType != 4 && shopInfo.scope == 1">
+      <el-col :span="24" v-if="form.saleType != 4">
         <el-form-item prop="saleType">
           <span slot="label">销售模式</span>
           <el-radio-group
@@ -50,15 +35,6 @@
           </el-radio-group>
         </el-form-item>
       </el-col>
-      <el-col :span="24" v-if="shopInfo.scope == 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" v-if="shopInfo.scope == 0">预售</el-radio>
-          </el-radio-group>
-        </el-form-item>
-      </el-col>
       <el-col :span="24" v-if="form.saleModel == 2 || form.saleType == 2">
         <el-form-item prop="datePicker">
           <span slot="label">预售时间</span>
@@ -279,10 +255,6 @@ export default {
       actionType: "",
     };
   },
-  created() {
-    this.getInfo();
-  },
-
   methods: {
     getFormInfo(record, type) {
       // 重置表单基础数据
@@ -389,18 +361,6 @@ export default {
       this.form.presaleEndTime = moment(this.form.datePicker[1]).valueOf();
       this.passValue();
     },
-    getInfo() {
-      getStoreInfo().then((res) => {
-        if (res.code == 200) {
-          this.shopInfo = res.data;
-          this.form.scope = res.data.scope;
-          if (res.data.scope == 1) {
-            this.form.saleType = 0;
-            this.form.saleModel = 1;
-          }
-        }
-      });
-    },
     draggableChange() {
       this.passValue();
     },

+ 4 - 208
src/views/product/module/sales-info.vue

@@ -68,156 +68,7 @@
           <el-button @click="addSpecification" type="primary"
             >添加规格</el-button
           >
-          <el-table
-            :data="form.skuList"
-            style="width: 100%; margin-top: 20px"
-            v-if="shopInfo.scope == 0"
-          >
-            <el-table-column prop="name" label="规格名称" width="140">
-              <template slot-scope="scope">
-                <el-input
-                  v-model="scope.row.skuSpecsList[0].specsName"
-                  placeholder="请输入规格名称"
-                  clearable
-                  maxlength="8"
-                  @input="passValue"
-                  show-word-limit
-                />
-              </template>
-            </el-table-column>
-            <el-table-column prop="address" label="规格内容" width="140">
-              <template slot-scope="scope">
-                <el-input
-                  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-number
-                  :controls="false"
-                  v-model="scope.row.predictStocks"
-                  placeholder="预计库存"
-                  clearable
-                  @input="passValue"
-                >
-                  <template slot="suffix"> {{ form.unit }} </template>
-                </el-input-number>
-              </template>
-            </el-table-column>
-            <el-table-column prop="name" label="实际库存" width="140">
-              <template slot-scope="scope">
-                <el-input-number
-                  :controls="false"
-                  v-model="scope.row.stock"
-                  placeholder="实际库存"
-                  clearable
-                  @input="passValue"
-                >
-                  <template slot="suffix"> {{ form.unit }} </template>
-                </el-input-number>
-              </template>
-            </el-table-column>
-            <el-table-column prop="address" label="起批量" width="140">
-              <template slot-scope="scope">
-                <el-input-number
-                  :controls="false"
-                  v-model="scope.row.skuPriceList[0].minPurchase"
-                  placeholder="起批量"
-                  clearable
-                  @input="passValue"
-                >
-                  <template slot="suffix">
-                    {{ form.unit }}
-                  </template>
-                </el-input-number>
-              </template>
-            </el-table-column>
-            <el-table-column prop="address" label="收购价" width="140">
-              <template slot-scope="scope">
-                <el-input-number
-                  :controls="false"
-                  v-model="scope.row.skuCost.purchaseFee"
-                  placeholder="收购价"
-                  clearable
-                  @input="passValue"
-                >
-                  <template slot="suffix"> {{ form.unit }}/元 </template>
-                </el-input-number>
-              </template>
-            </el-table-column>
-            <el-table-column prop="address" label="人工费" width="140">
-              <template slot-scope="scope">
-                <el-input-number
-                  :controls="false"
-                  v-model="scope.row.skuCost.laborFee"
-                  placeholder="人工费"
-                  clearable
-                  @input="passValue"
-                >
-                  <template slot="suffix"> {{ form.unit }}/元 </template>
-                </el-input-number>
-              </template>
-            </el-table-column>
-            <el-table-column prop="address" label="代办费" width="140">
-              <template slot-scope="scope">
-                <el-input-number
-                  :controls="false"
-                  v-model="scope.row.skuCost.agencyFee"
-                  placeholder="代办费"
-                  clearable
-                  @input="passValue"
-                >
-                  <template slot="suffix"> {{ form.unit }}/元 </template>
-                </el-input-number>
-              </template>
-            </el-table-column>
-            <el-table-column prop="address" label="材料费" width="140">
-              <template slot-scope="scope">
-                <el-input-number
-                  :controls="false"
-                  @input="passValue"
-                  v-model="scope.row.skuCost.materialFee"
-                  placeholder="材料费"
-                  clearable
-                >
-                  <template slot="suffix"> {{ form.unit }}/元 </template>
-                </el-input-number>
-              </template>
-            </el-table-column>
-            <el-table-column prop="address" label="商品单价" width="140">
-              <template slot-scope="scope">
-                {{ computePrice(scope.row) }}元/{{ form.unit }}
-              </template>
-            </el-table-column>
-            <!-- <el-table-column label="是否上架">
-              <template slot-scope="scope">
-                <el-switch v-model="scope.row.sj"> </el-switch>
-              </template>
-            </el-table-column> -->
-
-            <el-table-column prop="address" label="操作">
-              <template slot-scope="scope">
-                <el-button
-                  type="text"
-                  style="color: red"
-                  @click="removeSpecification(scope.row, scope.$index)"
-                  >删除</el-button
-                >
-              </template>
-            </el-table-column>
-          </el-table>
-
-          <el-table
-            :data="form.skuList"
-            style="width: 100%; margin-top: 20px"
-            v-if="shopInfo.scope == 1"
-          >
+          <el-table :data="form.skuList" style="width: 100%; margin-top: 20px">
             <el-table-column prop="name" label="规格名称" width="160">
               <template slot-scope="scope">
                 <el-input
@@ -402,11 +253,6 @@
                 </el-input-number>
               </template>
             </el-table-column>
-            <!-- <el-table-column label="是否上架">
-              <template slot-scope="scope">
-                <el-switch v-model="scope.row.sj"> </el-switch>
-              </template>
-            </el-table-column> -->
             <el-table-column prop="address" label="操作" width="160">
               <template slot-scope="scope">
                 <el-button
@@ -524,21 +370,6 @@
           />
         </el-form-item>
       </el-col>
-      <el-col :span="24" style="margin-top: 20px" v-if="!showCom">
-        <el-form-item prop="freeShipping">
-          <span slot="label">运费</span>
-          <div class="main1">
-            <el-radio-group v-model="form.freeShipping" class="radios">
-              <el-radio :label="0" :value="0"
-                >双方协商后卖家进行修改,买家和订单一起支付</el-radio
-              >
-              <el-radio :label="1" :value="1"
-                >全国包邮,由卖家承担运费</el-radio
-              >
-            </el-radio-group>
-          </div>
-        </el-form-item>
-      </el-col>
       <el-col :span="24" style="margin-top: 20px">
         <el-form-item prop="shippingAddrBean.addrDetail">
           <span slot="label"> 发货地址</span>
@@ -656,7 +487,6 @@ export default {
       shopInfo: {},
       saleType: undefined,
       sj: true,
-      showCom: true,
       skuIds: [],
       saleModel: 1,
       categoryprops: {
@@ -765,9 +595,6 @@ export default {
       this.form.skuList = record.skuList;
     },
 
-    setShowCom(val) {
-      this.showCom = val;
-    },
     compilatePrice(data) {
       if (data.price) {
         return data.price.toFixed(2);
@@ -814,44 +641,13 @@ export default {
         }
       });
     },
-    computePrice(data) {
-      if (this.shopInfo.scope == 0) {
-        if (
-          data.skuCost.purchaseFee &&
-          data.skuCost.laborFee &&
-          data.skuCost.agencyFee &&
-          data.skuCost.materialFee
-        ) {
-          return (
-            Number(data.skuCost.purchaseFee) +
-            Number(data.skuCost.laborFee) +
-            Number(data.skuCost.agencyFee) +
-            Number(data.skuCost.materialFee)
-          ).toFixed(2);
-        } else {
-          return 0;
-        }
-      } else {
-      }
-    },
-
     passValue() {
-      if (this.shopInfo.scope == 0) {
-        this.form.skuList.forEach((e) => {
+      if (this.saleType == 4) {
+        this.form?.skuList.forEach((e) => {
           e.skuPriceList.forEach((a) => {
-            a.price = this.computePrice(e);
-            a.originalPrice = this.computePrice(e);
-            a.lowestPrice = this.computePrice(e);
+            a.price = a.originalPrice;
           });
         });
-      } else {
-        if (this.saleType == 4) {
-          this.form?.skuList.forEach((e) => {
-            e.skuPriceList.forEach((a) => {
-              a.price = a.originalPrice;
-            });
-          });
-        }
       }
       this.$emit("updateValue", this.form);
     },

+ 1 - 38
src/views/product/updateProduct.vue

@@ -277,7 +277,6 @@ export default {
     });
   },
   mounted() {
-    this.getInfo();
     if (
       (this.$route.query.params != "[object Object]" &&
         this.$route.query.params) ||
@@ -324,13 +323,6 @@ export default {
               });
             }
             this.headerImg.sort((a, b) => a.sort - b.sort); //排序 视频在最前面>封面>商品banner
-            if (this.form.scope == 0) {
-              this.$refs.salesRefs.setShowCom(false);
-            } else if (this.form.saleType == 2 && this.form.scope == 0) {
-              this.$refs.salesRefs.setShowCom(false);
-            } else {
-              this.$refs.salesRefs.setShowCom(true);
-            }
             this.$refs.basicRefs.getFormInfo(this.form, this.$route.query.type);
             this.$refs.salesRefs.getFormInfo(this.form);
             this.$refs.productRefs.getFormInfo(this.form);
@@ -366,13 +358,6 @@ export default {
               });
             }
             this.headerImg.sort((a, b) => a.sort - b.sort); //排序 视频在最前面>封面>商品banner
-            if (this.form.scope == 0) {
-              this.$refs.salesRefs.setShowCom(false);
-            } else if (this.form.saleType == 2 && this.form.scope == 0) {
-              this.$refs.salesRefs.setShowCom(false);
-            } else {
-              this.$refs.salesRefs.setShowCom(true);
-            }
             this.$refs.basicRefs.getFormInfo(this.form, this.$route.query.type);
             this.$refs.salesRefs.getFormInfo(this.form);
             this.$refs.productRefs.getFormInfo(this.form);
@@ -385,21 +370,7 @@ export default {
     skuRemove(list) {
       this.skulist = list;
     },
-    getInfo() {
-      getStoreInfo().then((res) => {
-        if (res.code == 200) {
-          if (res.data.scope == 0) {
-            if (this.form.saleType == 2) {
-              this.$refs.salesRefs.setShowCom(true);
-            } else {
-              this.$refs.salesRefs.setShowCom(false);
-            }
-          } else {
-            this.$refs.salesRefs.setShowCom(true);
-          }
-        }
-      });
-    },
+
     submitCancel() {
       this.$confirm("是否取消发布,所填写的信息将会消失?", "提示", {
         confirmButtonText: "确定",
@@ -515,14 +486,6 @@ export default {
     },
     updateValue(val) {
       this.form = { ...this.form, ...val };
-      if (this.form.saleType == 2) {
-        this.$refs.salesRefs.setShowCom(true);
-      } else if (this.form.scope == 0) {
-        this.$refs.salesRefs.setShowCom(false);
-      } else {
-        this.$refs.salesRefs.setShowCom(true);
-      }
-
       this.headerImg = [];
       if (val.vid || this.form.vid) {
         this.headerImg.push({

+ 463 - 0
src/views/productNationwide/createProduct.vue

@@ -0,0 +1,463 @@
+<template>
+  <div class="app-container">
+    <div style="width: 100%; height: 85vh; overflow: auto">
+      <el-row style="padding-top: 20px">
+        <el-col :span="24">
+          <el-descriptions title="基本信息" column="1"> </el-descriptions>
+          <basicInfo @updateValue="updateValue" ref="basicRefs"></basicInfo>
+          <el-descriptions title="销售信息" column="1"> </el-descriptions>
+          <salesInfo
+            @updateValue="updateValue"
+            ref="salesRefs"
+            :saleType="form.saleType"
+            :saleModels="form.saleModel"
+          ></salesInfo>
+          <el-descriptions title="商品详情" column="1"> </el-descriptions>
+          <productInfo @updateValue="updateValue" ref="productRefs"></productInfo>
+
+          <div class="dialog-footer" style="text-align: center">
+            <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>
+        </el-col>
+        <phoneView style="position: absolute; bottom: 50px; right: 50px">
+          <div slot="conts">
+            <div>
+              <el-carousel height="200px">
+                <el-carousel-item
+                  v-for="(item, index) in headerImg.slice(1)"
+                  :key="index"
+                >
+                  <el-image
+                    v-if="item.type == 'img'"
+                    style="width: 100%; height: 200px"
+                    :src="item.src"
+                    :preview-src-list="[item.src]"
+                  >
+                  </el-image>
+                  <video
+                    v-if="item.type == 'video'"
+                    :key="index"
+                    controls
+                    :src="item.src"
+                    style="width: 100%; height: 200px"
+                  ></video>
+                </el-carousel-item>
+              </el-carousel>
+            </div>
+            <img
+              style="width: 100%"
+              src="https://bucket.sxdirectpurchase.com/fileUpload/test/47fc6132-0b3e-4b5c-b858-f78d363eba90.png"
+              alt=""
+            />
+            <div class="card">
+              <div class="spuName">{{ form ? form.title : "" }}</div>
+              <div class="price_info">
+                <div class="price_group">
+                  <span>¥</span>
+                  <span
+                    class="price"
+                    :key="item"
+                    v-for="item in form.skuList ? form.skuList.slice(0, 1) : []"
+                    >{{ item.skuPriceList ? item.skuPriceList[0].price : 0 }}元</span
+                  >
+
+                  <span>/{{ form.unit }}</span>
+                </div>
+                <span class="ys">已售 0</span>
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div class="spuName">规格/价格</div>
+              <div v-for="(item, index) in form.skuList" :key="index">
+                <div class="price_info">
+                  <span
+                    >{{ item.skuSpecsList[0] ? item.skuSpecsList[0].specsName : "" }}
+                    {{
+                      item.skuSpecsList[0].specsValue
+                        ? item.skuSpecsList[0].specsValue
+                        : ""
+                    }}</span
+                  >
+                </div>
+                <div
+                  style="
+                    display: flex;
+                    flex-direction: row;
+                    justify-content: space-between;
+                  "
+                >
+                  <span style="font-size: 14px; color: red">
+                    <span>¥</span>
+                    <span
+                      >{{
+                        item.skuPriceList
+                          ? item.skuPriceList[0].price
+                            ? item.skuPriceList[0].price
+                            : ""
+                          : ""
+                      }}元</span
+                    ><span>/{{ form.unit }}</span></span
+                  >
+                  <span style="font-size: 14px"
+                    >{{
+                      item.skuPriceList
+                        ? item.skuPriceList[0].minPurchase
+                          ? item.skuPriceList[0].minPurchase
+                          : ""
+                        : ""
+                    }}/{{ form.unit }}起购</span
+                  >
+                  <span style="font-size: 14px"
+                    >库存:{{ item.stock + item.predictStocks }}{{ form.unit }}</span
+                  >
+                </div>
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <el-form
+                :model="form"
+                ref="queryForm"
+                size="small"
+                :inline="true"
+                label-width="80px"
+                label-position="left"
+              >
+                <el-row>
+                  <el-col :span="24">
+                    <el-form-item label="发货地" prop="spuName">
+                      <div style="width: 185px">
+                        {{ form.shippingAddrBean ? form.shippingAddrBean.addr : "" }}
+                        {{
+                          form.shippingAddrBean
+                            ? form.shippingAddrBean.addrDetail
+                              ? form.shippingAddrBean.addrDetail
+                              : ""
+                            : ""
+                        }}
+                      </div>
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="24">
+                    <el-form-item label="发货时间" prop="spuName">
+                      {{ form.shippingTimeDesc }}
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="24">
+                    <el-form-item label="商品属性" prop="spuName">
+                      <div>查看></div>
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="24">
+                    <el-form-item label="包装方式" prop="spuName">
+                      {{ form.packing }}
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+              </el-form>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div
+                style="
+                  display: flex;
+                  flex-direction: row;
+                  justify-content: space-between;
+                  align-items: center;
+                "
+              >
+                <span class="spuName">商品评价</span>
+                <span>好评率 <span style="color: red">100%</span></span>
+              </div>
+              <div
+                style="
+                  display: flex;
+                  flex-direction: column;
+                  justify-content: center;
+                  align-items: center;
+                "
+              >
+                <img
+                  style="width: 40%"
+                  src="https://directpurchase-oss-dev.oss-cn-chengdu.aliyuncs.com/wx/static/images/kong.png"
+                  alt=""
+                />
+                <span>还没有评价~</span>
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div class="spuName">商品介绍</div>
+              <div style="font-size: 14px; line-height: 25px">
+                {{ form.spuDesc }}
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div class="spuName">商品详情</div>
+              <div style="font-size: 14px; line-height: 25px">
+                <el-image
+                  v-for="(item, index) in form.spuDetailList"
+                  :key="index"
+                  :src="item.fileUrl"
+                  fit="fill"
+                  :preview-src-list="[item.fileUrl]"
+                >
+                </el-image>
+              </div>
+              <div style="font-size: 14px; line-height: 25px">
+                <el-image
+                  v-for="(item, index) in form.specialList"
+                  :key="index"
+                  :src="item.fileUrl"
+                  fit="fill"
+                  :preview-src-list="[item.fileUrl]"
+                >
+                </el-image>
+              </div>
+            </div>
+          </div>
+        </phoneView>
+      </el-row>
+    </div>
+
+    <Amap></Amap>
+  </div>
+</template>
+
+<script>
+import { getStoreInfo } from "@/api/common/index";
+import { publishGoods } from "@/api/publish/index";
+import { saveGoodsDraft, queryUserRelevanceTemplate } from "@/api/manage/product";
+import basicInfo from "./module/basic-info.vue";
+import productInfo from "./module/product-info.vue";
+import salesInfo from "./module/sales-info.vue";
+import phoneView from "@/components/phoneView/index.vue";
+import Amap from "@/components/Map/map.vue";
+import moment from "moment";
+export default {
+  components: { Amap, phoneView, basicInfo, salesInfo, productInfo },
+  data() {
+    return {
+      form: {},
+      headerImg: [],
+      btnLading: false,
+    };
+  },
+  methods: {
+    submitFormDraft() {
+      if (this.form.categoryId?.length > 0) {
+        this.form.categoryId = this.form.categoryId[this.form.categoryId.length - 1];
+      }
+      if (this.form.categoryIds.length < 1) {
+        this.form.categoryIds = "";
+      }
+      if (!this.form.presaleStartTime && !this.form.presaleEndTime) {
+        if (this.form.datePicke) {
+          this.form.presaleStartTime = moment(this.form.datePicker[0]).valueOf();
+          this.form.presaleEndTime = moment(this.form.datePicker[1]).valueOf();
+        }
+      }
+      // if (this.form.bannerList?.length > 0) {
+      //   this.form.bannerList.shift();
+      // }
+      if (this.form.saleModel == 2) {
+        this.form.merchantClassifyId = "[217527]";
+        this.form.merchantClassifyName = "集采预售";
+      } else if (this.form.saleModel == 3) {
+        this.form.merchantClassifyId = "[217526]";
+        this.form.merchantClassifyName = "团批秒杀";
+      } else if (this.form.saleModel == 4) {
+        this.form.merchantClassifyId = "[217528]";
+        this.form.merchantClassifyName = "清库专区";
+      } else if (this.form.saleModel == 5) {
+        this.form.merchantClassifyId = "[217525]";
+        this.form.merchantClassifyName = "新店福利";
+      }
+
+      saveGoodsDraft(this.form).then((res) => {
+        if (res.code == 200) {
+          this.$message.success(`发布成功!请前往草稿箱查看`);
+          this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
+          this.$router.replace({ path: "/product/productNationwide/index" });
+        }
+      });
+    },
+    submitCancel() {
+      this.$confirm("是否取消发布,所填写的信息将会消失?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
+          this.$router.replace({ path: "/product/productNationwide/index" });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消",
+          });
+        });
+    },
+    async submitForm() {
+      let bool = false;
+      queryUserRelevanceTemplate().then((res) => {
+        if (res.code == 200) {
+          if (res.data) {
+            bool = res.data;
+          }
+        }
+      });
+      if (bool) {
+        this.$message.error(
+          "您未设置同城运费规则,请先暂存草稿箱,待设置同城运费规则后再次进行发布!"
+        );
+        return;
+      }
+      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;
+      }
+      if (this.form.skuList.length < 1 || this.form.skuList === "") {
+        this.$message.error(`商品规格不能为空`);
+        return;
+      }
+      if(!this.form.shippingAddrBean.provinceCode){
+        this.$message.error(`请点击选择地址,选择发货地址的省市区!`);
+        return;
+      }
+      if (this.form.categoryId?.length > 0) {
+        this.form.categoryId = this.form.categoryId[this.form.categoryId.length - 1];
+      }
+      if (!this.form.presaleStartTime && !this.form.presaleEndTime) {
+        if (this.form.datePicke) {
+          this.form.presaleStartTime = moment(this.form.datePicker[0]).valueOf();
+          this.form.presaleEndTime = moment(this.form.datePicker[1]).valueOf();
+        }
+      }
+      if (this.form.saleModel == 2) {
+        this.form.merchantClassifyId = "[217527]";
+        this.form.merchantClassifyName = "集采预售";
+      } else if (this.form.saleModel == 3) {
+        this.form.merchantClassifyId = "[217526]";
+        this.form.merchantClassifyName = "团批秒杀";
+      } else if (this.form.saleModel == 4) {
+        this.form.merchantClassifyId = "[217528]";
+        this.form.merchantClassifyName = "清库专区";
+      } else if (this.form.saleModel == 5) {
+        this.form.merchantClassifyId = "[217525]";
+        this.form.merchantClassifyName = "新店福利";
+      }
+      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/productNationwide/index" });
+        } else {
+          this.btnLading = false;
+        }
+      });
+    },
+    updateValue(val) {
+      this.form = { ...this.form, ...val };
+      console.log(this.form);
+      this.headerImg = [];
+      if (val.vid || this.form.vid) {
+        this.headerImg.push({
+          type: "video",
+          src: val.vid ? val.vid : this.form.vid,
+          sort: 1,
+        });
+      }
+      if (this.form?.bannerList && this.form?.bannerList.length > 0) {
+        this.form.bannerList.forEach((e, index) => {
+          this.headerImg.push({
+            type: "img",
+            src: e.fileUrl,
+            sort: index + 4,
+          });
+        });
+      }
+
+      this.headerImg.sort((a, b) => a.sort - b.sort); //排序 视频在最前面>封面>商品banner
+    },
+    unique(arr) {
+      const res = new Map();
+      return arr.filter((arr) => !res.has(arr.src) && res.set(arr.src, 1));
+    },
+  },
+};
+</script>
+
+<style>
+.required {
+  color: red;
+}
+.el-upload-list__item {
+  width: 60px !important;
+  height: 60px !important;
+}
+.el-upload--picture-card {
+  width: 80px;
+  height: 80px;
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: center;
+}
+.tips {
+  font-size: 12px;
+  color: red;
+}
+</style>
+<style scoped>
+.card {
+  /* height: 85px; */
+  width: 95%;
+  background: white;
+  margin: auto;
+  border-radius: 10px;
+  line-height: 30px;
+  padding: 10px;
+}
+.spuName {
+  text-decoration: none;
+  font-weight: bold;
+  word-wrap: normal;
+  font-size: 18px;
+  color: #333333;
+}
+.price_group {
+  color: #ff2f2f;
+}
+.price {
+  text-decoration: none;
+  font-weight: bold;
+  word-wrap: normal;
+  font-size: 25px;
+  color: #ff2f2f;
+}
+.price_info {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+}
+.ys {
+  font-size: 14px;
+}
+</style>

+ 36 - 0
src/views/productNationwide/index.vue

@@ -0,0 +1,36 @@
+<template>
+  <div class="app-container">
+    <el-tabs v-model="activeName" @tab-click="handleClick">
+      <el-tab-pane label="全部商品" :name="1">
+        <allProduct></allProduct>
+      </el-tab-pane>
+      <el-tab-pane label="草稿箱" :name="2">
+        <draftProduct></draftProduct>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+import allProduct from "./list/allProduct.vue";
+import draftProduct from "./list/draftProduct.vue";
+export default {
+  components: {
+    allProduct,
+    draftProduct,
+  },
+  name: "product",
+  data() {
+    return {
+      activeName: 1,
+    };
+  },
+  mounted() {},
+  methods: {},
+};
+</script>
+<style>
+.el-form-item {
+  margin-bottom: 10px;
+}
+</style>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1198 - 0
src/views/productNationwide/list/allProduct.vue


+ 296 - 0
src/views/productNationwide/list/draftProduct.vue

@@ -0,0 +1,296 @@
+<template>
+  <div class="app-container">
+    <el-form
+      :model="queryParams"
+      ref="queryForm"
+      size="small"
+      :inline="true"
+      label-width="80px"
+    >
+      <el-form-item label="商品名称" prop="title">
+        <el-input
+          v-model="queryParams.title"
+          placeholder="请输入商品名称"
+          clearable
+          style="width: 240px"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+
+      <el-form-item>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
+          >搜索</el-button
+        >
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+          >重置</el-button
+        >
+      </el-form-item>
+    </el-form>
+    <el-col :span="1.5">
+      <el-button
+        type="danger"
+        :disabled="multipleSelection.length < 1"
+        plain
+        size="mini"
+        @click="handleRemoves"
+        >批量删除</el-button
+      >
+    </el-col>
+
+    <el-table
+      v-loading="loading"
+      :data="configList"
+      @selection-change="handleSelectionChange"
+      row-key="goodsDraftId"
+    >
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="商品图片" align="center">
+        <template slot-scope="scope">
+          <el-image
+            style="width: 60px; height: 60px"
+            :src="scope.row.pic"
+            :preview-src-list="[scope.row.pic]"
+          >
+          </el-image>
+        </template>
+      </el-table-column>
+      <el-table-column label="商品名称" align="center">
+        <template slot-scope="scope">
+          {{ scope.row.title }}
+        </template>
+      </el-table-column>
+      <el-table-column label="分类" align="center">
+        <template slot-scope="scope">
+          {{ scope.row.categoryName }}
+        </template>
+      </el-table-column>
+      <el-table-column label="价格" align="center">
+        <template slot-scope="scope">
+          {{
+            scope.row.skuList ? scope.row.skuList[0].skuPriceList[0].price : ""
+          }}/{{ scope.row.unit }}
+        </template>
+      </el-table-column>
+
+      <el-table-column label="起批量" align="center">
+        <template slot-scope="scope">
+          {{
+            scope.row.skuList
+              ? scope.row.skuList[0].skuPriceList[0].minPurchase
+              : ""
+          }}{{ scope.row.unit }}
+        </template>
+      </el-table-column>
+      <el-table-column label="库存" align="center">
+        <template slot-scope="scope">
+          {{
+            scope.row.skuList
+              ? scope.row.skuList[0].stock + "/" + scope.row.unit
+              : ""
+          }}
+        </template>
+      </el-table-column>
+      <el-table-column label="经营区域" align="center">
+        <template slot-scope="scope">
+          {{
+            scope.row.scope == 0
+              ? "全国"
+              : scope.row.scope == 1
+              ? "同城"
+              : "特价"
+          }}
+        </template>
+      </el-table-column>
+      <el-table-column label="销售方式" align="center">
+        <template slot-scope="scope">
+          <span v-if="scope.row.scope == 0">
+            {{ scope.row.saleType == 1 ? "现货" : "预售" }}
+          </span>
+          <span v-else> </span>
+        </template>
+      </el-table-column>
+
+      <el-table-column
+        label="操作"
+        align="center"
+        class-name="small-padding fixed-width"
+        width="200"
+      >
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['manage:order:detail']"
+            >编辑商品</el-button
+          >
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            style="color: red"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['manage:order:detail']"
+            >删除</el-button
+          >
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import {
+  deleteGoodsDraft,
+  getGoodsDraftByUserId,
+  deleteGoodsDrafts,
+} from "@/api/manage/product";
+import { getStoreInfo } from "@/api/common/index";
+export default {
+  name: "product",
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      configList: [],
+      // 查询参数
+      multipleSelection: [],
+      queryParams: {
+        pageNo: 1,
+        pageSize: 10,
+        title: "",
+        spuType: 2,
+      },
+      // 表单参数
+      form: {},
+      shopInfo: {},
+    };
+  },
+  mounted() {
+    this.getList();
+    this.getInfo();
+  },
+  methods: {
+    getInfo() {
+      getStoreInfo().then((res) => {
+        if (res.code == 200) {
+          this.shopInfo = res.data;
+        }
+      });
+    },
+    /** 查询参数列表 */
+    getList() {
+      this.loading = true;
+      this.configList = [];
+      getGoodsDraftByUserId(this.queryParams).then((res) => {
+        for (let index = 0; index < res.data.length; index++) {
+          res.data[index] = res.data[index].goodsDto;
+          this.configList.push(res.data[index]);
+        }
+        // this.configList = res.data;
+        console.log("1231231", this.configList);
+
+        this.loading = false;
+      });
+    },
+    handleDelete(record) {
+      this.$confirm("是否确认删除该商品?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          deleteGoodsDraft({
+            id: record.goodsDraftId,
+          }).then((res) => {
+            if (res.code == 200) {
+              this.$message.success(`删除成功!`);
+              this.getList();
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消操作",
+          });
+        });
+    },
+    handleRemoves() {
+      this.$confirm("是否确认批量删除草稿箱?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          let ids = [];
+
+          for (let index = 0; index < this.multipleSelection.length; index++) {
+            console.log("xzcz", this.multipleSelection[index]);
+            ids.push(this.multipleSelection[index].goodsDraftId);
+          }
+          deleteGoodsDrafts({
+            ids: ids.toString(),
+          }).then((res) => {
+            if (res.code == 200) {
+              this.$message.success(`删除成功!`);
+              this.getList();
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消操作",
+          });
+        });
+    },
+    handleSelectionChange(val) {
+      console.log(val);
+      this.multipleSelection = val;
+    },
+
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {};
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNo = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    handleUpdate(record) {
+      let params = {
+        id: record.goodsDraftId,
+        type: "draft",
+      };
+      window.localStorage.setItem("productInfo", JSON.stringify(params));
+      this.$router.push({
+        path: "/product/productNationwide/updateProduct",
+        query: { params },
+      });
+    },
+  },
+};
+</script>
+<style>
+.el-form-item {
+  margin-bottom: 10px;
+}
+</style>

+ 295 - 0
src/views/productNationwide/lookProduct.vue

@@ -0,0 +1,295 @@
+<template>
+  <el-dialog
+    :visible.sync="dialogVisible"
+    width="20%"
+    :before-close="closeDialog"
+    custom-class="phone"
+    :destroy-on-close="true"
+  >
+    <phoneView>
+      <div slot="conts">
+        <div>
+          <el-carousel height="200px">
+            <el-carousel-item v-for="(item, index) in headerImg" :key="index">
+              <el-image
+                v-if="item.type == 'img'"
+                style="width: 100%; height: 200px"
+                :src="item.src"
+                :preview-src-list="[item.src]"
+              >
+              </el-image>
+              <video
+                v-if="item.type == 'video'"
+                :key="index"
+                controls
+                :src="item.src"
+                style="width: 100%; height: 200px"
+              ></video>
+            </el-carousel-item>
+          </el-carousel>
+        </div>
+        <img
+          style="width: 100%"
+          src="https://bucket.sxdirectpurchase.com/fileUpload/test/47fc6132-0b3e-4b5c-b858-f78d363eba90.png"
+          alt=""
+        />
+        <div class="card">
+          <div class="spuName">{{ form ? form.title : "" }}</div>
+          <div class="price_info">
+            <div class="price_group">
+              <span>¥</span
+              ><span class="price"
+                >{{
+                  form.skuList
+                    ? form.skuList[0].skuPriceList
+                      ? form.skuList[0].skuPriceList[0].price
+                      : 0
+                    : 0
+                }}元</span
+              ><span>/{{ form.unit }}</span>
+            </div>
+            <span class="ys">已售 0</span>
+          </div>
+        </div>
+        <div class="card" style="margin-top: 10px">
+          <div class="spuName">规格/价格</div>
+          <div v-for="(item, index) in form.skuList" :key="index">
+            <div class="price_info">
+              <span
+                >{{ item.skuSpecsList ? item.skuSpecsList[0].specsName : "" }}
+                {{ item.skuSpecsList ? item.skuSpecsList[0].specsValue : "" }}</span
+              >
+            </div>
+            <div
+              style="display: flex; flex-direction: row; justify-content: space-between"
+            >
+              <span style="font-size: 14px; color: red">
+                <span>¥</span>
+                <span>{{ item.skuPriceList ? item.skuPriceList[0].price : 0 }}元</span
+                ><span>/{{ form.unit }}</span></span
+              >
+              <span style="font-size: 14px"
+                >{{ item.skuPriceList ? item.skuPriceList[0].minPurchase : 0 }}/{{
+                  form.unit
+                }}起购</span
+              >
+              <span style="font-size: 14px">库存:{{ item.stock }}{{ form.unit }}</span>
+            </div>
+          </div>
+        </div>
+        <div class="card" style="margin-top: 10px">
+          <el-form
+            :model="form"
+            ref="queryForm"
+            size="small"
+            :inline="true"
+            label-width="80px"
+            label-position="left"
+          >
+            <el-row>
+              <el-col :span="24">
+                <el-form-item label="发货地" prop="spuName">
+                  <div style="width: 185px">
+                    {{ form.shippingAddrBean ? form.shippingAddrBean.addr : "" }}
+                    {{ form.shippingAddrBean ? form.shippingAddrBean.addrDetail : "" }}
+                  </div>
+                </el-form-item>
+              </el-col>
+              <el-col :span="24">
+                <el-form-item label="发货时间" prop="spuName">
+                  {{ form.shippingTimeDesc }}
+                </el-form-item>
+              </el-col>
+              <el-col :span="24">
+                <el-form-item label="商品属性" prop="spuName">
+                  <div>查看></div>
+                </el-form-item>
+              </el-col>
+              <el-col :span="24">
+                <el-form-item label="包装方式" prop="spuName">
+                  {{ form.packing }}
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form>
+        </div>
+        <div class="card" style="margin-top: 10px">
+          <div
+            style="
+              display: flex;
+              flex-direction: row;
+              justify-content: space-between;
+              align-items: center;
+            "
+          >
+            <span class="spuName">商品评价</span>
+            <span>好评率 <span style="color: red">100%</span></span>
+          </div>
+          <div
+            style="
+              display: flex;
+              flex-direction: column;
+              justify-content: center;
+              align-items: center;
+            "
+          >
+            <img
+              style="width: 40%"
+              src="https://directpurchase-oss-dev.oss-cn-chengdu.aliyuncs.com/wx/static/images/kong.png"
+              alt=""
+            />
+            <span>还没有评价~</span>
+          </div>
+        </div>
+        <div class="card" style="margin-top: 10px">
+          <div class="spuName">商品介绍</div>
+          <div style="font-size: 14px; line-height: 25px">
+            {{ form.spuDesc }}
+          </div>
+        </div>
+        <div class="card" style="margin-top: 10px">
+          <div class="spuName">商品详情</div>
+          <div style="font-size: 14px; line-height: 25px">
+            <el-image
+              v-for="(item, index) in form.spuDetailList"
+              :key="index"
+              :src="item.fileUrl"
+              fit="fill"
+              :preview-src-list="[item.fileUrl]"
+            >
+            </el-image>
+          </div>
+          <div style="font-size: 14px; line-height: 25px">
+            <el-image
+              v-for="(item, index) in form.specialList"
+              :key="index"
+              :src="item.fileUrl"
+              fit="fill"
+              :preview-src-list="[item.fileUrl]"
+            >
+            </el-image>
+          </div>
+        </div>
+      </div>
+    </phoneView>
+  </el-dialog>
+</template>
+
+<script>
+import phoneView from "@/components/phoneView/index.vue";
+export default {
+  components: { phoneView },
+  data() {
+    return {
+      dialogVisible: false,
+      form: {},
+      headerImg: [],
+    };
+  },
+  methods: {
+    openDialog(record) {
+      this.form = record;
+      this.headerImg = [];
+      if (this.form.vid) {
+        this.headerImg.push({
+          type: "video",
+          src: this.form.vid,
+          sort: 1,
+        });
+      }
+      if (this.form.pic) {
+        this.headerImg.push({
+          type: "img",
+          src: this.form.pic,
+          sort: 2,
+        });
+      }
+      this.headerImg = this.unique(this.headerImg);
+      if (this.form.bannerList) {
+        this.form.bannerList.forEach((e, index) => {
+          this.headerImg.push({
+            type: "img",
+            src: e.fileUrl,
+            sort: index + 4,
+          });
+        });
+      }
+      this.headerImg.sort((a, b) => a.sort - b.sort); //排序 视频在最前面>封面>商品banner
+      this.dialogVisible = true;
+    },
+    unique(arr) {
+      const res = new Map();
+      return arr.filter((arr) => !res.has(arr.src) && res.set(arr.src, 1));
+    },
+    closeDialog() {
+      this.dialogVisible = false;
+    },
+  },
+};
+</script>
+<style scoped>
+/deep/ .el-dialog {
+  background: transparent !important;
+  /* margin: 0px !important; */
+  box-shadow: none !important;
+  padding: 0px !important;
+}
+/deep/ .el-dialog__body {
+  margin: 0px !important;
+  padding: 0px !important;
+}
+/deep/ .el-dialog__header {
+  margin: 0px !important;
+  padding: 0px !important;
+}
+/deep/ .phone {
+  margin: auto;
+}
+/* .phone /deep/ .el-dialog__headerbtn {
+  border-radius: 50%;
+  width: 30px !important;
+  height: 30px !important;
+  background: #fff !important;
+  top: -5px !important;
+  right: 6px !important;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+} */
+.card {
+  /* height: 85px; */
+  width: 95%;
+  background: white;
+  margin: auto;
+  border-radius: 10px;
+  line-height: 30px;
+  padding: 10px;
+}
+.spuName {
+  text-decoration: none;
+  font-weight: bold;
+  word-wrap: normal;
+  font-size: 18px;
+  color: #333333;
+}
+.price_group {
+  color: #ff2f2f;
+}
+.price {
+  text-decoration: none;
+  font-weight: bold;
+  word-wrap: normal;
+  font-size: 25px;
+  color: #ff2f2f;
+}
+.price_info {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+}
+.ys {
+  font-size: 14px;
+}
+</style>

+ 210 - 0
src/views/productNationwide/material.vue

@@ -0,0 +1,210 @@
+<template>
+  <div class="app-container">
+    <div>
+      <h4>设置同城运费</h4>
+      <el-form
+        :model="queryParams"
+        ref="queryForm"
+        size="small"
+        :inline="true"
+        label-width="120px"
+      >
+        <el-form-item label="小于商品金额:" prop="spuName">
+          <el-input
+            v-model="queryParams.referencePrice"
+            placeholder="请输入"
+            clearable
+            style="width: 180px"
+          >
+            <span slot="suffix">元</span>
+          </el-input>
+          ,运费
+          <el-input
+            v-model="queryParams.freight"
+            placeholder="请输入"
+            clearable
+            style="width: 180px"
+          >
+            <span slot="suffix">元</span>
+          </el-input>
+          <br />
+          <div style="margin-top: 10px">
+            <span>当用户商品金额大于所设置金额时,则包邮</span>
+          </div>
+        </el-form-item>
+      </el-form>
+      <el-row>
+        <el-col style="text-align: center">
+          <el-button size="mini" type="primary" @click="submitFree"
+            >保存</el-button
+          ></el-col
+        >
+      </el-row>
+    </div>
+    <div style="height: 20px; background: #f4f4f4; margin-top: 20px"></div>
+    <div>
+      <h4>异地运费</h4>
+      <el-tabs v-model="expressType" @tab-click="getFreightTemplate">
+        <el-tab-pane label="水果特惠" name="0"></el-tab-pane>
+        <el-tab-pane label="生鲜特快" name="1"></el-tab-pane>
+        <el-tab-pane label="京东标快" name="2"></el-tab-pane>
+      </el-tabs>
+      <el-row>
+        <el-col
+          :span="24"
+          v-for="(item, index) in tableData"
+          :key="index"
+          style="margin-bottom: 20px"
+        >
+          <div
+            style="
+              padding: 10px 10px;
+              background: #0ea0df2e;
+              display: flex;
+              flex-direction: row;
+              justify-content: space-between;
+              align-items: center;
+            "
+          >
+            <span style="font-size: 14px"> 发货地:{{ item.sendCityName }}</span>
+          </div>
+          <el-table :data="item.detailList" style="width: 100%" border>
+            <el-table-column prop="receiveCityJson" label="送达地区" width="800">
+              <template slot-scope="scope">
+                <span v-if="scope.row.isDefault == 0">
+                  {{ scope.row.receiveCityJson }}
+                </span>
+                <span
+                  v-else
+                  v-for="(item, index) in scope.row.receiveCityJson
+                    ? JSON.parse(scope.row.receiveCityJson)
+                    : []"
+                  :key="index"
+                >
+                  <div>
+                    {{ item.provinceName }}
+                    (<span v-for="(item, index) in item.cityList" :key="index">
+                      {{ item.cityName }}
+                    </span>
+                    )
+                  </div>
+                </span>
+              </template>
+            </el-table-column>
+            <el-table-column align="center" width="180">
+              <template slot="header" slot-scope="scope">
+                <div>首重价格(元)</div>
+                <div>1kg</div>
+              </template>
+              <template slot-scope="scope">
+                {{ scope.row.firstWeightPrice }}
+              </template>
+            </el-table-column>
+            <el-table-column align="center">
+              <template slot="header" slot-scope="scope">
+                <div>续重价格①(元/kg)</div>
+                {{ item.secondStartWeight }}-{{ item.secondEndWeight }}kg
+              </template>
+              <template slot-scope="scope">
+                {{ scope.row.secondWeightPrice }}
+              </template>
+            </el-table-column>
+            <el-table-column align="center">
+              <template slot="header" slot-scope="scope">
+                <div>续重价格②(元/kg)</div>
+                <div>{{ item.secondEndWeight }}kg以上</div>
+              </template>
+              <template slot-scope="scope">
+                {{ scope.row.lastWeightPrice }}
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-col>
+      </el-row>
+      <el-row v-if="tableData.length < 1">
+        <el-col :sm="24" :lg="24">
+          <el-result icon="info" title="信息提示" subTitle="暂无异地运费规则">
+          </el-result>
+        </el-col>
+      </el-row>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  getFreightTemplate,
+  savaLogisticsTemplate,
+  getLogisticsTemplateInfo,
+} from "@/api/manage/product";
+import { getStoreInfo } from "@/api/common/index";
+export default {
+  data() {
+    return {
+      queryParams: {
+        shopId: "",
+        freight: "",
+        referencePrice: "",
+      },
+      tableData: [],
+      shopInfo: {},
+      expressType: 0,
+    };
+  },
+  created() {
+    this.getInfo();
+  },
+  mounted() {},
+  methods: {
+    getFree() {
+      getLogisticsTemplateInfo(this.queryParams).then((res) => {
+        if (res.code == 200) {
+          this.queryParams = res.data;
+          //   this.queryParams.freight = res.data[0].freight;
+          //   this.queryParams.referencePrice = res.data[0].referencePrice;
+        }
+      });
+    },
+    submitFree() {
+      this.queryParams.shopId = this.shopInfo.id;
+      savaLogisticsTemplate(this.queryParams).then((res) => {
+        if (res.code == 200) {
+          this.$message.success("保存成功");
+          this.getFree();
+        }
+      });
+    },
+    getInfo() {
+      getStoreInfo().then((res) => {
+        if (res.code == 200) {
+          this.shopInfo = res.data;
+          this.getFreightTemplate();
+          this.getFree();
+        }
+      });
+    },
+    getFreightTemplate() {
+      this.tableData =[]
+      let cityCode = JSON.parse(this.shopInfo.storeCityCode);
+      getFreightTemplate({
+        sendCityCode: cityCode[1],
+        pageNo: 1,
+        pageSize: 999,
+        expressType: this.expressType,
+      }).then((res) => {
+        if (res.code == 200) {
+          res.data.records.forEach((e) => {
+            e.detailList.forEach((a, index) => {
+              e.secondStartWeight = a.secondStartWeight;
+              e.secondEndWeight = a.secondEndWeight;
+            });
+          });
+          this.tableData = res.data.records;
+        }
+      });
+    },
+  },
+};
+</script>
+
+<style></style>

+ 483 - 0
src/views/productNationwide/module/basic-info.vue

@@ -0,0 +1,483 @@
+<template>
+  <el-form
+    :model="form"
+    ref="queryForm"
+    size="small"
+    :inline="true"
+    label-width="120px"
+    :rules="rules"
+  >
+    <el-row>
+      <el-col :span="24">
+        <el-form-item prop="saleType">
+          <span slot="label">销售方式</span>
+          <el-radio-group v-model="form.saleType" @change="passValue">
+            <el-radio :label="0" :value="0">整车</el-radio>
+            <el-radio :label="2" :value="2">拼车</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="24">
+        <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-group>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24" v-if="form.saleModel == 2 || form.saleType == 2">
+        <el-form-item prop="datePicker">
+          <span slot="label">预售时间</span>
+          <el-date-picker
+            v-model="form.datePicker"
+            type="datetimerange"
+            range-separator="至"
+            value-format="yyyy-MM-dd HH:mm:ss"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            @change="pickerChange"
+          >
+          </el-date-picker>
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="24">
+        <el-form-item prop="categoryId">
+          <span slot="label">商品分类</span>
+          <el-cascader
+            :filterable="true"
+            v-model="form.categoryId"
+            ref="formCascader"
+            :placeholder="categoryName ? categoryName : '请选择分类'"
+            :props="categoryprops"
+            @change="cascaderChange"
+          />
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <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">
+        <el-form-item label="商品视频">
+          <span class="tips">上传视频用户看的更直接</span>
+          <el-upload
+            list-type="picture-card"
+            :show-file-list="false"
+            :http-request="(data) => requestUpload(data, 'video')"
+            :limit="1"
+            action="#"
+            accept=".mp4"
+            ref="files"
+          >
+            <video
+              v-if="form.vid"
+              controls
+              :src="form.vid"
+              style="width: 80px; height: 80px"
+            ></video>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <el-form-item prop="bannerList">
+          <span slot="label">商品图</span>
+          <span class="tips"
+            >图片要求:大小3M内,至多可上传11张,第一张图默认为商品封面图</span
+          >
+          <div style="display: flex; flex-direction: row; align-items: center">
+            <draggable
+              style="display: flex; flex-direction: row; align-items: center"
+              v-model="bannerList"
+              group="people"
+              @change="draggableChange"
+            >
+              <div
+                class="item"
+                v-for="(item, index) in this.bannerList"
+                :key="index"
+              >
+                <div class="fmt" v-if="index == 0">封面图</div>
+                <div class="gb" @click="removeImg(index)">X</div>
+                <img
+                  :src="item.url || item.fileUrl"
+                  style="width: 70px; height: 70px; border-radius: 10px"
+                />
+              </div>
+            </draggable>
+            <el-upload
+              list-type="picture-card"
+              :file-list="bannerList"
+              :before-remove="requestRemove"
+              :http-request="(data) => requestUpload(data, 'banner')"
+              :show-file-list="false"
+              :before-upload="beforeAvatarUpload"
+              :limit="11"
+              action="#"
+              :multiple="true"
+              accept=".png,.jpg,.jpeg"
+              ref="files"
+            >
+              <i class="el-icon-plus avatar-uploader-icon"></i>
+            </el-upload>
+          </div>
+        </el-form-item>
+      </el-col>
+    </el-row>
+  </el-form>
+</template>
+
+<script>
+import draggable from "vuedraggable";
+import { getStoreInfo } from "@/api/common/index";
+import { getClassificationListPage } from "@/api/common/index.js";
+import { getToken } from "@/utils/auth";
+import axios from "axios";
+import moment from "moment";
+export default {
+  props: ["data"],
+  components: { draggable },
+  data() {
+    return {
+      form: {
+        carpoolSuccessTime: "",
+        scope: 0,
+        saleType: 0,
+        saleModel: undefined,
+        categoryId: "",
+        title: "",
+        giftDesc: "",
+        vid: "",
+        bannerList: [],
+        pic: "",
+        categoryName: "",
+        categoryIds: [],
+        datePicker: [],
+        presaleStartTime: "",
+        presaleEndTime: "",
+      },
+      bannerList: [],
+      headers: {
+        Auth: "Bearer " + getToken(),
+        "Content-type": "multipart/form-data",
+      },
+      categoryprops: {
+        checkStrictly: true,
+        lazy: true,
+        lazyLoad: this.categoryLazyLoad,
+        label: "label",
+        value: "value",
+      },
+      rules: {
+        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" },
+        ],
+        bannerList: [
+          {
+            required: true,
+            message: "商品图最低上传两张图片",
+            trigger: "blur",
+          },
+        ],
+        carpoolSuccessTime: [
+          { required: true, message: "拼车成功时间不能为空", trigger: "blur" },
+        ],
+        datePicker: [
+          { required: true, message: "预售时间不能为空", trigger: "blur" },
+        ],
+      },
+      index: 0,
+      shopInfo: {},
+      categoryName: "",
+      radio: "",
+      actionType: "",
+    };
+  },
+  methods: {
+    getFormInfo(record, type) {
+      // 重置表单基础数据
+      this.actionType = type === "cg" ? "" : "edit";
+      this.form.datePicker = [];
+      // 解构赋值与默认值处理
+      const {
+        categoryId,
+        categoryIds,
+        carpoolSuccessTime,
+        scope,
+        saleType,
+        saleModel,
+        title,
+        giftDesc,
+        vid,
+        bannerList = [],
+        pic,
+        categoryName,
+        presaleStartTime,
+        presaleEndTime,
+      } = record || {};
+      // 更新表单数据
+      this.form = {
+        ...this.form,
+        categoryId,
+        categoryIds,
+        carpoolSuccessTime,
+        scope,
+        saleType,
+        saleModel,
+        title,
+        giftDesc,
+        vid,
+        bannerList,
+        pic,
+        categoryName,
+        presaleStartTime: presaleStartTime
+          ? moment(presaleStartTime).format("yyyy-MM-DD HH:mm:ss")
+          : "",
+        presaleEndTime: presaleEndTime
+          ? moment(presaleEndTime).format("yyyy-MM-DD HH:mm:ss")
+          : "",
+      };
+
+      // 更新日期选择器
+      if (presaleStartTime && presaleEndTime) {
+        this.$nextTick(() => {
+          this.$set(this.form, "datePicker", [
+            this.form.presaleStartTime,
+            this.form.presaleEndTime,
+          ]);
+        });
+      }
+      // 更新轮播图列表(优化添加逻辑)
+      this.bannerList = [...bannerList];
+      if (pic) {
+        this.bannerList.unshift({
+          fileUrl: pic,
+          sort: 1,
+        });
+      }
+      // 触发强制更新(尽量避免使用)
+      // this.$forceUpdate();
+    },
+
+    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, row) => {
+          if (valid) {
+            resolve(valid);
+          } else {
+            for (const key in row) {
+              for (let index = 0; index < row[key].length; index++) {
+                this.$message.error(row[key][index].message);
+                return;
+              }
+            }
+            resolve(valid);
+          }
+        });
+      });
+    },
+
+    removeImg(index) {
+      this.bannerList.splice(index, 1);
+      this.passValue();
+    },
+    pickerChange(val) {
+      this.form.presaleStartTime = moment(this.form.datePicker[0]).valueOf();
+      this.form.presaleEndTime = moment(this.form.datePicker[1]).valueOf();
+      this.passValue();
+    },
+    draggableChange() {
+      this.passValue();
+    },
+
+    passValue() {
+      this.form.bannerList = [];
+      this.form.presaleStartTime = moment(this.form.datePicker[0]).valueOf();
+      this.form.presaleEndTime = moment(this.form.datePicker[1]).valueOf();
+      if (this.bannerList.length > 0) {
+        console.log("bannerList", this.bannerList);
+        for (let index = 0; index < this.bannerList.length; index++) {
+          this.form.bannerList.push({
+            fileUrl:
+              this.bannerList[index].url || this.bannerList[index].fileUrl,
+            sort: this.bannerList[index].name,
+          });
+        }
+        this.form.pic = this.bannerList[0].url || this.bannerList[0].fileUrl;
+        if (this.form.pic) {
+          this.form.bannerList.shift();
+        }
+      } else {
+        this.form.pic = "";
+      }
+      this.$emit("updateValue", this.form);
+    },
+
+    requestRemove(val, list, index) {
+      this.bannerList.forEach((e, index) => {
+        if (e.uid == val.uid) {
+          this.bannerList.splice(index, 1);
+        }
+      });
+      this.passValue();
+    },
+    cascaderChange(val) {
+      this.$nextTick(() => {
+        const dom = document.getElementsByClassName("el-radio is-checked");
+        //这里我把dom打出来看了 最后一个选项才是我选中的节点 即[length-1] 有的博主写的是 第一个元素 即[0] 大家自行尝试
+        let radioDom = dom[dom.length - 1];
+        const brother = radioDom.nextElementSibling;
+        brother.click();
+        let nodes = this.$refs.formCascader.getCheckedNodes();
+        this.form.categoryName = nodes[0].label;
+        this.form.categoryIds = val;
+        this.form.categoryIds = JSON.stringify(this.form.categoryIds);
+        this.passValue();
+      });
+    },
+    categoryLazyLoad(node, resolve) {
+      let level = node.level;
+      if (!node.data) {
+        getClassificationListPage({ parentId: 0 }).then((res) => {
+          //接口
+          const nodes = Array.from(res.data).map((item, index) => ({
+            value: item.id,
+            label: `${item.className}`,
+            leaf: level >= 2,
+          }));
+          // 通过调用resolve将子节点数据返回,通知组件数据加载完成
+          resolve(nodes);
+        });
+      } else if (level == 1) {
+        getClassificationListPage({ parentId: node.data.value }).then((res) => {
+          const nodes = Array.from(res.data).map((item) => ({
+            value: item.id,
+            label: `${item.className}`,
+            leaf: level >= 2,
+            // level: 2,
+          }));
+          // 通过调用resolve将子节点数据返回,通知组件数据加载完成
+          resolve(nodes);
+        });
+      } else if (level == 2) {
+        getClassificationListPage({ parentId: node.data.value }).then((res) => {
+          const nodes = Array.from(res.data).map((item) => ({
+            value: item.id,
+            label: `${item.className}`,
+            leaf: level >= 1,
+            level: 1,
+          }));
+          // 通过调用resolve将子节点数据返回,通知组件数据加载完成
+          resolve(nodes);
+        });
+      } else {
+        resolve({});
+      }
+    },
+
+    // 可以获取图片参数
+    async requestUpload(data, type) {
+      const formdata = new FormData();
+      formdata.append("file", data.file);
+      const res = await axios.post(
+        `${process.env.VUE_APP_NSY_UPLOAD_API}/api/third/op/v1/third/uploadPic`,
+        formdata,
+        {
+          headers: this.headers,
+        }
+      );
+      if (res.data.data) {
+        if (type == "video") {
+          this.form.vid = res.data.data;
+        } else if (type == "banner") {
+          this.bannerList.push({
+            name: this.index,
+            url: res.data.data,
+          });
+          this.index++;
+        }
+        this.passValue();
+        this.$forceUpdate();
+      }
+    },
+  },
+};
+</script>
+<style scoped>
+.item {
+  position: relative;
+  margin-right: 10px;
+}
+.gb {
+  position: absolute;
+  left: 59px;
+  top: -8px;
+  cursor: pointer;
+}
+.fmt {
+  border-bottom-left-radius: 10px;
+  border-bottom-right-radius: 10px;
+  position: absolute;
+  width: 70px;
+  height: 20px;
+  background: #0000003d;
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: center;
+  color: #fff;
+  bottom: 10px;
+}
+</style>

+ 225 - 0
src/views/productNationwide/module/product-info.vue

@@ -0,0 +1,225 @@
+<template>
+  <el-form
+    :model="form"
+    ref="queryForm"
+    size="small"
+    :rules="rules"
+    :inline="true"
+    label-width="120px"
+  >
+    <el-row>
+      <el-col :span="24">
+        <el-form-item prop="spuDesc">
+          <span slot="label">商品介绍</span>
+          <el-input
+            style="width: 700px"
+            type="textarea"
+            :rows="3"
+            placeholder="请输入商品介绍"
+            v-model="form.spuDesc"
+            @input="passValue"
+          >
+          </el-input>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <el-form-item label="商品详情图" prop="spuDetailList">
+          <span class="tips">最多可上传10张</span>
+          <el-upload
+            list-type="picture-card"
+            :file-list="spuDetailList"
+            :before-remove="requestRemove"
+            :http-request="(data) => requestUpload(data, 'detail')"
+            :show-file-list="true"
+            :limit="10"
+            action="#"
+            :multiple="true"
+            accept=".png,.jpg,.jpeg"
+            ref="files"
+          >
+            <i class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <el-form-item label="特殊资质图" prop="spuName">
+          <span class="tips">例如农残检测报告等,最多可上传10张</span>
+          <el-upload
+            list-type="picture-card"
+            :file-list="specialList"
+            :before-remove="requestRemove1"
+            :http-request="(data) => requestUpload(data, 'zz')"
+            :show-file-list="true"
+            :limit="10"
+            action="#"
+            :multiple="true"
+            accept=".png,.jpg,.jpeg"
+            ref="files"
+          >
+            <i class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <el-form-item prop="spuStatus">
+          <span slot="label"> 发布状态</span>
+          <el-radio-group v-model="form.spuStatus" @change="radioChange">
+            <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-row>
+  </el-form>
+</template>
+
+<script>
+import { getToken } from "@/utils/auth";
+import axios from "axios";
+export default {
+  props: ["data"],
+  data() {
+    return {
+      form: {
+        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" },
+        ],
+        spuDetailList: [
+          { required: true, message: "商品详情图不能为空", trigger: "blur" },
+        ],
+      },
+    };
+  },
+  methods: {
+    getFormInfo(record) {
+      // 基础信息赋值
+      this.form.spuDesc = record.spuDesc;
+      // 提取通用转换逻辑
+      const transformFileList = (list) =>
+        Array.isArray(list)
+          ? list.map((item) => ({
+              url: item.fileUrl,
+              id: item.id,
+              sort: item.sort,
+            }))
+          : [];
+
+      // 转换并赋值商品详情和特殊列表
+      this.spuDetailList = transformFileList(record.spuDetailList);
+      this.specialList = transformFileList(record.specialList);
+
+      // 更新表单数据
+      this.form.specialList = this.specialList;
+      this.form.spuDetailList = this.spuDetailList;
+    },
+
+    formvalidate() {
+      let that = this;
+      return new Promise((resolve) => {
+        that.$refs.queryForm.validate((valid, row) => {
+          if (valid) {
+            resolve(valid);
+          } else {
+            for (const key in row) {
+              for (let index = 0; index < row[key].length; index++) {
+                this.$message.error(row[key][index].message);
+                return;
+              }
+            }
+            resolve(valid);
+          }
+        });
+      });
+    },
+    radioChange() {
+      this.passValue();
+    },
+    passValue() {
+      if (this.specialList) {
+        this.form.specialList = [];
+        for (let index = 0; index < this.specialList.length; index++) {
+          this.form.specialList.push({
+            fileUrl: this.specialList[index].url,
+            sort: this.specialList[index].name,
+          });
+        }
+      }
+      if (this.spuDetailList) {
+        this.form.spuDetailList = [];
+        for (let index = 0; index < this.spuDetailList.length; index++) {
+          this.form.spuDetailList.push({
+            fileUrl: this.spuDetailList[index].url,
+            sort: this.spuDetailList[index].name,
+          });
+        }
+      }
+      this.$emit("updateValue", this.form);
+    },
+    requestRemove1(val) {
+      this.specialList.forEach((e, index) => {
+        if (e.uid == val.uid) {
+          this.specialList.splice(index, 1);
+        }
+      });
+      this.passValue();
+    },
+    requestRemove(val) {
+      this.spuDetailList.forEach((e, index) => {
+        if (e.uid == val.uid) {
+          this.spuDetailList.splice(index, 1);
+        }
+      });
+      this.passValue();
+    },
+
+    // 可以获取图片参数
+    async requestUpload(data, type) {
+      const formdata = new FormData();
+      formdata.append("file", data.file);
+      const res = await axios.post(
+        `${process.env.VUE_APP_NSY_UPLOAD_API}/api/third/op/v1/third/uploadPic`,
+        formdata,
+        {
+          headers: this.headers,
+        }
+      );
+      if (res.data.data) {
+        if (type == "detail") {
+          this.spuDetailList.push({
+            name: this.index,
+            url: res.data.data,
+          });
+          this.index++;
+        } else if (type == "zz") {
+          this.specialList.push({
+            name: this.index1,
+            url: res.data.data,
+          });
+          this.index1++;
+        }
+        this.passValue();
+        this.$forceUpdate();
+      }
+    },
+  },
+};
+</script>
+
+<style></style>

+ 750 - 0
src/views/productNationwide/module/sales-info.vue

@@ -0,0 +1,750 @@
+<template>
+  <el-form
+    :model="form"
+    ref="queryForm"
+    size="small"
+    :inline="true"
+    label-width="120px"
+    :rules="rules"
+  >
+    <el-row>
+      <el-col :span="24">
+        <el-form-item prop="lookSalesVolume">
+          <span slot="label">展示销量</span>
+          <el-input
+            v-model="form.lookSalesVolume"
+            placeholder="请输入展示销量"
+            clearable
+            @input="passValue"
+          />
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <el-form-item prop="giftDesc" label="快递类型">
+          <el-radio
+            v-model="form.expressType"
+            :label="0"
+            :value="0"
+            @change="passValue"
+            >水果特惠</el-radio
+          >
+          <el-radio
+            v-model="form.expressType"
+            :label="1"
+            :value="1"
+            @change="passValue"
+            >生鲜特快</el-radio
+          >
+          <el-radio
+            v-model="form.expressType"
+            :label="2"
+            :value="2"
+            @change="passValue"
+            >京东标快</el-radio
+          >
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <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"
+              :key="item.dictLabel"
+              :label="item.dictLabel"
+              :value="item.dictLabel"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <el-form-item>
+          <span slot="label"><span class="required">*</span> 商品规格</span>
+          <el-button @click="addSpecification" type="primary"
+            >添加规格</el-button
+          >
+          <el-table :data="form.skuList" style="width: 100%; margin-top: 20px">
+            <el-table-column prop="name" label="规格名称" width="140">
+              <template slot-scope="scope">
+                <el-input
+                  v-model="scope.row.skuSpecsList[0].specsName"
+                  placeholder="请输入规格名称"
+                  clearable
+                  maxlength="8"
+                  @input="passValue"
+                  show-word-limit
+                />
+              </template>
+            </el-table-column>
+            <el-table-column prop="address" label="规格内容" width="140">
+              <template slot-scope="scope">
+                <el-input
+                  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-number
+                  :controls="false"
+                  v-model="scope.row.predictStocks"
+                  placeholder="预计库存"
+                  clearable
+                  @input="passValue"
+                >
+                  <template slot="suffix"> {{ form.unit }} </template>
+                </el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column prop="name" label="实际库存" width="140">
+              <template slot-scope="scope">
+                <el-input-number
+                  :controls="false"
+                  v-model="scope.row.stock"
+                  placeholder="实际库存"
+                  clearable
+                  @input="passValue"
+                >
+                  <template slot="suffix"> {{ form.unit }} </template>
+                </el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column prop="address" label="起批量" width="140">
+              <template slot-scope="scope">
+                <el-input-number
+                  :controls="false"
+                  v-model="scope.row.skuPriceList[0].minPurchase"
+                  placeholder="起批量"
+                  clearable
+                  @input="passValue"
+                >
+                  <template slot="suffix">
+                    {{ form.unit }}
+                  </template>
+                </el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column prop="address" label="收购价" width="140">
+              <template slot-scope="scope">
+                <el-input-number
+                  :controls="false"
+                  v-model="scope.row.skuCost.purchaseFee"
+                  placeholder="收购价"
+                  clearable
+                  @input="passValue"
+                >
+                  <template slot="suffix"> {{ form.unit }}/元 </template>
+                </el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column prop="address" label="人工费" width="140">
+              <template slot-scope="scope">
+                <el-input-number
+                  :controls="false"
+                  v-model="scope.row.skuCost.laborFee"
+                  placeholder="人工费"
+                  clearable
+                  @input="passValue"
+                >
+                  <template slot="suffix"> {{ form.unit }}/元 </template>
+                </el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column prop="address" label="代办费" width="140">
+              <template slot-scope="scope">
+                <el-input-number
+                  :controls="false"
+                  v-model="scope.row.skuCost.agencyFee"
+                  placeholder="代办费"
+                  clearable
+                  @input="passValue"
+                >
+                  <template slot="suffix"> {{ form.unit }}/元 </template>
+                </el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column prop="address" label="材料费" width="140">
+              <template slot-scope="scope">
+                <el-input-number
+                  :controls="false"
+                  @input="passValue"
+                  v-model="scope.row.skuCost.materialFee"
+                  placeholder="材料费"
+                  clearable
+                >
+                  <template slot="suffix"> {{ form.unit }}/元 </template>
+                </el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column prop="address" label="商品单价" width="140">
+              <template slot-scope="scope">
+                {{ computePrice(scope.row) }}元/{{ form.unit }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="address" label="操作">
+              <template slot-scope="scope">
+                <el-button
+                  type="text"
+                  style="color: red"
+                  @click="removeSpecification(scope.row, scope.$index)"
+                  >删除</el-button
+                >
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24" style="margin-top: 20px">
+        <el-form-item>
+          <span slot="label"><span class="required">*</span> 商品属性</span>
+          <div class="main">
+            <div style="padding-top: 20px">
+              <el-form-item label="包装方式" prop="packing">
+                <el-select
+                  v-model="form.packing"
+                  placeholder="请选择包装方式"
+                  @change="passValue"
+                >
+                  <el-option
+                    v-for="item in package"
+                    :key="item.dictLabel"
+                    :label="item.dictLabel"
+                    :value="item.dictLabel"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item prop="shippingTimeDesc">
+                <span slot="label">发货时间</span>
+                <el-select
+                  v-model="form.shippingTimeDesc"
+                  placeholder="请选择发货时间"
+                  @change="passValue"
+                >
+                  <el-option label="付款24小时之内" value="付款24小时之内" />
+                  <el-option label="付款36小时之内" value="付款36小时之内" />
+                  <el-option label="付款48小时之内" value="付款48小时之内" />
+                  <el-option label="付款72小时之内" value="付款72小时之内" />
+                </el-select>
+              </el-form-item>
+            </div>
+
+            <el-form-item
+              label="自定义属性"
+              v-if="form.props && form.props.length > 0"
+            >
+              <div
+                style="
+                  width: 100%;
+                  display: flex;
+                  flex-direction: row;
+                  flex-flow: wrap;
+                  justify-content: center;
+                "
+              >
+                <div
+                  class="item"
+                  v-for="(item, index) in form.props ? form.props : []"
+                  :key="index"
+                >
+                  <el-input
+                    v-model="item.name"
+                    placeholder="请输入属性名称"
+                    clearable
+                    maxlength="8"
+                    show-word-limit
+                    style="width: 200px"
+                  />
+                  <el-input
+                    v-model="item.value"
+                    placeholder="请输入属性值"
+                    clearable
+                    maxlength="8"
+                    show-word-limit
+                    @input="passValue"
+                    style="width: 200px"
+                  />
+                  <i
+                    class="el-icon-delete"
+                    size="22"
+                    style="color: red"
+                    @click="removeAttribute(item, index)"
+                  ></i>
+                </div>
+              </div>
+            </el-form-item>
+          </div>
+          <div class="item1" style="width: 180px">
+            <span @click="addattribute" style="cursor: pointer">
+              <i class="el-icon-plus" size="22"></i>自定义添加商品属性</span
+            >
+          </div>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24" v-if="saleModel == 1">
+        <el-form-item prop="merchantClassifyIds">
+          <span slot="label">店铺内所属分类</span>
+          <el-cascader
+            :filterable="true"
+            v-model="form.merchantClassifyIds"
+            ref="formCascader"
+            :placeholder="
+              form.merchantClassifyName
+                ? form.merchantClassifyName
+                : '请选择分类'
+            "
+            :props="categoryprops"
+            @change="cascaderChange"
+          />
+        </el-form-item>
+      </el-col>
+      <el-col :span="24" style="margin-top: 20px">
+        <el-form-item prop="freeShipping">
+          <span slot="label">运费</span>
+          <div class="main1">
+            <el-radio-group v-model="form.freeShipping" class="radios">
+              <el-radio :label="0" :value="0"
+                >双方协商后卖家进行修改,买家和订单一起支付</el-radio
+              >
+              <el-radio :label="1" :value="1"
+                >全国包邮,由卖家承担运费</el-radio
+              >
+            </el-radio-group>
+          </div>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24" style="margin-top: 20px">
+        <el-form-item prop="shippingAddrBean.addrDetail">
+          <span slot="label"> 发货地址</span>
+          <div style="display: flex; flex-direction: row; align-items: center">
+            <el-button
+              @click="selectAddr"
+              type="text"
+              style="
+                font-size: 16px;
+                display: flex;
+                flex-direction: row;
+                align-items: center;
+              "
+              ><img
+                src="@/assets/images/point.png"
+                style="width: 20px; height: 20px"
+              />
+              选择地址</el-button
+            >
+            <span style="margin-left: 20px">已选择地址:{{ addr }}</span>
+          </div>
+
+          <el-input
+            type="textarea"
+            :rows="3"
+            placeholder="请输入详细地址"
+            v-model="form.shippingAddrBean.addrDetail"
+            style="width: 700px"
+            @blur="passValue"
+          >
+          </el-input>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <el-form-item prop="shareRate">
+          <span slot="label">分享比例</span>
+          <el-input-number
+            v-model="form.shareRate"
+            :min="0"
+            :max="100"
+            placeholder="请输入分享比例"
+            :controls="false"
+            @change="passValue"
+          >
+          </el-input-number
+          >%
+        </el-form-item>
+      </el-col>
+    </el-row>
+    <Amap ref="mapOpen" @address="Mapaddress"></Amap>
+  </el-form>
+</template>
+
+<script>
+import { getMerchantClassifyList } from "@/api/sort/index.js";
+import { getStoreInfo } from "@/api/common/index";
+import Amap from "@/components/Map/map.vue";
+import { getDict } from "@/api/common/index.js";
+export default {
+  props: ["data", "saleType", "saleModels"],
+  components: { Amap },
+  data() {
+    return {
+      form: {
+        expressType: 0,
+        unit: "斤",
+        props: [],
+        freeShipping: 0,
+        lookSalesVolume: "",
+        shippingAddrBean: {
+          addr: "",
+          addrDetail: "",
+          cityCode: "",
+          countyCode: "",
+          latitude: "",
+          longitude: "",
+          provinceCode: "",
+        },
+        shippingAddr: "",
+        skuList: [],
+        packing: "",
+        shippingTimeDesc: "",
+        merchantClassifyId: "",
+        merchantClassifyIds: [],
+        merchantClassifyName: "",
+      },
+      addr: "",
+      measure: [],
+      package: [],
+      rules: {
+        freeShipping: [
+          { required: true, message: "请选择运费方式", trigger: "blur" },
+        ],
+        props: [
+          { 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" },
+        ],
+        merchantClassifyIds: [
+          { required: true, message: "店铺所属分类不能为空", trigger: "blur" },
+        ],
+      },
+
+      shopInfo: {},
+      saleType: undefined,
+      sj: true,
+      skuIds: [],
+      saleModel: 1,
+      categoryprops: {
+        checkStrictly: true,
+        lazy: true,
+        lazyLoad: this.categoryLazyLoad,
+        label: "label",
+        value: "value",
+      },
+    };
+  },
+  watch: {
+    //监听文件url改变时重新赋值
+    saleModels(newVal, oldVal) {
+      this.saleModel = newVal;
+      this.$forceUpdate();
+    },
+  },
+  mounted() {
+    this.getInfo();
+    this.getdictImpl();
+  },
+
+  methods: {
+    categoryLazyLoad(node, resolve) {
+      let level = node.level;
+      if (!node.data) {
+        getMerchantClassifyList({ classifyType: 1, isDefault: 1 }).then(
+          (res) => {
+            //接口
+            const nodes = Array.from(res.data).map((item, index) => ({
+              value: item.id,
+              label: `${item.classifyName}`,
+              leaf: level >= 2,
+            }));
+            // 通过调用resolve将子节点数据返回,通知组件数据加载完成
+            resolve(nodes);
+          }
+        );
+      } else if (level == 1) {
+        getMerchantClassifyList({
+          parentId: node.data.value,
+          classifyType: 1,
+        }).then((res) => {
+          const nodes = Array.from(res.data).map((item) => ({
+            value: item.id,
+            label: `${item.classifyName}`,
+            leaf: level >= 2,
+            // level: 2,
+          }));
+          // 通过调用resolve将子节点数据返回,通知组件数据加载完成
+          resolve(nodes);
+        });
+      } else {
+        resolve({});
+      }
+    },
+    cascaderChange(val) {
+      const dom = document.getElementsByClassName("el-radio is-checked");
+      //这里我把dom打出来看了 最后一个选项才是我选中的节点 即[length-1] 有的博主写的是 第一个元素 即[0] 大家自行尝试
+      let radioDom = dom[dom.length - 1];
+      const brother = radioDom.nextElementSibling;
+      let nodes = this.$refs.formCascader.getCheckedNodes();
+      this.form.merchantClassifyName = nodes[0].label;
+      this.form.merchantClassifyIds = val;
+      this.form.merchantClassifyId = JSON.stringify(val);
+      brother.click();
+      // this.form.merchantClassifyId = `["${this.form.merchantClassifyId.join('')}"]`;
+      this.passValue();
+    },
+    getFormInfo(record) {
+      this.form.merchantClassifyName = record.merchantClassifyName;
+      this.saleModel = record.saleModel;
+      this.addr = record.shippingAddr;
+      this.form.expressType = record.expressType;
+      this.form.shareRate = record.shareRate;
+      this.form.merchantClassifyIds = record.merchantClassifyId;
+      this.form.merchantClassifyId = record.merchantClassifyId;
+      this.form.shippingAddrBean = {
+        addr: record.shippingAddr,
+        addrDetail: record.shippingAddrBean
+          ? record.shippingAddrBean.addrDetail
+          : undefined,
+        cityCode: record.cityCode,
+        countyCode: record.countyCode,
+        latitude: record.latitude,
+        longitude: record.longitude,
+        provinceCode: record.provinceCode,
+      };
+      if (record.props && record.props?.length < 1) {
+        this.form.props = [];
+      } else if (!record.props) {
+        this.form.props = [];
+      } else {
+        this.form.props = record.props;
+      }
+      this.form.lookSalesVolume = record.lookSalesVolume;
+      this.form.unit = record.unit;
+      this.form.shippingAddr = record.shippingAddr;
+      this.form.packing = record.packing;
+      this.form.shippingTimeDesc = record.shippingTimeDesc;
+      if (this.form.freeShipping) {
+        this.form.freeShipping = record.freeShipping;
+      }
+      this.form.skuList = record.skuList;
+    },
+    compilatePrice(data) {
+      if (data.price) {
+        return data.price.toFixed(2);
+      } else if (data.originalPrice) {
+        return data.originalPrice.toFixed(2);
+      } else if (data.originalPrice && data.price) {
+        return data.price.toFixed(2);
+      }
+    },
+    formvalidate() {
+      let that = this;
+      return new Promise((resolve) => {
+        that.$refs.queryForm.validate((valid, row) => {
+          if (valid) {
+            resolve(valid);
+          } else {
+            for (const key in row) {
+              for (let index = 0; index < row[key].length; index++) {
+                this.$message.error(row[key][index].message);
+                return;
+              }
+            }
+            resolve(valid);
+          }
+        });
+      });
+    },
+    getInfo() {
+      getStoreInfo().then((res) => {
+        if (res.code == 200) {
+          this.shopInfo = res.data;
+        }
+      });
+    },
+    getdictImpl() {
+      getDict("stockUnit").then((res) => {
+        if (res.code == 200) {
+          this.measure = res.data;
+        }
+      });
+      getDict("packType").then((res) => {
+        if (res.code == 200) {
+          this.package = res.data;
+        }
+      });
+    },
+    computePrice(data) {
+      if (
+        data.skuCost.purchaseFee &&
+        data.skuCost.laborFee &&
+        data.skuCost.agencyFee &&
+        data.skuCost.materialFee
+      ) {
+        return (
+          Number(data.skuCost.purchaseFee) +
+          Number(data.skuCost.laborFee) +
+          Number(data.skuCost.agencyFee) +
+          Number(data.skuCost.materialFee)
+        ).toFixed(2);
+      } else {
+        return 0;
+      }
+    },
+
+    passValue() {
+      this.form.skuList.forEach((e) => {
+        e.skuPriceList.forEach((a) => {
+          a.price = this.computePrice(e);
+          a.originalPrice = this.computePrice(e);
+          a.lowestPrice = this.computePrice(e);
+        });
+      });
+
+      this.$emit("updateValue", this.form);
+    },
+
+    Mapaddress(data) {
+      this.form.shippingAddr = data.pname + data.cityname + data.adname;
+      this.form.shippingAddrBean.addr = data.address;
+      // this.form.shippingAddrBean.addrDetail = data.name ? data.name : undefined;
+      this.form.shippingAddrBean.cityCode = data.cityCode;
+      this.form.shippingAddrBean.countyCode = data.adcode;
+      if (data.location) {
+        this.form.shippingAddrBean.latitude = data.location.lat;
+        this.form.shippingAddrBean.longitude = data.location.lng;
+      }
+      this.form.shippingAddrBean.provinceCode = data.pcode;
+      this.addr = data.address;
+      this.$refs.mapOpen.closeMap();
+      // this.passValue();
+    },
+    selectAddr() {
+      this.$refs.mapOpen.loadMap();
+    },
+    addattribute() {
+      if (this.form.prop?.length > 0) {
+        this.form.props.push({
+          name: "",
+          id: "",
+          value: "",
+        });
+      } else {
+        this.form.prop = [];
+        this.form.props.push({
+          name: "",
+          id: "",
+          value: "",
+        });
+      }
+    },
+    removeAttribute(record, index) {
+      this.form.props.splice(index, 1);
+      this.passValue();
+    },
+    removeSpecification(record, index) {
+      console.log("record", record.id);
+      this.skuIds.push(record.id);
+      this.form.skuList.splice(index, 1);
+      this.$emit("skuRemove", this.skuIds);
+    },
+    addSpecification() {
+      if (!this.form.skuList) {
+        this.form.skuList = [];
+      }
+      this.form.skuList.push({
+        stock: undefined,
+        weight: undefined,
+        sj: true,
+        skuCost: {
+          purchaseFee: undefined,
+          laborFee: undefined,
+          agencyFee: undefined,
+          materialFee: undefined,
+        },
+        skuSpecsList: [
+          {
+            specsId: "0",
+            specsName: "",
+            specsValue: "",
+          },
+        ],
+        skuPriceList: [
+          {
+            minPurchase: undefined,
+            maxPurchase: undefined,
+            price: undefined,
+            originalPrice: undefined,
+            lowestPrice: 1,
+          },
+        ],
+      });
+    },
+  },
+};
+</script>
+<style>
+.el-upload-list__item {
+  transition: none !important;
+  -webkit-transition: nonne !important;
+}
+.el-upload-list__item-name {
+  transition: none !important;
+  -webkit-transition: nonne !important;
+}
+</style>
+<style scoped>
+/deep/ .el-radio-group {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  height: 50px;
+}
+.item {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-bottom: 20px;
+  margin-right: 10px;
+}
+.main1 {
+  background: #f1f1f1;
+  min-height: 80px;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  align-items: center;
+  padding: 0px 20px;
+}
+.main {
+  width: 58vw;
+  background: #f1f1f1;
+  min-height: 80px;
+  display: flex;
+  flex-direction: column;
+  align-items: flex-start;
+  /* display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  align-items: center;
+  padding: 20px 20px 0px 20px; */
+}
+</style>

+ 610 - 0
src/views/productNationwide/updateProduct.vue

@@ -0,0 +1,610 @@
+<template>
+  <div class="app-container">
+    <div style="width: 100%; height: 85vh; overflow: auto">
+      <el-row style="padding-top: 20px">
+        <el-col :span="24">
+          <el-descriptions title="基本信息" column="1"> </el-descriptions>
+          <basicInfo ref="basicRefs" @updateValue="updateValue"></basicInfo>
+          <el-descriptions title="销售信息" column="1"> </el-descriptions>
+          <salesInfo
+            ref="salesRefs"
+            @updateValue="updateValue"
+            @skuRemove="skuRemove"
+            :saleModels="form.saleModel"
+          ></salesInfo>
+          <el-descriptions title="商品详情" column="1"> </el-descriptions>
+          <productInfo
+            ref="productRefs"
+            @updateValue="updateValue"
+          ></productInfo>
+
+          <div class="dialog-footer" style="text-align: center">
+            <el-button @click="submitCancel">取 消</el-button>
+            <el-button type="primary" @click="submitForm" :loading="btnLading"
+              >发 布</el-button
+            >
+            <el-button
+              type="primary"
+              @click="submitFormDraft"
+              v-if="$route.query.params.type == 'draft'"
+              >存入草稿箱</el-button
+            >
+          </div>
+        </el-col>
+        <phoneView style="position: absolute; bottom: 50px; right: 50px">
+          <div slot="conts">
+            <div>
+              <el-carousel height="200px">
+                <el-carousel-item
+                  v-for="(item, index) in headerImg.slice(1)"
+                  :key="index"
+                >
+                  <el-image
+                    v-if="item.type == 'img'"
+                    style="width: 100%; height: 200px"
+                    :src="item.src"
+                    :preview-src-list="[item.src]"
+                  >
+                  </el-image>
+                  <video
+                    v-if="item.type == 'video'"
+                    :key="index"
+                    controls
+                    :src="item.src"
+                    style="width: 100%; height: 200px"
+                  ></video>
+                </el-carousel-item>
+              </el-carousel>
+            </div>
+            <img
+              style="width: 100%"
+              src="https://bucket.sxdirectpurchase.com/fileUpload/test/47fc6132-0b3e-4b5c-b858-f78d363eba90.png"
+              alt=""
+            />
+            <div class="card">
+              <div class="spuName">{{ form ? form.title : "" }}</div>
+              <div class="price_info">
+                <div class="price_group">
+                  <span>¥</span>
+                  <span
+                    class="price"
+                    :key="item"
+                    v-for="item in form.skuList ? form.skuList.slice(0, 1) : []"
+                    >{{
+                      item.skuPriceList ? item.skuPriceList[0].price : 0
+                    }}元</span
+                  >
+
+                  <span>/{{ form.unit }}</span>
+                </div>
+                <span class="ys">已售 0</span>
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div class="spuName">规格/价格</div>
+              <div v-for="(item, index) in form.skuList" :key="index">
+                <div class="price_info">
+                  <span
+                    >{{
+                      item.skuSpecsList[0] ? item.skuSpecsList[0].specsName : ""
+                    }}
+                    {{
+                      item.skuSpecsList[0].specsValue
+                        ? item.skuSpecsList[0].specsValue
+                        : ""
+                    }}</span
+                  >
+                </div>
+                <div
+                  style="
+                    display: flex;
+                    flex-direction: row;
+                    justify-content: space-between;
+                  "
+                >
+                  <span style="font-size: 14px; color: red">
+                    <span>¥</span>
+                    <span
+                      >{{
+                        item.skuPriceList
+                          ? item.skuPriceList[0].price
+                            ? item.skuPriceList[0].price
+                            : ""
+                          : ""
+                      }}元</span
+                    ><span>/{{ form.unit }}</span></span
+                  >
+                  <span style="font-size: 14px"
+                    >{{
+                      item.skuPriceList
+                        ? item.skuPriceList[0].minPurchase
+                          ? item.skuPriceList[0].minPurchase
+                          : ""
+                        : ""
+                    }}/{{ form.unit }}起购</span
+                  >
+                  <span style="font-size: 14px"
+                    >库存:{{ item.stock + item.predictStocks
+                    }}{{ form.unit }}</span
+                  >
+                </div>
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <el-form
+                :model="form"
+                ref="queryForm"
+                size="small"
+                :inline="true"
+                label-width="80px"
+                label-position="left"
+              >
+                <el-row>
+                  <el-col :span="24">
+                    <el-form-item label="发货地" prop="spuName">
+                      <div style="width: 185px">
+                        {{
+                          form.shippingAddrBean
+                            ? form.shippingAddrBean.addr
+                            : ""
+                        }}
+                        {{
+                          form.shippingAddrBean
+                            ? form.shippingAddrBean.addrDetail
+                              ? form.shippingAddrBean.addrDetail
+                              : ""
+                            : ""
+                        }}
+                      </div>
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="24">
+                    <el-form-item label="发货时间" prop="spuName">
+                      {{ form.shippingTimeDesc }}
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="24">
+                    <el-form-item label="商品属性" prop="spuName">
+                      <div>查看></div>
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="24">
+                    <el-form-item label="包装方式" prop="spuName">
+                      {{ form.packing }}
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+              </el-form>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div
+                style="
+                  display: flex;
+                  flex-direction: row;
+                  justify-content: space-between;
+                  align-items: center;
+                "
+              >
+                <span class="spuName">商品评价</span>
+                <span>好评率 <span style="color: red">100%</span></span>
+              </div>
+              <div
+                style="
+                  display: flex;
+                  flex-direction: column;
+                  justify-content: center;
+                  align-items: center;
+                "
+              >
+                <img
+                  style="width: 40%"
+                  src="https://directpurchase-oss-dev.oss-cn-chengdu.aliyuncs.com/wx/static/images/kong.png"
+                  alt=""
+                />
+                <span>还没有评价~</span>
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div class="spuName">商品介绍</div>
+              <div style="font-size: 14px; line-height: 25px">
+                {{ form.spuDesc }}
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div class="spuName">商品详情</div>
+              <div style="font-size: 14px; line-height: 25px">
+                <el-image
+                  v-for="(item, index) in form.spuDetailList"
+                  :key="index"
+                  :src="item.fileUrl"
+                  fit="fill"
+                  :preview-src-list="[item.fileUrl]"
+                >
+                </el-image>
+              </div>
+              <div style="font-size: 14px; line-height: 25px">
+                <el-image
+                  v-for="(item, index) in form.specialList"
+                  :key="index"
+                  :src="item.fileUrl"
+                  fit="fill"
+                  :preview-src-list="[item.fileUrl]"
+                >
+                </el-image>
+              </div>
+            </div>
+          </div>
+        </phoneView>
+      </el-row>
+    </div>
+
+    <Amap></Amap>
+  </div>
+</template>
+
+<script>
+import { publishGoods } from "@/api/publish/index";
+import { getStoreInfo } from "@/api/common/index";
+import {
+  saveGoodsDraft,
+  updateGoods,
+  getGoodsInfo,
+  getGoodsDraftById,
+  removeSkuBySkuId,
+} from "@/api/manage/product";
+import basicInfo from "./module/basic-info.vue";
+import productInfo from "./module/product-info.vue";
+import salesInfo from "./module/sales-info.vue";
+import phoneView from "@/components/phoneView/index.vue";
+import Amap from "@/components/Map/map.vue";
+import moment from "moment";
+export default {
+  name: "updateProduct",
+  components: { Amap, phoneView, basicInfo, salesInfo, productInfo },
+  data() {
+    return {
+      form: {},
+      headerImg: [],
+      btnLading: false,
+      skulist: [],
+    };
+  },
+
+  created() {
+    window.addEventListener("beforeunload", function (e) {
+      this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
+      this.$router.replace({ path: "/product/productNationwide/index" });
+    });
+  },
+  mounted() {
+    this.getInfo();
+    if (
+      (this.$route.query.params != "[object Object]" &&
+        this.$route.query.params) ||
+      JSON.parse(localStorage.getItem("productInfo"))
+    ) {
+      let info = {};
+      if (
+        this.$route.query.params != "[object Object]" &&
+        this.$route.query.params
+      ) {
+        info = this.$route.query.params;
+      } else {
+        info = JSON.parse(localStorage.getItem("productInfo"));
+      }
+      if (info.type == "draft") {
+        this.form.goodsDraftId = info.id;
+        getGoodsDraftById({ goodsDraftId: info.id }).then((res) => {
+          if (res.code == 200) {
+            this.form = res.data.goodsDto;
+            this.form.goodsDraftId = info.id;
+            this.headerImg = [];
+            if (this.form.vid) {
+              this.headerImg.push({
+                type: "video",
+                src: this.form.vid,
+                sort: 1,
+              });
+            }
+            if (this.form.pic) {
+              this.headerImg.push({
+                type: "img",
+                src: this.form.pic,
+                sort: 2,
+              });
+            }
+            this.headerImg = this.unique(this.headerImg);
+            if (this.form.bannerList?.length > 0) {
+              this.form.bannerList.forEach((e, index) => {
+                this.headerImg.push({
+                  type: "img",
+                  src: e.fileUrl,
+                  sort: index + 4,
+                });
+              });
+            }
+            this.headerImg.sort((a, b) => a.sort - b.sort); //排序 视频在最前面>封面>商品banner
+            if (this.form.scope == 0) {
+              this.$refs.salesRefs.setShowCom(false);
+            } else if (this.form.saleType == 2 && this.form.scope == 0) {
+              this.$refs.salesRefs.setShowCom(false);
+            } else {
+              this.$refs.salesRefs.setShowCom(true);
+            }
+            this.$refs.basicRefs.getFormInfo(this.form, this.$route.query.type);
+            this.$refs.salesRefs.getFormInfo(this.form);
+            this.$refs.productRefs.getFormInfo(this.form);
+          }
+        });
+      } else {
+        getGoodsInfo({ spuId: info.id }).then((res) => {
+          if (res.code == 200) {
+            this.form = res.data;
+            this.headerImg = [];
+            if (this.form.vid) {
+              this.headerImg.push({
+                type: "video",
+                src: this.form.vid,
+                sort: 1,
+              });
+            }
+            if (this.form.pic) {
+              this.headerImg.push({
+                type: "img",
+                src: this.form.pic,
+                sort: 2,
+              });
+            }
+            this.headerImg = this.unique(this.headerImg);
+            if (this.form.bannerList?.length > 0) {
+              this.form.bannerList.forEach((e, index) => {
+                this.headerImg.push({
+                  type: "img",
+                  src: e.fileUrl,
+                  sort: index + 4,
+                });
+              });
+            }
+            this.headerImg.sort((a, b) => a.sort - b.sort); //排序 视频在最前面>封面>商品banner
+            if (this.form.scope == 0) {
+              this.$refs.salesRefs.setShowCom(false);
+            } else if (this.form.saleType == 2 && this.form.scope == 0) {
+              this.$refs.salesRefs.setShowCom(false);
+            } else {
+              this.$refs.salesRefs.setShowCom(true);
+            }
+            this.$refs.basicRefs.getFormInfo(this.form, this.$route.query.type);
+            this.$refs.salesRefs.getFormInfo(this.form);
+            this.$refs.productRefs.getFormInfo(this.form);
+          }
+        });
+      }
+    }
+  },
+  methods: {
+    skuRemove(list) {
+      this.skulist = list;
+    },
+    getInfo() {
+      getStoreInfo().then((res) => {
+        if (res.code == 200) {
+          if (res.data.scope == 0) {
+            if (this.form.saleType == 2) {
+              this.$refs.salesRefs.setShowCom(true);
+            } else {
+              this.$refs.salesRefs.setShowCom(false);
+            }
+          } else {
+            this.$refs.salesRefs.setShowCom(true);
+          }
+        }
+      });
+    },
+    submitCancel() {
+      this.$confirm("是否取消发布,所填写的信息将会消失?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
+          this.$router.replace({ path: "/product/productNationwide/index" });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+
+    submitFormDraft() {
+      if (!this.form.presaleStartTime && !this.form.presaleEndTime) {
+        if (this.form.datePicke) {
+          this.form.presaleStartTime = moment(
+            this.form.datePicker[0]
+          ).valueOf();
+          this.form.presaleEndTime = moment(this.form.datePicker[1]).valueOf();
+        }
+      }
+      if (this.form.categoryId?.length > 0) {
+        this.form.categoryId =
+          this.form.categoryId[this.form.categoryId.length - 1];
+      }
+      // if (this.form.bannerList?.length > 0) {
+      //   this.form.bannerList.shift();
+      // }
+      saveGoodsDraft(this.form).then((res) => {
+        if (res.code == 200) {
+          this.$message.success(`保存成功!请前往草稿箱查看`);
+          this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
+          this.$router.replace({ path: "/product/productNationwide/index" });
+        }
+      });
+    },
+    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;
+      }
+      if (this.form.skuList === "") {
+        this.$message.error(`商品规格不能为空`);
+        return;
+      }
+      if (!this.form.shippingAddrBean.provinceCode) {
+        this.$message.error(`请选择发货地址的省市区!`);
+        return;
+      }
+      this.btnLading = true;
+      if (!this.form.presaleStartTime && !this.form.presaleEndTime) {
+        if (this.form.datePicke) {
+          this.form.presaleStartTime = moment(
+            this.form.datePicker[0]
+          ).valueOf();
+          this.form.presaleEndTime = moment(this.form.datePicker[1]).valueOf();
+        }
+      }
+
+      if (this.form.categoryId?.length > 0) {
+        this.form.categoryId =
+          this.form.categoryId[this.form.categoryId.length - 1];
+      }
+
+      if (this.form.id) {
+        if (this.skulist?.length > 0) {
+          removeSkuBySkuId({ skuIds: this.skulist.toString() }).then(
+            (res) => {}
+          );
+        }
+        if (this.form.skuList.length < 1 || this.form.skuList === "") {
+          this.$message.error(`规格不能为空`);
+          return;
+        }
+        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/productNationwide/index" });
+          } else {
+            this.btnLading = false;
+          }
+        });
+      } else {
+        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/productNationwide/index" });
+          } else {
+            this.btnLading = false;
+          }
+        });
+      }
+    },
+    updateValue(val) {
+      this.form = { ...this.form, ...val };
+      if (this.form.saleType == 2) {
+        this.$refs.salesRefs.setShowCom(true);
+      } else if (this.form.scope == 0) {
+        this.$refs.salesRefs.setShowCom(false);
+      } else {
+        this.$refs.salesRefs.setShowCom(true);
+      }
+
+      this.headerImg = [];
+      if (val.vid || this.form.vid) {
+        this.headerImg.push({
+          type: "video",
+          src: val.vid ? val.vid : this.form.vid,
+          sort: 1,
+        });
+      }
+      if (this.form?.bannerList && this.form?.bannerList.length > 0) {
+        this.form.bannerList.forEach((e, index) => {
+          this.headerImg.push({
+            type: "img",
+            src: e.fileUrl,
+            sort: index + 4,
+          });
+        });
+      }
+      this.headerImg.sort((a, b) => a.sort - b.sort); //排序 视频在最前面>封面>商品banner
+    },
+    unique(arr) {
+      const res = new Map();
+      return arr.filter((arr) => !res.has(arr.src) && res.set(arr.src, 1));
+    },
+  },
+};
+</script>
+
+<style>
+.required {
+  color: red;
+}
+.el-upload-list__item {
+  width: 60px !important;
+  height: 60px !important;
+}
+.el-upload--picture-card {
+  width: 80px;
+  height: 80px;
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: center;
+}
+.tips {
+  font-size: 12px;
+  color: red;
+}
+</style>
+<style scoped>
+.card {
+  /* height: 85px; */
+  width: 95%;
+  background: white;
+  margin: auto;
+  border-radius: 10px;
+  line-height: 30px;
+  padding: 10px;
+}
+.spuName {
+  text-decoration: none;
+  font-weight: bold;
+  word-wrap: normal;
+  font-size: 18px;
+  color: #333333;
+}
+.price_group {
+  color: #ff2f2f;
+}
+.price {
+  text-decoration: none;
+  font-weight: bold;
+  word-wrap: normal;
+  font-size: 25px;
+  color: #ff2f2f;
+}
+.price_info {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+}
+.ys {
+  font-size: 14px;
+}
+</style>

+ 486 - 0
src/views/shipping/createProduct.vue

@@ -0,0 +1,486 @@
+<template>
+  <div class="app-container">
+    <div style="width: 100%; height: 85vh; overflow: auto">
+      <el-row style="padding-top: 20px">
+        <el-col :span="24">
+          <el-descriptions title="基本信息" column="1"> </el-descriptions>
+          <basicInfo @updateValue="updateValue" ref="basicRefs"></basicInfo>
+          <el-descriptions title="销售信息" column="1"> </el-descriptions>
+          <salesInfo
+            @updateValue="updateValue"
+            ref="salesRefs"
+            :saleType="form.saleType"
+            :saleModels="form.saleModel"
+          ></salesInfo>
+          <el-descriptions title="商品详情" column="1"> </el-descriptions>
+          <productInfo
+            @updateValue="updateValue"
+            ref="productRefs"
+          ></productInfo>
+
+          <div class="dialog-footer" style="text-align: center">
+            <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>
+        </el-col>
+        <phoneView style="position: absolute; bottom: 50px; right: 50px">
+          <div slot="conts">
+            <div>
+              <el-carousel height="200px">
+                <el-carousel-item
+                  v-for="(item, index) in headerImg.slice(1)"
+                  :key="index"
+                >
+                  <el-image
+                    v-if="item.type == 'img'"
+                    style="width: 100%; height: 200px"
+                    :src="item.src"
+                    :preview-src-list="[item.src]"
+                  >
+                  </el-image>
+                  <video
+                    v-if="item.type == 'video'"
+                    :key="index"
+                    controls
+                    :src="item.src"
+                    style="width: 100%; height: 200px"
+                  ></video>
+                </el-carousel-item>
+              </el-carousel>
+            </div>
+            <img
+              style="width: 100%"
+              src="https://bucket.sxdirectpurchase.com/fileUpload/test/47fc6132-0b3e-4b5c-b858-f78d363eba90.png"
+              alt=""
+            />
+            <div class="card">
+              <div class="spuName">{{ form ? form.title : "" }}</div>
+              <div class="price_info">
+                <div class="price_group">
+                  <span>¥</span>
+                  <span
+                    class="price"
+                    :key="item"
+                    v-for="item in form.skuList ? form.skuList.slice(0, 1) : []"
+                    >{{
+                      item.skuPriceList ? item.skuPriceList[0].price : 0
+                    }}元</span
+                  >
+
+                  <span>/{{ form.unit }}</span>
+                </div>
+                <span class="ys">已售 0</span>
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div class="spuName">规格/价格</div>
+              <div v-for="(item, index) in form.skuList" :key="index">
+                <div class="price_info">
+                  <span
+                    >{{
+                      item.skuSpecsList[0] ? item.skuSpecsList[0].specsName : ""
+                    }}
+                    {{
+                      item.skuSpecsList[0].specsValue
+                        ? item.skuSpecsList[0].specsValue
+                        : ""
+                    }}</span
+                  >
+                </div>
+                <div
+                  style="
+                    display: flex;
+                    flex-direction: row;
+                    justify-content: space-between;
+                  "
+                >
+                  <span style="font-size: 14px; color: red">
+                    <span>¥</span>
+                    <span
+                      >{{
+                        item.skuPriceList
+                          ? item.skuPriceList[0].price
+                            ? item.skuPriceList[0].price
+                            : ""
+                          : ""
+                      }}元</span
+                    ><span>/{{ form.unit }}</span></span
+                  >
+                  <span style="font-size: 14px"
+                    >{{
+                      item.skuPriceList
+                        ? item.skuPriceList[0].minPurchase
+                          ? item.skuPriceList[0].minPurchase
+                          : ""
+                        : ""
+                    }}/{{ form.unit }}起购</span
+                  >
+                  <span style="font-size: 14px"
+                    >库存:{{ item.stock + item.predictStocks
+                    }}{{ form.unit }}</span
+                  >
+                </div>
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <el-form
+                :model="form"
+                ref="queryForm"
+                size="small"
+                :inline="true"
+                label-width="80px"
+                label-position="left"
+              >
+                <el-row>
+                  <el-col :span="24">
+                    <el-form-item label="发货地" prop="spuName">
+                      <div style="width: 185px">
+                        {{
+                          form.shippingAddrBean
+                            ? form.shippingAddrBean.addr
+                            : ""
+                        }}
+                        {{
+                          form.shippingAddrBean
+                            ? form.shippingAddrBean.addrDetail
+                              ? form.shippingAddrBean.addrDetail
+                              : ""
+                            : ""
+                        }}
+                      </div>
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="24">
+                    <el-form-item label="发货时间" prop="spuName">
+                      {{ form.shippingTimeDesc }}
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="24">
+                    <el-form-item label="商品属性" prop="spuName">
+                      <div>查看></div>
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="24">
+                    <el-form-item label="包装方式" prop="spuName">
+                      {{ form.packing }}
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+              </el-form>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div
+                style="
+                  display: flex;
+                  flex-direction: row;
+                  justify-content: space-between;
+                  align-items: center;
+                "
+              >
+                <span class="spuName">商品评价</span>
+                <span>好评率 <span style="color: red">100%</span></span>
+              </div>
+              <div
+                style="
+                  display: flex;
+                  flex-direction: column;
+                  justify-content: center;
+                  align-items: center;
+                "
+              >
+                <img
+                  style="width: 40%"
+                  src="https://directpurchase-oss-dev.oss-cn-chengdu.aliyuncs.com/wx/static/images/kong.png"
+                  alt=""
+                />
+                <span>还没有评价~</span>
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div class="spuName">商品介绍</div>
+              <div style="font-size: 14px; line-height: 25px">
+                {{ form.spuDesc }}
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div class="spuName">商品详情</div>
+              <div style="font-size: 14px; line-height: 25px">
+                <el-image
+                  v-for="(item, index) in form.spuDetailList"
+                  :key="index"
+                  :src="item.fileUrl"
+                  fit="fill"
+                  :preview-src-list="[item.fileUrl]"
+                >
+                </el-image>
+              </div>
+              <div style="font-size: 14px; line-height: 25px">
+                <el-image
+                  v-for="(item, index) in form.specialList"
+                  :key="index"
+                  :src="item.fileUrl"
+                  fit="fill"
+                  :preview-src-list="[item.fileUrl]"
+                >
+                </el-image>
+              </div>
+            </div>
+          </div>
+        </phoneView>
+      </el-row>
+    </div>
+
+    <Amap></Amap>
+  </div>
+</template>
+
+<script>
+import { getStoreInfo } from "@/api/common/index";
+import { publishGoods } from "@/api/publish/index";
+import {
+  saveGoodsDraft,
+  queryUserRelevanceTemplate,
+} from "@/api/manage/product";
+import basicInfo from "./module/basic-info.vue";
+import productInfo from "@/views/product/module/product-info.vue";
+import salesInfo from "@/views/product/module/sales-info.vue";
+import phoneView from "@/components/phoneView/index.vue";
+import Amap from "@/components/Map/map.vue";
+import moment from "moment";
+export default {
+  components: { Amap, phoneView, basicInfo, salesInfo, productInfo },
+  data() {
+    return {
+      form: {},
+      headerImg: [],
+      btnLading: false,
+    };
+  },
+  methods: {
+    submitFormDraft() {
+      if (this.form.categoryId?.length > 0) {
+        this.form.categoryId =
+          this.form.categoryId[this.form.categoryId.length - 1];
+      }
+      if (this.form.categoryIds.length < 1) {
+        this.form.categoryIds = "";
+      }
+      if (!this.form.presaleStartTime && !this.form.presaleEndTime) {
+        if (this.form.datePicke) {
+          this.form.presaleStartTime = moment(
+            this.form.datePicker[0]
+          ).valueOf();
+          this.form.presaleEndTime = moment(this.form.datePicker[1]).valueOf();
+        }
+      }
+      // if (this.form.bannerList?.length > 0) {
+      //   this.form.bannerList.shift();
+      // }
+      if (this.form.saleModel == 2) {
+        this.form.merchantClassifyId = "[217527]";
+        this.form.merchantClassifyName = "集采预售";
+      } else if (this.form.saleModel == 3) {
+        this.form.merchantClassifyId = "[217526]";
+        this.form.merchantClassifyName = "团批秒杀";
+      } else if (this.form.saleModel == 4) {
+        this.form.merchantClassifyId = "[217528]";
+        this.form.merchantClassifyName = "清库专区";
+      } else if (this.form.saleModel == 5) {
+        this.form.merchantClassifyId = "[217525]";
+        this.form.merchantClassifyName = "新店福利";
+      }
+
+      saveGoodsDraft(this.form).then((res) => {
+        if (res.code == 200) {
+          this.$message.success(`发布成功!请前往草稿箱查看`);
+          this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
+          this.$router.replace({ path: "/product/shipping/index" });
+        }
+      });
+    },
+    submitCancel() {
+      this.$confirm("是否取消发布,所填写的信息将会消失?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
+          this.$router.replace({ path: "/product/shipping/index" });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消",
+          });
+        });
+    },
+    async submitForm() {
+      let bool = false;
+      queryUserRelevanceTemplate().then((res) => {
+        if (res.code == 200) {
+          if (res.data) {
+            bool = res.data;
+          }
+        }
+      });
+      if (bool) {
+        this.$message.error(
+          "您未设置同城运费规则,请先暂存草稿箱,待设置同城运费规则后再次进行发布!"
+        );
+        return;
+      }
+      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;
+      }
+      if (this.form.skuList.length < 1 || this.form.skuList === "") {
+        this.$message.error(`商品规格不能为空`);
+        return;
+      }
+      if (!this.form.shippingAddrBean.provinceCode) {
+        this.$message.error(`请点击选择地址,选择发货地址的省市区!`);
+        return;
+      }
+      if (this.form.categoryId?.length > 0) {
+        this.form.categoryId =
+          this.form.categoryId[this.form.categoryId.length - 1];
+      }
+      if (!this.form.presaleStartTime && !this.form.presaleEndTime) {
+        if (this.form.datePicke) {
+          this.form.presaleStartTime = moment(
+            this.form.datePicker[0]
+          ).valueOf();
+          this.form.presaleEndTime = moment(this.form.datePicker[1]).valueOf();
+        }
+      }
+      if (this.form.saleModel == 2) {
+        this.form.merchantClassifyId = "[217527]";
+        this.form.merchantClassifyName = "集采预售";
+      } else if (this.form.saleModel == 3) {
+        this.form.merchantClassifyId = "[217526]";
+        this.form.merchantClassifyName = "团批秒杀";
+      } else if (this.form.saleModel == 4) {
+        this.form.merchantClassifyId = "[217528]";
+        this.form.merchantClassifyName = "清库专区";
+      } else if (this.form.saleModel == 5) {
+        this.form.merchantClassifyId = "[217525]";
+        this.form.merchantClassifyName = "新店福利";
+      }
+      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/shipping/index" });
+        } else {
+          this.btnLading = false;
+        }
+      });
+    },
+    updateValue(val) {
+      this.form = { ...this.form, ...val };
+      console.log(this.form);
+      this.headerImg = [];
+      if (val.vid || this.form.vid) {
+        this.headerImg.push({
+          type: "video",
+          src: val.vid ? val.vid : this.form.vid,
+          sort: 1,
+        });
+      }
+      if (this.form?.bannerList && this.form?.bannerList.length > 0) {
+        this.form.bannerList.forEach((e, index) => {
+          this.headerImg.push({
+            type: "img",
+            src: e.fileUrl,
+            sort: index + 4,
+          });
+        });
+      }
+
+      this.headerImg.sort((a, b) => a.sort - b.sort); //排序 视频在最前面>封面>商品banner
+    },
+    unique(arr) {
+      const res = new Map();
+      return arr.filter((arr) => !res.has(arr.src) && res.set(arr.src, 1));
+    },
+  },
+};
+</script>
+
+<style>
+.required {
+  color: red;
+}
+.el-upload-list__item {
+  width: 60px !important;
+  height: 60px !important;
+}
+.el-upload--picture-card {
+  width: 80px;
+  height: 80px;
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: center;
+}
+.tips {
+  font-size: 12px;
+  color: red;
+}
+</style>
+<style scoped>
+.card {
+  /* height: 85px; */
+  width: 95%;
+  background: white;
+  margin: auto;
+  border-radius: 10px;
+  line-height: 30px;
+  padding: 10px;
+}
+.spuName {
+  text-decoration: none;
+  font-weight: bold;
+  word-wrap: normal;
+  font-size: 18px;
+  color: #333333;
+}
+.price_group {
+  color: #ff2f2f;
+}
+.price {
+  text-decoration: none;
+  font-weight: bold;
+  word-wrap: normal;
+  font-size: 25px;
+  color: #ff2f2f;
+}
+.price_info {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+}
+.ys {
+  font-size: 14px;
+}
+</style>

+ 36 - 0
src/views/shipping/index.vue

@@ -0,0 +1,36 @@
+<template>
+  <div class="app-container">
+    <el-tabs v-model="activeName" @tab-click="handleClick">
+      <el-tab-pane label="全部商品" :name="1">
+        <allProduct></allProduct>
+      </el-tab-pane>
+      <el-tab-pane label="草稿箱" :name="2">
+        <draftProduct></draftProduct>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+import allProduct from "./list/allProduct.vue";
+import draftProduct from "./list/draftProduct.vue";
+export default {
+  components: {
+    allProduct,
+    draftProduct,
+  },
+  name: "product",
+  data() {
+    return {
+      activeName: 1,
+    };
+  },
+  mounted() {},
+  methods: {},
+};
+</script>
+<style>
+.el-form-item {
+  margin-bottom: 10px;
+}
+</style>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1197 - 0
src/views/shipping/list/allProduct.vue


+ 296 - 0
src/views/shipping/list/draftProduct.vue

@@ -0,0 +1,296 @@
+<template>
+  <div class="app-container">
+    <el-form
+      :model="queryParams"
+      ref="queryForm"
+      size="small"
+      :inline="true"
+      label-width="80px"
+    >
+      <el-form-item label="商品名称" prop="title">
+        <el-input
+          v-model="queryParams.title"
+          placeholder="请输入商品名称"
+          clearable
+          style="width: 240px"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+
+      <el-form-item>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
+          >搜索</el-button
+        >
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+          >重置</el-button
+        >
+      </el-form-item>
+    </el-form>
+    <el-col :span="1.5">
+      <el-button
+        type="danger"
+        :disabled="multipleSelection.length < 1"
+        plain
+        size="mini"
+        @click="handleRemoves"
+        >批量删除</el-button
+      >
+    </el-col>
+
+    <el-table
+      v-loading="loading"
+      :data="configList"
+      @selection-change="handleSelectionChange"
+      row-key="goodsDraftId"
+    >
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="商品图片" align="center">
+        <template slot-scope="scope">
+          <el-image
+            style="width: 60px; height: 60px"
+            :src="scope.row.pic"
+            :preview-src-list="[scope.row.pic]"
+          >
+          </el-image>
+        </template>
+      </el-table-column>
+      <el-table-column label="商品名称" align="center">
+        <template slot-scope="scope">
+          {{ scope.row.title }}
+        </template>
+      </el-table-column>
+      <el-table-column label="分类" align="center">
+        <template slot-scope="scope">
+          {{ scope.row.categoryName }}
+        </template>
+      </el-table-column>
+      <el-table-column label="价格" align="center">
+        <template slot-scope="scope">
+          {{
+            scope.row.skuList ? scope.row.skuList[0].skuPriceList[0].price : ""
+          }}/{{ scope.row.unit }}
+        </template>
+      </el-table-column>
+
+      <el-table-column label="起批量" align="center">
+        <template slot-scope="scope">
+          {{
+            scope.row.skuList
+              ? scope.row.skuList[0].skuPriceList[0].minPurchase
+              : ""
+          }}{{ scope.row.unit }}
+        </template>
+      </el-table-column>
+      <el-table-column label="库存" align="center">
+        <template slot-scope="scope">
+          {{
+            scope.row.skuList
+              ? scope.row.skuList[0].stock + "/" + scope.row.unit
+              : ""
+          }}
+        </template>
+      </el-table-column>
+      <el-table-column label="经营区域" align="center">
+        <template slot-scope="scope">
+          {{
+            scope.row.scope == 0
+              ? "全国"
+              : scope.row.scope == 1
+              ? "同城"
+              : "特价"
+          }}
+        </template>
+      </el-table-column>
+      <el-table-column label="销售方式" align="center">
+        <template slot-scope="scope">
+          <span v-if="scope.row.scope == 0">
+            {{ scope.row.saleType == 1 ? "现货" : "预售" }}
+          </span>
+          <span v-else> </span>
+        </template>
+      </el-table-column>
+
+      <el-table-column
+        label="操作"
+        align="center"
+        class-name="small-padding fixed-width"
+        width="200"
+      >
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['manage:order:detail']"
+            >编辑商品</el-button
+          >
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            style="color: red"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['manage:order:detail']"
+            >删除</el-button
+          >
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import {
+  deleteGoodsDraft,
+  getGoodsDraftByUserId,
+  deleteGoodsDrafts,
+} from "@/api/manage/product";
+import { getStoreInfo } from "@/api/common/index";
+export default {
+  name: "product",
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      configList: [],
+      // 查询参数
+      multipleSelection: [],
+      queryParams: {
+        pageNo: 1,
+        pageSize: 10,
+        title: "",
+        spuType: 0,
+      },
+      // 表单参数
+      form: {},
+      shopInfo: {},
+    };
+  },
+  mounted() {
+    this.getList();
+    this.getInfo();
+  },
+  methods: {
+    getInfo() {
+      getStoreInfo().then((res) => {
+        if (res.code == 200) {
+          this.shopInfo = res.data;
+        }
+      });
+    },
+    /** 查询参数列表 */
+    getList() {
+      this.loading = true;
+      this.configList = [];
+      getGoodsDraftByUserId(this.queryParams).then((res) => {
+        for (let index = 0; index < res.data.length; index++) {
+          res.data[index] = res.data[index].goodsDto;
+          this.configList.push(res.data[index]);
+        }
+        // this.configList = res.data;
+        console.log("1231231", this.configList);
+
+        this.loading = false;
+      });
+    },
+    handleDelete(record) {
+      this.$confirm("是否确认删除该商品?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          deleteGoodsDraft({
+            id: record.goodsDraftId,
+          }).then((res) => {
+            if (res.code == 200) {
+              this.$message.success(`删除成功!`);
+              this.getList();
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消操作",
+          });
+        });
+    },
+    handleRemoves() {
+      this.$confirm("是否确认批量删除草稿箱?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          let ids = [];
+
+          for (let index = 0; index < this.multipleSelection.length; index++) {
+            console.log("xzcz", this.multipleSelection[index]);
+            ids.push(this.multipleSelection[index].goodsDraftId);
+          }
+          deleteGoodsDrafts({
+            ids: ids.toString(),
+          }).then((res) => {
+            if (res.code == 200) {
+              this.$message.success(`删除成功!`);
+              this.getList();
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消操作",
+          });
+        });
+    },
+    handleSelectionChange(val) {
+      console.log(val);
+      this.multipleSelection = val;
+    },
+
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {};
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNo = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    handleUpdate(record) {
+      let params = {
+        id: record.goodsDraftId,
+        type: "draft",
+      };
+      window.localStorage.setItem("productInfo", JSON.stringify(params));
+      this.$router.push({
+        path: "/product/shipping/updateProduct",
+        query: { params },
+      });
+    },
+  },
+};
+</script>
+<style>
+.el-form-item {
+  margin-bottom: 10px;
+}
+</style>

+ 295 - 0
src/views/shipping/lookProduct.vue

@@ -0,0 +1,295 @@
+<template>
+  <el-dialog
+    :visible.sync="dialogVisible"
+    width="20%"
+    :before-close="closeDialog"
+    custom-class="phone"
+    :destroy-on-close="true"
+  >
+    <phoneView>
+      <div slot="conts">
+        <div>
+          <el-carousel height="200px">
+            <el-carousel-item v-for="(item, index) in headerImg" :key="index">
+              <el-image
+                v-if="item.type == 'img'"
+                style="width: 100%; height: 200px"
+                :src="item.src"
+                :preview-src-list="[item.src]"
+              >
+              </el-image>
+              <video
+                v-if="item.type == 'video'"
+                :key="index"
+                controls
+                :src="item.src"
+                style="width: 100%; height: 200px"
+              ></video>
+            </el-carousel-item>
+          </el-carousel>
+        </div>
+        <img
+          style="width: 100%"
+          src="https://bucket.sxdirectpurchase.com/fileUpload/test/47fc6132-0b3e-4b5c-b858-f78d363eba90.png"
+          alt=""
+        />
+        <div class="card">
+          <div class="spuName">{{ form ? form.title : "" }}</div>
+          <div class="price_info">
+            <div class="price_group">
+              <span>¥</span
+              ><span class="price"
+                >{{
+                  form.skuList
+                    ? form.skuList[0].skuPriceList
+                      ? form.skuList[0].skuPriceList[0].price
+                      : 0
+                    : 0
+                }}元</span
+              ><span>/{{ form.unit }}</span>
+            </div>
+            <span class="ys">已售 0</span>
+          </div>
+        </div>
+        <div class="card" style="margin-top: 10px">
+          <div class="spuName">规格/价格</div>
+          <div v-for="(item, index) in form.skuList" :key="index">
+            <div class="price_info">
+              <span
+                >{{ item.skuSpecsList ? item.skuSpecsList[0].specsName : "" }}
+                {{ item.skuSpecsList ? item.skuSpecsList[0].specsValue : "" }}</span
+              >
+            </div>
+            <div
+              style="display: flex; flex-direction: row; justify-content: space-between"
+            >
+              <span style="font-size: 14px; color: red">
+                <span>¥</span>
+                <span>{{ item.skuPriceList ? item.skuPriceList[0].price : 0 }}元</span
+                ><span>/{{ form.unit }}</span></span
+              >
+              <span style="font-size: 14px"
+                >{{ item.skuPriceList ? item.skuPriceList[0].minPurchase : 0 }}/{{
+                  form.unit
+                }}起购</span
+              >
+              <span style="font-size: 14px">库存:{{ item.stock }}{{ form.unit }}</span>
+            </div>
+          </div>
+        </div>
+        <div class="card" style="margin-top: 10px">
+          <el-form
+            :model="form"
+            ref="queryForm"
+            size="small"
+            :inline="true"
+            label-width="80px"
+            label-position="left"
+          >
+            <el-row>
+              <el-col :span="24">
+                <el-form-item label="发货地" prop="spuName">
+                  <div style="width: 185px">
+                    {{ form.shippingAddrBean ? form.shippingAddrBean.addr : "" }}
+                    {{ form.shippingAddrBean ? form.shippingAddrBean.addrDetail : "" }}
+                  </div>
+                </el-form-item>
+              </el-col>
+              <el-col :span="24">
+                <el-form-item label="发货时间" prop="spuName">
+                  {{ form.shippingTimeDesc }}
+                </el-form-item>
+              </el-col>
+              <el-col :span="24">
+                <el-form-item label="商品属性" prop="spuName">
+                  <div>查看></div>
+                </el-form-item>
+              </el-col>
+              <el-col :span="24">
+                <el-form-item label="包装方式" prop="spuName">
+                  {{ form.packing }}
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form>
+        </div>
+        <div class="card" style="margin-top: 10px">
+          <div
+            style="
+              display: flex;
+              flex-direction: row;
+              justify-content: space-between;
+              align-items: center;
+            "
+          >
+            <span class="spuName">商品评价</span>
+            <span>好评率 <span style="color: red">100%</span></span>
+          </div>
+          <div
+            style="
+              display: flex;
+              flex-direction: column;
+              justify-content: center;
+              align-items: center;
+            "
+          >
+            <img
+              style="width: 40%"
+              src="https://directpurchase-oss-dev.oss-cn-chengdu.aliyuncs.com/wx/static/images/kong.png"
+              alt=""
+            />
+            <span>还没有评价~</span>
+          </div>
+        </div>
+        <div class="card" style="margin-top: 10px">
+          <div class="spuName">商品介绍</div>
+          <div style="font-size: 14px; line-height: 25px">
+            {{ form.spuDesc }}
+          </div>
+        </div>
+        <div class="card" style="margin-top: 10px">
+          <div class="spuName">商品详情</div>
+          <div style="font-size: 14px; line-height: 25px">
+            <el-image
+              v-for="(item, index) in form.spuDetailList"
+              :key="index"
+              :src="item.fileUrl"
+              fit="fill"
+              :preview-src-list="[item.fileUrl]"
+            >
+            </el-image>
+          </div>
+          <div style="font-size: 14px; line-height: 25px">
+            <el-image
+              v-for="(item, index) in form.specialList"
+              :key="index"
+              :src="item.fileUrl"
+              fit="fill"
+              :preview-src-list="[item.fileUrl]"
+            >
+            </el-image>
+          </div>
+        </div>
+      </div>
+    </phoneView>
+  </el-dialog>
+</template>
+
+<script>
+import phoneView from "@/components/phoneView/index.vue";
+export default {
+  components: { phoneView },
+  data() {
+    return {
+      dialogVisible: false,
+      form: {},
+      headerImg: [],
+    };
+  },
+  methods: {
+    openDialog(record) {
+      this.form = record;
+      this.headerImg = [];
+      if (this.form.vid) {
+        this.headerImg.push({
+          type: "video",
+          src: this.form.vid,
+          sort: 1,
+        });
+      }
+      if (this.form.pic) {
+        this.headerImg.push({
+          type: "img",
+          src: this.form.pic,
+          sort: 2,
+        });
+      }
+      this.headerImg = this.unique(this.headerImg);
+      if (this.form.bannerList) {
+        this.form.bannerList.forEach((e, index) => {
+          this.headerImg.push({
+            type: "img",
+            src: e.fileUrl,
+            sort: index + 4,
+          });
+        });
+      }
+      this.headerImg.sort((a, b) => a.sort - b.sort); //排序 视频在最前面>封面>商品banner
+      this.dialogVisible = true;
+    },
+    unique(arr) {
+      const res = new Map();
+      return arr.filter((arr) => !res.has(arr.src) && res.set(arr.src, 1));
+    },
+    closeDialog() {
+      this.dialogVisible = false;
+    },
+  },
+};
+</script>
+<style scoped>
+/deep/ .el-dialog {
+  background: transparent !important;
+  /* margin: 0px !important; */
+  box-shadow: none !important;
+  padding: 0px !important;
+}
+/deep/ .el-dialog__body {
+  margin: 0px !important;
+  padding: 0px !important;
+}
+/deep/ .el-dialog__header {
+  margin: 0px !important;
+  padding: 0px !important;
+}
+/deep/ .phone {
+  margin: auto;
+}
+/* .phone /deep/ .el-dialog__headerbtn {
+  border-radius: 50%;
+  width: 30px !important;
+  height: 30px !important;
+  background: #fff !important;
+  top: -5px !important;
+  right: 6px !important;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+} */
+.card {
+  /* height: 85px; */
+  width: 95%;
+  background: white;
+  margin: auto;
+  border-radius: 10px;
+  line-height: 30px;
+  padding: 10px;
+}
+.spuName {
+  text-decoration: none;
+  font-weight: bold;
+  word-wrap: normal;
+  font-size: 18px;
+  color: #333333;
+}
+.price_group {
+  color: #ff2f2f;
+}
+.price {
+  text-decoration: none;
+  font-weight: bold;
+  word-wrap: normal;
+  font-size: 25px;
+  color: #ff2f2f;
+}
+.price_info {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+}
+.ys {
+  font-size: 14px;
+}
+</style>

+ 494 - 0
src/views/shipping/module/basic-info.vue

@@ -0,0 +1,494 @@
+<template>
+  <el-form
+    :model="form"
+    ref="queryForm"
+    size="small"
+    :inline="true"
+    label-width="120px"
+    :rules="rules"
+  >
+    <el-row>
+      <el-col :span="24">
+        <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">
+        <el-form-item prop="categoryId">
+          <span slot="label">商品分类</span>
+          <el-cascader
+            :filterable="true"
+            v-model="form.categoryId"
+            ref="formCascader"
+            :placeholder="categoryName ? categoryName : '请选择分类'"
+            :props="categoryprops"
+            @change="cascaderChange"
+          />
+        </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 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">
+        <el-form-item label="商品视频">
+          <span class="tips">上传视频用户看的更直接</span>
+          <el-upload
+            list-type="picture-card"
+            :show-file-list="false"
+            :http-request="(data) => requestUpload(data, 'video')"
+            :limit="1"
+            action="#"
+            accept=".mp4"
+            ref="files"
+          >
+            <video
+              v-if="form.vid"
+              controls
+              :src="form.vid"
+              style="width: 80px; height: 80px"
+            ></video>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <el-form-item prop="bannerList">
+          <span slot="label">商品图</span>
+          <span class="tips"
+            >图片要求:大小3M内,至多可上传11张,第一张图默认为商品封面图</span
+          >
+          <div style="display: flex; flex-direction: row; align-items: center">
+            <draggable
+              style="display: flex; flex-direction: row; align-items: center"
+              v-model="bannerList"
+              group="people"
+              @change="draggableChange"
+            >
+              <div
+                class="item"
+                v-for="(item, index) in this.bannerList"
+                :key="index"
+              >
+                <div class="fmt" v-if="index == 0">封面图</div>
+                <div class="gb" @click="removeImg(index)">X</div>
+                <img
+                  :src="item.url || item.fileUrl"
+                  style="width: 70px; height: 70px; border-radius: 10px"
+                />
+              </div>
+            </draggable>
+            <el-upload
+              list-type="picture-card"
+              :file-list="bannerList"
+              :before-remove="requestRemove"
+              :http-request="(data) => requestUpload(data, 'banner')"
+              :show-file-list="false"
+              :before-upload="beforeAvatarUpload"
+              :limit="11"
+              action="#"
+              :multiple="true"
+              accept=".png,.jpg,.jpeg"
+              ref="files"
+            >
+              <i class="el-icon-plus avatar-uploader-icon"></i>
+            </el-upload>
+          </div>
+        </el-form-item>
+      </el-col>
+    </el-row>
+  </el-form>
+</template>
+
+<script>
+import draggable from "vuedraggable";
+import { getStoreInfo } from "@/api/common/index";
+import { getClassificationListPage } from "@/api/common/index.js";
+import { getToken } from "@/utils/auth";
+import axios from "axios";
+import moment from "moment";
+export default {
+  props: ["data"],
+  components: { draggable },
+  data() {
+    return {
+      form: {
+        carpoolSuccessTime: "",
+        scope: 1,
+        saleType: 3,
+        saleModel: undefined,
+        categoryId: "",
+        title: "",
+        giftDesc: "",
+        vid: "",
+        bannerList: [],
+        pic: "",
+        categoryName: "",
+        categoryIds: [],
+        datePicker: [],
+        presaleStartTime: "",
+        presaleEndTime: "",
+      },
+      bannerList: [],
+      headers: {
+        Auth: "Bearer " + getToken(),
+        "Content-type": "multipart/form-data",
+      },
+      categoryprops: {
+        checkStrictly: true,
+        lazy: true,
+        lazyLoad: this.categoryLazyLoad,
+        label: "label",
+        value: "value",
+      },
+      rules: {
+        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" },
+        ],
+        bannerList: [
+          {
+            required: true,
+            message: "商品图最低上传两张图片",
+            trigger: "blur",
+          },
+        ],
+        carpoolSuccessTime: [
+          { required: true, message: "拼车成功时间不能为空", trigger: "blur" },
+        ],
+        datePicker: [
+          { required: true, message: "预售时间不能为空", trigger: "blur" },
+        ],
+      },
+      index: 0,
+      shopInfo: {},
+      categoryName: "",
+      radio: "",
+      actionType: "",
+    };
+  },
+  created() {
+    this.getInfo();
+  },
+
+  methods: {
+    getFormInfo(record, type) {
+      // 重置表单基础数据
+      this.actionType = type === "cg" ? "" : "edit";
+      this.form.datePicker = [];
+      // 解构赋值与默认值处理
+      const {
+        categoryId,
+        categoryIds,
+        carpoolSuccessTime,
+        scope,
+        saleType,
+        saleModel,
+        title,
+        giftDesc,
+        vid,
+        bannerList = [],
+        pic,
+        categoryName,
+        presaleStartTime,
+        presaleEndTime,
+      } = record || {};
+      // 更新表单数据
+      this.form = {
+        ...this.form,
+        categoryId,
+        categoryIds,
+        carpoolSuccessTime,
+        scope,
+        saleType,
+        saleModel,
+        title,
+        giftDesc,
+        vid,
+        bannerList,
+        pic,
+        categoryName,
+        presaleStartTime: presaleStartTime
+          ? moment(presaleStartTime).format("yyyy-MM-DD HH:mm:ss")
+          : "",
+        presaleEndTime: presaleEndTime
+          ? moment(presaleEndTime).format("yyyy-MM-DD HH:mm:ss")
+          : "",
+      };
+
+      // 更新日期选择器
+      if (presaleStartTime && presaleEndTime) {
+        this.$nextTick(() => {
+          this.$set(this.form, "datePicker", [
+            this.form.presaleStartTime,
+            this.form.presaleEndTime,
+          ]);
+        });
+      }
+      // 更新轮播图列表(优化添加逻辑)
+      this.bannerList = [...bannerList];
+      if (pic) {
+        this.bannerList.unshift({
+          fileUrl: pic,
+          sort: 1,
+        });
+      }
+      // 触发强制更新(尽量避免使用)
+      // this.$forceUpdate();
+    },
+
+    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, row) => {
+          if (valid) {
+            resolve(valid);
+          } else {
+            for (const key in row) {
+              for (let index = 0; index < row[key].length; index++) {
+                this.$message.error(row[key][index].message);
+                return;
+              }
+            }
+            resolve(valid);
+          }
+        });
+      });
+    },
+
+    removeImg(index) {
+      this.bannerList.splice(index, 1);
+      this.passValue();
+    },
+    pickerChange(val) {
+      this.form.presaleStartTime = moment(this.form.datePicker[0]).valueOf();
+      this.form.presaleEndTime = moment(this.form.datePicker[1]).valueOf();
+      this.passValue();
+    },
+    getInfo() {
+      getStoreInfo().then((res) => {
+        if (res.code == 200) {
+          this.shopInfo = res.data;
+          this.form.scope = res.data.scope;
+          if (res.data.scope == 1) {
+            this.form.saleType = 0;
+            this.form.saleModel = 1;
+          }
+        }
+      });
+    },
+    draggableChange() {
+      this.passValue();
+    },
+
+    passValue() {
+      this.form.bannerList = [];
+      this.form.presaleStartTime = moment(this.form.datePicker[0]).valueOf();
+      this.form.presaleEndTime = moment(this.form.datePicker[1]).valueOf();
+      if (this.bannerList.length > 0) {
+        console.log("bannerList", this.bannerList);
+        for (let index = 0; index < this.bannerList.length; index++) {
+          this.form.bannerList.push({
+            fileUrl:
+              this.bannerList[index].url || this.bannerList[index].fileUrl,
+            sort: this.bannerList[index].name,
+          });
+        }
+        this.form.pic = this.bannerList[0].url || this.bannerList[0].fileUrl;
+        if (this.form.pic) {
+          this.form.bannerList.shift();
+        }
+      } else {
+        this.form.pic = "";
+      }
+      this.$emit("updateValue", this.form);
+    },
+
+    requestRemove(val, list, index) {
+      this.bannerList.forEach((e, index) => {
+        if (e.uid == val.uid) {
+          this.bannerList.splice(index, 1);
+        }
+      });
+      this.passValue();
+    },
+    cascaderChange(val) {
+      this.$nextTick(() => {
+        const dom = document.getElementsByClassName("el-radio is-checked");
+        //这里我把dom打出来看了 最后一个选项才是我选中的节点 即[length-1] 有的博主写的是 第一个元素 即[0] 大家自行尝试
+        let radioDom = dom[dom.length - 1];
+        const brother = radioDom.nextElementSibling;
+        brother.click();
+        let nodes = this.$refs.formCascader.getCheckedNodes();
+        this.form.categoryName = nodes[0].label;
+        this.form.categoryIds = val;
+        this.form.categoryIds = JSON.stringify(this.form.categoryIds);
+        this.passValue();
+      });
+    },
+    categoryLazyLoad(node, resolve) {
+      let level = node.level;
+      if (!node.data) {
+        getClassificationListPage({ parentId: 0 }).then((res) => {
+          //接口
+          const nodes = Array.from(res.data).map((item, index) => ({
+            value: item.id,
+            label: `${item.className}`,
+            leaf: level >= 2,
+          }));
+          // 通过调用resolve将子节点数据返回,通知组件数据加载完成
+          resolve(nodes);
+        });
+      } else if (level == 1) {
+        getClassificationListPage({ parentId: node.data.value }).then((res) => {
+          const nodes = Array.from(res.data).map((item) => ({
+            value: item.id,
+            label: `${item.className}`,
+            leaf: level >= 2,
+            // level: 2,
+          }));
+          // 通过调用resolve将子节点数据返回,通知组件数据加载完成
+          resolve(nodes);
+        });
+      } else if (level == 2) {
+        getClassificationListPage({ parentId: node.data.value }).then((res) => {
+          const nodes = Array.from(res.data).map((item) => ({
+            value: item.id,
+            label: `${item.className}`,
+            leaf: level >= 1,
+            level: 1,
+          }));
+          // 通过调用resolve将子节点数据返回,通知组件数据加载完成
+          resolve(nodes);
+        });
+      } else {
+        resolve({});
+      }
+    },
+
+    // 可以获取图片参数
+    async requestUpload(data, type) {
+      const formdata = new FormData();
+      formdata.append("file", data.file);
+      const res = await axios.post(
+        `${process.env.VUE_APP_NSY_UPLOAD_API}/api/third/op/v1/third/uploadPic`,
+        formdata,
+        {
+          headers: this.headers,
+        }
+      );
+      if (res.data.data) {
+        if (type == "video") {
+          this.form.vid = res.data.data;
+        } else if (type == "banner") {
+          this.bannerList.push({
+            name: this.index,
+            url: res.data.data,
+          });
+          this.index++;
+        }
+        this.passValue();
+        this.$forceUpdate();
+      }
+    },
+  },
+};
+</script>
+
+<style>
+/* .el-cascader-panel
+  > .el-scrollbar:first-child
+  > .el-cascader-menu__wrap
+  > .el-cascader-menu__list
+  > .el-cascader-node
+  > .el-radio {
+  display: none;
+} */
+/* .el-cascader-menu__wrap > .el-cascader-menu__list > .el-cascader-node > .el-radio {
+    display: none;
+  } */
+</style>
+
+<style scoped>
+.item {
+  position: relative;
+  margin-right: 10px;
+}
+.gb {
+  position: absolute;
+  left: 59px;
+  top: -8px;
+  cursor: pointer;
+}
+.fmt {
+  border-bottom-left-radius: 10px;
+  border-bottom-right-radius: 10px;
+  position: absolute;
+  width: 70px;
+  height: 20px;
+  background: #0000003d;
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: center;
+  color: #fff;
+  bottom: 10px;
+}
+</style>

+ 610 - 0
src/views/shipping/updateProduct.vue

@@ -0,0 +1,610 @@
+<template>
+  <div class="app-container">
+    <div style="width: 100%; height: 85vh; overflow: auto">
+      <el-row style="padding-top: 20px">
+        <el-col :span="24">
+          <el-descriptions title="基本信息" column="1"> </el-descriptions>
+          <basicInfo ref="basicRefs" @updateValue="updateValue"></basicInfo>
+          <el-descriptions title="销售信息" column="1"> </el-descriptions>
+          <salesInfo
+            ref="salesRefs"
+            @updateValue="updateValue"
+            @skuRemove="skuRemove"
+            :saleModels="form.saleModel"
+          ></salesInfo>
+          <el-descriptions title="商品详情" column="1"> </el-descriptions>
+          <productInfo
+            ref="productRefs"
+            @updateValue="updateValue"
+          ></productInfo>
+
+          <div class="dialog-footer" style="text-align: center">
+            <el-button @click="submitCancel">取 消</el-button>
+            <el-button type="primary" @click="submitForm" :loading="btnLading"
+              >发 布</el-button
+            >
+            <el-button
+              type="primary"
+              @click="submitFormDraft"
+              v-if="$route.query.params.type == 'draft'"
+              >存入草稿箱</el-button
+            >
+          </div>
+        </el-col>
+        <phoneView style="position: absolute; bottom: 50px; right: 50px">
+          <div slot="conts">
+            <div>
+              <el-carousel height="200px">
+                <el-carousel-item
+                  v-for="(item, index) in headerImg.slice(1)"
+                  :key="index"
+                >
+                  <el-image
+                    v-if="item.type == 'img'"
+                    style="width: 100%; height: 200px"
+                    :src="item.src"
+                    :preview-src-list="[item.src]"
+                  >
+                  </el-image>
+                  <video
+                    v-if="item.type == 'video'"
+                    :key="index"
+                    controls
+                    :src="item.src"
+                    style="width: 100%; height: 200px"
+                  ></video>
+                </el-carousel-item>
+              </el-carousel>
+            </div>
+            <img
+              style="width: 100%"
+              src="https://bucket.sxdirectpurchase.com/fileUpload/test/47fc6132-0b3e-4b5c-b858-f78d363eba90.png"
+              alt=""
+            />
+            <div class="card">
+              <div class="spuName">{{ form ? form.title : "" }}</div>
+              <div class="price_info">
+                <div class="price_group">
+                  <span>¥</span>
+                  <span
+                    class="price"
+                    :key="item"
+                    v-for="item in form.skuList ? form.skuList.slice(0, 1) : []"
+                    >{{
+                      item.skuPriceList ? item.skuPriceList[0].price : 0
+                    }}元</span
+                  >
+
+                  <span>/{{ form.unit }}</span>
+                </div>
+                <span class="ys">已售 0</span>
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div class="spuName">规格/价格</div>
+              <div v-for="(item, index) in form.skuList" :key="index">
+                <div class="price_info">
+                  <span
+                    >{{
+                      item.skuSpecsList[0] ? item.skuSpecsList[0].specsName : ""
+                    }}
+                    {{
+                      item.skuSpecsList[0].specsValue
+                        ? item.skuSpecsList[0].specsValue
+                        : ""
+                    }}</span
+                  >
+                </div>
+                <div
+                  style="
+                    display: flex;
+                    flex-direction: row;
+                    justify-content: space-between;
+                  "
+                >
+                  <span style="font-size: 14px; color: red">
+                    <span>¥</span>
+                    <span
+                      >{{
+                        item.skuPriceList
+                          ? item.skuPriceList[0].price
+                            ? item.skuPriceList[0].price
+                            : ""
+                          : ""
+                      }}元</span
+                    ><span>/{{ form.unit }}</span></span
+                  >
+                  <span style="font-size: 14px"
+                    >{{
+                      item.skuPriceList
+                        ? item.skuPriceList[0].minPurchase
+                          ? item.skuPriceList[0].minPurchase
+                          : ""
+                        : ""
+                    }}/{{ form.unit }}起购</span
+                  >
+                  <span style="font-size: 14px"
+                    >库存:{{ item.stock + item.predictStocks
+                    }}{{ form.unit }}</span
+                  >
+                </div>
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <el-form
+                :model="form"
+                ref="queryForm"
+                size="small"
+                :inline="true"
+                label-width="80px"
+                label-position="left"
+              >
+                <el-row>
+                  <el-col :span="24">
+                    <el-form-item label="发货地" prop="spuName">
+                      <div style="width: 185px">
+                        {{
+                          form.shippingAddrBean
+                            ? form.shippingAddrBean.addr
+                            : ""
+                        }}
+                        {{
+                          form.shippingAddrBean
+                            ? form.shippingAddrBean.addrDetail
+                              ? form.shippingAddrBean.addrDetail
+                              : ""
+                            : ""
+                        }}
+                      </div>
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="24">
+                    <el-form-item label="发货时间" prop="spuName">
+                      {{ form.shippingTimeDesc }}
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="24">
+                    <el-form-item label="商品属性" prop="spuName">
+                      <div>查看></div>
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="24">
+                    <el-form-item label="包装方式" prop="spuName">
+                      {{ form.packing }}
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+              </el-form>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div
+                style="
+                  display: flex;
+                  flex-direction: row;
+                  justify-content: space-between;
+                  align-items: center;
+                "
+              >
+                <span class="spuName">商品评价</span>
+                <span>好评率 <span style="color: red">100%</span></span>
+              </div>
+              <div
+                style="
+                  display: flex;
+                  flex-direction: column;
+                  justify-content: center;
+                  align-items: center;
+                "
+              >
+                <img
+                  style="width: 40%"
+                  src="https://directpurchase-oss-dev.oss-cn-chengdu.aliyuncs.com/wx/static/images/kong.png"
+                  alt=""
+                />
+                <span>还没有评价~</span>
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div class="spuName">商品介绍</div>
+              <div style="font-size: 14px; line-height: 25px">
+                {{ form.spuDesc }}
+              </div>
+            </div>
+            <div class="card" style="margin-top: 10px">
+              <div class="spuName">商品详情</div>
+              <div style="font-size: 14px; line-height: 25px">
+                <el-image
+                  v-for="(item, index) in form.spuDetailList"
+                  :key="index"
+                  :src="item.fileUrl"
+                  fit="fill"
+                  :preview-src-list="[item.fileUrl]"
+                >
+                </el-image>
+              </div>
+              <div style="font-size: 14px; line-height: 25px">
+                <el-image
+                  v-for="(item, index) in form.specialList"
+                  :key="index"
+                  :src="item.fileUrl"
+                  fit="fill"
+                  :preview-src-list="[item.fileUrl]"
+                >
+                </el-image>
+              </div>
+            </div>
+          </div>
+        </phoneView>
+      </el-row>
+    </div>
+
+    <Amap></Amap>
+  </div>
+</template>
+
+<script>
+import { publishGoods } from "@/api/publish/index";
+import { getStoreInfo } from "@/api/common/index";
+import {
+  saveGoodsDraft,
+  updateGoods,
+  getGoodsInfo,
+  getGoodsDraftById,
+  removeSkuBySkuId,
+} from "@/api/manage/product";
+import basicInfo from "./module/basic-info.vue";
+import productInfo from "@/views/product/module/product-info.vue";
+import salesInfo from "@/views/product/module/sales-info.vue";
+import phoneView from "@/components/phoneView/index.vue";
+import Amap from "@/components/Map/map.vue";
+import moment from "moment";
+export default {
+  name: "updateProduct",
+  components: { Amap, phoneView, basicInfo, salesInfo, productInfo },
+  data() {
+    return {
+      form: {},
+      headerImg: [],
+      btnLading: false,
+      skulist: [],
+    };
+  },
+
+  created() {
+    window.addEventListener("beforeunload", function (e) {
+      this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
+      this.$router.replace({ path: "/product/shipping/index" });
+    });
+  },
+  mounted() {
+    this.getInfo();
+    if (
+      (this.$route.query.params != "[object Object]" &&
+        this.$route.query.params) ||
+      JSON.parse(localStorage.getItem("productInfo"))
+    ) {
+      let info = {};
+      if (
+        this.$route.query.params != "[object Object]" &&
+        this.$route.query.params
+      ) {
+        info = this.$route.query.params;
+      } else {
+        info = JSON.parse(localStorage.getItem("productInfo"));
+      }
+      if (info.type == "draft") {
+        this.form.goodsDraftId = info.id;
+        getGoodsDraftById({ goodsDraftId: info.id }).then((res) => {
+          if (res.code == 200) {
+            this.form = res.data.goodsDto;
+            this.form.goodsDraftId = info.id;
+            this.headerImg = [];
+            if (this.form.vid) {
+              this.headerImg.push({
+                type: "video",
+                src: this.form.vid,
+                sort: 1,
+              });
+            }
+            if (this.form.pic) {
+              this.headerImg.push({
+                type: "img",
+                src: this.form.pic,
+                sort: 2,
+              });
+            }
+            this.headerImg = this.unique(this.headerImg);
+            if (this.form.bannerList?.length > 0) {
+              this.form.bannerList.forEach((e, index) => {
+                this.headerImg.push({
+                  type: "img",
+                  src: e.fileUrl,
+                  sort: index + 4,
+                });
+              });
+            }
+            this.headerImg.sort((a, b) => a.sort - b.sort); //排序 视频在最前面>封面>商品banner
+            if (this.form.scope == 0) {
+              this.$refs.salesRefs.setShowCom(false);
+            } else if (this.form.saleType == 2 && this.form.scope == 0) {
+              this.$refs.salesRefs.setShowCom(false);
+            } else {
+              this.$refs.salesRefs.setShowCom(true);
+            }
+            this.$refs.basicRefs.getFormInfo(this.form, this.$route.query.type);
+            this.$refs.salesRefs.getFormInfo(this.form);
+            this.$refs.productRefs.getFormInfo(this.form);
+          }
+        });
+      } else {
+        getGoodsInfo({ spuId: info.id }).then((res) => {
+          if (res.code == 200) {
+            this.form = res.data;
+            this.headerImg = [];
+            if (this.form.vid) {
+              this.headerImg.push({
+                type: "video",
+                src: this.form.vid,
+                sort: 1,
+              });
+            }
+            if (this.form.pic) {
+              this.headerImg.push({
+                type: "img",
+                src: this.form.pic,
+                sort: 2,
+              });
+            }
+            this.headerImg = this.unique(this.headerImg);
+            if (this.form.bannerList?.length > 0) {
+              this.form.bannerList.forEach((e, index) => {
+                this.headerImg.push({
+                  type: "img",
+                  src: e.fileUrl,
+                  sort: index + 4,
+                });
+              });
+            }
+            this.headerImg.sort((a, b) => a.sort - b.sort); //排序 视频在最前面>封面>商品banner
+            if (this.form.scope == 0) {
+              this.$refs.salesRefs.setShowCom(false);
+            } else if (this.form.saleType == 2 && this.form.scope == 0) {
+              this.$refs.salesRefs.setShowCom(false);
+            } else {
+              this.$refs.salesRefs.setShowCom(true);
+            }
+            this.$refs.basicRefs.getFormInfo(this.form, this.$route.query.type);
+            this.$refs.salesRefs.getFormInfo(this.form);
+            this.$refs.productRefs.getFormInfo(this.form);
+          }
+        });
+      }
+    }
+  },
+  methods: {
+    skuRemove(list) {
+      this.skulist = list;
+    },
+    getInfo() {
+      getStoreInfo().then((res) => {
+        if (res.code == 200) {
+          if (res.data.scope == 0) {
+            if (this.form.saleType == 2) {
+              this.$refs.salesRefs.setShowCom(true);
+            } else {
+              this.$refs.salesRefs.setShowCom(false);
+            }
+          } else {
+            this.$refs.salesRefs.setShowCom(true);
+          }
+        }
+      });
+    },
+    submitCancel() {
+      this.$confirm("是否取消发布,所填写的信息将会消失?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
+          this.$router.replace({ path: "/product/shipping/index" });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+
+    submitFormDraft() {
+      if (!this.form.presaleStartTime && !this.form.presaleEndTime) {
+        if (this.form.datePicke) {
+          this.form.presaleStartTime = moment(
+            this.form.datePicker[0]
+          ).valueOf();
+          this.form.presaleEndTime = moment(this.form.datePicker[1]).valueOf();
+        }
+      }
+      if (this.form.categoryId?.length > 0) {
+        this.form.categoryId =
+          this.form.categoryId[this.form.categoryId.length - 1];
+      }
+      // if (this.form.bannerList?.length > 0) {
+      //   this.form.bannerList.shift();
+      // }
+      saveGoodsDraft(this.form).then((res) => {
+        if (res.code == 200) {
+          this.$message.success(`保存成功!请前往草稿箱查看`);
+          this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
+          this.$router.replace({ path: "/product/shipping/index" });
+        }
+      });
+    },
+    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;
+      }
+      if (this.form.skuList === "") {
+        this.$message.error(`商品规格不能为空`);
+        return;
+      }
+      if (!this.form.shippingAddrBean.provinceCode) {
+        this.$message.error(`请选择发货地址的省市区!`);
+        return;
+      }
+      this.btnLading = true;
+      if (!this.form.presaleStartTime && !this.form.presaleEndTime) {
+        if (this.form.datePicke) {
+          this.form.presaleStartTime = moment(
+            this.form.datePicker[0]
+          ).valueOf();
+          this.form.presaleEndTime = moment(this.form.datePicker[1]).valueOf();
+        }
+      }
+
+      if (this.form.categoryId?.length > 0) {
+        this.form.categoryId =
+          this.form.categoryId[this.form.categoryId.length - 1];
+      }
+
+      if (this.form.id) {
+        if (this.skulist?.length > 0) {
+          removeSkuBySkuId({ skuIds: this.skulist.toString() }).then(
+            (res) => {}
+          );
+        }
+        if (this.form.skuList.length < 1 || this.form.skuList === "") {
+          this.$message.error(`规格不能为空`);
+          return;
+        }
+        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/shipping/index" });
+          } else {
+            this.btnLading = false;
+          }
+        });
+      } else {
+        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/shipping/index" });
+          } else {
+            this.btnLading = false;
+          }
+        });
+      }
+    },
+    updateValue(val) {
+      this.form = { ...this.form, ...val };
+      if (this.form.saleType == 2) {
+        this.$refs.salesRefs.setShowCom(true);
+      } else if (this.form.scope == 0) {
+        this.$refs.salesRefs.setShowCom(false);
+      } else {
+        this.$refs.salesRefs.setShowCom(true);
+      }
+
+      this.headerImg = [];
+      if (val.vid || this.form.vid) {
+        this.headerImg.push({
+          type: "video",
+          src: val.vid ? val.vid : this.form.vid,
+          sort: 1,
+        });
+      }
+      if (this.form?.bannerList && this.form?.bannerList.length > 0) {
+        this.form.bannerList.forEach((e, index) => {
+          this.headerImg.push({
+            type: "img",
+            src: e.fileUrl,
+            sort: index + 4,
+          });
+        });
+      }
+      this.headerImg.sort((a, b) => a.sort - b.sort); //排序 视频在最前面>封面>商品banner
+    },
+    unique(arr) {
+      const res = new Map();
+      return arr.filter((arr) => !res.has(arr.src) && res.set(arr.src, 1));
+    },
+  },
+};
+</script>
+
+<style>
+.required {
+  color: red;
+}
+.el-upload-list__item {
+  width: 60px !important;
+  height: 60px !important;
+}
+.el-upload--picture-card {
+  width: 80px;
+  height: 80px;
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: center;
+}
+.tips {
+  font-size: 12px;
+  color: red;
+}
+</style>
+<style scoped>
+.card {
+  /* height: 85px; */
+  width: 95%;
+  background: white;
+  margin: auto;
+  border-radius: 10px;
+  line-height: 30px;
+  padding: 10px;
+}
+.spuName {
+  text-decoration: none;
+  font-weight: bold;
+  word-wrap: normal;
+  font-size: 18px;
+  color: #333333;
+}
+.price_group {
+  color: #ff2f2f;
+}
+.price {
+  text-decoration: none;
+  font-weight: bold;
+  word-wrap: normal;
+  font-size: 25px;
+  color: #ff2f2f;
+}
+.price_info {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+}
+.ys {
+  font-size: 14px;
+}
+</style>

+ 1 - 1
src/views/transmission/list/allProduct.vue

@@ -479,7 +479,7 @@ export default {
         spuStatus: "",
         saleType: "",
         scope: "",
-        spuType: 1,
+        spuType: 3,
       },
       // 表单参数
       form: {},

+ 9 - 3
src/views/transmission/list/draftProduct.vue

@@ -18,10 +18,16 @@
       </el-form-item>
 
       <el-form-item>
-        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
           >搜索</el-button
         >
-        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+          >重置</el-button
+        >
       </el-form-item>
     </el-form>
     <el-col :span="1.5">
@@ -159,7 +165,7 @@ export default {
         pageNo: 1,
         pageSize: 10,
         title: "",
-        spuType: 1,
+        spuType: 3,
       },
       // 表单参数
       form: {},