Преглед на файлове

bind product with destination

fengchang преди 1 година
родител
ревизия
b713db31c1

+ 64 - 0
hichina-admin-backend/src/main/java/com/hichina/admin/hichinaadminbackend/controller/DestinationController.java

@@ -2,8 +2,10 @@ package com.hichina.admin.hichinaadminbackend.controller;
 
 import com.github.pagehelper.PageHelper;
 import com.hichina.admin.hichinaadminbackend.mapper.DestinationMapper;
+import com.hichina.admin.hichinaadminbackend.mapper.ProductSkuGroupDestinationMappingMapper;
 import com.hichina.admin.hichinaadminbackend.model.DTO.*;
 import com.hichina.admin.hichinaadminbackend.model.Destination;
+import com.hichina.admin.hichinaadminbackend.model.ProductSkuGroupDestinationMapping;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -19,6 +21,36 @@ public class DestinationController {
     @Autowired
     private DestinationMapper destinationMapper;
 
+    @Autowired
+    private ProductSkuGroupDestinationMappingMapper productSkuGroupDestinationMappingMapper;
+
+    @PostMapping("/bind-skugroup-destination")
+    public HichinaResponse bindSkuGroupAndDestination(@RequestBody SkuGroupDestinationBindRequest request){
+        HichinaResponse ret = new HichinaResponse();
+
+        ProductSkuGroupDestinationMapping newObj = new ProductSkuGroupDestinationMapping();
+        newObj.setSkuGroupId(request.getSkuGroupId());
+        newObj.setDestinationId(request.getDestinationId());
+        productSkuGroupDestinationMappingMapper.insert(newObj);
+
+        ret.setOk(true);
+        ret.setMessage("Succceed binding destination and product sku group");
+
+        return ret;
+    }
+
+    @DeleteMapping("/unbind-skugroup-destination")
+    public HichinaResponse unbindSkuGroupAndDestination(@RequestBody SkuGroupDestinationBindRequest request){
+        HichinaResponse ret = new HichinaResponse();
+
+        productSkuGroupDestinationMappingMapper.delete(request.getSkuGroupId(), request.getDestinationId());
+
+        ret.setOk(true);
+        ret.setMessage("Succceed unbinding destination and product sku group");
+
+        return ret;
+    }
+
     @PostMapping
     public HichinaResponse createDestination(@RequestBody DestinationCreateDTO request){
         HichinaResponse ret = new HichinaResponse();
@@ -93,6 +125,17 @@ public class DestinationController {
         return destinations.get(0);
     }
 
+    @GetMapping("/sku-group-binded/{skuGroupId}")
+    public HichinaResponse getBindedDestinationsBySkuGroupId(@PathVariable("skuGroupId") String skuGroupId){
+        HichinaResponse ret = new HichinaResponse();
+        List<DestinationShortDTO> destinationShortDTOS = productSkuGroupDestinationMappingMapper.getShortDestinationsBySkuGroupId(skuGroupId);
+
+        ret.setMessage("Succeed get binded destinations");
+        ret.setOk(true);
+        ret.setData(destinationShortDTOS);
+        return ret;
+    }
+
     @GetMapping
     public HichinaResponse getDestinations(@RequestParam(value = "page", required = true) Integer page,
                                                            @RequestParam(value = "pageSize", required = true) Integer size,
@@ -136,4 +179,25 @@ public class DestinationController {
 
         return ret;
     }
+
+    @GetMapping("/filter-short")
+    public HichinaResponse getDestinationsFilterShort(@RequestParam(value = "query") String query){
+        HichinaResponse ret = new HichinaResponse();
+
+        List<DestinationShortDTO> rawData;
+        if(!StringUtils.isEmpty(query)){
+            rawData = destinationMapper.findDestinationShortByQuery(query);
+        }else{
+            ret.setOk(false);
+            ret.setData(null);
+            ret.setMessage("Do not accept empty query");
+            return ret;
+        }
+
+        ret.setMessage("Successfully got all filtered destinations");
+
+        ret.setData(rawData);
+        ret.setOk(true);
+        return ret;
+    }
 }

+ 4 - 0
hichina-admin-backend/src/main/java/com/hichina/admin/hichinaadminbackend/mapper/DestinationMapper.java

@@ -1,5 +1,6 @@
 package com.hichina.admin.hichinaadminbackend.mapper;
 
+import com.hichina.admin.hichinaadminbackend.model.DTO.DestinationShortDTO;
 import com.hichina.admin.hichinaadminbackend.model.Destination;
 import org.apache.ibatis.annotations.*;
 import org.springframework.stereotype.Component;
@@ -41,6 +42,9 @@ public interface DestinationMapper {
     @Select("select * from destination where destination_name like CONCAT('%',CONCAT(#{query},'%')) or description like CONCAT('%',CONCAT(#{query},'%')) order by created_date desc")
     List<Destination> findDestinationsByQuery(String query);
 
+    @Select("select destination_id, destination_name from destination where destination_name like CONCAT('%',CONCAT(#{query},'%')) order by created_date desc")
+    List<DestinationShortDTO> findDestinationShortByQuery(String query);
+
     @Select("select * from destination where destination_name like CONCAT('%',CONCAT(#{query},'%')) or description like CONCAT('%',CONCAT(#{query},'%')) and level=#{level} order by created_date desc")
     List<Destination> findDestinationsByQueryAndLevel(String query, Integer level);
 

+ 24 - 0
hichina-admin-backend/src/main/java/com/hichina/admin/hichinaadminbackend/mapper/ProductSkuGroupDestinationMappingMapper.java

@@ -0,0 +1,24 @@
+package com.hichina.admin.hichinaadminbackend.mapper;
+
+import com.hichina.admin.hichinaadminbackend.model.DTO.DestinationShortDTO;
+import com.hichina.admin.hichinaadminbackend.model.ProductSkuGroupDestinationMapping;
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Mapper
+@Component(value = "skuGroupDestinationMappingMapper")
+public interface ProductSkuGroupDestinationMappingMapper {
+    @Insert("INSERT INTO product_sku_group_destination_mapping(product_sku_group_id, destination_id) VALUES(#{skuGroupId}, #{destinationId})")
+    void insert(ProductSkuGroupDestinationMapping productSkuGroupDestinationMapping);
+
+    @Select("select d.destination_id, d.destination_name from product_sku_group_destination_mapping m inner join destination d on d.destination_id=m.destination_id where m.product_sku_group_id=#{skuGroupId}")
+    List<DestinationShortDTO> getShortDestinationsBySkuGroupId(String skuGroupId);
+
+    @Delete("Delete FROM product_sku_group_destination_mapping WHERE product_sku_group_id=#{skuGroupId} and destination_id=#{destinationId} ")
+    void delete(String skuGroupId, String destinationId);
+}

+ 11 - 0
hichina-admin-backend/src/main/java/com/hichina/admin/hichinaadminbackend/model/DTO/DestinationShortDTO.java

@@ -0,0 +1,11 @@
+package com.hichina.admin.hichinaadminbackend.model.DTO;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+public class DestinationShortDTO {
+    private String destinationId;
+    private String destinationName;
+}

+ 11 - 0
hichina-admin-backend/src/main/java/com/hichina/admin/hichinaadminbackend/model/DTO/SkuGroupDestinationBindRequest.java

@@ -0,0 +1,11 @@
+package com.hichina.admin.hichinaadminbackend.model.DTO;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+public class SkuGroupDestinationBindRequest {
+    private String skuGroupId;
+    private String destinationId;
+}

+ 11 - 0
hichina-admin-backend/src/main/java/com/hichina/admin/hichinaadminbackend/model/ProductSkuGroupDestinationMapping.java

@@ -0,0 +1,11 @@
+package com.hichina.admin.hichinaadminbackend.model;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+public class ProductSkuGroupDestinationMapping {
+    private String skuGroupId;
+    private String destinationId;
+}

+ 13 - 0
hichina-admin-backend/src/main/resources/db/changelog/liquibase-changeLog.xml

@@ -476,4 +476,17 @@
                 newDataType="VARCHAR(500)"
                 tableName="product_sku_group"/>
     </changeSet>
+    <changeSet author="xiefengchang (generated)" id="168321xget0780d495-1">
+        <createTable tableName="product_sku_group_destination_mapping">
+            <column name="product_sku_group_id" type="VARCHAR(50)">
+                <constraints nullable="false"/>
+            </column>
+            <column name="destination_id" type="VARCHAR(50)">
+                <constraints nullable="false"/>
+            </column>
+        </createTable>
+    </changeSet>
+    <changeSet author="xiefengchang (generated)" id="16d83x2dgds107g80495-27">
+        <addUniqueConstraint columnNames="product_sku_group_id, destination_id" constraintName="uniquebindingofskugroupidanddestinationid" tableName="product_sku_group_destination_mapping"/>
+    </changeSet>
 </databaseChangeLog>

+ 13 - 0
hichina-admin-backend/src/main/resources/db/changelog/liquibase-changeLogProd.xml

@@ -476,4 +476,17 @@
                 newDataType="VARCHAR(500)"
                 tableName="product_sku_group"/>
     </changeSet>
+    <changeSet author="xiefengchang (generated)" id="168321xget0780d495-1">
+        <createTable tableName="product_sku_group_destination_mapping">
+            <column name="product_sku_group_id" type="VARCHAR(50)">
+                <constraints nullable="false"/>
+            </column>
+            <column name="destination_id" type="VARCHAR(50)">
+                <constraints nullable="false"/>
+            </column>
+        </createTable>
+    </changeSet>
+    <changeSet author="xiefengchang (generated)" id="16d83x2dgds107g80495-27">
+        <addUniqueConstraint columnNames="product_sku_group_id, destination_id" constraintName="uniquebindingofskugroupidanddestinationid" tableName="product_sku_group_destination_mapping"/>
+    </changeSet>
 </databaseChangeLog>

+ 206 - 2
hichina-admin-front/src/pages/SkuGroupPage.vue

@@ -1,5 +1,90 @@
 <template>
   <q-page padding>
+    <q-dialog v-model="popupBindDestinationWindow">
+      <q-card>
+        <q-card-section>
+          <div class="text-h6">产品-目的地关联</div>
+        </q-card-section>
+        <q-card-section>
+          <div class="text-h6">
+            <q-input
+              outlined
+              @update:model-value="(val) => goFilterDestination(val)"
+              :debounce="500"
+              v-model="filterDestination"
+              label="Filter Destination"
+            />
+          </div>
+        </q-card-section>
+
+        <q-separator />
+
+        <div style="width: 50vw; height: 70vh; display: flex">
+          <div style="width: 38%; max-width: 38%; height: 100%">
+            <label style="color: red; font-weight: bold">候选目的地</label>
+            <q-list bordered separator>
+              <q-item
+                clickable
+                v-ripple
+                :active="item.destinationId === selected_left_destination"
+                @click="setActiveSelectLeft(item.destinationId)"
+                active-class="bg-teal-1 text-grey-8"
+                v-for="item in candidateDestinations"
+                v-bind:key="item.destinationId"
+              >
+                <q-item-section>
+                  <q-item-label
+                    >目的地: {{ item.destinationName }}</q-item-label
+                  >
+                </q-item-section>
+              </q-item>
+            </q-list>
+          </div>
+
+          <div style="min-width: 10px; height: 100%">
+            <div>
+              <q-btn
+                style="margin-top: 10px"
+                round
+                color="secondary"
+                icon="navigate_next"
+                @click="doBind"
+              />
+            </div>
+            <div>
+              <q-btn
+                style="margin-top: 10px"
+                round
+                color="secondary"
+                @click="unBind"
+                icon="navigate_before"
+              />
+            </div>
+          </div>
+          <div style="width: 38%; height: 100%">
+            <label style="color: red; font-weight: bold">已关联目的地</label>
+            <q-list bordered separator>
+              <q-item
+                clickable
+                v-ripple
+                :active="item.destinationId === selected_right_destination"
+                @click="setActiveSelectRight(item.destinationId)"
+                active-class="bg-teal-1 text-grey-8"
+                v-for="item in bindedDestinations"
+                v-bind:key="item.destinationId"
+                ou
+              >
+                <q-item-section>
+                  <q-item-label
+                    >目的地: {{ item.destinationName }}</q-item-label
+                  >
+                </q-item-section>
+              </q-item>
+            </q-list>
+          </div>
+        </div>
+      </q-card>
+    </q-dialog>
     <div class="row justify-center q-pa-md">
       <q-table
         ref="skuGroupTableRef"
@@ -63,6 +148,12 @@
               label="停用"
               @click="disableGroup(props.row.skuGroupId)"
             />
+            <q-btn
+              color="orange"
+              dense
+              label="绑定目的地"
+              @click="bindDestination(props.row.skuGroupId)"
+            />
           </q-td>
         </template>
       </q-table></div
@@ -99,6 +190,112 @@ export default {
     this.$refs.skuGroupTableRef.requestServerInteraction();
   },
   methods: {
+    unBind() {
+      if (!this.selected_right_destination?.trim()) {
+        alert("Haven't selected anything");
+        return;
+      }
+      console.log("unbind: " + this.selected_right_destination);
+      var params = {};
+      params.skuGroupId = this.currentSkuGroupId;
+      params.destinationId = this.selected_right_destination;
+      api
+        .delete("/api/v1/destination/unbind-skugroup-destination", {
+          data: params,
+        })
+        .then((response) => {
+          if (response.data.ok == true) {
+            this.showNotifyMessageSucceed(response.data.message);
+            this.loadBindedDestinations(this.currentSkuGroupId);
+          } else {
+            this.showNotifyMessageFail(response.data.message);
+          }
+          this.selected_right_destination = "";
+        })
+        .catch((e) => {
+          this.showNotifyMessageFail(e.toString());
+        });
+    },
+    doBind() {
+      if (!this.selected_left_destination?.trim()) {
+        alert("Haven't selected anything");
+        return;
+      }
+
+      var params = {};
+      params.skuGroupId = this.currentSkuGroupId;
+      params.destinationId = this.selected_left_destination;
+      api
+        .post("/api/v1/destination/bind-skugroup-destination", params)
+        .then((response) => {
+          if (response.data.ok == true) {
+            this.showNotifyMessageSucceed(response.data.message);
+            this.loadBindedDestinations(this.currentSkuGroupId);
+          } else {
+            this.showNotifyMessageFail(response.data.message);
+          }
+          this.selected_left_destination = "";
+        })
+        .catch((e) => {
+          this.showNotifyMessageFail(e.toString());
+        });
+    },
+    setActiveSelectRight(val) {
+      this.selected_right_destination = val;
+    },
+    setActiveSelectLeft(val) {
+      this.selected_left_destination = val;
+    },
+    goFilterDestination(val) {
+      console.log(val);
+      var params = {};
+      params.query = val;
+      api
+        .get("/api/v1/destination/filter-short", {
+          params: params,
+        })
+        .then((response) => {
+          if (response.data.ok == true) {
+            this.candidateDestinations = response.data.data;
+          } else {
+            this.candidateDestinations = [];
+          }
+        })
+        .catch((e) => {
+          console.log(e);
+          this.showNotifyMessageFail(e.response);
+        });
+    },
+    loadBindedDestinations(skuGroupId) {
+      console.log(
+        "loading already binded destination for product sku group:" + skuGroupId
+      );
+      // after this, should have bindedDestinations ready, once loaded
+      api
+        .get("/api/v1/destination/sku-group-binded/" + this.currentSkuGroupId)
+        .then((response) => {
+          console.log("get all binded:");
+          console.log(response.data.data);
+          if (response.data.ok === true) {
+            this.bindedDestinations = response.data.data;
+          } else {
+            this.bindedDestinations = [];
+          }
+        })
+        .catch((e) => {
+          console.log(e);
+          this.showNotifyMessageFail(e.response);
+        });
+    },
+    bindDestination(skuGroupId) {
+      this.currentSkuGroupId = skuGroupId;
+      this.selected_left_destination = "";
+      this.selected_right_destination = "";
+      this.filterDestination = "";
+      this.candidateDestinations = [];
+      this.loadBindedDestinations(skuGroupId);
+      this.popupBindDestinationWindow = true;
+    },
     copyText(text) {
       const unsecuredCopyToClipboard = (text) => {
         const textArea = document.createElement("textarea");
@@ -168,8 +365,8 @@ export default {
         })
         .then((response) => {
           this.skuGroups = response.data.data.data;
-          console.log("this is the group stats I got:");
-          console.log(this.skuGroups);
+          // console.log("this is the group stats I got:");
+          // console.log(this.skuGroups);
 
           this.serverPagination.page = response.data.data.currentPage;
           this.serverPagination.rowsNumber = response.data.data.total;
@@ -184,6 +381,13 @@ export default {
   },
   data() {
     return {
+      bindedDestinations: [],
+      currentSkuGroupId: "",
+      selected_left_destination: "",
+      selected_right_destination: "",
+      filterDestination: "",
+      popupBindDestinationWindow: false,
+      candidateDestinations: [],
       selected: [],
       filter: "",
       loading: false,