Browse Source

初始化 master 分支,上传全部最新代码

master
wangfukang 2 months ago
parent
commit
d3719deeb8
  1. 25
      hiver-admin/src/main/resources/apiclient_cert.pem
  2. 28
      hiver-admin/src/main/resources/apiclient_key.pem
  3. 2
      hiver-admin/src/main/resources/application.yml
  4. BIN
      hiver-admin/test-output/spark/FontAwesome.otf
  5. 4
      hiver-admin/test-output/spark/font-awesome.min.css
  6. BIN
      hiver-admin/test-output/spark/fontawesome-webfont.eot
  7. 2671
      hiver-admin/test-output/spark/fontawesome-webfont.svg
  8. BIN
      hiver-admin/test-output/spark/fontawesome-webfont.ttf
  9. BIN
      hiver-admin/test-output/spark/fontawesome-webfont.woff
  10. BIN
      hiver-admin/test-output/spark/fontawesome-webfont.woff2
  11. 2
      hiver-admin/test-output/spark/jsontree.js
  12. BIN
      hiver-admin/test-output/spark/logo.png
  13. 395
      hiver-admin/test-output/spark/spark-script.js
  14. 521
      hiver-admin/test-output/spark/spark-style.css
  15. 69
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AreasController.java
  16. 65
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ProductGroupBuyPriceController.java
  17. 99
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ShopTakeawayController.java
  18. 20
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/AreasMapper.java
  19. 9
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/CommentMapper.java
  20. 18
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/ProductGroupBuyPriceMapper.java
  21. 45
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/ShopTakeawayMapper.java
  22. 46
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/Areas.java
  23. 62
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/Comment.java
  24. 54
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/ProductGroupBuyPrice.java
  25. 91
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/ShopTakeaway.java
  26. 14
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/query/ShopTakeawayQuery.java
  27. 36
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/CategoryNumberVo.java
  28. 48
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/ShopTakeawayService.java
  29. 16
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/AreasService.java
  30. 15
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/ProductGroupBuyPriceService.java
  31. 69
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/ShopTakeawayServiceImpl.java
  32. 39
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/AreasServiceImpl.java
  33. 36
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/ProductGroupBuyPriceServiceImpl.java
  34. 57
      hiver-modules/hiver-mall/src/main/resources/mapper/AreasMapper.xml
  35. 22
      hiver-modules/hiver-mall/src/main/resources/mapper/CommentMapper.xml
  36. 41
      hiver-modules/hiver-mall/src/main/resources/mapper/ProductGroupBuyPriceMapper.xml
  37. 105
      hiver-modules/hiver-mall/src/main/resources/mapper/ShopTakeawayMapper.xml
  38. 27
      hiver-modules/hiver-social/src/main/java/cc/hiver/social/controller/KeyUtils.java
  39. 63
      hiver-modules/hiver-social/src/main/java/cc/hiver/social/controller/UnifiedOrderService.java
  40. 103
      hiver-modules/hiver-social/src/main/java/cc/hiver/social/controller/WechatPayConfig.java
  41. 112
      hiver-modules/hiver-social/src/main/java/cc/hiver/social/controller/WechatPayController.java
  42. 110
      hiver-modules/hiver-social/src/main/java/cc/hiver/social/controller/WechatPaySigner.java
  43. 121
      hiver-modules/hiver-social/src/main/java/cc/hiver/social/serviceimpl/WechatPhoneService.java
  44. 13
      hiver-plus-back.iml

25
hiver-admin/src/main/resources/apiclient_cert.pem

@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIEITCCAwmgAwIBAgIUS0Kl7fnKL8Ks6yEnGnc6TxW0MqQwDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
Q0EwHhcNMjYwMjEwMDkzODU1WhcNMzEwMjA5MDkzODU1WjB7MRMwEQYDVQQDDAox
MTA2Mzc1OTYwMRswGQYDVQQKDBLlvq7kv6HllYbmiLfns7vnu58xJzAlBgNVBAsM
Huays+WMl+W/q+aLvuenkeaKgOaciemZkOWFrOWPuDELMAkGA1UEBhMCQ04xETAP
BgNVBAcMCFNoZW5aaGVuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
4DGM21ZX1weGlJPPCTMfHPiL1jmxG7cuTHwS37bfzWB4T+SmfOuwEfYILeY7iFCr
l14yr89wvlzfp4kwCIV55FEDBvsjp714JjAOIKv2piHXD1Sw+MhHo0QdGnNYBl+H
alkVpg/wSBkP43f3mXc5+EMFOKY6ET0ytXHx1AIILoACvNU70SPfIsOkU6h8CAg+
/ocIDEm5Z9i8wG8KLlvNX5/M40nraVwJzMLsU0mx4BVe0MNRQ4fj/DfLgijKpk7R
juK3XlRycX7bgg8oIO7KHPY/H4iDYpAKSH8Psq+h6Jjab4IIYITpqNurvmSa+VDR
RAzJFAmxcW1xt8I0HnCJvQIDAQABo4G5MIG2MAkGA1UdEwQCMAAwCwYDVR0PBAQD
AgP4MIGbBgNVHR8EgZMwgZAwgY2ggYqggYeGgYRodHRwOi8vZXZjYS5pdHJ1cy5j
b20uY24vcHVibGljL2l0cnVzY3JsP0NBPTFCRDQyMjBFNTBEQkMwNEIwNkFEMzk3
NTQ5ODQ2QzAxQzNFOEVCRDImc2c9SEFDQzQ3MUI2NTQyMkUxMkIyN0E5RDMzQTg3
QUQxQ0RGNTkyNkUxNDAzNzEwDQYJKoZIhvcNAQELBQADggEBAKZasaeU83GcoPmX
XTq9tZz/IvgWUpRavJWiTT3aR8V/jMRbpVpH9qpZnUvzRxiGctePajBNY7QEWIxv
BgmGkXRqFcnSiD+nB3JW1pvGMsXZsJaKSCwpHW3JIsEhGkX5+idzwdyiV/xWFtYc
O54cS9dc67u1De0JPIByxoml6Uz1u7PfUfbAq9rUWo6ufSV+va7cpOPAtgQsPJn1
3vqKVJClPOVAEX/ge7k11LcZtB0jAyWh9M2HA91n1oa4U1psW+tgEAAlyz2cpSSA
YfcYi1J0Isx9lX4trC0hKgj+2kWJ7etgFe8bEhlMwYn4ZiYEejWW8BfcwQifLVn8
TDuL0m0=
-----END CERTIFICATE-----

28
hiver-admin/src/main/resources/apiclient_key.pem

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDgMYzbVlfXB4aU
k88JMx8c+IvWObEbty5MfBLftt/NYHhP5KZ867AR9ggt5juIUKuXXjKvz3C+XN+n
iTAIhXnkUQMG+yOnvXgmMA4gq/amIdcPVLD4yEejRB0ac1gGX4dqWRWmD/BIGQ/j
d/eZdzn4QwU4pjoRPTK1cfHUAggugAK81TvRI98iw6RTqHwICD7+hwgMSbln2LzA
bwouW81fn8zjSetpXAnMwuxTSbHgFV7Qw1FDh+P8N8uCKMqmTtGO4rdeVHJxftuC
Dygg7soc9j8fiINikApIfw+yr6HomNpvgghghOmo26u+ZJr5UNFEDMkUCbFxbXG3
wjQecIm9AgMBAAECggEBALfirH/zMBUlDROssLIBBlIC4t+Rbl0nQIhndCuema6g
o84T4yKvRjlVLZxILSg/0p5TGwvs/7KEBsYp1gYHRNUqRWtibfpVg8j+vXe61JGr
S/Q9KPLFg0y8v4pEdTy0+iMWcpVEmXbpZ4jRi3qKujeQ8SVn4lTld0Qv84RLLl7E
A1YHVWjA3B6av0OGhDlbguLu2vh485Ks5VyepVHuGGhrEQis5KMClbGw/IZGTBCw
PMGm7BP4MmDTxdd+5aJ+2yAn6+dgp2Tt51Cm1WuUhB8cPetqtDzJLNgDE7fp0lUM
WWD9drYbQaJlWEWILyBJfFffRc+/ppwSSJ3E4GdU2UECgYEA9iPqDQZvoFOdBeDi
iB+K38razmfannuH23erxvP9iJq2uoT/Us6Y3ioM8dV0IvKcNPPmZa+nz9zziJEd
FbbN00cWLzFYybBNgnBBCIDTN7c5lsbIYhR3s2TXN5fI/4zLRxcJzbNvbuFFZyq6
6AYo6jXUHA7R7nKin5dc1W0xNWkCgYEA6SyUYDJo3IFqC8/GcJH+4WK8g143jk8n
PyKWRuRwB+mOHKC6TC1rqX719L32FYm3xe2ltyEjK47XHN/Ie/+vLmLCRfsvMdHO
t3o5w4cHbZ03tFvyqUP5Ei5DrB/AUvIS3fKRjDh4lk7khWOvFkNwJ731Ba68CprG
383TyAlWQzUCgYEAuYme7syQLkF41qqK9+MW8tTdlMMSN26UnSmbEbBvx54f6X9B
WzEiaC04br7g+Ur51qyXWsVK8NPzu1jvnKOciQtHvLEs5XOBKbbmPruk+5Wg0nfr
KouVI2P7GwvOVlvSCzdhi24brHAgucCq/SVPiCSlS7UcJ+q/jR8yuirB8ikCgYBs
a38eb7IUfdRaY6UoqKn0EN4I02FPuXxNPf7UPdndw/qBUzbsvt3ltRQWVdG72Aps
bQD18uGQml1pnqBxD8Vb8y3ULmSWbLEK3TlIsluA226QXYSqseF5U6vBuA3MQ6UE
MIr+wS9I7KwTXfOGjZrzz77DgqkK4UcBv4nu5HCI1QKBgGDZYIZ4DGkBSNCjQaC9
x0l7oHFtntUj13vGQINvx1yaKm7SJS0Vbj6Oa75qmQtDQUSuF6SDImNy4+X1Oz1Q
J43IsnQoSGJ2YjU4qXyhXmjd4jXeeG0J6Tnvc2Ad+WToBjhsXBhQymKhU2zDy0XG
MzUWVMBqAPae3sijI8n1INyW
-----END PRIVATE KEY-----

2
hiver-admin/src/main/resources/application.yml

@ -458,7 +458,7 @@ logging:
# 最大保存天数
max-history: 7
# 每个文件最大大小
max-file-size: 10MB
max-file-size: 9MB
jpush:
appKey: 130f556e8473c9b558777fe3
masterSecret: 2b4e5196dfc40a78db36480d

BIN
hiver-admin/test-output/spark/FontAwesome.otf

Binary file not shown.

4
hiver-admin/test-output/spark/font-awesome.min.css

File diff suppressed because one or more lines are too long

BIN
hiver-admin/test-output/spark/fontawesome-webfont.eot

Binary file not shown.

2671
hiver-admin/test-output/spark/fontawesome-webfont.svg

File diff suppressed because it is too large

Before

Width:  |  Height:  |  Size: 434 KiB

BIN
hiver-admin/test-output/spark/fontawesome-webfont.ttf

Binary file not shown.

BIN
hiver-admin/test-output/spark/fontawesome-webfont.woff

Binary file not shown.

BIN
hiver-admin/test-output/spark/fontawesome-webfont.woff2

Binary file not shown.

2
hiver-admin/test-output/spark/jsontree.js

@ -1,2 +0,0 @@
/*! json-tree - v0.2.2 - 2017-09-25, MIT LICENSE */
var JSONTree=function(){var n={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;"},t=0,r=0;this.create=function(n,t){return r+=1,N(u(n,0,!1),{class:"jstValue"})};var e=function(t){return t.replace(/[&<>'"]/g,function(t){return n[t]})},s=function(){return r+"_"+t++},u=function(n,t,r){if(null===n)return f(r?t:0);switch(typeof n){case"boolean":return l(n,r?t:0);case"number":return i(n,r?t:0);case"string":return o(n,r?t:0);default:return n instanceof Array?a(n,t,r):c(n,t,r)}},c=function(n,t,r){var e=s(),u=Object.keys(n).map(function(r){return j(r,n[r],t+1,!0)}).join(m()),c=[g("{",r?t:0,e),N(u,{id:e}),p("}",t)].join("\n");return N(c,{})},a=function(n,t,r){var e=s(),c=n.map(function(n){return u(n,t+1,!0)}).join(m());return[g("[",r?t:0,e),N(c,{id:e}),p("]",t)].join("\n")},o=function(n,t){var r=e(JSON.stringify(n));return N(v(r,t),{class:"jstStr"})},i=function(n,t){return N(v(n,t),{class:"jstNum"})},l=function(n,t){return N(v(n,t),{class:"jstBool"})},f=function(n){return N(v("null",n),{class:"jstNull"})},j=function(n,t,r){var s=v(e(JSON.stringify(n))+": ",r),c=N(u(t,r,!1),{});return N(s+c,{class:"jstProperty"})},m=function(){return N(",\n",{class:"jstComma"})},N=function(n,t){return d("span",t,n)},d=function(n,t,r){return"<"+n+Object.keys(t).map(function(n){return" "+n+'="'+t[n]+'"'}).join("")+">"+r+"</"+n+">"},g=function(n,t,r){return N(v(n,t),{class:"jstBracket"})+N("",{class:"jstFold",onclick:"JSONTree.toggle('"+r+"')"})};this.toggle=function(n){var t=document.getElementById(n),r=t.parentNode,e=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",r.className="jstFolded",e.className="jstExpand"):(t.className="",r.className="",e.className="jstFold")};var p=function(n,t){return N(v(n,t),{})},v=function(n,t){return Array(2*t+1).join(" ")+n};return this}();

BIN
hiver-admin/test-output/spark/logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

395
hiver-admin/test-output/spark/spark-script.js

File diff suppressed because one or more lines are too long

521
hiver-admin/test-output/spark/spark-style.css

File diff suppressed because one or more lines are too long

69
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AreasController.java

@ -0,0 +1,69 @@
package cc.hiver.mall.controller;
import cc.hiver.core.common.utils.ResultUtil;
import cc.hiver.core.common.utils.StringUtils;
import cc.hiver.core.common.vo.Result;
import cc.hiver.mall.entity.Areas;
import cc.hiver.mall.service.mybatis.AreasService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Slf4j
@RestController
@Api(tags = "区域数据字典接口")
@RequestMapping("/hiver/app/areas/")
@Transactional
public class AreasController {
@Autowired
private AreasService areasService;
@RequestMapping(value = "/save", method = RequestMethod.POST)
@ApiOperation("新增")
@Transactional
public Result save(Areas areas) {
try {
final Areas addAreas = areasService.insert(areas);
// 添加成功,返回信息
return new ResultUtil<Areas>().setData(addAreas);
}catch (Exception e){
log.error("添加区域数据字典失败", e);
return ResultUtil.error("添加失败");
}
}
@RequestMapping(value = "/edit", method = RequestMethod.POST)
@ApiOperation("根据id修改区域数据字典")
public Result edit(Areas areas) {
if (StringUtils.isEmpty(areas.getId())) {
return ResultUtil.error("id不能为空");
}
final Areas updateAreas = areasService.updateByAreasId(areas);
return new ResultUtil<Areas>().setData(updateAreas);
}
@RequestMapping(value = "/delById", method = RequestMethod.POST)
@ApiOperation("根据id删除")
public Result delById(@RequestParam String id,@RequestParam Integer delFlag) {
if (StringUtils.isEmpty(id)) {
return ResultUtil.error("id不能为空");
}
areasService.delById(id,delFlag);
return ResultUtil.success("删除成功");
}
@RequestMapping(value = "/listBySchoolId", method = RequestMethod.GET)
@ApiOperation("根据学校id查询列表")
public Result listBySchoolId(@RequestParam String schoolId) {
final List<Areas> list = areasService.listBySchoolId(schoolId);
return new ResultUtil<List<Areas>>().setData(list);
}
}

65
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ProductGroupBuyPriceController.java

@ -0,0 +1,65 @@
/*
Copyright [2022] [https://hiver.cc]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cc.hiver.mall.controller;
import cc.hiver.core.common.utils.ResultUtil;
import cc.hiver.core.common.vo.Result;
import cc.hiver.mall.entity.ProductGroupBuyPrice;
import cc.hiver.mall.service.mybatis.ProductGroupBuyPriceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 店铺外卖业务配置控制器
*
* @author cc
*/
@Slf4j
@RestController
@Api(tags = "商品拼团价格接口")
@RequestMapping("/hiver/app/productGroupBuyPrice")
public class ProductGroupBuyPriceController {
@Autowired
private ProductGroupBuyPriceService productGroupBuyPriceService;
@RequestMapping(value = "/getByProductId", method = RequestMethod.GET)
@ApiOperation("根据商品id获取拼团配置")
public Result<List<ProductGroupBuyPrice>> getByProductId(@RequestParam String productId) {
final List<ProductGroupBuyPrice> productGroupBuyPriceList = productGroupBuyPriceService.selectByProductId(productId);
return new ResultUtil<List<ProductGroupBuyPrice>>().setData(productGroupBuyPriceList);
}
@PostMapping(value = "/batchAddproductGroupBuyPrice")
@ApiOperation("批量新增")
public Result batchAddproductGroupBuyPrice(@RequestBody List<ProductGroupBuyPrice> productGroupBuyPrices) {
if(productGroupBuyPrices != null && productGroupBuyPrices.size() > 0){
productGroupBuyPriceService.deleteByProductId(productGroupBuyPrices.get(0).getProductId());
}
// 批量新增
final boolean b = productGroupBuyPriceService.saveBatch(productGroupBuyPrices);
if (b) {
return ResultUtil.success("保存成功!");
} else {
return ResultUtil.error("保存失败!");
}
}
}

99
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/ShopTakeawayController.java

@ -0,0 +1,99 @@
/*
Copyright [2022] [https://hiver.cc]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cc.hiver.mall.controller;
import cc.hiver.core.common.utils.ResultUtil;
import cc.hiver.core.common.vo.Result;
import cc.hiver.mall.entity.Sale;
import cc.hiver.mall.entity.ShopTakeaway;
import cc.hiver.mall.pojo.query.SalePageQuery;
import cc.hiver.mall.pojo.query.ShopTakeawayQuery;
import cc.hiver.mall.service.ShopTakeawayService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
/**
* 店铺外卖业务配置控制器
*
* @author cc
*/
@Slf4j
@RestController
@Api(tags = "店铺外卖业务配置接口")
@RequestMapping("/hiver/app/shoptakeaway")
public class ShopTakeawayController {
@Autowired
private ShopTakeawayService shopTakeawayService;
@RequestMapping(value = "/getByShopId", method = RequestMethod.GET)
@ApiOperation("根据店铺id获取外卖业务配置")
public Result<ShopTakeaway> getByShopId(
@ApiParam("店铺id") @RequestParam String shopId) {
final ShopTakeaway shopTakeaway = shopTakeawayService.selectByPrimaryKey(shopId);
return new ResultUtil<ShopTakeaway>().setData(shopTakeaway);
}
@RequestMapping(value = "/save", method = RequestMethod.POST)
@ApiOperation("保存或更新外卖业务配置")
@ResponseBody
public Result<ShopTakeaway> save(ShopTakeaway shopTakeaway) {
// 1. 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 2. 定义格式化器 (例如:yyyy-MM-dd HH:mm:ss)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 3. 转换为字符串
String timeStr = now.format(formatter);
shopTakeaway.setJoinTime(timeStr);
final ShopTakeaway result = shopTakeawayService.insert(shopTakeaway);
return new ResultUtil<ShopTakeaway>().setData(result);
}
@RequestMapping(value = "/update", method = RequestMethod.POST)
@ApiOperation("保存或更新外卖业务配置")
@ResponseBody
public Result<ShopTakeaway> update(ShopTakeaway shopTakeaway) {
shopTakeawayService.updateByPrimaryKeySelective(shopTakeaway);
return ResultUtil.success("更新成功!");
}
@RequestMapping(value = "/deleteByShopId", method = RequestMethod.POST)
@ApiOperation("删除外卖业务配置")
public Result<Object> deleteByShopId(
@ApiParam("店铺id") @RequestParam String shopId) {
shopTakeawayService.deleteByPrimaryKey(shopId);
return ResultUtil.success("删除成功");
}
@RequestMapping(value = "/getList", method = RequestMethod.POST)
@ApiOperation("根据学校id获取外卖业务配置列表")
public Result<Page<ShopTakeaway>> getList(
@ApiParam("店铺id列表") @RequestBody ShopTakeawayQuery shopTakeawayQuery) {
final Page<ShopTakeaway> shopTakeawaysPage = shopTakeawayService.selectList(shopTakeawayQuery);
return ResultUtil.data(shopTakeawaysPage);
}
}

20
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/AreasMapper.java

@ -0,0 +1,20 @@
package cc.hiver.mall.dao.mapper;
import cc.hiver.mall.entity.Areas;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface AreasMapper extends BaseMapper<Areas> {
List<Areas> listBySchoolId(String schoolId);
int insert(Areas areas);
int updateByAreasId(@Param("areas") Areas areas);
void delById(@Param("id") String id,@Param("delFlag") Integer delFlag);
}

9
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/CommentMapper.java

@ -0,0 +1,9 @@
package cc.hiver.mall.dao.mapper;
import cc.hiver.mall.entity.Comment;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface CommentMapper extends BaseMapper<Comment> {
}

18
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/ProductGroupBuyPriceMapper.java

@ -0,0 +1,18 @@
package cc.hiver.mall.dao.mapper;
import cc.hiver.mall.entity.ProductGroupBuyPrice;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ProductGroupBuyPriceMapper extends BaseMapper<ProductGroupBuyPrice> {
int insert(ProductGroupBuyPrice record);
List<ProductGroupBuyPrice> selectByProductId(String productId);
void deleteByProductId(String productId);
}

45
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/ShopTakeawayMapper.java

@ -0,0 +1,45 @@
/*
Copyright [2022] [https://hiver.cc]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cc.hiver.mall.dao.mapper;
import cc.hiver.mall.entity.Sale;
import cc.hiver.mall.entity.ShopTakeaway;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 店铺外卖业务配置Mapper
*
* @author cc
*/
@Repository
public interface ShopTakeawayMapper extends BaseMapper<ShopTakeaway> {
ShopTakeaway selectByPrimaryKey(String shopId);
void deleteByPrimaryKey(String shopId);
int insert(ShopTakeaway shopTakeaway);
void updateByPrimaryKeySelective(ShopTakeaway shopTakeaway);
Page<ShopTakeaway> selectList(Page<ShopTakeaway> page,@Param("regionId")String regionId);
}

46
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/Areas.java

@ -0,0 +1,46 @@
package cc.hiver.mall.entity;
import cc.hiver.core.base.HiverBaseEntity;
import cc.hiver.core.common.utils.SnowFlakeUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
@Data
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "areas")
@TableName("areas")
@ApiModel(value = "客户地址表")
public class Areas extends HiverBaseEntity {
private static final long serialVersionUID = 1L;
private String id = SnowFlakeUtil.nextId().toString();
private Integer delFlag;
@ApiModelProperty(value = "名称")
private String name;
@ApiModelProperty(value = "备注")
private String remark;
@ApiModelProperty(value = "排序字段")
private String orderByField;
@ApiModelProperty(value = "学校Id")
private String schoolId;
}

62
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/Comment.java

@ -0,0 +1,62 @@
package cc.hiver.mall.entity;
import cc.hiver.core.base.HiverBaseEntity;
import cc.hiver.core.common.utils.SnowFlakeUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
@Data
@ApiModel(value = "客户表")
@TableName(value = "t_comment", autoResultMap = true)
public class Comment implements Serializable {
private static final long serialVersionUID = 1L;
private String id = SnowFlakeUtil.nextId().toString();
@ApiModelProperty(value = "上级id")
private String linkedId;
@ApiModelProperty(value = "备注")
private String remark;
@ApiModelProperty(value = "等级 0 一级评论 1回复评论")
private Integer level;
@ApiModelProperty(value = "图片")
private String picture;
@ApiModelProperty(value = "创建时间")
private String createTime;
@ApiModelProperty(value = "创建人id")
private String createBy;
@ApiModelProperty(value = "创建人名称")
private String createByName;
@ApiModelProperty(value = "创建人头像")
private String createByIcon;
@ApiModelProperty(value = "评分")
private String score;
@ApiModelProperty(value = "订单id")
private String orderId;
@ApiModelProperty(value = "店铺id")
private String shopId;
}

54
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/ProductGroupBuyPrice.java

@ -0,0 +1,54 @@
/*
Copyright [2022] [https://hiver.cc]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cc.hiver.mall.entity;
import cc.hiver.core.base.HiverBaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.math.BigDecimal;
/**
* 店铺外卖业务配置实体类
*
* @author cc
*/
@Data
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "t_product_group_buy_price")
@TableName("t_product_group_buy_price")
@ApiModel(value = "商品拼团价格配置")
public class ProductGroupBuyPrice extends HiverBaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "商品id")
private String productId;
@ApiModelProperty(value = "成团人数")
private Integer groupCount;
@ApiModelProperty(value = "成团价格")
private BigDecimal groupPrice;
}

91
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/ShopTakeaway.java

@ -0,0 +1,91 @@
/*
Copyright [2022] [https://hiver.cc]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cc.hiver.mall.entity;
import cc.hiver.core.base.HiverBaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.math.BigDecimal;
/**
* 店铺外卖业务配置实体类
*
* @author cc
*/
@Data
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "t_shop_takeaway")
@TableName("t_shop_takeaway")
@ApiModel(value = "店铺外卖业务配置")
public class ShopTakeaway extends HiverBaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "店铺id")
private String shopId;
@ApiModelProperty(value = "店铺名称")
private String shopName;
@ApiModelProperty(value = "所属学校")
private String regionId;
@ApiModelProperty(value = "拼团合作佣金比例")
private BigDecimal commissionRateMore;
@ApiModelProperty(value = "单独购买合作佣金比例")
private BigDecimal commissionRateOne;
@TableField(exist = false)
@ApiModelProperty(value = "预计送达时间")
private String estimatedDeliveryTime;
@ApiModelProperty(value = "营业开始时间")
private String businessHourBegin;
@ApiModelProperty(value = "营业结束时间")
private String businessHourEnd;
@ApiModelProperty(value = "状态 0正常营业 1暂停营业 2冻结")
private Integer status;
@ApiModelProperty(value = "经营品类")
private String type;
@ApiModelProperty(value = "是否支持配送 0支持 1不支持")
private Integer isDelivery;
@ApiModelProperty(value = "出餐时间")
private Integer cookingTime;
@ApiModelProperty(value = "排名")
private Integer shoprank;
@ApiModelProperty(value = "是否价格锁定")
private Integer isPriceLock;
@ApiModelProperty(value = "入驻时间")
private String joinTime;
}

14
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/query/ShopTakeawayQuery.java

@ -0,0 +1,14 @@
package cc.hiver.mall.pojo.query;
import cc.hiver.core.base.HiverBasePageQuery;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("分享页查询对象")
@Data
public class ShopTakeawayQuery extends HiverBasePageQuery {
@ApiModelProperty("学校id")
private String regionId;
}

36
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/CategoryNumberVo.java

@ -0,0 +1,36 @@
package cc.hiver.mall.pojo.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
@ApiModel(value = "客户商品购买数量Vo")
public class CategoryNumberVo {
@ApiModelProperty(value = "销售金额")
private BigDecimal totalAmount;
@ApiModelProperty(value = "销售利润")
private BigDecimal totalProfit;
@ApiModelProperty(value = "销售件数")
private Integer totalJCount;
@ApiModelProperty(value = "进货金额")
private BigDecimal purchasingCost;
@ApiModelProperty(value = "进货件数")
private Integer purchasingCount;
@ApiModelProperty(value = "退货金额")
private BigDecimal returnTotalAmount;
@ApiModelProperty(value = "退货成本")
private BigDecimal saleReturnCost;
@ApiModelProperty(value = "退货件数")
private Integer returnTotalCount;
}

48
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/ShopTakeawayService.java

@ -0,0 +1,48 @@
/*
Copyright [2022] [https://hiver.cc]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cc.hiver.mall.service;
import cc.hiver.core.base.HiverBaseService;
import cc.hiver.mall.entity.DealingsRecord;
import cc.hiver.mall.entity.Sale;
import cc.hiver.mall.entity.Shop;
import cc.hiver.mall.entity.ShopTakeaway;
import cc.hiver.mall.pojo.query.SalePageQuery;
import cc.hiver.mall.pojo.query.ShopTakeawayQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 店铺外卖业务配置服务接口
*
* @author cc
*/
public interface ShopTakeawayService extends IService<ShopTakeaway> {
ShopTakeaway selectByPrimaryKey(String shopId);
void deleteByPrimaryKey(String shopId);
ShopTakeaway insert(ShopTakeaway shopTakeaway);
void updateByPrimaryKeySelective(ShopTakeaway shopTakeaway);
Page<ShopTakeaway> selectList(ShopTakeawayQuery shopTakeawayQuery);
}

16
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/AreasService.java

@ -0,0 +1,16 @@
package cc.hiver.mall.service.mybatis;
import cc.hiver.mall.entity.Areas;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
public interface AreasService extends IService<Areas> {
List<Areas> listBySchoolId(String schoolId);
Areas insert(Areas areas);
Areas updateByAreasId(Areas areas);
void delById(String id,Integer delFlag);
}

15
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/ProductGroupBuyPriceService.java

@ -0,0 +1,15 @@
package cc.hiver.mall.service.mybatis;
import cc.hiver.mall.entity.ProductGroupBuyPrice;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
public interface ProductGroupBuyPriceService extends IService<ProductGroupBuyPrice> {
ProductGroupBuyPrice insert(ProductGroupBuyPrice record);
List<ProductGroupBuyPrice> selectByProductId(String productId);
void deleteByProductId(String productId);
}

69
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/ShopTakeawayServiceImpl.java

@ -0,0 +1,69 @@
/*
Copyright [2022] [https://hiver.cc]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cc.hiver.mall.serviceimpl;
import cc.hiver.mall.dao.mapper.ShopTakeawayMapper;
import cc.hiver.mall.entity.ShopTakeaway;
import cc.hiver.mall.pojo.query.ShopTakeawayQuery;
import cc.hiver.mall.service.ShopTakeawayService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 店铺外卖业务配置服务实现类
*
* @author cc
*/
@Slf4j
@Service
@Transactional
public class ShopTakeawayServiceImpl extends ServiceImpl<ShopTakeawayMapper, ShopTakeaway> implements ShopTakeawayService {
@Autowired
private ShopTakeawayMapper shopTakeawayMapper;
@Override
public ShopTakeaway selectByPrimaryKey(String shopId) {
return shopTakeawayMapper.selectByPrimaryKey(shopId);
}
@Override
public void deleteByPrimaryKey(String shopId) {
shopTakeawayMapper.deleteByPrimaryKey(shopId);
}
@Override
public ShopTakeaway insert(ShopTakeaway shopTakeaway) {
shopTakeawayMapper.insert(shopTakeaway);
return shopTakeaway;
}
@Override
public void updateByPrimaryKeySelective(ShopTakeaway shopTakeaway) {
shopTakeawayMapper.updateByPrimaryKeySelective(shopTakeaway);
}
@Override
public Page<ShopTakeaway> selectList(ShopTakeawayQuery shopTakeawayQuery) {
final Page<ShopTakeaway> page = new Page<>(shopTakeawayQuery.getPageNum(), shopTakeawayQuery.getPageSize());
final Page<ShopTakeaway> salePage = shopTakeawayMapper.selectList(page, shopTakeawayQuery.getRegionId());
return salePage;
}
}

39
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/AreasServiceImpl.java

@ -0,0 +1,39 @@
package cc.hiver.mall.serviceimpl.mybatis;
import cc.hiver.mall.dao.mapper.AreasMapper;
import cc.hiver.mall.entity.Areas;
import cc.hiver.mall.service.mybatis.AreasService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class AreasServiceImpl extends ServiceImpl<AreasMapper, Areas> implements AreasService {
@Autowired
private AreasMapper areasMapper;
@Override
public List<Areas> listBySchoolId(String schoolId) {
return areasMapper.listBySchoolId(schoolId);
}
@Override
public Areas insert(Areas areas) {
areasMapper.insert(areas);
return areas;
}
@Override
public Areas updateByAreasId(Areas areas) {
areasMapper.updateByAreasId(areas);
return areas;
}
@Override
public void delById(String id,Integer delFlag) {
areasMapper.delById(id,delFlag);
}
}

36
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/ProductGroupBuyPriceServiceImpl.java

@ -0,0 +1,36 @@
package cc.hiver.mall.serviceimpl.mybatis;
import cc.hiver.mall.dao.mapper.ProductGroupBuyPriceMapper;
import cc.hiver.mall.entity.ProductGroupBuyPrice;
import cc.hiver.mall.service.mybatis.ProductGroupBuyPriceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@Slf4j
public class ProductGroupBuyPriceServiceImpl extends ServiceImpl<ProductGroupBuyPriceMapper, ProductGroupBuyPrice> implements ProductGroupBuyPriceService {
@Autowired
private ProductGroupBuyPriceMapper productGroupBuyPriceMapper;
@Override
public ProductGroupBuyPrice insert(ProductGroupBuyPrice record) {
productGroupBuyPriceMapper.insert(record);
return record;
}
@Override
public List<ProductGroupBuyPrice> selectByProductId(String productId) {
return productGroupBuyPriceMapper.selectByProductId(productId);
}
@Override
public void deleteByProductId(String productId) {
productGroupBuyPriceMapper.deleteByProductId(productId);
}
}

57
hiver-modules/hiver-mall/src/main/resources/mapper/AreasMapper.xml

@ -0,0 +1,57 @@
<?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="cc.hiver.mall.dao.mapper.AreasMapper">
<resultMap id="BaseResultMap" type="cc.hiver.mall.entity.Areas">
<id column="id" jdbcType="VARCHAR" property="id" />
<result column="delFlag" jdbcType="INTEGER" property="delFlag" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="remark" jdbcType="VARCHAR" property="remark" />
<result column="schoolId" jdbcType="VARCHAR" property="schoolId" />
<result column="orderByField" jdbcType="INTEGER" property="orderByField" />
</resultMap>
<sql id="Base_Column_List">
id,delFlag,name,remark,schoolId,orderByField
</sql>
<select id="listBySchoolId" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from areas
where schoolId = #{schoolId,jdbcType=VARCHAR} order by orderByField asc
</select>
<insert id="insert" parameterType="cc.hiver.mall.entity.Areas">
insert into areas (id,delFlag,name,remark,schoolId,orderByField)
values (#{id,jdbcType=VARCHAR}, #{delFlag,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}
, #{remark,jdbcType=VARCHAR}
, #{schoolId,jdbcType=VARCHAR}, #{orderByField,jdbcType=INTEGER})
</insert>
<update id="updateByAreasId" parameterType="cc.hiver.mall.entity.Areas">
update areas
<set>
<if test="areas.delFlag != null">
delFlag = #{areas.delFlag,jdbcType=INTEGER},
</if>
<if test="areas.name != null">
name = #{areas.name,jdbcType=VARCHAR},
</if>
<if test="areas.remark != null">
remark = #{areas.remark,jdbcType=VARCHAR},
</if>
<if test="areas.schoolId != null">
schoolId = #{areas.schoolId,jdbcType=VARCHAR},
</if>
<if test="areas.orderByField != null">
orderByField = #{areas.orderByField,jdbcType=INTEGER},
</if>
</set>
where id = #{areas.id,jdbcType=VARCHAR}
</update>
<update id="delById">
update areas set delFlag = #{delFlag,jdbcType=INTEGER} where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

22
hiver-modules/hiver-mall/src/main/resources/mapper/CommentMapper.xml

@ -0,0 +1,22 @@
<?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="cc.hiver.mall.dao.mapper.CommentMapper">
<resultMap id="BaseResultMap" type="cc.hiver.mall.entity.Comment">
<id column="id" jdbcType="VARCHAR" property="id"/>
<result column="linked_id" jdbcType="VARCHAR" property="linkedId"/>
<result column="remark" jdbcType="VARCHAR" property="remark"/>
<result column="level" jdbcType="INTEGER" property="level"/>
<result column="picture" jdbcType="VARCHAR" property="picture"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
<result column="create_by" jdbcType="VARCHAR" property="createBy"/>
<result column="create_by_name" jdbcType="TIMESTAMP" property="createByName"/>
<result column="create_by_icon" jdbcType="TIMESTAMP" property="createByIcon"/>
<result column="score" jdbcType="TIMESTAMP" property="score"/>
<result column="order_id" jdbcType="TIMESTAMP" property="orderId"/>
<result column="shop_id" jdbcType="TIMESTAMP" property="shopId"/>
</resultMap>
<sql id="Base_Column_List">
id, linked_id, remark, level, picture, create_time, create_by, create_by_name, create_by_icon, score, order_id, shop_id
</sql>
</mapper>

41
hiver-modules/hiver-mall/src/main/resources/mapper/ProductGroupBuyPriceMapper.xml

@ -0,0 +1,41 @@
<?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="cc.hiver.mall.dao.mapper.ProductGroupBuyPriceMapper">
<resultMap id="BaseResultMap" type="cc.hiver.mall.entity.ProductGroupBuyPrice">
<id column="id" jdbcType="VARCHAR" property="id"/>
<result column="create_by" jdbcType="VARCHAR" property="createBy"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
<result column="del_flag" jdbcType="INTEGER" property="delFlag"/>
<result column="update_by" jdbcType="VARCHAR" property="updateBy"/>
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
<result column="group_count" jdbcType="INTEGER" property="groupCount"/>
<result column="product_id" jdbcType="VARCHAR" property="productId"/>
<result column="group_price" jdbcType="DECIMAL" property="groupPrice"/>
</resultMap>
<sql id="Base_Column_List">
id, create_by, create_time, del_flag, update_by, update_time, group_count, product_id, group_price
</sql>
<insert id="insert" parameterType="cc.hiver.mall.entity.ProductGroupBuyPrice">
insert into t_product_group_buy_price (id, create_by, create_time,
del_flag, update_by, update_time,
group_count, product_id, group_price)
values (#{id,jdbcType=VARCHAR}, #{createBy,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP},
#{delFlag,jdbcType=INTEGER}, #{updateBy,jdbcType=VARCHAR}, #{updateTime,jdbcType=TIMESTAMP},
#{groupCount,jdbcType=INTEGER}, #{productId,jdbcType=VARCHAR}, #{groupPrice,jdbcType=DECIMAL})
</insert>
<select id="selectByProductId" parameterType="java.lang.String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from t_product_group_buy_price
where product_id = #{productId,jdbcType=VARCHAR}
</select>
<delete id="deleteByProductId" parameterType="java.lang.String">
delete
from t_product_group_buy_price
where product_id = #{productId,jdbcType=VARCHAR}
</delete>
</mapper>

105
hiver-modules/hiver-mall/src/main/resources/mapper/ShopTakeawayMapper.xml

@ -0,0 +1,105 @@
<?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="cc.hiver.mall.dao.mapper.ShopTakeawayMapper" >
<resultMap id="BaseResultMap" type="cc.hiver.mall.entity.ShopTakeaway" >
<result column="id" property="id" jdbcType="VARCHAR" />
<result column="create_by" jdbcType="VARCHAR" property="createBy"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
<result column="del_flag" jdbcType="INTEGER" property="delFlag"/>
<result column="update_by" jdbcType="VARCHAR" property="updateBy"/>
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
<result column="shop_id" property="shopId" jdbcType="VARCHAR" />
<result column="shop_name" property="shopName" jdbcType="VARCHAR" />
<result column="region_id" property="regionId" jdbcType="VARCHAR" />
<result column="commission_rate_more" property="commissionRateMore" jdbcType="VARCHAR" />
<result column="commission_rate_one" property="commissionRateOne" jdbcType="VARCHAR" />
<result column="business_hour_begin" property="businessHourBegin" jdbcType="VARCHAR" />
<result column="business_hour_end" property="businessHourEnd" jdbcType="VARCHAR" />
<result column="status" property="status" jdbcType="INTEGER" />
<result column="type" property="type" jdbcType="VARCHAR" />
<result column="is_delivery" property="isDelivery" jdbcType="INTEGER" />
<result column="cooking_time" property="cookingTime" jdbcType="INTEGER" />
<result column="shoprank" property="shoprank" jdbcType="INTEGER" />
<result column="is_price_lock" property="isPriceLock" jdbcType="INTEGER" />
<result column="join_time" property="joinTime" jdbcType="VARCHAR" />
</resultMap>
<sql id="Base_Column_List" >
id,create_by, create_time, update_time, update_by,
del_flag,shop_id,shop_name,region_id,commission_rate_more,commission_rate_one,business_hour_begin,business_hour_end,status,type,is_delivery,cooking_time,shoprank,is_price_lock,join_time
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" >
select
<include refid="Base_Column_List" />
from t_shop_takeaway
where shop_id = #{shopId,jdbcType=VARCHAR}
</select>
<select id="selectList" resultMap="BaseResultMap" parameterType="java.lang.String" >
select
<include refid="Base_Column_List" />
from t_shop_takeaway
where region_id = #{regionId,jdbcType=VARCHAR}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.String" >
delete from t_shop_takeaway
where shop_id = #{shopId,jdbcType=VARCHAR}
</delete>
<insert id="insert" parameterType="cc.hiver.mall.entity.ShopTakeaway" >
insert into t_shop_takeaway (id,create_by, create_time, update_time, update_by,
del_flag,shop_id, shop_name,region_id,commission_rate_more, commission_rate_one, business_hour_begin, business_hour_end, status, type, is_delivery, cooking_time, shoprank, is_price_lock, join_time)
values (#{id,jdbcType=VARCHAR},#{createBy,jdbcType=VARCHAR},#{createTime,jdbcType=TIMESTAMP},
#{updateTime,jdbcType=TIMESTAMP},#{updateBy,jdbcType=VARCHAR},#{delFlag,jdbcType=INTEGER}
,#{shopId,jdbcType=VARCHAR},#{shopName,jdbcType=VARCHAR},#{regionId,jdbcType=VARCHAR}, #{commissionRateMore,jdbcType=DECIMAL}, #{commissionRateOne,jdbcType=DECIMAL}, #{businessHourBegin,jdbcType=VARCHAR}, #{businessHourEnd,jdbcType=VARCHAR}, #{status,jdbcType=INTEGER}, #{type,jdbcType=VARCHAR}, #{isDelivery,jdbcType=INTEGER}, #{cookingTime,jdbcType=INTEGER}, #{shoprank,jdbcType=INTEGER}, #{isPriceLock,jdbcType=INTEGER}, #{joinTime,jdbcType=VARCHAR})
</insert>
<update id="updateByPrimaryKeySelective" parameterType="cc.hiver.mall.entity.ShopTakeaway" >
update t_shop_takeaway
<set >
<if test="shopId != null" >
shop_id = #{shopId,jdbcType=VARCHAR},
</if>
<if test="shopName != null" >
shop_name = #{shopName,jdbcType=VARCHAR},
</if>
<if test="regionId != null" >
region_id = #{regionId,jdbcType=VARCHAR},
</if>
<if test="commissionRateMore != null" >
commission_rate_more = #{commissionRateMore,jdbcType=DECIMAL},
</if>
<if test="commissionRateOne != null" >
commission_rate_one = #{commissionRateOne,jdbcType=DECIMAL},
</if>
<if test="businessHourBegin != null" >
business_hour_begin = #{businessHourBegin,jdbcType=VARCHAR},
</if>
<if test="businessHourEnd != null" >
business_hour_end = #{businessHourEnd,jdbcType=VARCHAR},
</if>
<if test="status != null" >
status = #{status,jdbcType=INTEGER},
</if>
<if test="type != null" >
type = #{type,jdbcType=VARCHAR},
</if>
<if test="isDelivery != null" >
is_delivery = #{isDelivery,jdbcType=INTEGER},
</if>
<if test="cookingTime != null" >
cooking_time = #{cookingTime,jdbcType=INTEGER},
</if>
<if test="shoprank != null" >
shoprank = #{shoprank,jdbcType=INTEGER},
</if>
<if test="isPriceLock != null" >
is_price_lock = #{isPriceLock,jdbcType=INTEGER},
</if>
<if test="joinTime != null" >
join_time = #{joinTime,jdbcType=VARCHAR},
</if>
</set>
where shop_id = #{shopId,jdbcType=VARCHAR}
</update>
</mapper>

27
hiver-modules/hiver-social/src/main/java/cc/hiver/social/controller/KeyUtils.java

@ -0,0 +1,27 @@
package cc.hiver.social.controller;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import java.io.StringReader;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Base64;
public class KeyUtils {
public static PrivateKey loadPrivateKey(byte[] keyBytes) throws Exception {
PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(keyBytes);
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
return converter.getPrivateKey(pkInfo);
}
public static String signWithSha256Rsa(String message, PrivateKey privateKey) throws Exception {
Signature sign = Signature.getInstance("SHA256withRSA");
sign.initSign(privateKey);
sign.update(message.getBytes("utf-8"));
byte[] signed = sign.sign();
return Base64.getEncoder().encodeToString(signed);
}
}

63
hiver-modules/hiver-social/src/main/java/cc/hiver/social/controller/UnifiedOrderService.java

@ -0,0 +1,63 @@
package cc.hiver.social.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class UnifiedOrderService {
private static final String UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
@Autowired
private WechatPayConfig config;
@Autowired
private WechatPaySigner signer;
private final OkHttpClient httpClient = new OkHttpClient();
private final ObjectMapper objectMapper = new ObjectMapper();
public Map<String, Object> createJsapiOrder(String outTradeNo, String description,
String openid, long amount) throws Exception {
Map<String, Object> reqBody = new HashMap<>();
reqBody.put("appid", config.getAppId());
reqBody.put("mchid", config.getMchId());
reqBody.put("description", description);
reqBody.put("out_trade_no", outTradeNo);
reqBody.put("notify_url", config.getNotifyUrl());
Map<String, Object> amountMap = new HashMap<>();
amountMap.put("total", amount); // 单位:分
amountMap.put("currency", "CNY");
reqBody.put("amount", amountMap);
Map<String, Object> payer = new HashMap<>();
payer.put("openid", openid);
reqBody.put("payer", payer);
String jsonBody = objectMapper.writeValueAsString(reqBody);
String authorization = signer.sign("POST", UNIFIED_ORDER_URL, jsonBody);
Request request = new Request.Builder()
.url(UNIFIED_ORDER_URL)
.post(RequestBody.create(MediaType.get("application/json"), jsonBody))
.addHeader("Authorization", "WECHATPAY2-SHA256-RSA2048 " + authorization)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.addHeader("User-Agent", "MyApp/1.0")
.build();
try (Response response = httpClient.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new RuntimeException("WeChat Pay API error: " + response.code() + " - " + response.body().string());
}
String responseBody = response.body().string();
return objectMapper.readValue(responseBody, Map.class);
}
}
}

103
hiver-modules/hiver-social/src/main/java/cc/hiver/social/controller/WechatPayConfig.java

@ -0,0 +1,103 @@
package cc.hiver.social.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WechatPayConfig {
// 小程序APPID
@Value("${wechatpay.appid}")
private String appId;
// 微信支付商户号
@Value("${wechatpay.mchId}")
private String mchId;
// 微信支付API v3密钥
@Value("${wechatpay.apiV3Key}")
private String apiV3Key;
// 商户API证书序列号
@Value("${wechatpay.merchantSerialNo}")
private String serialNo;
// 商户API私钥路径
@Value("${wechatpay.privateKeyPath}")
private String privateKeyPath;
// 微信支付平台证书路径
@Value("${wechatpay.platformCertificatePath}")
private String platformCertificatePath;
// 微信支付回调地址
@Value("${wechatpay.notifyUrl}")
private String notifyUrl;
// ==================== API v3 接口地址 ====================
// 微信支付统一下单接口 (API v3)
public static final String UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
// 微信支付查询订单接口 (API v3)
public static final String ORDER_QUERY_URL = "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/%s";
// 微信支付关闭订单接口 (API v3)
public static final String CLOSE_ORDER_URL = "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/%s/close";
// 微信支付申请退款接口 (API v3)
public static final String REFUND_URL = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
// 微信支付查询退款接口 (API v3)
public static final String REFUND_QUERY_URL = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds/%s";
// 微信支付下载对账单接口 (API v3)
public static final String DOWNLOAD_BILL_URL = "https://api.mch.weixin.qq.com/v3/bill/tradebill";
// 获取平台证书列表接口 (API v3)
public static final String GET_CERTIFICATES_URL = "https://api.mch.weixin.qq.com/v3/certificates";
// ==================== 常量定义 ====================
// 成功状态码
public static final String SUCCESS = "SUCCESS";
// 失败状态码
public static final String FAIL = "FAIL";
// ==================== Getter 方法 ====================
// 获取APPID
public String getAppId() {
return appId;
}
// 获取商户号
public String getMchId() {
return mchId;
}
// 获取API v3密钥
public String getApiV3Key() {
return apiV3Key;
}
// 获取商户API证书序列号
public String getSerialNo() {
return serialNo;
}
// 获取商户API私钥路径
public String getPrivateKeyPath() {
return privateKeyPath;
}
// 获取微信支付平台证书路径
public String getPlatformCertificatePath() {
return platformCertificatePath;
}
// 获取回调地址
public String getNotifyUrl() {
return notifyUrl;
}
}

112
hiver-modules/hiver-social/src/main/java/cc/hiver/social/controller/WechatPayController.java

@ -0,0 +1,112 @@
package cc.hiver.social.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.*;
import java.util.Map;
@RestController
@RequestMapping("/hiver/api/wechat/pay")
public class WechatPayController {
@Autowired
private UnifiedOrderService orderService;
@Autowired
private WechatPayConfig config;
@Autowired
private ResourceLoader resourceLoader;
private PrivateKey privateKey;
@PostConstruct
public void init() throws Exception {
Resource resource = resourceLoader.getResource(config.getPrivateKeyPath());
byte[] keyBytes;
try (InputStream is = resource.getInputStream()) {
keyBytes = readAllBytes(is);
}
String key = new String(keyBytes, StandardCharsets.UTF_8)
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s+", "");
byte[] decodedKey = Base64.getDecoder().decode(key);
privateKey = KeyUtils.loadPrivateKey(decodedKey);
}
private byte[] readAllBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] data = new byte[1024];
int nRead;
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
return buffer.toByteArray();
}
@PostMapping("/unified-order")
public ResponseEntity<Map<String, String>> jsapiPay(@RequestBody Map<String, String> request) throws Exception {
String outTradeNo = "ORDER_" + System.currentTimeMillis();
String description = request.get("description");
String openid = request.get("openid");
long amount = Long.parseLong(request.get("amount")); // 单位:分
Map<String, Object> orderResult = orderService.createJsapiOrder(outTradeNo, description, openid, amount);
String prepayId = (String) orderResult.get("prepay_id");
if (prepayId == null) {
Map<String, String> payParams = new HashMap<>();
payParams.put("code","101");
payParams.put("message","调起微信支付失败");
return ResponseEntity.ok(payParams);
}else{
// 2. 生成前端支付参数
Map<String, String> payParams = buildPaySign(prepayId);
payParams.put("code","200");
return ResponseEntity.ok(payParams);
}
}
public Map<String, String> buildPaySign(String prepayId) throws Exception {
// 1. 生成参数
String timeStamp = String.valueOf(System.currentTimeMillis() / 1000); // 秒
String nonceStr = UUID.randomUUID().toString().replace("-", "").substring(0, 32);
String packageValue = "prepay_id=" + prepayId;
String signType = "RSA";
// 2. 构建签名字符串
String message = String.join("\n",
config.getAppId(),
timeStamp,
nonceStr,
packageValue,
"" // 最后一个 \n
);
// 3. 使用商户私钥签名(和 API v3 同一套私钥)
String paySign = KeyUtils.signWithSha256Rsa(message, privateKey); // ← 复用之前的签名方法
// 4. 返回给前端
Map<String, String> result = new HashMap<>();
result.put("timeStamp", timeStamp);
result.put("nonceStr", nonceStr);
result.put("package", packageValue);
result.put("signType", signType);
result.put("paySign", paySign);
return result;
}
}

110
hiver-modules/hiver-social/src/main/java/cc/hiver/social/controller/WechatPaySigner.java

@ -0,0 +1,110 @@
package cc.hiver.social.controller;
import com.alipay.api.internal.util.file.IOUtils;
import okhttp3.HttpUrl;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.UUID;
@Component
public class WechatPaySigner {
static {
Security.addProvider(new BouncyCastleProvider());
}
@Autowired
private WechatPayConfig config;
@Autowired
private ResourceLoader resourceLoader;
private PrivateKey privateKey;
@PostConstruct
public void init() throws Exception {
Resource resource = resourceLoader.getResource(config.getPrivateKeyPath());
byte[] keyBytes;
try (InputStream is = resource.getInputStream()) {
keyBytes = readAllBytes(is);
}
String key = new String(keyBytes, StandardCharsets.UTF_8)
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s+", "");
byte[] decodedKey = Base64.getDecoder().decode(key);
privateKey = KeyUtils.loadPrivateKey(decodedKey);
}
// 辅助方法:Java 8 兼容的 readAllBytes
private byte[] readAllBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] data = new byte[1024];
int nRead;
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
return buffer.toByteArray();
}
public String sign(String method, String url, String body) throws Exception {
// 解析 URL 获取 path 和 query
HttpUrl httpUrl = HttpUrl.parse(url);
if (httpUrl == null) {
throw new IllegalArgumentException("Invalid URL: " + url);
}
String path = httpUrl.encodedPath(); // 如 "/v3/pay/transactions/jsapi"
String query = httpUrl.query(); // 如 "a=1&b=2",若无则为 null
String nonceStr = UUID.randomUUID().toString().replace("-", "").substring(0, 32);
long timestamp = System.currentTimeMillis() / 1000; // 秒!
// 构建签名消息(严格按格式)
StringBuilder sb = new StringBuilder();
sb.append(method).append("\n")
.append(path).append("\n")
.append(timestamp).append("\n")
.append(nonceStr).append("\n")
.append(body == null ? "" : body).append("\n");
String message = sb.toString();
// 打印用于调试(上线前删除)
System.out.println("Sign message:\n" + message);
String signature = KeyUtils.signWithSha256Rsa(message, privateKey);
return String.format(
"mchid=\"%s\",nonce_str=\"%s\",timestamp=\"%d\",serial_no=\"%s\",signature=\"%s\"",
config.getMchId(), nonceStr, timestamp, config.getSerialNo(), signature
);
}
private String buildMessage(String method, String path, String query, String body,
String nonceStr, long timestamp) {
StringBuilder sb = new StringBuilder();
sb.append(method).append("\n")
.append(path).append("\n")
.append(query == null ? "" : query).append("\n")
.append(timestamp).append("\n")
.append(nonceStr).append("\n")
.append(body == null ? "" : body).append("\n");
return sb.toString();
}
}

121
hiver-modules/hiver-social/src/main/java/cc/hiver/social/serviceimpl/WechatPhoneService.java

@ -0,0 +1,121 @@
package cc.hiver.social.serviceimpl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
@Service
public class WechatPhoneService {
private static final Logger log = LoggerFactory.getLogger(WechatPhoneService.class);
// 微信获取手机号接口地址 (新版接口)
private static final String GET_PHONE_NUMBER_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={accessToken}";
// 微信获取 Access Token 接口地址
private static final String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={secret}";
private final RestTemplate restTemplate;
private final ObjectMapper objectMapper;
// 请替换为你的实际配置,建议放入 application.yml
@Value("${hiver.social.wechat.appId}")
private String appId;
@Value("${hiver.social.wechat.appSecret}")
private String appSecret;
public WechatPhoneService() {
this.restTemplate = new RestTemplate();
this.objectMapper = new ObjectMapper();
}
/**
* 获取手机号核心方法
* @param code 前端传来的 code (注意不是登录code getPhoneNumber 返回的 code)
* @return 手机号字符串失败返回 null
*/
public String getPhoneNumber(String code) {
try {
// 1. 获取 Access Token (生产环境建议缓存此 Token,有效期2小时)
String accessToken = getAccessToken();
if (accessToken == null) {
log.error("获取 AccessToken 失败");
return null;
}
// 2. 构建请求参数
Map<String, Object> params = new HashMap<>();
params.put("code", code);
// 3. 调用微信接口
ResponseEntity<String> response = restTemplate.postForEntity(
GET_PHONE_NUMBER_URL,
params,
String.class,
accessToken
);
// 4. 解析响应
JsonNode root = objectMapper.readTree(response.getBody());
// 检查错误码
int errcode = root.path("errcode").asInt(-1);
if (errcode != 0) {
String errmsg = root.path("errmsg").asText("未知错误");
log.error("微信手机号获取失败: errcode={}, errmsg={}", errcode, errmsg);
return null;
}
// 5. 提取手机号
// 新版接口返回结构: { "phone_info": { "phoneNumber": "138...", ... } }
JsonNode phoneInfo = root.path("phone_info");
if (phoneInfo.isMissingNode()) {
// 兼容旧版接口直接返回 phone_number 的情况 (极少见,主要是为了容错)
return root.path("phone_number").asText(null);
}
return phoneInfo.path("phoneNumber").asText(null);
} catch (Exception e) {
log.error("解析手机号异常", e);
return null;
}
}
/**
* 获取 Access Token (简易版生产环境请务必加 Redis 缓存)
*/
public String getAccessToken() {
if (appId == null || appSecret == null) {
throw new IllegalStateException("配置未加载: appId=" + appId + ", appSecret=" + (appSecret != null));
}
try {
ResponseEntity<String> response = restTemplate.getForEntity(
GET_ACCESS_TOKEN_URL,
String.class,
appId, // 对应 {appid}
appSecret // 对应 {secret}
);
JsonNode root = objectMapper.readTree(response.getBody());
if (root.has("access_token")) {
return root.path("access_token").asText();
} else {
log.error("获取 Token 失败: {}", response.getBody());
return null;
}
} catch (Exception e) {
log.error("获取 AccessToken 异常", e);
return null;
}
}
}

13
hiver-plus-back.iml

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/target/generated-sources/annotations" isTestSource="false" generated="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
Loading…
Cancel
Save