Commit c5408965ebf63ef1c9fc4639f455d857818c51de

Authored by YunaiV
1 parent fc48ab49

trade:增加管理后台的订单详情接口

yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.http
... ... @@ -2,3 +2,8 @@
2 2 GET {{baseUrl}}/trade/order/page?pageNo=1&pageSize=10
3 3 Authorization: Bearer {{token}}
4 4 tenant-id: {{adminTenentId}}
  5 +
  6 +### 获得交易订单分页 => 成功
  7 +GET {{baseUrl}}/trade/order/get-detail?id=21
  8 +Authorization: Bearer {{token}}
  9 +tenant-id: {{adminTenentId}}
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java
... ... @@ -3,9 +3,12 @@ package cn.iocoder.yudao.module.trade.controller.admin.order;
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
  7 +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
6 8 import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi;
7 9 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
8 10 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO;
  11 +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO;
9 12 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO;
10 13 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO;
11 14 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
... ... @@ -13,6 +16,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
13 16 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
14 17 import cn.iocoder.yudao.module.trade.service.order.TradeOrderService;
15 18 import io.swagger.annotations.Api;
  19 +import io.swagger.annotations.ApiImplicitParam;
16 20 import io.swagger.annotations.ApiOperation;
17 21 import lombok.extern.slf4j.Slf4j;
18 22 import org.springframework.security.access.prepost.PreAuthorize;
... ... @@ -38,6 +42,8 @@ public class TradeOrderController {
38 42  
39 43 @Resource
40 44 private ProductPropertyValueApi productPropertyValueApi;
  45 + @Resource
  46 + private MemberUserApi memberUserApi;
41 47  
42 48 @GetMapping("/page")
43 49 @ApiOperation("获得交易订单分页")
... ... @@ -58,6 +64,24 @@ public class TradeOrderController {
58 64 return success(TradeOrderConvert.INSTANCE.convertPage(pageResult, orderItems, propertyValueDetails));
59 65 }
60 66  
  67 + @GetMapping("/get-detail")
  68 + @ApiOperation("获得交易订单详情")
  69 + @ApiImplicitParam(name = "id", value = "订单编号", required = true, example = "1")
  70 + @PreAuthorize("@ss.hasPermission('trade:order:query')")
  71 + public CommonResult<TradeOrderDetailRespVO> getOrderDetail(@RequestParam("id") Long id) {
  72 + // 查询订单
  73 + TradeOrderDO order = tradeOrderService.getOrder(id);
  74 + // 查询订单项
  75 + List<TradeOrderItemDO> orderItems = tradeOrderService.getOrderItemListByOrderId(id);
  76 + // 查询商品属性
  77 + List<ProductPropertyValueDetailRespDTO> propertyValueDetails = productPropertyValueApi
  78 + .getPropertyValueDetailList(TradeOrderConvert.INSTANCE.convertPropertyValueIds(orderItems));
  79 + // 查询会员
  80 + MemberUserRespDTO user = memberUserApi.getUser(order.getUserId());
  81 + // 最终组合
  82 + return success(TradeOrderConvert.INSTANCE.convert(order, orderItems, propertyValueDetails, user));
  83 + }
  84 +
61 85 @PostMapping("/delivery")
62 86 @ApiOperation("发货订单")
63 87 @PreAuthorize("@ss.hasPermission('trade:order:delivery')")
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDetailRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.order.vo;
  2 +
  3 +import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
  4 +import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
  5 +import io.swagger.annotations.ApiModel;
  6 +import io.swagger.annotations.ApiModelProperty;
  7 +import lombok.Data;
  8 +
  9 +import java.util.List;
  10 +
  11 +@ApiModel("管理后台 - 交易订单的详情 Response VO")
  12 +@Data
  13 +public class TradeOrderDetailRespVO extends TradeOrderBaseVO {
  14 +
  15 + @ApiModelProperty(value = "收件人地区名字", required = true, example = "上海 上海市 普陀区")
  16 + private String receiverAreaName;
  17 +
  18 + /**
  19 + * 订单项列表
  20 + */
  21 + private List<Item> items;
  22 +
  23 + /**
  24 + * 用户信息
  25 + */
  26 + private MemberUserRespVO user;
  27 +
  28 + @ApiModel("管理后台 - 交易订单的详情的订单项目")
  29 + @Data
  30 + public static class Item extends TradeOrderItemBaseVO {
  31 +
  32 + /**
  33 + * 属性数组
  34 + */
  35 + private List<ProductPropertyValueDetailRespVO> properties;
  36 +
  37 + }
  38 +
  39 +}
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
... ... @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 6 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
7 7 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
  8 +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
8 9 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
9 10 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
10 11 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
... ... @@ -12,7 +13,9 @@ import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
12 13 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
13 14 import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO;
14 15 import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO;
  16 +import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
15 17 import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
  18 +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO;
16 19 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO;
17 20 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO;
18 21 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
... ... @@ -138,9 +141,37 @@ public interface TradeOrderConvert {
138 141 });
139 142 return new PageResult<>(orderVOs, pageResult.getTotal());
140 143 }
141   -
142 144 TradeOrderPageItemRespVO convert(TradeOrderDO order, List<TradeOrderItemDO> items);
143   -
144 145 ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean);
145 146  
  147 + default TradeOrderDetailRespVO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
  148 + List<ProductPropertyValueDetailRespDTO> propertyValueDetails, MemberUserRespDTO user) {
  149 + TradeOrderDetailRespVO orderVO = convert2(order, orderItems);
  150 + // 处理商品属性
  151 + Map<Long, ProductPropertyValueDetailRespDTO> propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId);
  152 + for (int i = 0; i < orderItems.size(); i++) {
  153 + List<TradeOrderItemDO.Property> properties = orderItems.get(i).getProperties();
  154 + if (CollUtil.isEmpty(properties)) {
  155 + continue;
  156 + }
  157 + TradeOrderDetailRespVO.Item item = orderVO.getItems().get(i);
  158 + item.setProperties(new ArrayList<>(properties.size()));
  159 + // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中
  160 + properties.forEach(property -> {
  161 + ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId());
  162 + if (propertyValueDetail == null) {
  163 + return;
  164 + }
  165 + item.getProperties().add(convert(propertyValueDetail));
  166 + });
  167 + }
  168 + // 处理收货地址
  169 + orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId()));
  170 + // 处理用户信息
  171 + orderVO.setUser(convert(user));
  172 + return orderVO;
  173 + }
  174 + TradeOrderDetailRespVO convert2(TradeOrderDO order, List<TradeOrderItemDO> items);
  175 + MemberUserRespVO convert(MemberUserRespDTO bean);
  176 +
146 177 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java
... ... @@ -10,6 +10,8 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
10 10 import java.util.Collection;
11 11 import java.util.List;
12 12  
  13 +import static java.util.Collections.singleton;
  14 +
13 15 /**
14 16 * 交易订单 Service 接口
15 17 *
... ... @@ -55,6 +57,14 @@ public interface TradeOrderService {
55 57 void receiveOrder(Long userId, Long id);
56 58  
57 59 /**
  60 + * 获得指定编号的交易订单
  61 + *
  62 + * @param id 交易订单编号
  63 + * @return 交易订单
  64 + */
  65 + TradeOrderDO getOrder(Long id);
  66 +
  67 + /**
58 68 * 获得指定用户,指定的交易订单
59 69 *
60 70 * @param userId 用户编号
... ... @@ -102,6 +112,16 @@ public interface TradeOrderService {
102 112 List<TradeOrderItemDO> getOrderItemList(Collection<Long> ids);
103 113  
104 114 /**
  115 + * 根据交易订单编号,查询交易订单项
  116 + *
  117 + * @param orderId 交易订单编号
  118 + * @return 交易订单项数组
  119 + */
  120 + default List<TradeOrderItemDO> getOrderItemListByOrderId(Long orderId) {
  121 + return getOrderItemListByOrderId(singleton(orderId));
  122 + }
  123 +
  124 + /**
105 125 * 根据交易订单编号数组,查询交易订单项
106 126 *
107 127 * @param orderIds 交易订单编号数组
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
... ... @@ -390,6 +390,11 @@ public class TradeOrderServiceImpl implements TradeOrderService {
390 390 // TODO 芋艿:lili 发送商品被购买完成的数据
391 391 }
392 392  
  393 + @Override
  394 + public TradeOrderDO getOrder(Long id) {
  395 + return tradeOrderMapper.selectById(id);
  396 + }
  397 +
393 398 /**
394 399 * 校验交易订单满足可售货的条件
395 400 *
... ...
yudao-ui-admin/src/api/mall/trade/order.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获得交易订单分页
  4 +export function getOrderPage(query) {
  5 + return request({
  6 + url: '/trade/order/page',
  7 + method: 'get',
  8 + params: query
  9 + })
  10 +}
  11 +
  12 +// 获得交易订单详情
  13 +export function getOrderDetail(id) {
  14 + return request({
  15 + url: '/trade/order/get-detail?id=' + id,
  16 + method: 'get',
  17 + })
  18 +}
... ...
yudao-ui-admin/src/views/mall/trade/order/detail.vue
1 1 <template>
2 2 <div class="app-container order-detail-page">
  3 + <!-- 订单信息 -->
  4 + <el-descriptions title="订单信息">
  5 + <el-descriptions-item label="支付单号">123</el-descriptions-item>
  6 + </el-descriptions>
  7 +
3 8 <template v-for="(group, index) in detailGroups">
4 9 <el-descriptions v-bind="group.groupProps" :key="`group_${index}`" :title="group.title">
5 10 <!-- 商品信息 -->
... ... @@ -92,6 +97,9 @@
92 97 </template>
93 98  
94 99 <script>
  100 +import {DICT_TYPE, getDictDatas} from "@/utils/dict";
  101 +import { getOrderDetail } from "@/api/mall/trade/order";
  102 +
95 103 export default {
96 104 name: "detail",
97 105 data () {
... ... @@ -100,7 +108,7 @@ export default {
100 108 {
101 109 title: '订单详情',
102 110 children: [
103   - { label: '交易流水号', valueKey: 'jylsh'},
  111 + { label: '支付单号', valueKey: 'jylsh'},
104 112 { label: '配送方式', valueKey: 'psfs'},
105 113 { label: '营销活动', valueKey: 'yxhd'},
106 114 { label: '订单编号', valueKey: 'ddbh'},
... ... @@ -242,9 +250,17 @@ export default {
242 250 }
243 251 ],
244 252 goodsInfo: [] // 商品详情tableData
245   - }
  253 + },
  254 + order: {
  255 + items: [],
  256 + },
246 257 }
247 258 },
  259 + created() {
  260 + getOrderDetail(this.$route.query.id).then(res => {
  261 + this.order = res.data
  262 + })
  263 + },
248 264 methods: {
249 265 clipboardSuccess() {
250 266 this.$modal.msgSuccess("复制成功");
... ...
yudao-ui-admin/src/views/mall/trade/order/index.vue
... ... @@ -8,7 +8,7 @@
8 8 <el-form-item label="搜索方式" prop="searchValue">
9 9 <el-input v-model="queryParams.searchValue" style="width: 240px">
10 10 <el-select v-model="queryParams.searchType" slot="prepend" style="width: 100px">
11   - <el-option v-for="dict in dicData.searchType" v-bind="dict" :key="dict.value"/>
  11 + <el-option v-for="dict in searchTypes" :key="dict.value" :label="dict.label" :value="dict.value"/>
12 12 </el-select>
13 13 </el-input>
14 14 </el-form-item>
... ... @@ -156,103 +156,100 @@ import { getOrderPage } from &quot;@/api/mall/trade/order&quot;;
156 156 import { datePickerOptions } from "@/utils/constants";
157 157 import { DICT_TYPE, getDictDatas } from "@/utils/dict";
158 158  
159   -const dicData = {
160   - searchType: [
161   - { label: '订单号', value: 'no' },
162   - { label: '会员编号', value: 'userId' },
163   - { label: '会员昵称', value: 'userNickname' },
164   - { label: '会员手机号', value: 'userMobile' },
165   - { label: '收货人姓名', value: 'receiverName' },
166   - { label: '收货人手机号码', value: 'receiverMobile' },
167   - ],
168   - }
169   - export default {
170   - name: "index",
171   - data () {
172   - return {
173   - dicData,
174   - // 遮罩层
175   - loading: true,
176   - // 导出遮罩层
177   - exportLoading: false,
178   - // 显示搜索条件
179   - showSearch: true,
180   - // 总条数
181   - total: 0,
182   - // 交易售后列表
183   - list: [],
184   - queryParams: {
185   - pageNo: 1,
186   - pageSize: 10,
187   - searchType: 'no',
188   - searchValue: '',
189   - type: null,
190   - status: null,
191   - payChannelCode: null,
192   - createTime: [],
193   - },
194   - // Tab 筛选
195   - activeTab: 'all',
196   - statusTabs: [{
197   - label: '全部',
198   - value: 'all'
199   - }],
200   - // 静态变量
201   - datePickerOptions: datePickerOptions
202   - }
  159 +export default {
  160 + name: "index",
  161 + data () {
  162 + return {
  163 + // 遮罩层
  164 + loading: true,
  165 + // 导出遮罩层
  166 + exportLoading: false,
  167 + // 显示搜索条件
  168 + showSearch: true,
  169 + // 总条数
  170 + total: 0,
  171 + // 交易售后列表
  172 + list: [],
  173 + queryParams: {
  174 + pageNo: 1,
  175 + pageSize: 10,
  176 + searchType: 'no',
  177 + searchValue: '',
  178 + type: null,
  179 + status: null,
  180 + payChannelCode: null,
  181 + createTime: [],
  182 + },
  183 + // Tab 筛选
  184 + activeTab: 'all',
  185 + statusTabs: [{
  186 + label: '全部',
  187 + value: 'all'
  188 + }],
  189 + // 静态变量
  190 + datePickerOptions: datePickerOptions,
  191 + searchTypes: [
  192 + { label: '订单号', value: 'no' },
  193 + { label: '会员编号', value: 'userId' },
  194 + { label: '会员昵称', value: 'userNickname' },
  195 + { label: '会员手机号', value: 'userMobile' },
  196 + { label: '收货人姓名', value: 'receiverName' },
  197 + { label: '收货人手机号码', value: 'receiverMobile' },
  198 + ],
  199 + }
  200 + },
  201 + created() {
  202 + this.getList();
  203 + // 设置 statuses 过滤
  204 + for (const dict of getDictDatas(DICT_TYPE.TRADE_ORDER_STATUS)) {
  205 + this.statusTabs.push({
  206 + label: dict.label,
  207 + value: dict.value
  208 + })
  209 + }
  210 + },
  211 + methods: {
  212 + /** 查询列表 */
  213 + getList() {
  214 + this.loading = true;
  215 + // 执行查询
  216 + getOrderPage({
  217 + ...this.queryParams,
  218 + searchType: undefined,
  219 + searchValue: undefined,
  220 + no: this.queryParams.searchType === 'no' ? this.queryParams.searchValue : undefined,
  221 + userId: this.queryParams.searchType === 'userId' ? this.queryParams.searchValue : undefined,
  222 + userNickname: this.queryParams.searchType === 'userNickname' ? this.queryParams.searchValue : undefined,
  223 + userMobile: this.queryParams.searchType === 'userMobile' ? this.queryParams.searchValue : undefined,
  224 + receiverName: this.queryParams.searchType === 'receiverName' ? this.queryParams.searchValue : undefined,
  225 + receiverMobile: this.queryParams.searchType === 'receiverMobile' ? this.queryParams.searchValue : undefined,
  226 + }).then(response => {
  227 + this.list = response.data.list;
  228 + this.total = response.data.total;
  229 + this.loading = false;
  230 + });
203 231 },
204   - created() {
  232 + /** 搜索按钮操作 */
  233 + handleQuery() {
  234 + this.queryParams.pageNo = 1;
  235 + this.activeTab = this.queryParams.status ? this.queryParams.status : 'all'; // 处理 tab
205 236 this.getList();
206   - // 设置 statuses 过滤
207   - for (const dict of getDictDatas(DICT_TYPE.TRADE_ORDER_STATUS)) {
208   - this.statusTabs.push({
209   - label: dict.label,
210   - value: dict.value
211   - })
212   - }
213 237 },
214   - methods: {
215   - /** 查询列表 */
216   - getList() {
217   - this.loading = true;
218   - // 执行查询
219   - getOrderPage({
220   - ...this.queryParams,
221   - searchType: undefined,
222   - searchValue: undefined,
223   - no: this.queryParams.searchType === 'no' ? this.queryParams.searchValue : undefined,
224   - userId: this.queryParams.searchType === 'userId' ? this.queryParams.searchValue : undefined,
225   - userNickname: this.queryParams.searchType === 'userNickname' ? this.queryParams.searchValue : undefined,
226   - userMobile: this.queryParams.searchType === 'userMobile' ? this.queryParams.searchValue : undefined,
227   - receiverName: this.queryParams.searchType === 'receiverName' ? this.queryParams.searchValue : undefined,
228   - receiverMobile: this.queryParams.searchType === 'receiverMobile' ? this.queryParams.searchValue : undefined,
229   - }).then(response => {
230   - this.list = response.data.list;
231   - this.total = response.data.total;
232   - this.loading = false;
233   - });
234   - },
235   - /** 搜索按钮操作 */
236   - handleQuery() {
237   - this.queryParams.pageNo = 1;
238   - this.activeTab = this.queryParams.status ? this.queryParams.status : 'all'; // 处理 tab
239   - this.getList();
240   - },
241   - /** 重置按钮操作 */
242   - resetQuery() {
243   - this.resetForm("queryForm");
244   - this.handleQuery();
245   - },
246   - /** tab 切换 */
247   - tabClick(tab) {
248   - this.queryParams.status = tab.name === 'all' ? undefined : tab.name;
249   - this.getList();
250   - },
251   - goToDetail (row) {
252   - this.$router.push({ path: '/mall/trade/order/detail', query: { orderNo: row.orderNo }})
253   - }
  238 + /** 重置按钮操作 */
  239 + resetQuery() {
  240 + this.resetForm("queryForm");
  241 + this.handleQuery();
  242 + },
  243 + /** tab 切换 */
  244 + tabClick(tab) {
  245 + this.queryParams.status = tab.name === 'all' ? undefined : tab.name;
  246 + this.getList();
  247 + },
  248 + goToDetail (row) {
  249 + this.$router.push({ path: '/mall/trade/order/detail', query: { id: row.id }})
254 250 }
255 251 }
  252 +}
256 253 </script>
257 254  
258 255 <style lang="scss" scoped>
... ...