ソースを参照

feat[litemall-admin,litemall-admin-api]:订单列表,订单æ”收款

linlinjava 5 年 前
コミット
3ed76ec730

+ 32 - 4
litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/service/AdminOrderService.java

@@ -1,5 +1,6 @@
 package org.linlinjava.litemall.admin.service;
 
+import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
 import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
 import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
 import com.github.binarywang.wxpay.exception.WxPayException;
@@ -8,11 +9,13 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.linlinjava.litemall.core.notify.NotifyService;
 import org.linlinjava.litemall.core.notify.NotifyType;
+import org.linlinjava.litemall.core.util.DateTimeUtil;
 import org.linlinjava.litemall.core.util.JacksonUtil;
 import org.linlinjava.litemall.core.util.ResponseUtil;
 import org.linlinjava.litemall.db.domain.*;
 import org.linlinjava.litemall.db.service.*;
 import org.linlinjava.litemall.db.util.CouponUserConstant;
+import org.linlinjava.litemall.db.util.GrouponConstant;
 import org.linlinjava.litemall.db.util.OrderUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -26,6 +29,7 @@ import java.util.List;
 import java.util.Map;
 
 import static org.linlinjava.litemall.admin.util.AdminResponseCode.*;
+import static org.linlinjava.litemall.admin.util.AdminResponseCode.ORDER_PAY_FAILED;
 
 @Service
 
@@ -51,11 +55,10 @@ public class AdminOrderService {
     @Autowired
     private LitemallCouponUserService couponUserService;
 
-    public Object list(Integer userId, String orderSn, LocalDateTime start, LocalDateTime end, List<Short> orderStatusArray,
+    public Object list(String nickname, String consignee, String orderSn, LocalDateTime start, LocalDateTime end, List<Short> orderStatusArray,
                        Integer page, Integer limit, String sort, String order) {
-        List<LitemallOrder> orderList = orderService.querySelective(userId, orderSn, start, end, orderStatusArray, page, limit,
-                sort, order);
-        return ResponseUtil.okList(orderList);
+        Map<String, Object> data = (Map)orderService.queryVoSelective(nickname, consignee, orderSn, start, end, orderStatusArray, page, limit, sort, order);
+        return ResponseUtil.ok(data);
     }
 
     public Object detail(Integer id) {
@@ -287,4 +290,29 @@ public class AdminOrderService {
         return ResponseUtil.ok();
     }
 
+    public Object pay(String body) {
+        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
+        String newMoney = JacksonUtil.parseString(body, "newMoney");
+
+        if (orderId == null || StringUtils.isEmpty(newMoney)) {
+            return ResponseUtil.badArgument();
+        }
+        BigDecimal actualPrice = new BigDecimal(newMoney);
+
+        LitemallOrder order = orderService.findById(orderId);
+        if (order == null) {
+            return ResponseUtil.badArgument();
+        }
+        if (!order.getOrderStatus().equals(OrderUtil.STATUS_CREATE)) {
+            return ResponseUtil.fail(ORDER_PAY_FAILED, "当前订单状态不支持线下收款");
+        }
+
+        order.setActualPrice(actualPrice);
+        order.setOrderStatus(OrderUtil.STATUS_PAY);
+        if (orderService.updateWithOptimisticLocker(order) == 0) {
+            return WxPayNotifyResponse.fail("更新数据已失效");
+        }
+
+        return ResponseUtil.ok();
+    }
 }

+ 1 - 1
litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/util/AdminResponseCode.java

@@ -13,7 +13,7 @@ public class AdminResponseCode {
     public static final Integer ORDER_REFUND_FAILED = 621;
     public static final Integer ORDER_REPLY_EXIST = 622;
     public static final Integer ORDER_DELETE_FAILED = 623;
-    public static final Integer USER_INVALID_NAME = 630;
+    public static final Integer ORDER_PAY_FAILED = 624;public static final Integer USER_INVALID_NAME = 630;
     public static final Integer USER_INVALID_PASSWORD = 631;
     public static final Integer USER_INVALID_MOBILE = 632;
     public static final Integer USER_NAME_EXIST = 633;

+ 8 - 2
litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminOrderController.java

@@ -45,7 +45,7 @@ public class AdminOrderController {
     @RequiresPermissions("admin:order:list")
     @RequiresPermissionsDesc(menu = {"商场管理", "订单管理"}, button = "查询")
     @GetMapping("/list")
-    public Object list(Integer userId, String orderSn,
+    public Object list(String nickname, String consignee, String orderSn,
                        @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime start,
                        @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime end,
                        @RequestParam(required = false) List<Short> orderStatusArray,
@@ -53,7 +53,7 @@ public class AdminOrderController {
                        @RequestParam(defaultValue = "10") Integer limit,
                        @Sort @RequestParam(defaultValue = "add_time") String sort,
                        @Order @RequestParam(defaultValue = "desc") String order) {
-        return adminOrderService.list(userId, orderSn, start, end, orderStatusArray, page, limit, sort, order);
+         return adminOrderService.list(nickname, consignee, orderSn, start, end, orderStatusArray, page, limit, sort, order);
     }
 
     /**
@@ -105,6 +105,12 @@ public class AdminOrderController {
         return adminOrderService.ship(body);
     }
 
+    @RequiresPermissions("admin:order:pay")
+    @RequiresPermissionsDesc(menu = {"商场管理", "订单管理"}, button = "订单收款")
+    @PostMapping("/pay")
+    public Object pay(@RequestBody String body) {
+        return adminOrderService.pay(body);
+    }
 
     /**
      * 删除订单

+ 8 - 0
litemall-admin/src/api/order.js

@@ -36,6 +36,14 @@ export function refundOrder(data) {
   })
 }
 
+export function payOrder(data) {
+  return request({
+    url: '/order/pay',
+    method: 'post',
+    data
+  })
+}
+
 export function deleteOrder(data) {
   return request({
     url: '/order/delete',

+ 200 - 22
litemall-admin/src/views/mall/order.vue

@@ -3,8 +3,8 @@
 
     <!-- 查询和其他操作 -->
     <div class="filter-container">
-      <el-input v-model="listQuery.userId" clearable class="filter-item" style="width: 160px;" placeholder="请输入用户ID" />
-      <el-input v-model="listQuery.orderId" clearable class="filter-item" style="width: 160px;" placeholder="请输入订单ID" />
+      <el-input v-model="listQuery.nickname" clearable class="filter-item" style="width: 160px;" placeholder="请输入用户昵称" />
+      <el-input v-model="listQuery.consignee" clearable class="filter-item" style="width: 160px;" placeholder="请输入收货人名称" />
       <el-input v-model="listQuery.orderSn" clearable class="filter-item" style="width: 160px;" placeholder="请输入订单编号" />
       <el-date-picker v-model="listQuery.timeArray" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss" class="filter-item" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" :picker-options="pickerOptions" />
       <el-select v-model="listQuery.orderStatusArray" multiple style="width: 200px" class="filter-item" placeholder="请选择订单状态">
@@ -17,32 +17,85 @@
     <!-- 查询结果 -->
     <el-table v-loading="listLoading" :data="list" element-loading-text="正在查询中。。。" border fit highlight-current-row>
 
-      <el-table-column align="center" min-width="100" label="订单编号" prop="orderSn" />
+      <el-table-column type="expand">
+        <template slot-scope="props">
+          <div v-for="item in props.row.goodsVoList" :key="item.id" class="order-goods">
+            <div class="picture">
+              <img :src="item.picUrl" width="40">
+            </div>
+            <div class="name">
+              商品名称:{{ item.goodsName }}
+            </div>
+            <div class="spec">
+              规格:{{ item.specifications.join('-') }}
+            </div>
+            <div class="price">
+              单价:{{ item.price }} 元
+            </div>
+            <div class="num">
+              数量:{{ item.number }} 件
+            </div>
+            <div class="price">
+              小计:{{ item.price * item.number }} 元
+            </div>
+          </div>
+        </template>
+      </el-table-column>
 
-      <el-table-column align="center" label="用户ID" prop="userId" />
+      <el-table-column align="center" min-width="120" label="订单编号" prop="orderSn" />
 
+      <el-table-column align="center" label="用户头像" width="80">
+        <template slot-scope="scope">
+          <el-avatar :src="scope.row.avatar" />
+        </template>
+      </el-table-column>
+
+      <el-table-column align="center" label="下单用户" prop="userName" />
+
+      <el-table-column align="center" label="下单时间" prop="addTime" min-width="100">
+        <template slot-scope="scope">
+          {{ (scope.row.addTime || '').substring(0, 10) }}
+        </template>
+      </el-table-column>
       <el-table-column align="center" label="订单状态" prop="orderStatus">
         <template slot-scope="scope">
           <el-tag>{{ scope.row.orderStatus | orderStatusFilter }}</el-tag>
         </template>
       </el-table-column>
 
-      <el-table-column align="center" label="订单金额" prop="orderPrice" />
+      <el-table-column align="center" label="订单金额" prop="orderPrice">
+        <template slot-scope="scope">
+          {{ scope.row.orderPrice }} 元
+        </template>
+      </el-table-column>
 
-      <el-table-column align="center" label="支付金额" prop="actualPrice" />
+      <el-table-column align="center" label="实付金额" prop="actualPrice">
+        <template slot-scope="scope">
+          {{ scope.row.actualPrice }} 元
+        </template>
+      </el-table-column>
 
       <el-table-column align="center" label="支付时间" prop="payTime" />
 
+      <el-table-column align="center" label="收货人" prop="consignee">
+        <template slot-scope="scope">
+          <span style="color:red; font-weight:bold;">{{ scope.row.consignee }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column align="center" label="收货电话" prop="mobile" min-width="100" />
+
       <el-table-column align="center" label="物流单号" prop="shipSn" />
 
       <el-table-column align="center" label="物流渠道" prop="shipChannel" />
 
-      <el-table-column align="center" label="操作" width="250" class-name="small-padding fixed-width">
+      <el-table-column align="center" label="操作" width="250" class-name="oper">
         <template slot-scope="scope">
-          <el-button v-permission="['GET /admin/order/detail']" type="primary" size="mini" @click="handleDetail(scope.row)">详情</el-button>
-          <el-button v-permission="['POST /admin/order/delete']" type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
-          <el-button v-if="scope.row.orderStatus==201" v-permission="['POST /admin/order/ship']" type="primary" size="mini" @click="handleShip(scope.row)">发货</el-button>
-          <el-button v-if="scope.row.orderStatus==202||scope.row.orderStatus==204" v-permission="['POST /admin/order/refund']" type="primary" size="mini" @click="handleRefund(scope.row)">退款</el-button>
+          <el-button type="primary" size="mini" @click="handleDetail(scope.row)">详情</el-button>
+          <el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
+          <el-button type="warning" size="mini" @click="handlePay(scope.row)">收款</el-button>
+          <el-button type="primary" size="mini" @click="handleShip(scope.row)">发货</el-button>
+          <el-button type="danger" size="mini" @click="handleRefund(scope.row)">退款</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -119,6 +172,39 @@
       </span>
     </el-dialog>
 
+    <!-- 收款对话框 -->
+    <el-dialog :visible.sync="payDialogVisible" title="订单收款" width="40%" center>
+      <el-form ref="payForm" :model="payForm" status-icon label-position="left" label-width="100px">
+        <div style="margin-bottom: 10px;">
+          确认当前订单(订单编号 {{ payForm.orderSn }} ) 已经完成线下收款  ?
+        </div>
+        <el-form-item label="订单金额" prop="oldMoney">
+          <el-input-number v-model="payForm.oldMoney" :controls="false" disabled />
+        </el-form-item>
+        <el-form-item label="付款金额" prop="newMoney">
+          <el-input-number v-model="payForm.newMoney" :controls="false" />
+        </el-form-item>
+      </el-form>
+      <el-table :data="payForm.goodsList">
+        <el-table-column property="goodsName" label="商品" />
+        <el-table-column label="规格">
+          <template slot-scope="scope">
+            {{ scope.row.specifications.join('-') }}
+          </template>
+        </el-table-column>
+        <el-table-column property="onumber" width="100" label="下单数量" />
+        <!-- <el-table-column label="实际数量" width="100">
+          <template slot-scope="scope">
+            <el-input-number v-model="scope.row.number" :min="0" :controls="false" />
+          </template>
+        </el-table-column> -->
+      </el-table>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="payDialogVisible = false">取消</el-button>
+        <el-button type="primary" @click="confirmPay">确定</el-button>
+      </div>
+    </el-dialog>
+
     <!-- 发货对话框 -->
     <el-dialog :visible.sync="shipDialogVisible" title="发货">
       <el-form ref="shipForm" :model="shipForm" status-icon label-position="left" label-width="100px" style="width: 400px; margin-left:50px;">
@@ -153,8 +239,53 @@
   </div>
 </template>
 
+<style lang="scss" scoped>
+.el-table--medium th, .el-table--medium td {
+    padding: 3px 0;
+}
+
+.el-input-number--medium {
+  width: 100%;
+}
+
+.oper .el-button--mini {
+  padding: 7px 4px;
+  width: 40px;
+  font-size: 10px;
+  margin-left: 1px;
+}
+
+::v-deep .el-table__expanded-cell {
+  padding: 6px 80px;
+}
+
+.order-goods {
+  display: flex;
+  justify-content: space-around;
+  justify-items: center;
+  align-items:center;
+  padding: 6px 0;
+}
+
+.name {
+  width: 400px;
+}
+
+.spec {
+  width: 180px;
+}
+
+.price {
+  width: 120px;
+}
+
+.num {
+  width: 120px;
+}
+</style>
+
 <script>
-import { detailOrder, listOrder, listChannel, refundOrder, deleteOrder, shipOrder } from '@/api/order'
+import { detailOrder, listOrder, listChannel, refundOrder, payOrder, deleteOrder, shipOrder } from '@/api/order'
 import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
 import checkPermission from '@/utils/permission' // 权限判断函数
 
@@ -186,13 +317,13 @@ export default {
       listQuery: {
         page: 1,
         limit: 20,
-        id: undefined,
-        name: undefined,
+        nickname: undefined,
+        consignee: undefined,
+        orderSn: undefined,
         timeArray: [],
         orderStatusArray: [],
         sort: 'add_time',
-        order: 'desc',
-        orderId:undefined
+        order: 'desc'
       },
       pickerOptions: {
         shortcuts: [{
@@ -234,6 +365,14 @@ export default {
         shipSn: undefined
       },
       shipDialogVisible: false,
+      payForm: {
+        orderId: undefined,
+        orderSn: '',
+        oldMoney: 0,
+        newMoney: 0,
+        goodsList: []
+      },
+      payDialogVisible: false,
       refundForm: {
         orderId: undefined,
         refundMoney: undefined
@@ -258,12 +397,12 @@ export default {
         this.listQuery.start = null
         this.listQuery.end = null
       }
-      if(this.listQuery.orderId){
+      if (this.listQuery.orderId) {
         detailOrder(this.listQuery.orderId).then(response => {
-          this.list = [];
-          if(response.data.data.order){
-            this.list.push(response.data.data.order);
-            this.total = 1;
+          this.list = []
+          if (response.data.data.order) {
+            this.list.push(response.data.data.order)
+            this.total = 1
             this.listLoading = false
           }
         }).catch(() => {
@@ -271,7 +410,7 @@ export default {
           this.total = 0
           this.listLoading = false
         })
-      }else{
+      } else {
         listOrder(this.listQuery).then(response => {
           this.list = response.data.data.list
           this.total = response.data.data.total
@@ -298,6 +437,45 @@ export default {
       })
       this.orderDialogVisible = true
     },
+    handlePay(row) {
+      this.payForm.orderId = row.id
+      this.payForm.orderSn = row.orderSn
+      this.payForm.oldMoney = row.actualPrice
+      this.payForm.newMoney = row.actualPrice
+      this.payForm.goodsList = row.goodsVoList
+      this.payForm.goodsList.forEach(element => {
+        element.onumber = element.number
+      })
+      this.payDialogVisible = true
+    },
+    confirmPay() {
+      if (this.payForm.oldMoney !== this.payForm.newMoney) {
+        const diff = this.payForm.newMoney - this.payForm.oldMoney
+        this.$confirm('差额 ' + diff + '元, 是否确认提交')
+          .then(_ => {
+            this.confirmPay2()
+          })
+          .catch(_ => {})
+      } else {
+        this.confirmPay2()
+      }
+    },
+    confirmPay2() {
+      payOrder(this.payForm).then(response => {
+        this.$notify.success({
+          title: '成功',
+          message: '订单收款操作成功'
+        })
+        this.getList()
+      }).catch(response => {
+        this.$notify.error({
+          title: '失败',
+          message: response.data.errmsg
+        })
+      }).finally(() => {
+        this.payDialogVisible = false
+      })
+    },
     handleShip(row) {
       this.shipForm.orderId = row.id
       this.shipForm.shipChannel = row.shipChannel

+ 5 - 0
litemall-db/src/main/java/org/linlinjava/litemall/db/dao/OrderMapper.java

@@ -2,9 +2,14 @@ package org.linlinjava.litemall.db.dao;
 
 import org.apache.ibatis.annotations.Param;
 import org.linlinjava.litemall.db.domain.LitemallOrder;
+import org.linlinjava.litemall.db.domain.OrderVo;
 
 import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
 
 public interface OrderMapper {
     int updateWithOptimisticLocker(@Param("lastUpdateTime") LocalDateTime lastUpdateTime, @Param("order") LitemallOrder order);
+    List<Map> getOrderIds(@Param("query") String query, @Param("orderByClause") String orderByClause);
+    List<OrderVo> getOrderList(@Param("query") String query, @Param("orderByClause") String orderByClause);
 }

+ 88 - 0
litemall-db/src/main/java/org/linlinjava/litemall/db/domain/OrderGoodsVo.java

@@ -0,0 +1,88 @@
+package org.linlinjava.litemall.db.domain;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+
+public class OrderGoodsVo {
+    private Integer id;
+    private String goodsName;
+    private String picUrl;
+    private Integer goodsId;
+    private Integer productId;
+    private String[] specifications;
+    private Integer number;
+    private BigDecimal price;
+    private String location;
+
+    public Integer getProductId() {
+        return productId;
+    }
+
+    public void setProductId(Integer productId) {
+        this.productId = productId;
+    }
+
+    public Integer getGoodsId() {
+        return goodsId;
+    }
+
+    public void setGoodsId(Integer goodsId) {
+        this.goodsId = goodsId;
+    }
+
+    public String getLocation() {
+        return location;
+    }
+
+    public void setLocation(String location) {
+        this.location = location;
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+    public String getPicUrl() {
+        return picUrl;
+    }
+
+    public void setPicUrl(String picUrl) {
+        this.picUrl = picUrl;
+    }
+
+    public String getGoodsName() {
+        return goodsName;
+    }
+
+    public void setGoodsName(String goodsName) {
+        this.goodsName = goodsName;
+    }
+
+    public String[] getSpecifications() {
+        return specifications;
+    }
+
+    public void setSpecifications(String[] specifications) {
+        this.specifications = specifications;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public BigDecimal getPrice() {
+        return price;
+    }
+
+    public void setPrice(BigDecimal price) {
+        this.price = price;
+    }
+
+}

+ 204 - 0
litemall-db/src/main/java/org/linlinjava/litemall/db/domain/OrderVo.java

@@ -0,0 +1,204 @@
+package org.linlinjava.litemall.db.domain;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+
+public class OrderVo {
+    private Integer id;
+    private String orderSn;
+    private Integer orderStatus;
+    private BigDecimal actualPrice;
+    private BigDecimal integralPrice;
+    private BigDecimal freightPrice;
+    private BigDecimal orderPrice;
+    private LocalDateTime addTime;
+    private Integer userId;
+    private String userName;
+    private String userAvatar;
+    private String consignee;
+    private String address;
+    private String mobile;
+    private String shipChannel;
+    private String shipSn;
+    private String message;
+    private LocalDateTime payTime;
+    private List<OrderGoodsVo> goodsVoList;
+
+    public LocalDateTime getPayTime() {
+        return payTime;
+    }
+
+    public void setPayTime(LocalDateTime payTime) {
+        this.payTime = payTime;
+    }
+
+    public BigDecimal getIntegralPrice() {
+        return integralPrice;
+    }
+
+    public void setIntegralPrice(BigDecimal integralPrice) {
+        this.integralPrice = integralPrice;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getShipChannel() {
+        return shipChannel;
+    }
+
+    public void setShipChannel(String shipChannel) {
+        this.shipChannel = shipChannel;
+    }
+
+    public String getShipSn() {
+        return shipSn;
+    }
+
+    public void setShipSn(String shipSn) {
+        this.shipSn = shipSn;
+    }
+
+    public BigDecimal getOrderPrice() {
+        return orderPrice;
+    }
+
+    public void setOrderPrice(BigDecimal orderPrice) {
+        this.orderPrice = orderPrice;
+    }
+
+    public BigDecimal getFreightPrice() {
+        return freightPrice;
+    }
+
+    public void setFreightPrice(BigDecimal freightPrice) {
+        this.freightPrice = freightPrice;
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getOrderSn() {
+        return orderSn;
+    }
+
+    public void setOrderSn(String orderSn) {
+        this.orderSn = orderSn;
+    }
+
+    public Integer getOrderStatus() {
+        return orderStatus;
+    }
+
+    public void setOrderStatus(Integer orderStatus) {
+        this.orderStatus = orderStatus;
+    }
+
+    public BigDecimal getActualPrice() {
+        return actualPrice;
+    }
+
+    public void setActualPrice(BigDecimal actualPrice) {
+        this.actualPrice = actualPrice;
+    }
+
+    public LocalDateTime getAddTime() {
+        return addTime;
+    }
+
+    public void setAddTime(LocalDateTime addTime) {
+        this.addTime = addTime;
+    }
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getUserAvatar() {
+        return userAvatar;
+    }
+
+    public void setUserAvatar(String userAvatar) {
+        this.userAvatar = userAvatar;
+    }
+
+    public String getConsignee() {
+        return consignee;
+    }
+
+    public void setConsignee(String consignee) {
+        this.consignee = consignee;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public String getMobile() {
+        return mobile;
+    }
+
+    public void setMobile(String mobile) {
+        this.mobile = mobile;
+    }
+
+    public List<OrderGoodsVo> getGoodsVoList() {
+        return goodsVoList;
+    }
+
+    public void setGoodsVoList(List<OrderGoodsVo> goodsVoList) {
+        this.goodsVoList = goodsVoList;
+    }
+
+    @Override
+    public String toString() {
+        return "OrderVo{" +
+                "id=" + id +
+                ", orderSn='" + orderSn + '\'' +
+                ", orderStatus=" + orderStatus +
+                ", actualPrice=" + actualPrice +
+                ", integralPrice=" + integralPrice +
+                ", freightPrice=" + freightPrice +
+                ", orderPrice=" + orderPrice +
+                ", addTime=" + addTime +
+                ", userId=" + userId +
+                ", userName='" + userName + '\'' +
+                ", userAvatar='" + userAvatar + '\'' +
+                ", consignee='" + consignee + '\'' +
+                ", address='" + address + '\'' +
+                ", mobile='" + mobile + '\'' +
+                ", shipChannel='" + shipChannel + '\'' +
+                ", shipSn='" + shipSn + '\'' +
+                ", message='" + message + '\'' +
+                ", payTime=" + payTime +
+                ", goodsVoList=" + goodsVoList +
+                '}';
+    }
+}

+ 55 - 4
litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallOrderService.java

@@ -1,10 +1,12 @@
 package org.linlinjava.litemall.db.service;
 
+import com.github.pagehelper.Page;
 import com.github.pagehelper.PageHelper;
 import org.linlinjava.litemall.db.dao.LitemallOrderMapper;
 import org.linlinjava.litemall.db.dao.OrderMapper;
 import org.linlinjava.litemall.db.domain.LitemallOrder;
 import org.linlinjava.litemall.db.domain.LitemallOrderExample;
+import org.linlinjava.litemall.db.domain.OrderVo;
 import org.linlinjava.litemall.db.util.OrderUtil;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
@@ -13,10 +15,7 @@ import javax.annotation.Resource;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
+import java.util.*;
 
 @Service
 public class LitemallOrderService {
@@ -204,4 +203,56 @@ public class LitemallOrderService {
         order.setUpdateTime(LocalDateTime.now());
         litemallOrderMapper.updateByPrimaryKeySelective(order);
     }
+
+
+    public Map<String, Object> queryVoSelective(String nickname, String consignee, String orderSn, LocalDateTime start, LocalDateTime end, List<Short> orderStatusArray, Integer page, Integer limit, String sort, String order) {
+        List<String> querys = new ArrayList<>(4);
+        if (!StringUtils.isEmpty(nickname)) {
+            querys.add(" u.nickname like '%" + nickname + "%' ");
+        }
+        if (!StringUtils.isEmpty(consignee)) {
+            querys.add(" o.consignee like '%" + consignee + "%' ");
+        }
+        if (!StringUtils.isEmpty(orderSn)) {
+            querys.add(" o.order_sn = '" + orderSn + "' ");
+        }
+        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        if (start != null) {
+            querys.add(" o.add_time >= '" + df.format(start) + "' ");
+        }
+        if (end != null) {
+            querys.add(" o.add_time < '" + df.format(end) + "' ");
+        }
+        if (orderStatusArray != null && orderStatusArray.size() > 0) {
+            querys.add(" o.order_status in (" + StringUtils.collectionToDelimitedString(orderStatusArray, ",") + ") ");
+        }
+        querys.add(" o.deleted = 0 and og.deleted = 0 ");
+        String query = StringUtils.collectionToDelimitedString(querys, "and");
+        String orderByClause = null;
+        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
+            orderByClause = "o." + sort + " " + order +", o.id desc ";
+        }
+
+        PageHelper.startPage(page, limit);
+        Page<Map> list1 = (Page) orderMapper.getOrderIds(query, orderByClause);
+        List<Integer> ids = new ArrayList<>();
+        for (Map map : list1) {
+            Integer id = (Integer) map.get("id");
+            ids.add(id);
+        }
+
+        List<OrderVo> list2 = new ArrayList<>();
+        if (!ids.isEmpty()) {
+            querys.add(" o.id in (" + StringUtils.collectionToDelimitedString(ids, ",") + ") ");
+            query = StringUtils.collectionToDelimitedString(querys, "and");
+            list2 = orderMapper.getOrderList(query, orderByClause);
+        }
+        Map<String, Object> data = new HashMap<String, Object>(5);
+        data.put("list", list2);
+        data.put("total", list1.getTotal());
+        data.put("page", list1.getPageNum());
+        data.put("limit", list1.getPageSize());
+        data.put("pages", list1.getPages());
+        return data;
+    }
 }

+ 71 - 0
litemall-db/src/main/resources/org/linlinjava/litemall/db/dao/OrderMapper.xml

@@ -100,4 +100,75 @@
         </set>
         where id = #{order.id,jdbcType=INTEGER} and update_time = #{lastUpdateTime,jdbcType=INTEGER}
     </update>
+
+    <select id="getOrderIds" resultType="hashmap">
+        select o.id, o.add_time
+        from litemall_order o
+        left join litemall_user u
+        on o.user_id = u.id
+        left join litemall_order_goods og
+        on o.id = og.order_id
+        <where>
+            <if test="query != null">
+                ${query}
+            </if>
+        </where>
+        group by o.id
+        <if test="orderByClause != null">
+            order by ${orderByClause}
+        </if>
+    </select>
+    <resultMap type="org.linlinjava.litemall.db.domain.OrderVo" id="orderList">
+        <id column="id" property="id"/>
+        <result column="order_sn" property="orderSn"/>
+        <result column="order_status" property="orderStatus"/>
+        <result column="actual_price" property="actualPrice"/>
+        <result column="freight_price" property="freightPrice"/>
+        <result column="integral_price" property="integralPrice"/>
+        <result column="order_price" property="orderPrice"/>
+        <result column="pay_time" property="payTime"/>
+        <result column="add_time" property="addTime"/>
+        <result column="ship_channel" property="shipChannel"/>
+        <result column="ship_sn" property="shipSn"/>
+        <result column="consignee" property="consignee"/>
+        <result column="address" property="address"/>
+        <result column="mobile" property="mobile"/>
+        <result column="message" property="message"/>
+        <result column="user_id" property="userId"/>
+        <result column="user_name" property="userName"/>
+        <result column="user_avatar" property="userAvatar"/>
+
+        <collection property="goodsVoList" ofType="org.linlinjava.litemall.db.domain.OrderGoodsVo">
+            <id column="ogid" property="id"/>
+            <result column="goods_id" property="goodsId"/>
+            <result column="product_id" property="productId"/>
+            <result column="goods_name" property="goodsName"/>
+            <result column="goods_picture" property="picUrl"/>
+            <result column="goods_specifications" property="specifications" typeHandler="org.linlinjava.litemall.db.mybatis.JsonStringArrayTypeHandler"/>
+            <result column="goods_number" property="number"/>
+            <result column="goods_price" property="price"/>
+        </collection>
+    </resultMap>
+    <select id="getOrderList" resultMap="orderList">
+        select o.id, o.order_sn, o.order_status, o.actual_price, o.freight_price, o.add_time, o.message,
+        o.consignee, o.address, o.mobile, o.pay_time, o.order_price, o.ship_channel, o.ship_sn,
+        u.id user_id, u.nickname user_name, u.avatar user_avatar, o.integral_price,
+        og.id ogid, og.goods_id, og.product_id, og.goods_name, og.pic_url goods_picture,
+        og.specifications goods_specifications, og.number goods_number, og.price goods_price
+        from litemall_order o
+        left join litemall_user u
+        on o.user_id = u.id
+        left join litemall_order_goods og
+        on o.id = og.order_id
+        left join litemall_goods g
+        on og.goods_id = g.id
+        <where>
+            <if test="query != null">
+                ${query}
+            </if>
+        </where>
+        <if test="orderByClause != null">
+            order by ${orderByClause}
+        </if>
+    </select>
 </mapper>