潘超林 4 mesiacov pred
rodič
commit
969a171736

+ 7 - 0
src/api/common/index.js

@@ -15,6 +15,13 @@ export function getClassificationListPage(query) {
         params: query
     })
 }
+export function modifyStoreInfo(query) {
+    return request({
+        url: '/system/appUser/modifyStoreInfo',
+        method: 'post',
+        data: query
+    })
+}
 
 
 export function getStoreInfo(query) {

+ 42 - 0
src/api/sort/index.js

@@ -0,0 +1,42 @@
+import request from '@/utils/request'
+
+
+export function getMerchantClassifyList(query) {
+    return request({
+        url: '/system/merchantClassify/getMerchantClassifyList',
+        method: 'get',
+        params: query
+    })
+}
+
+
+export function merchantClassifySave(query) {
+    return request({
+        url: '/system/merchantClassify/save',
+        method: 'post',
+        data: query
+    })
+}
+export function merchantClassifyEdit(query) {
+    return request({
+        url: '/system/merchantClassify/edit',
+        method: 'post',
+        data: query
+    })
+}
+
+export function merchantClassifyDelete(query) {
+    return request({
+        url: '/system/merchantClassify/delete',
+        method: 'post',
+        data: query
+    })
+}
+export function merchantClassifyUpdateSort(query) {
+    return request({
+        url: '/system/merchantClassify/updateSort',
+        method: 'post',
+        data: query
+    })
+}
+

+ 157 - 0
src/views/manage/sendSetting.vue

@@ -0,0 +1,157 @@
+<template>
+  <div style="padding: 20px">
+    <span style="color: orange">*所有信息只针对于同城秒送商品</span>
+    <el-form
+      ref="form"
+      :rules="rules"
+      :model="shopInfo"
+      label-width="120px"
+      style="padding: 35px"
+    >
+      <el-row>
+        <el-col :span="12">
+          <el-form-item
+            label="营业时间:"
+            prop="businessEndTime"
+            style="margin-top: 30px"
+          >
+            <el-time-picker
+              value-format="HH:mm"
+              format="HH:mm"
+              type="time"
+              placeholder="开始时间"
+              v-model="shopInfo.businessStartTime"
+              style="width: 200px"
+            ></el-time-picker>
+            -
+            <el-time-picker
+              value-format="HH:mm"
+              format="HH:mm"
+              type="time"
+              placeholder="结束时间"
+              v-model="shopInfo.businessEndTime"
+              style="width: 200px"
+            ></el-time-picker>
+          </el-form-item>
+          <el-form-item label="配送范围:" prop="deliveryRange" style="margin-top: 30px">
+            店铺地址附近
+            <el-input-number
+              v-model="shopInfo.deliveryRange"
+              @change="handleChange"
+              style="width: 150px"
+              :controls="false"
+              max="9999"
+              min="1"
+              step="1"
+            ></el-input-number>
+            公里
+          </el-form-item>
+          <el-form-item
+            label="起送金额:"
+            prop="minDeliveryAmount"
+            style="margin-top: 30px"
+          >
+            <el-input-number
+              v-model="shopInfo.minDeliveryAmount"
+              @change="handleChange"
+              style="width: 150px"
+              :controls="false"
+              max="9999"
+              min="1"
+              step="1"
+            ></el-input-number>
+            元
+          </el-form-item>
+          <!-- <el-form-item label="配送费:">
+            <span style="color: orange; font-size: 12px"
+              >*平台3公里内配送费收取4元,每增加一公里,增加配送费2元</span
+            >
+            <br />
+            3公里内
+            <el-input type="text" style="width: 70px" v-model="form.desc"></el-input>
+            ,每增加1公里,增加配送费<el-input
+              type="text"
+              style="width: 70px"
+              v-model="form.desc"
+            ></el-input
+            >元 <br /><br />
+            免配送费,需下单满
+            <el-input type="text" style="width: 70px" v-model="form.desc"></el-input>元
+          </el-form-item>
+          <el-form-item label="商品打包费:">
+            打包费收取方式:
+            <el-select v-model="value" placeholder="请选择" style="width: 120px">
+              <el-option label="商品数量" value="0" />
+              <el-option label="整笔订单" value="1" />
+            </el-select>
+            <br />
+            <br />
+            每件商品收取打包费:<el-input
+              type="text"
+              style="width: 70px"
+              v-model="form.desc"
+            ></el-input
+            >元
+          </el-form-item> -->
+        </el-col>
+        <el-col :span="24" style="margin-top: 30px">
+          <el-form-item>
+            <el-button type="primary" @click="submitForm">保存</el-button>
+            <el-button>取消</el-button>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import { getStoreInfo, modifyStoreInfo } from "@/api/common/index";
+export default {
+  data() {
+    return {
+      form: {},
+      rules: {
+        businessEndTime: [{ required: true, message: "请选择营业时间", trigger: "blur" }],
+        deliveryRange: [{ required: true, message: "请输入配送范围", trigger: "blur" }],
+        minDeliveryAmount: [
+          { required: true, message: "请输入起送金额", trigger: "blur" },
+        ],
+      },
+      shopInfo: {},
+    };
+  },
+  mounted() {
+    this.getInfo();
+  },
+  methods: {
+    submitForm() {
+      this.$refs.form.validate((valid) => {
+        if (valid) {
+          modifyStoreInfo(this.shopInfo).then((res) => {
+            if (res.code == 200) {
+              this.$message.success("保存成功!");
+              this.getInfo();
+            }
+          });
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    resetForm(formName) {
+      this.$refs[formName].resetFields();
+    },
+    getInfo() {
+      getStoreInfo().then((res) => {
+        if (res.code == 200) {
+          this.shopInfo = res.data;
+        }
+      });
+    },
+  },
+};
+</script>
+
+<style></style>

+ 3 - 0
src/views/member/list/allProduct.vue

@@ -49,6 +49,7 @@
           <el-option label="全部" value=""> </el-option>
           <el-option label="返券商品" value="7"> </el-option>
           <el-option label="会员礼包" value="6"> </el-option>
+          <el-option label="业务专员商品" value="8"> </el-option>
         </el-select>
       </el-form-item>
       <el-form-item label="关联活动商品" prop="promotionTag">
@@ -195,6 +196,8 @@
                 ? "返券商品"
                 : scope.row.saleModel == 6
                 ? "会员礼包"
+                : scope.row.saleModel == 8
+                ? "业务专员商品"
                 : ""
             }}
           </span>

+ 1 - 0
src/views/member/module/basic-info.vue

@@ -14,6 +14,7 @@
           <el-radio-group v-model="form.saleModel" @change="passValue">
             <el-radio :label="6" :value="6">会员商品</el-radio>
             <el-radio :label="7" :value="7">返券商品</el-radio>
+            <el-radio :label="8" :value="8">业务专员商品</el-radio>
           </el-radio-group>
         </el-form-item>
       </el-col>

+ 3 - 0
src/views/member/module/sales-info.vue

@@ -545,6 +545,9 @@ export default {
       this.$emit("skuRemove", this.skuIds);
     },
     addSpecification() {
+      if(!this.form.skuList){
+        this.form.skuList=[]
+      }
       this.form.skuList.push({
         stock: undefined,
         weight: undefined,

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

@@ -280,6 +280,20 @@ export default {
       // 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(`发布成功!请前往草稿箱查看`);
@@ -347,9 +361,19 @@ export default {
           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 = "新店福利";
+      }
       this.btnLading = true;
       publishGoods(this.form).then((res) => {
         if (res.code == 200) {

+ 1 - 0
src/views/product/material.vue

@@ -184,6 +184,7 @@ export default {
       });
     },
     getFreightTemplate() {
+      this.tableData =[]
       let cityCode = JSON.parse(this.shopInfo.storeCityCode);
       getFreightTemplate({
         sendCityCode: cityCode[1],

+ 75 - 1
src/views/product/module/sales-info.vue

@@ -482,6 +482,20 @@
           </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
+            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" v-if="!showCom">
         <el-form-item prop="freeShipping">
           <span slot="label">运费</span>
@@ -531,6 +545,7 @@
 </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";
@@ -558,6 +573,9 @@ export default {
         skuList: [],
         packing: "",
         shippingTimeDesc: "",
+        merchantClassifyId: "",
+        merchantClassifyIds: [],
+        merchantClassifyName: "",
       },
       addr: "",
       measure: [],
@@ -574,19 +592,29 @@ export default {
         "shippingAddrBean.addrDetail": [
           { required: true, message: "详细地址不能为空", trigger: "blur" },
         ],
+        merchantClassifyIds: [
+          { required: true, message: "店铺所属分类不能为空", trigger: "blur" },
+        ],
       },
+
       shopInfo: {},
       saleType: undefined,
       sj: true,
       showCom: true,
       skuIds: [],
       saleModel: 1,
+      categoryprops: {
+        checkStrictly: true,
+        lazy: true,
+        lazyLoad: this.categoryLazyLoad,
+        label: "label",
+        value: "value",
+      },
     };
   },
   watch: {
     //监听文件url改变时重新赋值
     saleModels(newVal, oldVal) {
-      console.log("azxczx", newVal);
       this.saleModel = newVal;
       this.$forceUpdate();
     },
@@ -597,6 +625,49 @@ export default {
   },
 
   methods: {
+    categoryLazyLoad(node, resolve) {
+      let level = node.level;
+      if (!node.data) {
+        getMerchantClassifyList({ classifyType: 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;
+      brother.click();
+      let nodes = this.$refs.formCascader.getCheckedNodes();
+      this.form.merchantClassifyName = nodes[0].label;
+      this.form.merchantClassifyIds = val;
+      this.form.merchantClassifyId = val;
+      this.form.merchantClassifyId = `["${this.form.merchantClassifyId.join('", "')}"]`;
+      this.passValue();
+    },
     getFormInfo(record) {
       this.saleModel = record.saleModel;
       this.addr = record.shippingAddr;
@@ -767,6 +838,9 @@ export default {
       this.$emit("skuRemove", this.skuIds);
     },
     addSpecification() {
+      if (!this.form.skuList) {
+        this.form.skuList = [];
+      }
       this.form.skuList.push({
         stock: undefined,
         weight: undefined,

+ 302 - 0
src/views/sortmanage/index.vue

@@ -0,0 +1,302 @@
+<template>
+  <div class="app-container">
+    <el-row :gutter="20">
+      <el-col :span="24" style="margin-bottom: 20px">
+        <span style="color: orange">*固定分类不可删除以及编辑添加</span></el-col
+      >
+      <el-col :span="6">
+        <el-card class="box-card">
+          <div>
+            <h3>一级分类</h3>
+            <el-input
+              @change="search(1)"
+              v-model="queryParams.classifyName"
+              placeholder="输入一级分类名称搜索"
+            />
+            <ul style="line-height: 40px; overflow: auto; height: 550px">
+              <li
+                class="items"
+                v-for="(item, index) in sortList"
+                :key="index"
+                :class="itemIndex == index ? 'itemActive' : ''"
+                @click="itemsChange(item, index)"
+              >
+                <div>
+                  <el-tag type="danger" v-if="item.classifyType == 0">秒送</el-tag>
+                  <el-tag type="warning" v-if="item.classifyType == 1">批发</el-tag>
+                  {{ item.classifyName }}
+                </div>
+                <div v-if="item.isDefault == 1">
+                  <el-button size="small" round @click.prevent="edit(item)"
+                    >编辑</el-button
+                  >
+                  <el-button size="small" round @click.prevent="remove(item, '1')"
+                    >删除</el-button
+                  >
+                </div>
+              </li>
+              <el-empty description="暂无分类数据" v-if="sortList.length == 0"></el-empty>
+            </ul>
+          </div>
+        </el-card>
+        <div style="text-align: center; margin-top: 20px">
+          <el-button type="primary" @click="addPrimary('f')">添加一级分类</el-button>
+        </div>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="box-card">
+          <div>
+            <h3>二级分类</h3>
+            <el-input
+              @change="search(2)"
+              v-model="queryParamsChildren.classifyName"
+              placeholder="输入二级分类名称搜索"
+            />
+            <ul style="line-height: 40px; overflow: auto; height: 550px">
+              <li
+                class="items"
+                v-for="(item, index) in sortListChildren"
+                :key="index"
+                :class="itemIndex == index ? 'itemActive' : ''"
+              >
+                <div>
+                  <el-tag type="danger" v-if="item.classifyType == 0">秒送</el-tag>
+                  <el-tag type="warning" v-if="item.classifyType == 1">批发</el-tag>
+                  {{ item.classifyName }}
+                </div>
+                <div v-if="item.isDefault == 1">
+                  <el-button size="small" round @click.prevent="edit1(item)"
+                    >编辑</el-button
+                  >
+                  <el-button size="small" round @click.prevent="remove(item, '2')"
+                    >删除</el-button
+                  >
+                </div>
+              </li>
+              <el-empty
+                description="暂无分类数据"
+                v-if="sortListChildren.length == 0"
+              ></el-empty>
+            </ul>
+          </div>
+        </el-card>
+        <div
+          style="text-align: center; margin-top: 20px"
+          v-if="selectSort.isDefault == 1"
+        >
+          <el-button type="primary" @click="addPrimary('z')">添加二级分类</el-button>
+        </div>
+      </el-col>
+    </el-row>
+    <el-dialog
+      title="添加分类"
+      :visible.sync="dialogVisible"
+      width="30%"
+      :before-close="handleClose"
+    >
+      <el-form ref="form" :model="form" label-width="80px" :rules="rules">
+        <el-form-item label="分类名称" prop="classifyName">
+          <el-input v-model="form.classifyName" placeholder="请输入分类名称" />
+        </el-form-item>
+      </el-form>
+
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="addSort">确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import draggable from "vuedraggable";
+import {
+  getMerchantClassifyList,
+  merchantClassifySave,
+  merchantClassifyEdit,
+  merchantClassifyDelete,
+} from "@/api/sort/index.js";
+export default {
+  components: { draggable },
+  data() {
+    return {
+      dialogVisible: false,
+      queryParams: {
+        classifyName: "",
+        name: "",
+      },
+      queryParamsChildren: {
+        classifyName: "",
+        name: "",
+      },
+      form: {
+        classifyName: "",
+      },
+      type: "f",
+      sortList: [],
+      sortListChildren: [],
+      selectSort: {},
+      itemIndex: null,
+      rules: {
+        classifyName: [{ required: true, message: "请输入分类名称", trigger: "blur" }],
+      },
+    };
+  },
+  mounted() {
+    this.getList();
+  },
+  methods: {
+    rest() {
+      this.queryParams = {
+        classifyName: "",
+        name: "",
+      };
+      this.queryParamsChildren = {
+        classifyName: "",
+        name: "",
+        parentId: "",
+      };
+      this.getList();
+    },
+    search(index) {
+      if (index == 1) {
+        this.getList();
+      } else {
+        this.getChildren();
+      }
+    },
+    getList() {
+      this.loading = true;
+      getMerchantClassifyList(this.queryParams).then((res) => {
+        if (res.code == 200) {
+          if (this.queryParams.parentId) {
+            this.sortListChildren = res.data;
+          } else {
+            this.sortList = res.data;
+          }
+        }
+      });
+    },
+    addSort() {
+      this.$refs.form.validate((valid) => {
+        if (valid) {
+          if (this.type == "z") {
+            this.form.parentId = this.queryParamsChildren.parentId;
+          } else {
+            this.form.parentId = "";
+          }
+          if (this.form.id) {
+            merchantClassifyEdit(this.form).then((res) => {
+              if (res.code == 200) {
+                this.$message.success("修改成功!");
+                if (this.type == "z") {
+                  this.getChildren();
+                } else {
+                  this.getList();
+                }
+
+                this.dialogVisible = false;
+              }
+            });
+          } else {
+            merchantClassifySave(this.form).then((res) => {
+              if (res.code == 200) {
+                this.$message.success("添加成功!");
+                if (this.type == "z") {
+                  this.getChildren();
+                } else {
+                  this.getList();
+                }
+                this.dialogVisible = false;
+              }
+            });
+          }
+          this.form.classifyName = "";
+        } else {
+          return false;
+        }
+      });
+    },
+    remove(item, type) {
+      this.$confirm("是否确认删除该分类?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          merchantClassifyDelete({ id: item.id }).then((res) => {
+            console.log("11", res);
+
+            if (res.code == 200) {
+              this.$message({
+                type: "success",
+                message: "删除成功!",
+              });
+              if (type == "1") {
+                this.rest();
+              } else {
+                this.getChildren();
+              }
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    edit(item) {
+      this.form = item;
+      this.dialogVisible = true;
+      this.type = "f";
+    },
+    edit1(item) {
+      this.form = item;
+      this.dialogVisible = true;
+      this.type = "z";
+    },
+    itemsChange(item, index) {
+      this.selectSort = item;
+      this.itemIndex = index;
+      this.queryParamsChildren.parentId = item.id;
+      console.log(this.queryParamsChildren.parentId);
+      this.getChildren();
+    },
+
+    getChildren() {
+      this.loading = true;
+      getMerchantClassifyList(this.queryParamsChildren).then((res) => {
+        if (res.code == 200) {
+          this.sortListChildren = res.data;
+        }
+      });
+    },
+
+    addPrimary(type) {
+      this.form = {};
+      this.type = type;
+      this.dialogVisible = true;
+    },
+  },
+};
+</script>
+
+<style scoped>
+.items {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+}
+.itemActive {
+  background: #f4f4f4;
+}
+/* .items:hover {
+  background: #f4f4f4;
+} */
+.box-card {
+  height: 700px;
+}
+</style>

+ 412 - 0
src/views/sortmanage/sort.vue

@@ -0,0 +1,412 @@
+<template>
+  <div class="app-container">
+    <el-tabs v-model="queryParams.classifyType" @tab-click="getList">
+      <el-tab-pane label="秒送商品" :name="0"></el-tab-pane>
+      <el-tab-pane label="批发商品" :name="1"></el-tab-pane>
+    </el-tabs>
+    <el-row :gutter="20">
+      <el-col :span="6">
+        <el-card class="box-card">
+          <div>
+            <h3>一级分类</h3>
+            <el-input
+              @change="search"
+              v-model="queryParams.classifyName"
+              placeholder="输入一级分类名称搜索"
+            />
+            <ul style="line-height: 40px; overflow: auto; height: 550px">
+              <draggable
+                :sort="true"
+                v-model="sortList"
+                group="people"
+                @change="change"
+                @start="start"
+                @end="end"
+              >
+                <transition-group>
+                  <li
+                    class="items"
+                    v-for="(item, index) in sortList"
+                    :key="index"
+                    :class="itemIndex == index ? 'itemActive' : ''"
+                    @click="itemsChange(item, index)"
+                  >
+                    <div>
+                      <el-tag type="danger" v-if="item.classifyType == 0">秒送</el-tag>
+                      <el-tag type="warning" v-if="item.classifyType == 1">批发</el-tag>
+                      {{ item.classifyName }}
+                    </div>
+                    <div v-if="item.isDefault == 1">
+                      <i class="el-icon-rank"></i>
+                    </div>
+                  </li>
+                </transition-group>
+              </draggable>
+
+              <el-empty description="暂无分类数据" v-if="sortList.length == 0"></el-empty>
+            </ul>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="box-card">
+          <div>
+            <h3>二级分类</h3>
+            <el-input
+              @change="search"
+              v-model="queryParamsChildren.classifyName"
+              placeholder="输入二级分类名称搜索"
+            />
+            <ul style="line-height: 40px; overflow: auto; height: 550px">
+              <draggable
+                :sort="true"
+                v-model="sortListChildren"
+                group="people"
+                @change="change1"
+                @start="start"
+                @end="end1"
+              >
+                <transition-group>
+                  <li
+                    class="items"
+                    v-for="(item, index) in sortListChildren"
+                    :key="index"
+                    :class="itemIndex == index ? 'itemActive' : ''"
+                  >
+                    <div>
+                      <el-tag type="danger" v-if="item.classifyType == 0">秒送</el-tag>
+                      <el-tag type="warning" v-if="item.classifyType == 1">批发</el-tag>
+                      {{ item.classifyName }}
+                    </div>
+                    <div>
+                      <i class="el-icon-rank"></i>
+                    </div>
+                  </li>
+                </transition-group>
+              </draggable>
+              <el-empty
+                description="暂无分类数据"
+                v-if="sortListChildren.length == 0"
+              ></el-empty>
+            </ul>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import draggable from "vuedraggable";
+import {
+  getMerchantClassifyList,
+  merchantClassifySave,
+  merchantClassifyEdit,
+  merchantClassifyDelete,
+  merchantClassifyUpdateSort,
+} from "@/api/sort/index.js";
+export default {
+  components: { draggable },
+  data() {
+    return {
+      dialogVisible: false,
+      queryParams: {
+        classifyName: "",
+        name: "",
+        classifyType: 0,
+      },
+      queryParamsChildren: {
+        classifyName: "",
+        name: "",
+      },
+      form: {
+        classifyName: "",
+      },
+      type: "f",
+      sortList: [],
+      sortListChildren: [],
+      selectSort: {},
+      itemIndex: null,
+      rules: {
+        classifyName: [{ required: true, message: "请输入分类名称", trigger: "blur" }],
+      },
+      newList: [],
+      newzList: [],
+      eventsrot: 0,
+    };
+  },
+  mounted() {
+    this.getList();
+  },
+  methods: {
+    // // 监听拖拽
+    change1(event) {
+      for (let index = 0; index < this.sortListChildren.length; index++) {
+        let e = this.sortListChildren[index];
+        if (this.queryParams.classifyType == 0) {
+          if (e.sortSecond == event.moved.newIndex) {
+            this.newzList.push({
+              id: e.id,
+              sort: event.moved.oldIndex,
+            });
+          }
+        } else {
+          if (e.sortWholesale == event.moved.newIndex) {
+            this.newzList.push({
+              id: e.id,
+              sort: event.moved.oldIndex,
+            });
+          }
+        }
+      }
+      this.newzList.push({
+        id: event.moved.element.id,
+        sort: event.moved.newIndex,
+      });
+    },
+    end1(event, e) {
+      merchantClassifyUpdateSort({
+        classifyType: Number(this.queryParams.classifyType),
+        list: this.newzList,
+      }).then((res) => {
+        if (res.code == 200) {
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+          this.newzList = [];
+          this.getChildren();
+        }
+      });
+    },
+
+    change(event) {
+      this.eventsrot = event.moved.element.isDefault;
+      if (event.moved.element.isDefault == 0) {
+        return false;
+      }
+      for (let index = 0; index < this.sortList.length; index++) {
+        let e = this.sortList[index];
+        if (this.queryParams.classifyType == 0) {
+          if (e.sortSecond == event.moved.newIndex) {
+            this.newList.push({
+              id: e.id,
+              sort: event.moved.oldIndex,
+            });
+          }
+        } else {
+          if (e.sortWholesale == event.moved.newIndex) {
+            this.newList.push({
+              id: e.id,
+              sort: event.moved.oldIndex,
+            });
+          }
+        }
+      }
+      this.newList.push({
+        id: event.moved.element.id,
+        sort: event.moved.newIndex,
+      });
+      console.log(this.newList);
+    },
+
+    // 结束拖拽
+    end(event, e) {
+      console.log(this.eventsrot);
+      if (this.eventsrot == 0) {
+        return false;
+      }
+
+      // event.item  拖拽的本身
+      // event.to      拖拽的目标列表
+      // event.from    拖拽之前的列表
+      // event.oldIndex    拖拽前的位置
+      // event.newIndex    拖拽后的位置
+      // console.log(event);
+      for (let index = 0; index < this.sortList.length; index++) {
+        let e = this.sortList[index];
+        if (e.isDefault == 1) {
+          e.sort = index;
+        }
+        if (e.classifyName == "其它") {
+          e.sort = 999;
+        }
+      }
+      merchantClassifyUpdateSort({
+        classifyType: Number(this.queryParams.classifyType),
+        list: this.sortList,
+      }).then((res) => {
+        if (res.code == 200) {
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+          this.newList = [];
+          this.getList();
+        }
+      });
+    },
+
+    rest() {
+      this.queryParams = {
+        classifyName: "",
+        name: "",
+      };
+      this.queryParamsChildren = {
+        classifyName: "",
+        name: "",
+        parentId: "",
+      };
+      this.getList();
+    },
+    search() {
+      if (this.queryParams.classifyNameChildren) {
+        this.queryParams.classifyName = this.queryParams.classifyNameChildren;
+      }
+      if (this.queryParams.name) {
+        this.queryParams.classifyName = this.queryParams.name;
+      }
+      this.getList();
+    },
+    getList() {
+      this.loading = true;
+      getMerchantClassifyList(this.queryParams).then((res) => {
+        if (res.code == 200) {
+          if (this.queryParams.parentId) {
+            this.sortListChildren = res.data;
+          } else {
+            this.sortList = res.data;
+          }
+        }
+      });
+    },
+    addSort() {
+      this.$refs.form.validate((valid) => {
+        if (valid) {
+          if (this.type == "z") {
+            this.form.parentId = this.queryParamsChildren.parentId;
+          } else {
+            this.form.parentId = "";
+          }
+          if (this.form.id) {
+            merchantClassifyEdit(this.form).then((res) => {
+              if (res.code == 200) {
+                this.$message({
+                  type: "success",
+                  message: "修改成功!",
+                });
+                if (this.type == "z") {
+                  this.getChildren();
+                } else {
+                  this.getList();
+                }
+
+                this.dialogVisible = false;
+              }
+            });
+          } else {
+            merchantClassifySave(this.form).then((res) => {
+              if (res.code == 200) {
+                this.$message({
+                  type: "success",
+                  message: "添加成功!",
+                });
+                if (this.type == "z") {
+                  this.getChildren();
+                } else {
+                  this.getList();
+                }
+                this.dialogVisible = false;
+              }
+            });
+          }
+          this.form.classifyName = "";
+        } else {
+          return false;
+        }
+      });
+    },
+    remove(item) {
+      this.$confirm("是否确认删除该分类?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          merchantClassifyDelete({ id: item.id }).then((res) => {
+            if (res.code == 200) {
+              this.$message({
+                type: "success",
+                message: "删除成功!",
+              });
+              this.rest();
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    edit(item) {
+      this.form = item;
+      this.dialogVisible = true;
+      this.type = "f";
+    },
+    edit1(item) {
+      this.form = item;
+      this.dialogVisible = true;
+      this.type = "z";
+    },
+    itemsChange(item, index) {
+      this.selectSort = item;
+      this.itemIndex = index;
+      this.queryParamsChildren.parentId = item.id;
+      this.getChildren();
+    },
+
+    getChildren() {
+      this.loading = true;
+      getMerchantClassifyList(this.queryParamsChildren).then((res) => {
+        if (res.code == 200) {
+          if (this.queryParams.classifyType == 0) {
+            this.sortListChildren = res.data.sort((a, b) => a.sortSecond - b.sortSecond);
+          }
+          if (this.queryParams.classifyType == 1) {
+            this.sortListChildren = res.data.sort(
+              (a, b) => a.sortWholesale - b.sortWholesale
+            );
+          }
+          console.log(this.sortListChildren);
+        }
+      });
+    },
+
+    addPrimary(type) {
+      this.form = {};
+      this.type = type;
+      this.dialogVisible = true;
+    },
+  },
+};
+</script>
+
+<style scoped>
+.items {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+}
+.itemActive {
+  background: #f4f4f4;
+}
+/* .items:hover {
+  background: #f4f4f4;
+} */
+.box-card {
+  height: 700px;
+}
+</style>

+ 13 - 3
src/views/storage/add.vue

@@ -115,13 +115,23 @@
                 <template slot-scope="scope">
                   <div style="display: flex; flex-direction: row; align-items: center">
                     <div style="width: 70px">1{{ scope.row.spuUnit }} ≈</div>
-                    <el-input
+
+                    <el-input-number
+                      :controls="false"
+                      v-model="scope.row.unitConversion"
+                      @change="handleChange"
+                      :precision="0"
+                      min=""
+                    >
+                    </el-input-number>
+                    <span>{{ form.storeUnit }}</span>
+                    <!-- <el-input
                       v-model="scope.row.unitConversion"
                       clearable
                       style="widht: 70px"
                     >
-                      <span slot="suffix">{{ form.storeUnit }}</span>
-                    </el-input>
+               
+                    </el-input> -->
                   </div>
                 </template>
               </el-table-column>

+ 14 - 10
src/views/storage/edit.vue

@@ -96,17 +96,12 @@
               <el-table-column label="skuId" align="center" prop="skuId" />
               <el-table-column label="规格名称" align="center" prop="skuSpecName">
                 <template slot-scope="scope">
-                  {{ scope.row.skuSpecName?JSON.parse(scope.row.skuSpecName)[0].specsName:'' }}
-                  <!-- {{
-                    scope.row.skuSpecName
-                      ? JSON.parse(scope.row.skuSpecName[0]).specsName
-                      : ""
-                  }} -->
+                  {{ scope.row.skuSpecName }}
                 </template>
               </el-table-column>
               <el-table-column label="规格内容" align="center" prop="skuSpecName">
                 <template slot-scope="scope">
-                  {{ scope.row.skuSpecName?JSON.parse(scope.row.skuSpecName)[0].specsValue:'' }}
+                  {{ scope.row.specsValue }}
                   <!-- {{
                     scope.row.skuSpecName
                       ? JSON.parse(scope.row.skuSpecName[0]).specsName
@@ -118,14 +113,23 @@
                 <template slot-scope="scope">
                   <div style="display: flex; flex-direction: row; align-items: center">
                     <div style="width: 70px">1{{ scope.row.spuUnit }} ≈</div>
-                    <el-input
+                    <el-input-number
+                      :controls="false"
+                      v-model="scope.row.unitConversion"
+                      @change="handleChange"
+                      :precision="0"
+                      min=""
+                    >
+                    </el-input-number>
+                    <span>{{ form.storeUnit }}</span>
+                    <!-- <el-input
                       oninput="value=value.replace(/[^\d.]/g,'')"
                       v-model="scope.row.unitConversion"
                       clearable
                       style="widht: 70px"
                     >
                       <span slot="suffix">{{ form.storeUnit }}</span>
-                    </el-input>
+                    </el-input> -->
                   </div>
                 </template>
               </el-table-column>
@@ -171,7 +175,7 @@
                   >
                     <span slot="suffix"> 元/{{ scope.row.spuUnit }}</span>
                   </el-input> -->
-                  {{scope.row.salePrice}}元/{{ scope.row.spuUnit }}
+                  {{ scope.row.salePrice }}元/{{ scope.row.spuUnit }}
                 </template>
               </el-table-column>
 

+ 28 - 3
src/views/transmission/createProduct.vue

@@ -277,6 +277,20 @@ export default {
           this.form.presaleEndTime = moment(this.form.datePicker[1]).valueOf();
         }
       }
+      if (this.form.saleModel == 2) {
+        this.form.merchantClassifyId = "217524";
+        this.form.merchantClassifyName = "预售专区";
+      } else if (this.form.saleModel == 3) {
+        this.form.merchantClassifyId = "217522";
+        this.form.merchantClassifyName = "团购秒杀";
+      } else if (this.form.saleModel == 4) {
+        this.form.merchantClassifyId = "217523";
+        this.form.merchantClassifyName = "特价卖场";
+      } else if (this.form.saleModel == 5) {
+        this.form.merchantClassifyId = "217521";
+        this.form.merchantClassifyName = "新人福利";
+      }
+
       saveGoodsDraft(this.form).then((res) => {
         if (res.code == 200) {
           this.$message.success(`发布成功!请前往草稿箱查看`);
@@ -344,9 +358,20 @@ export default {
           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 = "217524";
+        this.form.merchantClassifyName = "预售专区";
+      } else if (this.form.saleModel == 3) {
+        this.form.merchantClassifyId = "217522";
+        this.form.merchantClassifyName = "团购秒杀";
+      } else if (this.form.saleModel == 4) {
+        this.form.merchantClassifyId = "217523";
+        this.form.merchantClassifyName = "特价卖场";
+      } else if (this.form.saleModel == 5) {
+        this.form.merchantClassifyId = "217521";
+        this.form.merchantClassifyName = "新人福利";
+      }
+
       this.btnLading = true;
       publishGoods(this.form).then((res) => {
         if (res.code == 200) {

+ 7 - 6
src/views/transmission/module/basic-info.vue

@@ -28,6 +28,7 @@
         <el-form-item prop="categoryId">
           <span slot="label">商品分类</span>
           <el-cascader
+            class="fl"
             v-model="form.categoryId"
             ref="formCascader"
             :placeholder="categoryName ? categoryName : '请选择分类'"
@@ -380,6 +381,12 @@ export default {
 </script>
 
 <style>
+/* .el-cascader-menu__wrap > .el-cascader-menu__list > .el-cascader-node > .el-radio {
+    display: none;
+  } */
+</style>
+
+<style scoped>
 .el-cascader-panel
   > .el-scrollbar:first-child
   > .el-cascader-menu__wrap
@@ -388,12 +395,6 @@ export default {
   > .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;

+ 133 - 60
src/views/transmission/module/sales-info.vue

@@ -253,11 +253,26 @@
           </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
+            v-model="form.merchantClassifyIds"
+            ref="formCascader"
+            :placeholder="
+              form.merchantClassifyName ? form.merchantClassifyName : '请选择分类'
+            "
+            :props="categoryprops"
+            @change="cascaderChange"
+          />
+        </el-form-item>
+      </el-col>
     </el-row>
   </el-form>
 </template>
 
 <script>
+import { getMerchantClassifyList } from "@/api/sort/index.js";
 import { getStoreInfo } from "@/api/common/index";
 import { getDict } from "@/api/common/index.js";
 export default {
@@ -283,6 +298,9 @@ export default {
         skuList: [],
         packing: "",
         shippingTimeDesc: "",
+        merchantClassifyId: "",
+        merchantClassifyIds: [],
+        merchantClassifyName: "",
       },
       addr: "",
       measure: [],
@@ -299,6 +317,9 @@ export default {
         "shippingAddrBean.addrDetail": [
           { required: true, message: "详细地址不能为空", trigger: "blur" },
         ],
+        merchantClassifyIds: [
+          { required: true, message: "店铺所属分类不能为空", trigger: "blur" },
+        ],
       },
       shopInfo: {},
       saleType: undefined,
@@ -306,13 +327,19 @@ export default {
       showCom: true,
       skuIds: [],
       saleModel: 1,
+      categoryprops: {
+        checkStrictly: true,
+        lazy: true,
+        lazyLoad: this.categoryLazyLoad,
+        label: "label",
+        value: "value",
+      },
     };
   },
 
   watch: {
     //监听文件url改变时重新赋值
     saleModels(newVal, oldVal) {
-      console.log("azxczx", newVal);
       this.saleModel = newVal;
       this.$forceUpdate();
     },
@@ -322,43 +349,104 @@ export default {
     this.getdictImpl();
   },
   methods: {
+    cascaderChange(val) {
+      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.merchantClassifyName = nodes[0].label;
+      this.form.merchantClassifyIds = val;
+      this.form.merchantClassifyId = val;
+      this.form.merchantClassifyId = `["${this.form.merchantClassifyId.join('", "')}"]`;
+      this.passValue();
+    },
+
+    categoryLazyLoad(node, resolve) {
+      let level = node.level;
+      if (!node.data) {
+        getMerchantClassifyList({ classifyType: 0 }).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: 0 }).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({});
+      }
+    },
+
     getFormInfo(record) {
-      this.saleModel = record.saleModel;
-      this.addr = record.shippingAddr;
-      this.form.expressType = record.expressType;
+      const {
+        saleModel,
+        shippingAddr,
+        expressType,
+        merchantClassifyId,
+        merchantClassifyName,
+        shippingAddrBean,
+        props,
+        lookSalesVolume,
+        unit,
+        packing,
+        shippingTimeDesc,
+        freeShipping,
+        skuList,
+      } = record;
+
+      this.saleModel = saleModel;
+      this.addr = shippingAddr;
+
+      // 批量赋值一些表单属性
+      Object.assign(this.form, {
+        expressType,
+        merchantClassifyId,
+        merchantClassifyIds: JSON.parse(merchantClassifyId),
+        merchantClassifyName,
+        lookSalesVolume,
+        unit,
+        shippingAddr,
+        packing,
+        shippingTimeDesc,
+        skuList,
+      });
+      // 处理 shippingAddrBean
       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,
+        addr: shippingAddr,
+        addrDetail: shippingAddrBean?.addrDetail,
+        cityCode: shippingAddrBean?.cityCode,
+        countyCode: shippingAddrBean?.countyCode,
+        latitude: shippingAddrBean?.latitude,
+        longitude: shippingAddrBean?.longitude,
+        provinceCode: shippingAddrBean?.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;
+      // 处理 props
+      this.form.props = Array.isArray(props) ? props : [];
+      // 处理 freeShipping
       if (this.form.freeShipping) {
-        this.form.freeShipping = record.freeShipping;
+        this.form.freeShipping = freeShipping;
       }
-      this.form.skuList = record.skuList;
     },
-
     setShowCom(val) {
       this.showCom = val;
     },
-
     formvalidate() {
       let that = this;
       return new Promise((resolve) => {
@@ -384,23 +472,24 @@ export default {
         }
       });
     },
-    getdictImpl() {
-      getDict("stockUnit").then((res) => {
-        if (res.code == 200) {
-          this.measure = res.data;
+    async getdictImpl() {
+      try {
+        const [stockUnitRes, packTypeRes] = await Promise.all([
+          getDict("stockUnit"),
+          getDict("packType"),
+        ]);
+        if (stockUnitRes.code === 200) {
+          this.measure = stockUnitRes.data;
         }
-      });
-      getDict("packType").then((res) => {
-        if (res.code == 200) {
-          this.package = res.data;
+        if (packTypeRes.code === 200) {
+          this.package = packTypeRes.data;
         }
-      });
+      } catch (error) {
+        console.error("获取字典数据失败:", error);
+      }
     },
 
     passValue() {
-      console.log(this.form);
-      console.log("model", this.saleModel);
-
       if (this.saleModel == 1) {
         this.form.skuList.forEach((e) => {
           e.skuPriceList[0].price = e.skuPriceList[0].originalPrice;
@@ -409,24 +498,6 @@ export default {
 
       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({
@@ -448,12 +519,14 @@ export default {
       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,

+ 27 - 0
src/views/transmission/updateProduct.vue

@@ -413,6 +413,19 @@ export default {
       if (this.form.categoryId?.length > 0) {
         this.form.categoryId = this.form.categoryId[this.form.categoryId.length - 1];
       }
+      if (this.form.saleModel == 2) {
+        this.form.merchantClassifyId = "217524";
+        this.form.merchantClassifyName = "预售专区";
+      } else if (this.form.saleModel == 3) {
+        this.form.merchantClassifyId = "217522";
+        this.form.merchantClassifyName = "团购秒杀";
+      } else if (this.form.saleModel == 4) {
+        this.form.merchantClassifyId = "217523";
+        this.form.merchantClassifyName = "特价卖场";
+      } else if (this.form.saleModel == 5) {
+        this.form.merchantClassifyId = "217521";
+        this.form.merchantClassifyName = "新人福利";
+      }
 
       saveGoodsDraft(this.form).then((res) => {
         if (res.code == 200) {
@@ -465,6 +478,20 @@ export default {
           this.$message.error(`规格不能为空`);
           return;
         }
+        if (this.form.saleModel == 2) {
+          this.form.merchantClassifyId = "217524";
+          this.form.merchantClassifyName = "预售专区";
+        } else if (this.form.saleModel == 3) {
+          this.form.merchantClassifyId = "217522";
+          this.form.merchantClassifyName = "团购秒杀";
+        } else if (this.form.saleModel == 4) {
+          this.form.merchantClassifyId = "217523";
+          this.form.merchantClassifyName = "特价卖场";
+        } else if (this.form.saleModel == 5) {
+          this.form.merchantClassifyId = "217521";
+          this.form.merchantClassifyName = "新人福利";
+        }
+
         updateGoods(this.form).then((res) => {
           if (res.code == 200) {
             this.btnLading = false;