樂優商城(三十八)——訂單微服務
阿新 • • 發佈:2018-11-03
目錄
五、地址管理
5.1 頁面效果
點選“新增收貨地址”和“編輯”都會彈出模態框,如下所示:
5.2 資料庫表設計
CREATE TABLE `tb_address` ( `id` bigint(20) NOT NULL COMMENT '地址id\r\n', `name` varchar(50) DEFAULT NULL COMMENT '收貨人姓名', `phone` varchar(50) NOT NULL COMMENT '收貨人電話', `zip_code` varchar(50) DEFAULT NULL COMMENT '郵編', `state` varchar(50) DEFAULT NULL COMMENT '省份', `city` varchar(50) DEFAULT NULL COMMENT '市', `district` varchar(50) DEFAULT NULL COMMENT '區/縣', `address` varchar(100) DEFAULT NULL COMMENT '詳細地址', `default` tinyint(1) DEFAULT NULL COMMENT '1:預設地址 0:非預設地址', `userId` bigint(20) NOT NULL COMMENT '使用者id', `label` varchar(20) DEFAULT NULL COMMENT '地址標籤', PRIMARY KEY (`id`) USING BTREE, KEY `userId` (`userId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
5.3 頁面優化
5.3.1 在data中定義資料
5.3.2 模態框
改造模態框,繫結資料
<div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" data-dismiss="modal" aria-hidden="true" class="sui-close">×</button> <h4 id="myModalLabel" class="modal-title">{{isEdit ? "編輯" : "新增"}}收貨地址</h4> </div> <div class="modal-body"> <form action="" class="sui-form form-horizontal"> <div class="control-group"> <label class="control-label">收貨人:</label> <div class="controls"> <input type="text" v-model="addressForm.name" class="input-medium"> </div> </div> <div class="control-group"> <label class="control-label">聯絡電話:</label> <div class="controls"> <input type="text" v-model="addressForm.phone" class="input-medium"> </div> </div> <div class="control-group"> <label class="control-label">省:</label> <div class="controls"> <input type="text" v-model="addressForm.state" class="input-medium"> </div> </div> <div class="control-group"> <label class="control-label">市:</label> <div class="controls"> <input type="text" v-model="addressForm.city" class="input-medium"> </div> </div> <div class="control-group"> <label class="control-label">區/縣:</label> <div class="controls"> <input type="text" v-model="addressForm.district" class="input-medium"> </div> </div> <div class="control-group"> <label class="control-label">郵編:</label> <div class="controls"> <input type="text" v-model="addressForm.zipCode" class="input-medium"> </div> </div> <div class="control-group"> <label class="control-label">詳細地址:</label> <div class="controls"> <input type="text" v-model="addressForm.address" class="input-large"> </div> </div> <div class="control-group"> <label class="control-label">地址標籤:</label> <div class="controls"> <select class="select" v-model="addressForm.label"> <option value="家">家</option> <option value="公司">公司</option> <option value="學校">學校</option> </select> </div> </div> <div class="control-group"> <div style="margin-left: 100px"> <input type="checkbox" v-model="addressForm.defaultAddress" class="checkbox">設為預設收貨地址 </div> </div> </form> </div> <div class="modal-footer"> <button type="button" @click="addressSave" data-ok="modal" class="sui-btn btn-primary btn-large">確定</button> <button type="button" data-dismiss="modal" class="sui-btn btn-default btn-large">取消</button> </div> </div> </div>
5.3.3 方法繫結
新增地址:
修改地址:
模態框資料提交:
關閉模態框(兩個地方):
5.3.4 效果展示
點選確定,檢視提交的資料:
5.4 後臺介面
5.4.1 實體類
package com.leyou.order.pojo;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
/**
* @Author: 98050
* @Time: 2018-10-30 23:08
* @Feature: 收貨地址
*/
@Table(name = "tb_address")
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* 使用者id
*/
@NotNull
private Long userId;
/**
* 收貨人
*/
private String name;
/**
* 收貨電話
*/
private String phone;
/**
* 郵編
*/
private String zipCode;
/**
* 省
*/
private String state;
/**
* 市
*/
private String city;
/**
* 區/縣
*/
private String district;
/**
* 詳細地址
*/
private String address;
/**
* 是否是預設地址
*/
private boolean defaultAddress;
/**
* 地址標籤
*/
private String label;
}
5.4.2 Controller
最基本的CRUD,沒什麼可說的,直接上程式碼。需要注意的是,因為配置了使用者登入攔截器,需要的使用者資訊從後臺獲取。
package com.leyou.order.controller;
import com.leyou.order.pojo.Address;
import com.leyou.order.service.AddressService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* @Author: 98050
* @Time: 2018-10-31 09:44
* @Feature: 地址CRUD
*/
@RestController
@RequestMapping("address")
@Api("地址管理")
public class AddressController {
@Autowired
private AddressService addressService;
/**
* 建立收貨地址
* @return
*/
@PostMapping
@ApiOperation(value = "建立收貨地址介面",notes = "建立地址")
@ApiImplicitParam(name = "address",required = true,value = "地址物件")
@ApiResponses({
@ApiResponse(code = 201, message = "地址建立成功"),
@ApiResponse(code = 500,message = "伺服器異常")
})
public ResponseEntity<Void> addAddressByUserId(@RequestBody @Valid Address address){
System.out.println(address.getDefaultAddress());
this.addressService.addAddressByUserId(address);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
/**
* 根據使用者id查詢地址列表
* @return
*/
@GetMapping
@ApiOperation(value = "查詢收貨地址介面,返回地址列表",notes = "查詢地址")
@ApiResponses({
@ApiResponse(code = 200, message = "地址列表"),
@ApiResponse(code = 404,message = "沒有查詢到結果"),
@ApiResponse(code = 500,message = "伺服器異常")
})
public ResponseEntity<List<Address>> queryAddressByUserId(){
List<Address> addresses = this.addressService.queryAddressByUserId();
if (addresses == null || addresses.size() == 0){
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
return ResponseEntity.ok(addresses);
}
/**
* 修改收貨地址
* @param address
* @return
*/
@PutMapping
@ApiOperation(value = "修改收貨地址介面",notes = "修改地址")
@ApiImplicitParam(name = "address", required=true, value = "地址物件")
@ApiResponses({
@ApiResponse(code = 204, message = "修改成功"),
@ApiResponse(code = 500,message = "伺服器異常")
})
public ResponseEntity<Void> updateAddressByUserId(@RequestBody Address address){
this.addressService.updateAddressByUserId(address);
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}
/**
* 刪除收貨地址
* @param addressId
* @return
*/
@DeleteMapping("{addressId}")
@ApiOperation(value = "刪除收貨地址介面",notes = "建立地址")
@ApiImplicitParam(name = "addressId", required=true, value = "地址id")
@ApiResponses({
@ApiResponse(code = 200, message = "地址刪除成功"),
@ApiResponse(code = 500,message = "伺服器異常")
})
public ResponseEntity<Void> deleteAddress(@PathVariable("addressId") Long addressId){
this.addressService.deleteAddress(addressId);
return ResponseEntity.status(HttpStatus.OK).build();
}
@GetMapping("{addressId}")
@ApiOperation(value = "根據id查詢收貨地址介面",notes = "查詢地址")
@ApiImplicitParam(name = "addressId", required=true, value = "地址id")
@ApiResponses({
@ApiResponse(code = 200, message = "查詢成功"),
@ApiResponse(code = 404, message = "查詢失敗"),
@ApiResponse(code = 500,message = "伺服器異常")
})
public ResponseEntity<Address> queryAddressById(@PathVariable("addressId") Long addressId){
Address address = this.addressService.queryAddressById(addressId);
if (address == null){
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
return ResponseEntity.ok(address);
}
}
5.4.3 Mapper
package com.leyou.order.mapper;
import com.leyou.order.pojo.Address;
import tk.mybatis.mapper.common.Mapper;
/**
* @Author: 98050
* @Time: 2018-10-31 09:41
* @Feature:
*/
public interface AddressMapper extends Mapper<Address> {
}
5.4.4 Service
介面
package com.leyou.order.service;
import com.leyou.order.pojo.Address;
import java.util.List;
/**
* @Author: 98050
* @Time: 2018-10-31 09:43
* @Feature:
*/
public interface AddressService {
/**
* 刪除地址
* @param addressId
*/
void deleteAddress(Long addressId);
/**
* 更新地址
* @param address
*/
void updateAddressByUserId(Address address);
/**
* 查詢地址
* @return
*/
List<Address> queryAddressByUserId();
/**
* 新增收貨地址
* @param address
*/
void addAddressByUserId(Address address);
/**
* 根據地址id查詢地址
* @param addressId
* @return
*/
Address queryAddressById(Long addressId);
}
實現
package com.leyou.order.service.impl;
import com.leyou.auth.entity.UserInfo;
import com.leyou.order.interceptor.LoginInterceptor;
import com.leyou.order.mapper.AddressMapper;
import com.leyou.order.pojo.Address;
import com.leyou.order.service.AddressService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import java.util.List;
/**
* @Author: 98050
* @Time: 2018-10-31 09:44
* @Feature:
*/
@Service
public class AddressServiceImpl implements AddressService {
@Autowired
private AddressMapper addressMapper;
@Override
public void deleteAddress(Long addressId) {
UserInfo userInfo = LoginInterceptor.getLoginUser();
Example example = new Example(Address.class);
example.createCriteria().andEqualTo("userId",userInfo.getId()).andEqualTo("id",addressId);
this.addressMapper.deleteByExample(example);
}
@Override
public void updateAddressByUserId(Address address) {
UserInfo userInfo = LoginInterceptor.getLoginUser();
address.setUserId(userInfo.getId());
this.addressMapper.updateByPrimaryKeySelective(address);
}
@Override
public List<Address> queryAddressByUserId() {
UserInfo userInfo = LoginInterceptor.getLoginUser();
Example example = new Example(Address.class);
example.createCriteria().andEqualTo("userId",userInfo.getId());
return this.addressMapper.selectByExample(example);
}
@Override
public void addAddressByUserId(Address address) {
UserInfo userInfo = LoginInterceptor.getLoginUser();
address.setUserId(userInfo.getId());
this.addressMapper.insert(address);
}
@Override
public Address queryAddressById(Long addressId) {
UserInfo userInfo = LoginInterceptor.getLoginUser();
Example example = new Example(Address.class);
example.createCriteria().andEqualTo("id",addressId).andEqualTo("userId",userInfo.getId());
return this.addressMapper.selectByExample(example).get(0);
}
}
5.5 介面測試
在進行介面測試時,必須要設定cookie,假設使用者已經登入。可以使用工具:Edit This Cookie
5.5.1 新增地址
{
"name":"王五",
"phone":"18834888888",
"zipCode":"123132",
"state":"陝西省",
"city":"西安市",
"district":"碑林區",
"address":"陝西省西安市碑林區",
"label":"學校",
"defaultAddress":true
}
結果:
檢視資料庫:
5.5.2 查詢地址
結果:
5.5.3 修改地址
結果:
資料庫:
5.5.4 刪除地址
結果:
資料庫:
5.5.5 根據地址id查詢地址
結果:
5.6 頁面改造
5.6.1 地址查詢
在頁面載入時,查詢當前登入使用者下所有地址資訊。然後儲存在可選地址列表addresses中進行渲染,查詢地址時將預設地址放在第一位:
頁面渲染:
<ul class="addr-detail">
<li class="addr-item" v-for="(a,i) in addresses" :key="i">
<div>
<div :class="{con:true,name:true,selected:i === selectedAddress}"><a href="javascript:;" @click.stop="selectedAddress=i" >{{a.name}}<span title="點選取消選擇"></span> </a></div>
<div class="con address">{{a.state + a.city + a.district + a.address}} <span>{{a.phone}}</span>
<span class="base" v-if="a.defaultAddress">預設地址</span>
<span class="edittext">
<a data-toggle="modal" @click="editAddress(a.id)" data-target=".edit" data-keyboard="false" >編輯</a>
<a href="javascript:;" @click="deleteAddress(a.id)">刪除</a></span>
</div>
<div class="clearfix"></div>
</div>
</li>
</ul>
效果:
5.6.2 預設地址
一個使用者只設置一個預設地址,那麼在新增和修改地址時就要做處理,如果新增或修改的地址被設定為預設地址,那麼該使用者下其它地址都是非預設地址,對AddressServiceImpl中進行修改:
新增方法:setDefaultAddress
public void setDefaultAddress(Address address){
if (address.getDefaultAddress()){
//如果將本地址設定為預設地址,那麼該使用者下的其他地址都應該是非預設地址
List<Address> addressList = this.queryAddressByUserId();
addressList.forEach(addressTemp -> {
if (addressTemp.getDefaultAddress()){
addressTemp.setDefaultAddress(false);
this.addressMapper.updateByPrimaryKeySelective(addressTemp);
}
} );
}
}
5.6.3 地址新增
模態框開啟,輸入資訊,然後點選儲存。這裡面儲存修改二合一,通過isEdit來判斷是修改還是新增:
addressSave(){
//1.驗證是否登入
ly.verifyUser().then(() => {
//2.登入,發起請求,儲存或者修改地址
if (this.isEdit === false) {
//2.1新增
ly.http.post("/address", this.addressForm).then(() => {
//儲存成功,重新載入資料
this.loadData();
//清空表單
this.clear();
}).catch()
}else {
//2.2 修改
ly.http.put("/address", this.addressForm).then(() => {
//修改成功,重新載入資料
this.loadData();
//清空表單
this.clear();
}).catch()
}
}).catch(() => {
//3.未登入
window.location.href = "/login.html?returnUrl=" + window.location.href;
});
}
5.6.4 地址修改
當點選修改時,通過傳入的地址id查詢相應地址資訊,然後回顯到表單中
editAddress(id){
this.isEdit = true;
ly.verifyUser().then(() => {
ly.http.get("address/"+id).then(({data}) => {
this.addressForm = data;
})
}).catch(() => {
window.location = "/login.html?returnUrl=" + window.location.href;
})
},
5.6.5 地址刪除
deleteAddress(id){
ly.verifyUser().then(() => {
ly.http.delete("/address/"+id).then(() => {
this.loadData();
})
}).catch(() => {
window.location.href = "/login.html?returnUrl=" + window.location.href;
});
}