猿实战是一个原创系列文章,通过实战的方式,采用前后端分离的技术结合SpringMVC Spring Mybatis,手把手教你撸一个完整的电商系统,变身猿人找到工作不是问题。还等什么呢?关注公号,取基础代码,一起实战吧。
上一个章节,猿人君教会了你如何去设计和实现运费的基础数据——管理和维护承运商信息。今天我们一起来学习,如何实现运费计算的支柱模块——运费模板。
功能概览
运费模板,的出现是为了解决繁杂的商品运费计算问题,它的功能比较复杂,系统需要提供设置默认运费模板功能,也可以新增运费模板,一般而言,运费模板分为系统默认模板和自定义模板两类。
系统的默认模板用于处理未设置运费模板的商品运费计算。
自定义模板,用于计算设置地区的运费计算,其中计费方式支持按计费类型来支持按重量、体积、数量的计费方式(当运费类型为自定义运费时才支持这一选项)。
在列表页面,系统模板不允许新增和修改操作。
数据库设计
基于之前的设计文章猿设计14——真电商之运费模板,我们可以快速地整理运费模板的基本信息,并落地为数据库表,如上图所示。
后端功能实现
运费模板的后台管理功能相对传统,提供新增/修改/停用/启用删除/分页列表的功能。
代码语言:javascript复制/**
* Copyright(c) 2004-2020 pangzi
* com.pz.basic.mall.controller.freight.MallFreightTempleteController.java
*/
package com.pz.basic.mall.controller.freight;
import com.pz.basic.mall.domain.base.Result;
import com.pz.basic.mall.domain.base.enums.DataStatusEnum;
import com.pz.basic.mall.domain.freight.MallFreightTemplete;
import com.pz.basic.mall.domain.freight.query.QueryMallFreightTemplete;
import com.pz.basic.mall.domain.sys.AreaSelectedVo;
import com.pz.basic.mall.service.freight.MallFreightTempleteService;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
*
* @author pangzi
* @date 2020-06-22 20:47:27
*
*
*/
@RestController
@RequestMapping("/freightTemplete")
public class MallFreightTempleteController {
private MallFreightTempleteService mallFreightTempleteService;
public void setMallFreightTempleteService(MallFreightTempleteService mallFreightTempleteService) {
this.mallFreightTempleteService = mallFreightTempleteService;
}
/**
* 新增标准运费
* @param mallFreightTemplete
* @return
*/
@RequestMapping("/addMallFreightTemplete")
public Result<MallFreightTemplete> addMallFreightTemplete(@RequestBody MallFreightTemplete mallFreightTemplete){
try{
return mallFreightTempleteService.addMallFreightTemplete(mallFreightTemplete);
}catch(Exception e){
e.printStackTrace();
return new Result(false);
}
}
/**
* 根据ID查找标准运费
* @param id
* @return
*/
@RequestMapping("/findMallFreightTempleteById")
public Result<MallFreightTemplete> findMallFreightTempleteById(Long id){
return mallFreightTempleteService.getMallFreightTempleteById(id);
}
/**
* 修改标准运费
* @param mallFreightTemplete
* @return
*/
@RequestMapping("/updateMallFreightTemplete")
public Result updateMallFreightTemplete(@RequestBody MallFreightTemplete mallFreightTemplete){
try{
return mallFreightTempleteService.updateMallFreightTempleteById(mallFreightTemplete);
}catch(Exception e){
e.printStackTrace();
return new Result(false);
}
}
/**
* 启用标准运费
* @param mallFreightTemplete
* @return
*/
@RequestMapping("/enableMallFreightTemplete")
public Result enableMallFreightTemplete(@RequestBody MallFreightTemplete mallFreightTemplete){
try{
MallFreightTemplete modifiedData =new MallFreightTemplete ();
modifiedData.setTempleteId(mallFreightTemplete.getTempleteId());
modifiedData.setStatus(DataStatusEnum.STATUS_ENABLE.getStatusValue());
return mallFreightTempleteService.updateMallFreightTempleteById(modifiedData);
}catch(Exception e){
e.printStackTrace();
return new Result(false);
}
}
/**
* 停用标准运费
* @param mallFreightTemplete
* @return
*/
@RequestMapping("/disableMallFreightTemplete")
public Result disableMallFreightTemplete(@RequestBody MallFreightTemplete mallFreightTemplete){
try{
MallFreightTemplete modifiedData =new MallFreightTemplete ();
modifiedData.setTempleteId(mallFreightTemplete.getTempleteId());
modifiedData.setStatus(DataStatusEnum.STATUS_DISABLE.getStatusValue());
return mallFreightTempleteService.updateMallFreightTempleteById(modifiedData);
}catch(Exception e){
e.printStackTrace();
return new Result(false);
}
}
/**
* 删除标准运费
* @param mallFreightTemplete
* @return
*/
@RequestMapping("/deleteMallFreightTemplete")
public Result deleteMallFreightTemplete(@RequestBody MallFreightTemplete mallFreightTemplete){
try{
MallFreightTemplete modifiedData =new MallFreightTemplete ();
modifiedData.setTempleteId(mallFreightTemplete.getTempleteId());
modifiedData.setStatus(DataStatusEnum.STATUS_DELETED.getStatusValue());
return mallFreightTempleteService.updateMallFreightTempleteById(modifiedData);
}catch(Exception e){
e.printStackTrace();
return new Result(false);
}
}
/**
* 分页返回标准运费列表
* @param queryMallFreightTemplete
* @return
*/
@RequestMapping("/findByPage")
public Result<List<MallFreightTemplete>> findByPage(@RequestBody QueryMallFreightTemplete queryMallFreightTemplete){
return mallFreightTempleteService.getMallFreightTempletesByPage(queryMallFreightTemplete);
}
/**
* 获取默认运费模板
* @param queryMallFreightTemplete
* @return
*/
@RequestMapping("/findDefaultlFreightTemplete")
public Result<MallFreightTemplete> findDefaultlFreightTemplete(@RequestBody QueryMallFreightTemplete queryMallFreightTemplete){
return mallFreightTempleteService.findDefaultlFreightTemplete(queryMallFreightTemplete);
}
@RequestMapping("/selectForFreightTemplete")
public Result<List<AreaSelectedVo>> selectForFreightTemplete(@RequestBody QueryMallFreightTemplete queryMallFreightTemplete){
return mallFreightTempleteService.selectForFreightTemplete(queryMallFreightTemplete);
}
}
考虑到很多朋友编写mapper文件比较困难,这个章节的mapper就先给到你吧,不过做人不要太懒了,domain 和dao 以及service的实现,还是自己动手搞一下吧。
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.pz.basic.mall.dao.freight.MallFreightTempleteDao">
<resultMap id="ResultMap" type="MallFreightTemplete">
<id property="templeteId" column="templete_id"/>
<id property="templeteName" column="templete_name"/>
<id property="logisticsCode" column="logistics_code"/>
<id property="logisticsName" column="logistics_name"/>
<id property="templeteType" column="templete_type"/>
<id property="serviceType" column="service_type"/>
<id property="freightType" column="freight_type"/>
<id property="chargeType" column="charge_type"/>
<id property="numMin" column="num_min"/>
<id property="numMax" column="num_max"/>
<id property="fristNumPrice" column="frist_num_price"/>
<id property="nextNumPrice" column="next_num_price"/>
<id property="weightMin" column="weight_min"/>
<id property="weightMax" column="weight_max"/>
<id property="fristWeightPrice" column="frist_weight_price"/>
<id property="nextWeightPrice" column="next_weight_price"/>
<id property="volumeMin" column="volume_min"/>
<id property="volumeMax" column="volume_max"/>
<id property="fristVolumePrice" column="frist_volume_price"/>
<id property="nextVolumePrice" column="next_volume_price"/>
<id property="status" column="status"/>
<id property="createUser" column="create_user"/>
<id property="modifyUser" column="modify_user"/>
<id property="created" column="created"/>
<id property="modified" column="modified"/>
</resultMap>
<sql id="ALL_TABLE_COLOUM">
templete_id,
templete_name,
logistics_code,
logistics_name,
templete_type,
service_type,
freight_type,
charge_type,
num_min,
num_max,
frist_num_price,
next_num_price,
weight_min,
weight_max,
frist_weight_price,
next_weight_price,
volume_min,
volume_max,
frist_volume_price,
next_volume_price,
status,
create_user,
modify_user,
created,
modified
</sql>
<sql id="Query_Where_Clause" >
<where >
status>-1
<if test="templeteId != null and templeteId != ''">
and templete_id = #{templeteId}
</if>
<if test="templeteName != null and templeteName != ''">
and templete_name = #{templeteName}
</if>
<if test="logisticsCode != null and logisticsCode != ''">
and logistics_code = #{logisticsCode}
</if>
<if test="logisticsName != null and logisticsName != ''">
and logistics_name = #{logisticsName}
</if>
<if test="templeteType != null and templeteType != ''">
and templete_type = #{templeteType}
</if>
<if test="serviceType != null and serviceType != ''">
and service_type = #{serviceType}
</if>
<if test="freightType != null and freightType != ''">
and freight_type = #{freightType}
</if>
<if test="chargeType != null and chargeType != ''">
and charge_type = #{chargeType}
</if>
<if test="numMin != null and numMin != ''">
and num_min = #{numMin}
</if>
<if test="numMax != null and numMax != ''">
and num_max = #{numMax}
</if>
<if test="fristNumPrice != null and fristNumPrice != ''">
and frist_num_price = #{fristNumPrice}
</if>
<if test="nextNumPrice != null and nextNumPrice != ''">
and next_num_price = #{nextNumPrice}
</if>
<if test="weightMin != null and weightMin != ''">
and weight_min = #{weightMin}
</if>
<if test="weightMax != null and weightMax != ''">
and weight_max = #{weightMax}
</if>
<if test="fristWeightPrice != null and fristWeightPrice != ''">
and frist_weight_price = #{fristWeightPrice}
</if>
<if test="nextWeightPrice != null and nextWeightPrice != ''">
and next_weight_price = #{nextWeightPrice}
</if>
<if test="volumeMin != null and volumeMin != ''">
and volume_min = #{volumeMin}
</if>
<if test="volumeMax != null and volumeMax != ''">
and volume_max = #{volumeMax}
</if>
<if test="fristVolumePrice != null and fristVolumePrice != ''">
and frist_volume_price = #{fristVolumePrice}
</if>
<if test="nextVolumePrice != null and nextVolumePrice != ''">
and next_volume_price = #{nextVolumePrice}
</if>
<if test="status != null and status != ''">
and status = #{status}
</if>
<if test="createUser != null and createUser != ''">
and create_user = #{createUser}
</if>
<if test="modifyUser != null and modifyUser != ''">
and modify_user = #{modifyUser}
</if>
<if test="created != null and created != ''">
and created = #{created}
</if>
<if test="modified != null and modified != ''">
and modified = #{modified}
</if>
</where>
</sql>
<select id="selectMallFreightTempleteByQuery" resultMap="ResultMap" parameterType="QueryMallFreightTemplete" >
select
<include refid="ALL_TABLE_COLOUM" />
from mall_freight_templete
<if test="page != null" >
<include refid="Query_Where_Clause" />
</if>
</select>
<select id="selectMallFreightTempleteByPage" resultMap="ResultMap" parameterType="QueryMallFreightTemplete" >
select
<include refid="ALL_TABLE_COLOUM" />
from mall_freight_templete
<if test="page != null" >
<include refid="Query_Where_Clause" />
</if>
LIMIT #{startRow},#{pageSize}
</select>
<select id="selectMallFreightTempleteById" resultMap="ResultMap" parameterType="long" >
select
<include refid="ALL_TABLE_COLOUM" />
from mall_freight_templete
where templete_id = #{templeteId}
</select>
<delete id="deleteMallFreightTempleteById" parameterType="long" >
delete from mall_freight_templete
where templete_id = #{templeteId}
</delete>
<delete id="deleteMallFreightTempleteByQuery" parameterType= "QueryMallFreightTemplete" >
delete from mall_freight_templete
<if test="page != null" >
<include refid="Query_Where_Clause" />
</if>
</delete>
<insert id="insertMallFreightTemplete" parameterType="MallFreightTemplete" >
INSERT INTO
mall_freight_templete(templete_id,templete_name,logistics_code,logistics_name,templete_type,service_type,freight_type,charge_type,num_min,num_max,frist_num_price,next_num_price,weight_min,weight_max,frist_weight_price,next_weight_price,volume_min,volume_max,frist_volume_price,next_volume_price,status,create_user,modify_user,created,modified)
VALUES(#{templeteId},#{templeteName},#{logisticsCode},#{logisticsName},#{templeteType},#{serviceType},#{freightType},#{chargeType},#{numMin},#{numMax},#{fristNumPrice},#{nextNumPrice},#{weightMin},#{weightMax},#{fristWeightPrice},#{nextWeightPrice},#{volumeMin},#{volumeMax},#{fristVolumePrice},#{nextVolumePrice},#{status},#{createUser},#{modifyUser},#{created},#{modified})
<selectKey resultType="long" keyProperty="templeteId">
SELECT @@IDENTITY AS ID
</selectKey>
</insert>
<insert id="insertMallFreightTempleteModified" parameterType="MallFreightTemplete" >
insert into mall_freight_templete
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="templeteId != null" >
templete_id,
</if>
<if test="templeteName != null" >
templete_name,
</if>
<if test="logisticsCode != null" >
logistics_code,
</if>
<if test="logisticsName != null" >
logistics_name,
</if>
<if test="templeteType != null" >
templete_type,
</if>
<if test="serviceType != null" >
service_type,
</if>
<if test="freightType != null" >
freight_type,
</if>
<if test="chargeType != null" >
charge_type,
</if>
<if test="numMin != null" >
num_min,
</if>
<if test="numMax != null" >
num_max,
</if>
<if test="fristNumPrice != null" >
frist_num_price,
</if>
<if test="nextNumPrice != null" >
next_num_price,
</if>
<if test="weightMin != null" >
weight_min,
</if>
<if test="weightMax != null" >
weight_max,
</if>
<if test="fristWeightPrice != null" >
frist_weight_price,
</if>
<if test="nextWeightPrice != null" >
next_weight_price,
</if>
<if test="volumeMin != null" >
volume_min,
</if>
<if test="volumeMax != null" >
volume_max,
</if>
<if test="fristVolumePrice != null" >
frist_volume_price,
</if>
<if test="nextVolumePrice != null" >
next_volume_price,
</if>
<if test="status != null" >
status,
</if>
<if test="createUser != null" >
create_user,
</if>
<if test="modifyUser != null" >
modify_user,
</if>
<if test="created == null" >
created,
</if>
<if test="modified == null" >
modified,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="templeteId != null" >
#{templeteId},
</if>
<if test="templeteName != null" >
#{templeteName},
</if>
<if test="logisticsCode != null" >
#{logisticsCode},
</if>
<if test="logisticsName != null" >
#{logisticsName},
</if>
<if test="templeteType != null" >
#{templeteType},
</if>
<if test="serviceType != null" >
#{serviceType},
</if>
<if test="freightType != null" >
#{freightType},
</if>
<if test="chargeType != null" >
#{chargeType},
</if>
<if test="numMin != null" >
#{numMin},
</if>
<if test="numMax != null" >
#{numMax},
</if>
<if test="fristNumPrice != null" >
#{fristNumPrice},
</if>
<if test="nextNumPrice != null" >
#{nextNumPrice},
</if>
<if test="weightMin != null" >
#{weightMin},
</if>
<if test="weightMax != null" >
#{weightMax},
</if>
<if test="fristWeightPrice != null" >
#{fristWeightPrice},
</if>
<if test="nextWeightPrice != null" >
#{nextWeightPrice},
</if>
<if test="volumeMin != null" >
#{volumeMin},
</if>
<if test="volumeMax != null" >
#{volumeMax},
</if>
<if test="fristVolumePrice != null" >
#{fristVolumePrice},
</if>
<if test="nextVolumePrice != null" >
#{nextVolumePrice},
</if>
<if test="status != null" >
#{status},
</if>
<if test="createUser != null" >
#{createUser},
</if>
<if test="modifyUser != null" >
#{modifyUser},
</if>
<if test="created == null" >
now(),
</if>
<if test="modified == null" >
now(),
</if>
</trim>
<selectKey resultType="long" keyProperty="templeteId">
SELECT @@IDENTITY AS ID
</selectKey>
</insert>
<select id="countByQuery" parameterType="QueryMallFreightTemplete" resultType="java.lang.Long" >
select count(*) from mall_freight_templete
<if test="page != null" >
<include refid="Query_Where_Clause" />
</if>
</select>
<update id="updateMallFreightTempleteByIdModified" parameterType="MallFreightTemplete" >
update mall_freight_templete
<set >
<if test="templeteName != null" >
templete_name = #{templeteName},
</if>
<if test="logisticsCode != null" >
logistics_code = #{logisticsCode},
</if>
<if test="logisticsName != null" >
logistics_name = #{logisticsName},
</if>
<if test="templeteType != null" >
templete_type = #{templeteType},
</if>
<if test="serviceType != null" >
service_type = #{serviceType},
</if>
<if test="freightType != null" >
freight_type = #{freightType},
</if>
<if test="chargeType != null" >
charge_type = #{chargeType},
</if>
<if test="numMin != null" >
num_min = #{numMin},
</if>
<if test="numMax != null" >
num_max = #{numMax},
</if>
<if test="fristNumPrice != null" >
frist_num_price = #{fristNumPrice},
</if>
<if test="nextNumPrice != null" >
next_num_price = #{nextNumPrice},
</if>
<if test="weightMin != null" >
weight_min = #{weightMin},
</if>
<if test="weightMax != null" >
weight_max = #{weightMax},
</if>
<if test="fristWeightPrice != null" >
frist_weight_price = #{fristWeightPrice},
</if>
<if test="nextWeightPrice != null" >
next_weight_price = #{nextWeightPrice},
</if>
<if test="volumeMin != null" >
volume_min = #{volumeMin},
</if>
<if test="volumeMax != null" >
volume_max = #{volumeMax},
</if>
<if test="fristVolumePrice != null" >
frist_volume_price = #{fristVolumePrice},
</if>
<if test="nextVolumePrice != null" >
next_volume_price = #{nextVolumePrice},
</if>
<if test="status != null" >
status = #{status},
</if>
<if test="createUser != null" >
create_user = #{createUser},
</if>
<if test="modifyUser != null" >
modify_user = #{modifyUser},
</if>
<if test="created != null" >
created = #{created},
</if>
<if test="modified != null" >
modified=now(),
</if>
</set>
where templete_id = #{templeteId}
</update>
</mapper>
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.pz.basic.mall.dao.freight.MallFreightTempleteAreaDao">
<resultMap id="ResultMap" type="MallFreightTempleteArea">
<id property="id" column="id"/>
<id property="templeteId" column="templete_id"/>
<id property="privinceId" column="privince_id"/>
<id property="cityId" column="city_id"/>
<id property="areaId" column="area_id"/>
<id property="status" column="status"/>
<id property="createUser" column="create_user"/>
<id property="modifyUser" column="modify_user"/>
<id property="created" column="created"/>
<id property="modified" column="modified"/>
</resultMap>
<sql id="ALL_TABLE_COLOUM">
id,
templete_id,
privince_id,
city_id,
area_id,
status,
create_user,
modify_user,
created,
modified
</sql>
<sql id="Query_Where_Clause" >
<where >
1=1
<if test="id != null and id != ''">
and id = #{id}
</if>
<if test="templeteId != null and templeteId != ''">
and templete_id = #{templeteId}
</if>
<if test="privinceId != null and privinceId != ''">
and privince_id = #{privinceId}
</if>
<if test="cityId != null and cityId != ''">
and city_id = #{cityId}
</if>
<if test="areaId != null and areaId != ''">
and area_id = #{areaId}
</if>
<if test="status != null and status != ''">
and status = #{status}
</if>
<if test="createUser != null and createUser != ''">
and create_user = #{createUser}
</if>
<if test="modifyUser != null and modifyUser != ''">
and modify_user = #{modifyUser}
</if>
<if test="created != null and created != ''">
and created = #{created}
</if>
<if test="modified != null and modified != ''">
and modified = #{modified}
</if>
</where>
</sql>
<sql id="Update_By_Query_Where_Clause" >
<where >
<choose>
<when test="id != null and id != ''">
id = #{id},
</when>
<when test="templeteId != null and templeteId != ''">
templete_id = #{templeteId},
</when>
<when test="privinceId != null and privinceId != ''">
privince_id = #{privinceId},
</when>
<when test="cityId != null and cityId != ''">
city_id = #{cityId},
</when>
<when test="areaId != null and areaId != ''">
area_id = #{areaId},
</when>
<when test="status != null and status != ''">
status = #{status},
</when>
<when test="createUser != null and createUser != ''">
create_user = #{createUser},
</when>
<when test="modifyUser != null and modifyUser != ''">
modify_user = #{modifyUser},
</when>
<when test="created != null and created != ''">
created = #{created},
</when>
<when test="modified != null and modified != ''">
modified = #{modified},
</when>
</choose>
</where>
</sql>
<select id="selectMallFreightTempleteAreaByQuery" resultMap="ResultMap" parameterType="QueryMallFreightTempleteArea" >
select
<include refid="ALL_TABLE_COLOUM" />
from mall_freight_templete_area
<if test="page != null" >
<include refid="Query_Where_Clause" />
</if>
</select>
<select id="selectMallFreightTempleteAreaByPage" resultMap="ResultMap" parameterType="QueryMallFreightTempleteArea" >
select
<include refid="ALL_TABLE_COLOUM" />
from mall_freight_templete_area
<if test="page != null" >
<include refid="Query_Where_Clause" />
</if>
LIMIT #{startRow},#{pageSize}
</select>
<select id="selectMallFreightTempleteAreaById" resultMap="ResultMap" parameterType="long" >
select
<include refid="ALL_TABLE_COLOUM" />
from mall_freight_templete_area
where id = #{id}
</select>
<delete id="deleteMallFreightTempleteAreaById" parameterType="long" >
delete from mall_freight_templete_area
where id = #{id}
</delete>
<delete id="deleteMallFreightTempleteAreaByQuery" parameterType= "QueryMallFreightTempleteArea" >
delete from mall_freight_templete_area
<if test="page != null" >
<include refid="Query_Where_Clause" />
</if>
</delete>
<insert id="insertMallFreightTempleteArea" parameterType="MallFreightTempleteArea" >
INSERT INTO
mall_freight_templete_area(id,templete_id,privince_id,city_id,area_id,status,create_user,modify_user,created,modified)
VALUES(#{id},#{templeteId},#{privinceId},#{cityId},#{areaId},#{status},#{createUser},#{modifyUser},#{created},#{modified})
<selectKey resultType="long" keyProperty="id">
SELECT @@IDENTITY AS ID
</selectKey>
</insert>
<insert id="insertMallFreightTempleteAreaModified" parameterType="MallFreightTempleteArea" >
insert into mall_freight_templete_area
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="templeteId != null" >
templete_id,
</if>
<if test="privinceId != null" >
privince_id,
</if>
<if test="cityId != null" >
city_id,
</if>
<if test="areaId != null" >
area_id,
</if>
<if test="status != null" >
status,
</if>
<if test="createUser != null" >
create_user,
</if>
<if test="modifyUser != null" >
modify_user,
</if>
<if test="created == null" >
created,
</if>
<if test="modified == null" >
modified,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id},
</if>
<if test="templeteId != null" >
#{templeteId},
</if>
<if test="privinceId != null" >
#{privinceId},
</if>
<if test="cityId != null" >
#{cityId},
</if>
<if test="areaId != null" >
#{areaId},
</if>
<if test="status != null" >
#{status},
</if>
<if test="createUser != null" >
#{createUser},
</if>
<if test="modifyUser != null" >
#{modifyUser},
</if>
<if test="created == null" >
now(),
</if>
<if test="modified == null" >
now(),
</if>
</trim>
<selectKey resultType="long" keyProperty="id">
SELECT @@IDENTITY AS ID
</selectKey>
</insert>
<select id="countByQuery" parameterType="QueryMallFreightTempleteArea" resultType="java.lang.Long" >
select count(*) from mall_freight_templete_area
<if test="page != null" >
<include refid="Query_Where_Clause" />
</if>
</select>
<update id="updateMallFreightTempleteAreaByIdModified" parameterType="MallFreightTempleteArea" >
update mall_freight_templete_area
<set >
<if test="templeteId != null" >
templete_id = #{templeteId},
</if>
<if test="privinceId != null" >
privince_id = #{privinceId},
</if>
<if test="cityId != null" >
city_id = #{cityId},
</if>
<if test="areaId != null" >
area_id = #{areaId},
</if>
<if test="status != null" >
status = #{status},
</if>
<if test="createUser != null" >
create_user = #{createUser},
</if>
<if test="modifyUser != null" >
modify_user = #{modifyUser},
</if>
<if test="created != null" >
created = #{created},
</if>
<if test="modified != null" >
modified=now(),
</if>
</set>
where id = #{id}
</update>
</mapper>
前端功能实现
功能的实现,主要还是基于element-ui来实现的。这里提几个关键的点,最后也会把源代码给到你的。
列表展示:
主要是通过el-table组件实现的,属性data用于绑定需要展现的数据。需要你定义和操作。
页面数据展示的控制,需要使用v-if指令判断,展示不同的内容
新增/编辑弹框
弹框展示的标题和展示,通过页面定义的数据来控制。
表单中的下拉选项,通过el-select组件来实现。
注意使用的v-for指令,以及你需要在页面上定义你的选项数据。
不同计费方式的动态选择,记得使用v-if指令来进行判断,不同的计费类型,会展示不同的内容。
关键点已经都告诉你一些了,地区设置又是怎么一回事儿呢?不好好看看源码,自己动手去实现一次,比什么都强。
<template>
<div>
<el-form ref="listQuery" :model="listQuery" :inline="true">
<el-form-item label="供应商名称" prop="logisticsName">
<el-input v-model="listQuery.logisticsNameLike" placeholder="请输供应商名称" clearable />
</el-form-item>
<el-form-item label="供应商编码" prop="logisticsCode">
<el-input v-model="listQuery.logisticsCodeCodeLike" placeholder="请输供应商名称" clearable />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="fetchData()">查询</el-button>
<el-button icon="el-icon-s-tools" @click="setDefaultTemplete()">设置默认模板</el-button>
<el-button type="primary" icon="el-icon-edit" @click="addFreightTemplete()">新增</el-button>
</el-form-item>
</el-form>
<div style="margin-top:25px">
<el-table
v-loading="listLoading"
:data="list"
element-loading-text="Loading"
style="width: 100%"
border
>
<el-table-column label="模板" min-width="40%">
<template slot-scope="scope">
{{ scope.row.templeteName }}
</template>
</el-table-column>
<el-table-column label="供应商名称" min-width="40%">
<template slot-scope="scope">
{{ scope.row.logisticsName }}
</template>
</el-table-column>
<el-table-column label="供应商编码" min-width="40%">
<template slot-scope="scope">
{{ scope.row.logisticsCode }}
</template>
</el-table-column>
<el-table-column label="模板类型" min-width="40%">
<template slot-scope="scope">{{ scope.row.templeteType==1?'系统默认':'自定义' }}</template>
</el-table-column>
<el-table-column label="服务类型" min-width="40%">
<template slot-scope="scope">
<template v-if="scope.row.serviceType==1">经济服务</template>
<template v-if="scope.row.serviceType==2">快递服务</template>
<template v-if="scope.row.serviceType==3">标准服务</template>
</template>
</el-table-column>
<el-table-column label="运费类型" min-width="40%">
<template slot-scope="scope">{{ scope.row.freightType==2?'免邮':'按模板计算' }}</template>
</el-table-column>
<el-table-column label="计费类型" min-width="40%">
<template slot-scope="scope">
<template v-if="scope.row.chargeType==1">按数量</template>
<template v-if="scope.row.chargeType==2">按重量</template>
<template v-if="scope.row.chargeType==3">按体积</template>
</template>
</el-table-column>
<el-table-column label="最小限制" min-width="40%">
<template slot-scope="scope">
<template v-if="scope.row.chargeType==1">{{ scope.row.numMin }}</template>
<template v-if="scope.row.chargeType==2">{{ scope.row.weightMin }}</template>
<template v-if="scope.row.chargeType==3">{{ scope.row.volumeMin }}</template>
</template>
</el-table-column>
<el-table-column label="最大限制" min-width="40%">
<template slot-scope="scope">
<template v-if="scope.row.chargeType==1">{{ scope.row.numMax }}</template>
<template v-if="scope.row.chargeType==2">{{ scope.row.weightMax }}</template>
<template v-if="scope.row.chargeType==3">{{ scope.row.volumeMax }}</template>
</template>
</el-table-column>
<el-table-column label="首费" min-width="40%">
<template slot-scope="scope">
<template v-if="scope.row.chargeType==1">{{ scope.row.fristNumPrice }}</template>
<template v-if="scope.row.chargeType==2">{{ scope.row.fristWeightPrice }}</template>
<template v-if="scope.row.chargeType==3">{{ scope.row.fristVolumePrice }}</template>
</template>
</el-table-column>
<el-table-column label="续费" min-width="40%">
<template slot-scope="scope">
<template v-if="scope.row.chargeType==1">{{ scope.row.nextNumPrice }}</template>
<template v-if="scope.row.chargeType==2">{{ scope.row.nextWeightPrice }}</template>
<template v-if="scope.row.chargeType==3">{{ scope.row.nextVolumePrice }}</template>
</template>
</el-table-column>
<el-table-column label="操作" width="260">
<template slot-scope="scope">
<el-button
v-if="scope.row.templeteType==2"
type="primary"
size="mini"
@click="handleUpdate(scope.row)"
>编辑
</el-button>
<el-button
v-if="scope.row.status==1 && scope.row.templeteType==2"
type="primary"
size="mini"
@click="handleDisable(scope.$index, scope.row)"
>停用
</el-button>
<el-button
v-if="scope.row.status==0 && scope.row.templeteType==2"
type="primary"
size="mini"
@click="handleEnable(scope.$index, scope.row)"
>启用
</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.pageSize" @pagination="getList" />
<!-- 新增/编辑弹框 -->
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
<el-form ref="dataForm" :rules="rules" :model="temp" prop="logisticsCode" label-position="right" label-width="120px" style="width: 500px; margin-left:50px;">
<el-form-item label="模板名称:" prop="templeteName">
<el-input v-model="temp.templeteName" maxlength="50" />
</el-form-item>
<el-form-item label="物流供应商:" prop="logisticsName">
<el-select v-model="temp.logisticsName" clearable filterable allow-create placeholder="请选择物流供应商" @change="selectLogistics">
<el-option
v-for="item in logisticsList"
:key="item.id"
:label="item.logisticsName"
:value="item.logisticsCode"
/>
</el-select>
</el-form-item>
<el-form-item label="服务类型:" prop="status">
<el-select v-model="temp.serviceType" placeholder="请选择">
<el-option
v-for="(item,index) in serviceTypeList"
:key="index"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label="运费类型:" prop="status">
<el-select v-model="temp.freightType" placeholder="请选择">
<el-option
v-for="(item,index) in freightTypeList"
:key="index"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label="计费方式:" prop="status">
<el-select v-model="temp.chargeType" placeholder="请选择" @change="changeChargeType">
<el-option
v-for="(item,index) in chargeTypeList"
:key="index"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<template v-if="temp.freightType==1 && temp.chargeType==1">
<el-form-item label="最小数量:" prop="numMin">
<el-input v-model="temp.numMin" maxlength="20" oninput="value.replace(/[^d.]/g,'')" alt="只能是数字" />
</el-form-item>
<el-form-item label="最大数量:" prop="numMax">
<el-input v-model="temp.numMax" maxlength="20" oninput="value.replace(/[^d.]/g,'')" alt="只能是数字" />
</el-form-item>
<el-form-item label="数量首费:" prop="fristNumPrice">
<el-input v-model="temp.fristNumPrice" maxlength="20" oninput="value=value.replace(/[^d.]/g,'')" alt="只能是数字" />
</el-form-item>
<el-form-item label="数量续费:" prop="nextNumPrice">
<el-input v-model="temp.nextNumPrice" maxlength="20" oninput="value=value.replace(/[^d.]/g,'')" alt="只能是数字" />
</el-form-item>
</template>
<template v-if="temp.freightType==1 && temp.chargeType==2">
<el-form-item label="最小重量:" prop="weightMin">
<el-input v-model="temp.weightMin" maxlength="20" oninput="value.replace(/[^d.]/g,'')" alt="只能是数字" />
</el-form-item>
<el-form-item label="最大重量:" prop="weightMin">
<el-input v-model="temp.c" maxlength="20" oninput="value.replace(/[^d.]/g,'')" alt="只能是数字" />
</el-form-item>
<el-form-item label="重量首费:" prop="fristWeightPrice">
<el-input v-model="temp.fristWeightPrice" maxlength="20" oninput="value=value.replace(/[^d.]/g,'')" alt="只能是数字" />
</el-form-item>
<el-form-item label="重量续费:" prop="nextWeightPrice">
<el-input v-model="temp.nextWeightPrice" maxlength="20" oninput="value.replace(/[^d.]/g,'')" alt="只能是数字" />
</el-form-item>
</template>
<template v-if="temp.freightType==1 && temp.chargeType==3">
<el-form-item label="最小体积:" prop="volumeMin">
<el-input v-model="temp.volumeMin" maxlength="20" oninput="value.replace(/[^d.]/g,'')" alt="只能是数字" />
</el-form-item>
<el-form-item label="最大体积:" prop="volumeMax">
<el-input v-model="temp.volumeMax" maxlength="20" oninput="value.replace(/[^d.]/g,'')" alt="只能是数字" />
</el-form-item>
<el-form-item label="体积首费:" prop="fristVolumePrice">
<el-input v-model="temp.fristVolumePrice" maxlength="20" oninput="value=value.replace(/[^d.]/g,'')" alt="只能是数字" />
</el-form-item>
<el-form-item label="体积续费:" prop="nextVolumePrice">
<el-input v-model="temp.nextVolumePrice" maxlength="20" oninput="value.replace(/[^d.]/g,'')" alt="只能是数字" />
</el-form-item>
</template>
<el-form-item label="状态:" prop="status">
<el-select v-model="temp.status" placeholder="请选择">
<el-option
v-for="(item,index) in statusList"
:key="index"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<template v-if="temp.templeteType==2">
<el-button icon="el-icon-s-tools" @click="setArea()">设置地区</el-button>
<template v-if="dialogAreaVisible==true">
<div>
<el-tree
ref="tree"
:data="areaList"
show-checkbox
node-key="id"
:default-expanded-keys="[1,2]"
:default-checked-keys="defaultSelectedArea"
clearable
filterable
allow-create
@check-change="updateKeyChildren"
/>
</div>
</template>
</template>
</el-form>
<div slot="footer">
<el-button @click="dialogFormVisible = false">
取消
</el-button>
<el-button type="primary" @click="saveData()">
确定
</el-button>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import { getLogisticsList, getDefaultTemplete, getFreightTempleteList, selectForFreightTemplete, createFreightTemplete, updateFreightTemplete, enableFreightTemplete, disableFreightTemplete, deleteFreightTemplete } from '@/api/freightManage/carrier'
import Pagination from '@/components/Pagination' // secondary package based on el-pagination
export default {
components: { Pagination },
data() {
return {
listLoading: false,
rules: {
logisticsName: [{ required: true, message: '请输入供应商名称', trigger: 'change' }],
logisticsCode: [{ required: true, message: '请输入供应商编码', trigger: 'change' }],
templeteName: [{ required: true, message: '请输入模板名称', trigger: 'change' }]
},
areaList: [],
selectedArea: [],
defaultSelectedArea: [],
listQuery: {
page: 1,
pageSize: 10
},
listLogisticsQuery: {
page: 1,
pageSize: 500
},
defaultObjQuery: {
page: 1,
pageSize: 1
},
areaQuery: {
page: 1,
pageSize: 1
},
temp: {
id: undefined,
// 物流供应商编码
logisticsCode: '',
// 物流供应商名称L
logisticsName: '',
serviceType: 3,
freightType: 2,
chargeType: 1,
numMin: 1,
numMax: 1,
fristNumPrice: 1,
nextNumPrice: 1,
weightMin: 1,
weightMax: 2,
fristWeightPrice: 1,
nextWeightPrice: 1,
volumeMin: 1,
volumeMax: 1,
fristVolumePrice: 1,
nextVolumePrice: 1,
status: 1
},
defaultObj: null,
logisticsList: [],
dialogStatus: '',
textMap: {
update: '编辑运费模板',
create: '新增运费模板',
setDefault: '设置默认模板'
},
dialogImageUrl: '',
dialogVisible: false,
// 弹框是否显示
dialogFormVisible: false,
dialogAreaVisible: false,
// 分页
total: 0,
// table集合
list: null,
statusList: [
{
code: 1,
name: '启用'
},
{
code: 2,
name: '停用'
}
],
chargeTypeList: [
{
code: 1,
name: '按数量'
},
{
code: 2,
name: '按重量'
}, {
code: 3,
name: '按体积'
}
],
serviceTypeList: [
{
code: 1,
name: '经济服务'
},
{
code: 2,
name: '快递服务'
}, {
code: 3,
name: '标准服务'
}
],
freightTypeList: [
{
code: 1,
name: '自定义运费'
},
{
code: 2,
name: '卖家承担运费'
}
]
}
},
created() {
this.getList()
this.getLogisticsList()
this.findDefaultTemplete()
this.initAreaList()
},
methods: {
saveData() {
if (this.dialogStatus === 'setDefault') {
if (undefined === this.temp.templeteId) {
this.createData()
return
} else {
this.updateData()
return
}
} else if (this.dialogStatus === 'create') {
this.createData()
return
} else {
this.updateData()
return
}
},
// 更新保存方法
updateData() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
const tempData = Object.assign({}, this.temp)
updateFreightTemplete(tempData).then(() => {
const index = this.list.findIndex(v => v.id === this.temp.id)
this.list.splice(index, 1, this.temp)
this.dialogFormVisible = false
this.$notify({
title: 'Success',
message: 'Update Successfully',
type: 'success',
duration: 2000
})
})
}
})
},
// 创建保存方法
createData() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
createFreightTemplete(this.temp).then((res) => {
this.temp.id = res.model.id
this.list.unshift(this.temp)
this.dialogFormVisible = false
this.$notify({
title: 'Success',
message: 'Created Successfully',
type: 'success',
duration: 2000
})
})
}
})
},
// 编辑
handleUpdate(row) {
this.temp = Object.assign({}, row) // copy obj
this.dialogStatus = 'update'
this.dialogFormVisible = true
this.areaQuery.templeteId = this.temp.templeteId
this.initAreaList()
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
// 启用
handleEnable(index, row) {
enableFreightTemplete(Object.assign({}, row)).then((res) => {
this.$notify({
title: 'Success',
message: 'Created Successfully',
type: 'success',
duration: 2000
})
this.getList()
})
},
// 停用
handleDisable(index, row) {
disableFreightTemplete(row).then((res) => {
this.$notify({
title: 'Success',
message: 'Created Successfully',
type: 'success',
duration: 2000
})
this.getList()
})
},
// 删除
handleDelete(index, row) {
deleteFreightTemplete(row).then((res) => {
this.$notify({
title: 'Success',
message: 'Created Successfully',
type: 'success',
duration: 2000
})
this.getList()
})
},
resetTemp() {
this.temp = {
id: undefined,
// 物流供应商编码
logisticsCode: '',
// 物流供应商名称L
logisticsName: '',
serviceType: 3,
templeteType: 2,
freightType: 2,
chargeType: 1,
numMin: 1,
numMax: 1,
fristNumPrice: 1,
nextNumPrice: 1,
weightMin: 1,
weightMax: 2,
fristWeightPrice: 1,
nextWeightPrice: 1,
volumeMin: 1,
volumeMax: 1,
fristVolumePrice: 1,
nextVolumePrice: 1,
status: 1
}
},
// 新增
addFreightTemplete() {
this.resetTemp()
this.dialogStatus = 'create'
this.dialogFormVisible = true
this.areaQuery.templeteId = null
this.initAreaList()
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
setDefaultTemplete() {
if (undefined !== this.defaultObj && this.defaultObj !== null) {
this.temp = this.defaultObj
this.areaQuery.templeteId = null
} else {
this.resetTemp()
this.temp.templeteType = 1
}
this.dialogStatus = 'setDefault'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
// 查询方法
fetchData() {
this.listQuery.page = 1
this.listQuery.pageSize = 10
// this.listQuery.limit = 10
this.getList()
},
// 重置表单
resetForm(formName) {
this.$refs[formName].resetFields()
},
// 列表方法查询
getList() {
this.listLoading = true
getFreightTempleteList(this.listQuery).then(response => {
this.list = response.model
this.total = response.totalItem
// Just to simulate the time of the request
setTimeout(() => {
this.listLoading = false
}, 1.5 * 1000)
})
},
getLogisticsList() {
this.listLoading = true
getLogisticsList(this.listLogisticsQuery).then(response => {
this.logisticsList = response.model
})
setTimeout(() => {
this.listLoading = false
}, 1.5 * 1000)
},
initAreaList() {
this.defaultSelectedArea = []
selectForFreightTemplete(this.areaQuery).then(response => {
var tempList = response.model
if (undefined !== tempList && tempList != null) {
for (let i = 0; i < tempList.length; i ) {
for (let j = 0; j < tempList[i].children.length; j ) {
if (tempList[i].children[j].checkStatus === 1) {
this.defaultSelectedArea.push(tempList[i].children[j].id)
}
}
}
}
this.areaList = tempList
})
console.log(this.defaultSelectedArea)
},
findDefaultTemplete() {
this.listLoading = true
getDefaultTemplete(this.defaultObjQuery).then(response => {
this.defaultObj = response.model
})
setTimeout(() => {
this.listLoading = false
}, 1.5 * 1000)
},
selectLogistics(option) {
let selectedItem = {}
selectedItem = this.logisticsList.find((item) => {
return item.logisticsCode === option
})
this.temp.logisticsCode = option
if (undefined !== selectedItem) {
this.temp.logisticsName = selectedItem.logisticsName
} else {
this.logisticsName = ''
}
},
changeChargeType(option) {
if (option === 1) {
this.temp.weightMin = 0
this.temp.weightMax = 0
this.temp.fristWeightPrice = 0
this.temp.nextWeightPrice = 0
this.temp.volumeMin = 0
this.temp.volumeMax = 0
this.temp.fristVolumePrice = 0
this.temp.nextVolumePrice = 0
}
if (option === 2) {
this.temp.numMin = 0
this.temp.numMax = 0
this.temp.fristNumPrice = 0
this.temp.nextNumPrice = 0
this.temp.volumeMin = 0
this.temp.volumeMax = 0
this.temp.fristVolumePrice = 0
this.temp.nextWeightPrice = 0
}
if (option === 3) {
this.temp.numMin = 0
this.temp.numMax = 0
this.temp.fristNumPrice = 0
this.temp.nextNumPrice = 0
this.temp.weightMin = 0
this.temp.weightMax = 0
this.temp.fristWeightPrice = 0
this.temp.nextWeightPrice = 0
}
},
updateKeyChildren(data, key1, key2) {
const checkedNodes = this.$refs.tree.getCheckedNodes()
if (checkedNodes != null && checkedNodes.length > 0) {
for (let i = 0; i < checkedNodes.length; i ) {
var area = {
id: undefined,
parentId: undefined,
label: '',
level: 1
}
area.id = checkedNodes[i].id
area.label = checkedNodes[i].label
area.level = checkedNodes[i].level
if (undefined !== checkedNodes[i].parentId && checkedNodes[i].parentId !== null) {
area.parentId = checkedNodes[i].parentId
}
this.selectedArea.push(area)
this.temp.selectedArea = this.selectedArea
}
}
},
setArea() {
this.dialogAreaVisible = !this.dialogAreaVisible
}
}
}
</script>
<style scoped>
a, a:focus, a:hover {
cursor: pointer;
color: rgb(67, 149, 255);
text-decoration: none;
margin: 10px;
}
</style>