如何使用有赞云的扩展点实现自己的业务逻辑

很多用户在购买了有赞的微商城之后,在使用过程中发现有赞默认提供的标准化接口不能够满足自己的实际需求,事实上,不同的行业都会有一些自己行业的流程,比如说电子卡券,用户下单购买电子卡券,默认有赞这边会调用电子卡券创建接口生成卡券信息返回给用户,但是处于用户信息安全考虑这个卡券信息商家自己是看不到的,那么商家希望针对电子卡券实现定制化开发使用标准的接口就行不通了,打个比方,商家希望实现一个电子卡券增送给用户的功能,可以将卡券信息写到一张图片后通过微信分享给好友,那么通过有赞默认提供的电子卡券功能就无法实现,那么商家希望拿到电子卡券的信息就只能自己去定制化开发,这个时候就需要使用到有赞云的有容器服务开通扩展点实现对创建电子卡券接口的定制化开发。

那么本文就针对创建电子卡券的这个流程进行讲解如何去使用扩展点实现这一功能。

准备工作

首先,要使用扩展点,你必须具备以下条件:

  • 拥有有赞微商城、有赞零售的对应店铺,且店铺未过期
  • 拥有有赞云创建有容器的条件,需要通过审核

克隆项目

这里假设你已经创建了自用型容器,我们从首页进入到该容器中,将项目克隆到本地

切换到git 仓库信息,复制仓库地址,然后在克隆的时候填写username 和password,username就是你注册平的手机号,password 就是Gittoken

20200418200549

配置maven

克隆后先不要着急 import 项目,我们先配置下Maven的setting.xml文件,你可以复制我下面的,我这里使用的maven 版本是apache-maven-3.6.3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?xml version="1.0" encoding="UTF-8"?>

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

<pluginGroups>
</pluginGroups>
<proxies>
</proxies>
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
<profiles>
<profile>
<id>dev</id>
<repositories>
<repository>
<id>youzanyun-releases</id>
<name>Nexus Release Repository</name>
<url>http://maven.youzanyun.com/repository/maven-releases/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>youzanyun-snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://maven.youzanyun.com/repository/maven-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring</id>
<url>https://maven.aliyun.com/repository/spring</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>youzanyun-plugin</id>
<name>youzanyun repository</name>
<url>http://maven.youzanyun.com/repository/maven-releases/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>

<activeProfiles>
<activeProfile>dev</activeProfile>
</activeProfiles>

</settings>

工程说明

然后打开idea,导入项目并下载对应的jar包,整个项目大概是这样的

20200418200924

上图是创建应用后通过 git clone 下来的工程结构,应用名称为 youzanyun-demo,默认生成有六个 module。

项目根包名:com.youzan.cloud.youzanyun.demo。

接下来按图例说明一下:

  • youzanyun-demo-api:接口声明 XXService.java、DTO 封装等,一般在这个模块里不会去依赖其他模块和第三方依赖;

  • youzanyun-demo-biz:服务实现模块,除了在该模块里写 XXServiceImpl.java 外,最主要的还会在这里编写业务扩展点实现类和消息扩展点实现类;

  • youzanyun-demo-dal:如果你的应用中用到了数据库,需要在这个模块里去写 dao、mapper 等,应用框架默认支持 druid 和 mybatis;

  • youzanyun-demo-deploy:这个模块是用来打包的,执行 mvn package 后的最终 jar 包生成模块,所以生成后不需要去改动里面的内容,改动后可能会导致发布失败;

  • youzanyun-demo-web:项目的一些 web 相关的类放在这个模块里,如 XXController.java,以及一些静态资源(js、css、页面等等);

  • youzanyun-demo-ui:前端扩展点定制需要在该目录下实现。 h5-extension,H5定制目录;mp-extension,小程序定制目录,创建应用后默认不会有这个目录,通过开发者工具导入项目之后会自动生成。

实现电子卡券扩展点

按照说明我们要实现对应的扩展点,需要在如下目录中去创建对应的后端业务扩展点,也就是youzanyun-demo-biz\src\main\java\com.youzan.cloud.youzan.demo.biz,注意不要去修改包名称,否则可能无法加载到对应的Bean

20200418201129

接下来,我们开始创建扩展点,这里我演示下创建电子卡券扩展点,首先我们创建一个 CreateTicketExtImplDemo 的类,然后这个类的基本结构如下

1
2
3
4
5
6
7
8
9
10
@Slf4j
@ExtensionService("createticketdemo")
public class CreateTicketExtImplDemo implements CreateTicketExtPoint {


@Override
public OutParam<CreateTicketResponseDTO> create(CreateTicketRequestDTO request) {
return null;
}
}

说下上面的class

  • @Slf4j 这个没什么好说的,就是开启日志注解,Springboot 自带的
  • @ExtensionService 表示这个class 是一个扩展点,这个扩展点的名称是createticketdemo,最终会在控制台看到这个名称对应的扩展点
  • public class CreateTicketExtImplDemo implements CreateTicketExtPoint 表示这个CreateTicketExtImplDemo 实现了CreateTicketExtPoint 这个接口,CreateTicketExtPoint 就是创建电子卡券的扩展点接口
  • public OutParam create(CreateTicketRequestDTO request) 就是这个接口对应的方法,我们需要重写这个方法

那么,我们接下来只需要在这个方法里面写上具体的业务逻辑,然后将结果返回给有赞云就行,有赞云提供了丰富的扩展点接口,你可以参考文档 https://doc.youzanyun.com/doc#/content/EXT/0-1

以创建电子卡券接口为了,我们需要用到2个接口

  • 电子卡券扩展点 https://doc.youzanyun.com/doc#/content/EXT/0-1/detail/ext/753 可以看到request 里面的有很多参数,但是各位不要以正常的HTTP 请求逻辑去理解这个扩展点,这里面的request 是不需要用户去传参请求的,这些参数是用户下单购买电子卡券的时候会把这些信息传到你开启的这个扩展点里面来。
  • 第三方电子卡券创建接口 https://doc.youzanyun.com/doc#/content/API/1-307/detail/api/0/586 这个接口我们需要传入订单号、统一核销码和券码三个信息,有赞云会跟进用户自定义的卡券信息来生成卡券。

那么对应的业务逻辑基本如下:

  • 用户从页面创建电子卡券类型订单
  • 订单信息通过创建电子卡券扩展点传进来
  • 获取订单号并调用第三方卡券创建接口传入该订单号、用户自定义卡券信息和券码,有赞云跟进信息生成卡券,那么在调用第三方卡券的时候我们还需要生成token才能去调用接口
  • 返回成功信息

最终代码如下,仅供参考,实际请根据业务需要实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package com.youzan.cloud.youzanyun.demo.biz;

import com.alibaba.fastjson.JSON;
import com.youzan.api.rpc.annotation.ExtensionService;
import com.youzan.cloud.base.api.BifrostService;
import com.youzan.cloud.extension.api.trade.CreateTicketExtPoint;
import com.youzan.cloud.extension.param.trade.CreateTicketRequestDTO;
import com.youzan.cloud.extension.param.trade.CreateTicketResponseDTO;
import com.youzan.cloud.metadata.common.OutParam;
import com.youzan.cloud.open.sdk.common.constant.OAuthEnum;
import com.youzan.cloud.open.sdk.common.exception.SDKException;
import com.youzan.cloud.open.sdk.core.client.auth.Token;
import com.youzan.cloud.open.sdk.core.oauth.model.OAuthToken;
import com.youzan.cloud.open.sdk.gen.v3_0_1.api.YouzanTradeVirtualticketThirdCreate;
import com.youzan.cloud.open.sdk.gen.v3_0_1.model.YouzanTradeVirtualticketThirdCreateParams;
import com.youzan.cloud.open.sdk.gen.v3_0_1.model.YouzanTradeVirtualticketThirdCreateResult;
import com.youzan.cloud.youzanyun.demo.biz.util.OutParamUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
* @Auth: fangwenjun
* @E-mail: [email protected]
* @title: CreateTicketExtImplDemo
* @projectName: youzanyun-demo
* @description: TODO 描述信息
* @Date 2020/4/17 7:23 PM
**/
@Slf4j
@ExtensionService("createticketdemo")
public class CreateTicketExtImplDemo implements CreateTicketExtPoint {
@Resource
private BifrostService bifrostSdkService;
@SneakyThrows
@Override
public OutParam<CreateTicketResponseDTO> create(CreateTicketRequestDTO createTicketRequestDTO) {
log.info("创建商家自有卡券, 请求体,{}", JSON.toJSONString(createTicketRequestDTO));
CreateTicketResponseDTO createTicketResponseDTO = new CreateTicketResponseDTO();
// 创建Token
OAuthToken token = null;
try {
token = bifrostSdkService.getToken("43727705", OAuthEnum.TokenType.silent);
} catch (SDKException e) {
e.printStackTrace();
}
String accessToken = token.getAccessToken();
log.info("获取到的token {}",accessToken);
//调用创建电子卡券API
YouzanTradeVirtualticketThirdCreate youzanTradeVirtualticketThirdCreate = new YouzanTradeVirtualticketThirdCreate();
YouzanTradeVirtualticketThirdCreateParams youzanTradeVirtualticketThirdCreateParams = new YouzanTradeVirtualticketThirdCreateParams();
youzanTradeVirtualticketThirdCreateParams.setTid(createTicketRequestDTO.getOrderNo());
youzanTradeVirtualticketThirdCreateParams.setCode(RandomCode());
youzanTradeVirtualticketThirdCreateParams.setTicketNos(RandomTicketNos());
youzanTradeVirtualticketThirdCreate.setAPIParams(youzanTradeVirtualticketThirdCreateParams);
YouzanTradeVirtualticketThirdCreateResult result = null;
try {
result = bifrostSdkService.invoke(youzanTradeVirtualticketThirdCreate, new Token(accessToken), YouzanTradeVirtualticketThirdCreateResult.class);
} catch (SDKException e) {
e.printStackTrace();
}
log.info("自定义电子卡券返回信息 {}",result.getMessage() + " " + result.getCode() +" "+ result.getSuccess());
createTicketResponseDTO.setSuccess(true);
return OutParamUtil.successResult(createTicketResponseDTO);
}
//生成卡券统一核销码
public String RandomCode() {
Random random = new Random();
String resultCode = "";
for (int i = 0; i < 21; i++) {
resultCode += random.nextInt(10);
}
return resultCode;
}
//生成券码信息
public List<String> RandomTicketNos(){
List<String> TicketNos = new ArrayList();
Random random = new Random();
String resultCode ="";
for (int i = 0; i < 18; i++) {
resultCode += random.nextInt(10);
}
TicketNos.add(resultCode);

return TicketNos;

}

}

注意上述代码中创建token 部分与你直接调用API接口所使用的Token 创建方式并不一样,需要特别注意

1
2
3
4
5
6
7
8
9
// 创建Token
OAuthToken token = null;
try {
token = bifrostSdkService.getToken("43727705", OAuthEnum.TokenType.silent);
} catch (SDKException e) {
e.printStackTrace();
}
String accessToken = token.getAccessToken();
log.info("获取到的token {}",accessToken);

上传代码并发布

然后我们将实现好的业务代码push 到git仓库去,这样在开发环境下的业务配置-路由配置-交付-后端流程中,我们就可以看到我们实现的扩展点,我们将他开启

20200418203110

这里的业务标识,我们可以不用管,但是在实际的生产环境中如果你需要对特定类型的商品实现扩展点,那么你需要配置。

不过这里有个注意点创建电子卡券扩展点与下单中的电子卡券自定义交付扩展点会冲突,如果你开启了这个扩展点建议先关闭,否则可能看不到具体的效果

20200418203917

开启后,我们切换到应用管理-发布管理,我们点击发布,选择服务端,然后填写发布说明进行发布

20200418203349

最终发布的版本会在列表显示

20200418203321

接下来,我们可以在对应的授权测试店铺进行测试,如何判断店铺是否授权呢?我们在应用概况的店铺授权信息中点击新增/查看测试店铺就可以看到了,在这个店铺去创建一个电子卡券类型的商品,然后下单测试

20200418203522

当你创建完订单后会自动生成对应的电子卡券的卡券凭证,这里面就包括了券码和统一核销码

054a161ef5c327b8dc81200b868594a

好了,以上就是整个扩展点的使用说明