用户下单导入地址簿需求分析需要实现的功能如图一新增地址与新增员工相似将用户id信息等插入数据库查询所有信息根据用户id查询用户所有地址信息查询默认地址查询当前用户default为1的地址根据id修改地址接收前端传入地址更新数据库中的内容根据id删除地址根据主键id删除数据库的地址根据id查询地址根据主键id查询地址设置默认地址根据主键id更新defaultControllerpackagecom.sky.controller.user;importcom.sky.context.BaseContext;importcom.sky.entity.AddressBook;importcom.sky.result.Result;importcom.sky.service.AddressBookService;importio.swagger.annotations.Api;importio.swagger.annotations.ApiOperation;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.*;importjava.util.List;RestControllerRequestMapping(/user/addressBook)Api(tagsC端地址簿接口)publicclassAddressBookController{AutowiredprivateAddressBookServiceaddressBookService;/** * 查询当前登录用户的所有地址信息 * * return */GetMapping(/list)ApiOperation(查询当前登录用户的所有地址信息)publicResultListAddressBooklist(){AddressBookaddressBooknewAddressBook();addressBook.setUserId(BaseContext.getCurrentId());ListAddressBooklistaddressBookService.list(addressBook);returnResult.success(list);}/** * 新增地址 * * param addressBook * return */PostMappingApiOperation(新增地址)publicResultsave(RequestBodyAddressBookaddressBook){addressBookService.save(addressBook);returnResult.success();}GetMapping(/{id})ApiOperation(根据id查询地址)publicResultAddressBookgetById(PathVariableLongid){AddressBookaddressBookaddressBookService.getById(id);returnResult.success(addressBook);}/** * 根据id修改地址 * * param addressBook * return */PutMappingApiOperation(根据id修改地址)publicResultupdate(RequestBodyAddressBookaddressBook){addressBookService.update(addressBook);returnResult.success();}/** * 设置默认地址 * * param addressBook * return */PutMapping(/default)ApiOperation(设置默认地址)publicResultsetDefault(RequestBodyAddressBookaddressBook){addressBookService.setDefault(addressBook);returnResult.success();}/** * 根据id删除地址 * * param id * return */DeleteMappingApiOperation(根据id删除地址)publicResultdeleteById(Longid){addressBookService.deleteById(id);returnResult.success();}/** * 查询默认地址 */GetMapping(default)ApiOperation(查询默认地址)publicResultAddressBookgetDefault(){//SQL:select * from address_book where user_id ? and is_default 1AddressBookaddressBooknewAddressBook();addressBook.setIsDefault(1);addressBook.setUserId(BaseContext.getCurrentId());ListAddressBooklistaddressBookService.list(addressBook);if(list!nulllist.size()1){returnResult.success(list.get(0));}returnResult.error(没有查询到默认地址);}}Service实现类packagecom.sky.service.impl;importcom.sky.context.BaseContext;importcom.sky.entity.AddressBook;importcom.sky.mapper.AddressBookMapper;importcom.sky.service.AddressBookService;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;importjava.util.List;ServiceSlf4jpublicclassAddressBookServiceImplimplementsAddressBookService{AutowiredprivateAddressBookMapperaddressBookMapper;/** * 条件查询 * * param addressBook * return */publicListAddressBooklist(AddressBookaddressBook){returnaddressBookMapper.list(addressBook);}/** * 新增地址 * * param addressBook */publicvoidsave(AddressBookaddressBook){addressBook.setUserId(BaseContext.getCurrentId());addressBook.setIsDefault(0);addressBookMapper.insert(addressBook);}/** * 根据id查询 * * param id * return */publicAddressBookgetById(Longid){AddressBookaddressBookaddressBookMapper.getById(id);returnaddressBook;}/** * 根据id修改地址 * * param addressBook */publicvoidupdate(AddressBookaddressBook){addressBookMapper.update(addressBook);}/** * 设置默认地址 * * param addressBook */TransactionalpublicvoidsetDefault(AddressBookaddressBook){//1、将当前用户的所有地址修改为非默认地址 update address_book set is_default ? where user_id ?addressBook.setIsDefault(0);addressBook.setUserId(BaseContext.getCurrentId());addressBookMapper.updateIsDefaultByUserId(addressBook);//2、将当前地址改为默认地址 update address_book set is_default ? where id ?addressBook.setIsDefault(1);addressBookMapper.update(addressBook);}/** * 根据id删除地址 * * param id */publicvoiddeleteById(Longid){addressBookMapper.deleteById(id);}}Mapperpackagecom.sky.mapper;importcom.sky.entity.AddressBook;importorg.apache.ibatis.annotations.*;importjava.util.List;MapperpublicinterfaceAddressBookMapper{/** * 条件查询 * param addressBook * return */ListAddressBooklist(AddressBookaddressBook);/** * 新增 * param addressBook */Insert(insert into address_book (user_id, consignee, phone, sex, province_code, province_name, city_code, city_name, district_code, district_name, detail, label, is_default) values (#{userId}, #{consignee}, #{phone}, #{sex}, #{provinceCode}, #{provinceName}, #{cityCode}, #{cityName}, #{districtCode}, #{districtName}, #{detail}, #{label}, #{isDefault}))voidinsert(AddressBookaddressBook);/** * 根据id查询 * param id * return */Select(select * from address_book where id #{id})AddressBookgetById(Longid);/** * 根据id修改 * param addressBook */voidupdate(AddressBookaddressBook);/** * 根据 用户id修改 是否默认地址 * param addressBook */Update(update address_book set is_default #{isDefault} where user_id #{userId})voidupdateIsDefaultByUserId(AddressBookaddressBook);/** * 根据id删除地址 * param id */Delete(delete from address_book where id #{id})voiddeleteById(Longid);}?xml version1.0 encodingUTF-8 ?!DOCTYPEmapperPUBLIC-//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtdmappernamespacecom.sky.mapper.AddressBookMapperselectidlistparameterTypeAddressBookresultTypeAddressBookselect * from address_bookwhereiftestuserId ! nulland user_id #{userId}/ififtestphone ! nulland phone #{phone}/ififtestisDefault ! nulland is_default #{isDefault}/if/where/selectupdateidupdateparameterTypeaddressBookupdate address_booksetiftestconsignee ! nullconsignee #{consignee},/ififtestsex ! nullsex #{sex},/ififtestphone ! nullphone #{phone},/ififtestdetail ! nulldetail #{detail},/ififtestlabel ! nulllabel #{label},/ififtestisDefault ! nullis_default #{isDefault},/if/setwhere id #{id}/update/mapper接口文档与需求分析此时用到了两张表orders以及order_detailorders表记录用户下单的完整流程下单支付派送order_detail表记录下单菜品信息金额图片下单数量后端需要接收前端的传入的数据并用传入的地址簿查询其他信息存入orders中并进行初始设置Controller/** * 用户下单 * param ordersSubmitDTO * return */PostMapping(/submit)ApiOperation(用户下单)publicResultOrderSubmitVOsubmit(RequestBodyOrdersSubmitDTOordersSubmitDTO){log.info(用户订单信息:{},ordersSubmitDTO);OrderSubmitVOorderSubmitVOorderService.submit(ordersSubmitDTO);returnResult.success(orderSubmitVO);}接收前端DTO交给逻辑层处理Service实现类逻辑层需要实现的内容根据传入的DTO中的地址簿信息查询地址簿获取当前用户并获取购物车数据插入订单数据将前端传入的金额等浅克隆设置订单支付状态为未支付状态为等待支付用当前时间戳设置单号姑且这么办设置用户手机号用户id用户名称设置订单的基础信息并存入数据库清空购物车封装前端需要返回的内容为VO对象返回/** * 用户下单 * param ordersSubmitDTO * return */publicOrderSubmitVOsubmit(OrdersSubmitDTOordersSubmitDTO){//处理各种业务异常(地址簿为空购物车数据为空)AddressBookaddressBookaddressBookMapper.getById(ordersSubmitDTO.getAddressBookId());if(addressBooknull){thrownewAddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);}LonguserIdBaseContext.getCurrentId();ShoppingCartshoppingCartnewShoppingCart();shoppingCart.setUserId(userId);ListShoppingCartlistshoppingCartMapper.list(shoppingCart);if(listnull||list.isEmpty()){//抛出业务异常thrownewShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);}//插入一条订单数据OrdersordersnewOrders();BeanUtils.copyProperties(ordersSubmitDTO,orders);orders.setOrderTime(LocalDateTime.now());orders.setPayStatus(Orders.UN_PAID);orders.setStatus(Orders.PENDING_PAYMENT);orders.setNumber(String.valueOf(System.currentTimeMillis()));orders.setPhone(addressBook.getPhone());orders.setConsignee(addressBook.getConsignee());orders.setUserId(userId);orderMapper.insert(orders);ListOrderDetailorderDetailListnewArrayList();//向订单明细表插入n条数据for(ShoppingCartcart:list){OrderDetailorderDetailnewOrderDetail();BeanUtils.copyProperties(cart,orderDetail);orderDetail.setOrderId(orders.getId());orderDetailList.add(orderDetail);}orderDetailMapper.insertBatch(orderDetailList);//清空购物车shoppingCartMapper.clean(userId);//封装VO对象返回前端returnOrderSubmitVO.builder().id(orders.getId()).orderNumber(orders.getNumber()).orderAmount(orders.getAmount()).orderTime(orders.getOrderTime()).build();}Mapper批量插入订单基础信息insertidinsertBatchinsert into order_detail (name, image, order_id, dish_id, setmeal_id, dish_flavor, amount) VALUESforeachcollectionorderDetailListitemodseparator,(#{od.name},#{od.image},#{od.orderId},#{od.dishId},#{od.setmealId},#{od.dishFlavor},#{od.amount})/foreach/insert清空购物车Delete(delete from shopping_cart where user_id#{userId})voidclean(LonguserId);微信小程序下单流程简述1. 初始下单阶段此处为用户点击去下单确认支付的阶段进入下单微信用户通过微信小程序发起下单请求。创建订单小程序向商户系统发送下单指令。返回信息商户系统处理后返回订单号等相关信息给小程序。2. 支付申请与预处理阶段此处为点击确认支付后阶段申请支付小程序向商户系统发起微信支付申请。预下单商户系统调用微信后台的下单接口。获取标识微信后台返回预支付交易标识给商户系统。签名处理商户系统对数据进行再次签名并将支付参数返回给小程序。3. 用户确认与执行支付阶段此处为支付完成后阶段确认支付微信用户在小程序端确认支付。调起支付小程序调起微信支付功能并请求微信后台执行。返回结果微信后台将支付结果反馈给小程序。4. 结果展示与状态更新阶段此处为支付成功后回显订单阶段结果显示小程序向用户展示最终的支付结果。后台通知与此同时微信后台将支付结果推送给商户系统。更新状态商户系统根据接收到的结果更新内部订单状态。接口文档代码实现Controller接收前端传入单号以及支付方式交付给service处理/** * 订单支付 * * param ordersPaymentDTO * return */PutMapping(/payment)ApiOperation(订单支付)publicResultOrderPaymentVOpayment(RequestBodyOrdersPaymentDTOordersPaymentDTO)throwsException{log.info(订单支付{},ordersPaymentDTO);OrderPaymentVOorderPaymentVOorderService.payment(ordersPaymentDTO);log.info(生成预支付交易单{},orderPaymentVO);returnResult.success(orderPaymentVO);}Service实现类下单后按照流程此时为调用下单接口将返回的prepay_id给开发者服务器作为预支付交易会话标识后端进一步进行签名加密。由于只有企业才可获得mchid如果实现支付可以将VO按如下方式封装后返回给前端虽然有内容但是并没有实质内容/** * 订单支付 * param ordersPaymentDTO * return */publicOrderPaymentVOpayment(OrdersPaymentDTOordersPaymentDTO)throwsException{// 当前登录用户idLonguserIdBaseContext.getCurrentId();UseruseruserMapper.getById(userId);// 模拟支付数据OrderPaymentVOvonewOrderPaymentVO();vo.setNonceStr(testNonceStr);vo.setPaySign(testPaySign);vo.setTimeStamp(String.valueOf(System.currentTimeMillis()));vo.setSignType(RSA);vo.setPackageStr(prepay_idtest);paySuccess(ordersPaymentDTO.getOrderNumber());returnvo;}总结实现了用户下单微信支付。在用户下单方面按照需要实现的功能独立实现了大部分内容但是有一部分内容没有分析出比如清空购物车实现微信支付了解了微信支付流程对于后端支付有了进一步的认识。最后的支付代码由ai修改为当前形式。学习了cpolar用于将本地运行的springboot程序映射到公网域名可以通过公网URL访问前端