后端
框架调用说明:
- 用户通过前端发送HTTP请求到Controller
- Controller接收请求,并将请求数据(Request)传递给Service层
- Service层处理业务逻辑,可能调用DAO层访问数据库,或者调用Client层与远程服务交互
- DAO层执行数据库操作,将结果返回给Service层
- Service层将处理结果(或来自远程服务的结果)返回给Controller
- Controller将结果封装成HTTP响应(Response)发送给客户端
1. 申请git权限
2. git项目中点击我的-Settings-SSH Keys添加公钥
3. 公钥生成步骤
ssh-keygen -o -t rsa -b 4096 -C "your email"
cd ~/.ssh/
cat id_rsa.pub 把公钥内容粘贴到SSH Keys
4. 创建本地分支git checkout -b branchname
git远程仓库创建远程分支 branchname
关联远程分支 与 本地分支
# 将本地newbranch分支与远端branch分支关联 git branch --set-upstream-to=origin/branch newbranch
如git branch --set-upstream-to=origin/yutu yutu
git push -u
删除远程分支 git push origin --delete name
删除本地分支 git push origin --delete name
5. git修改提交的作者 mac如何修改git本地提交代码的用户名和邮箱
# 查看全局配置列表,按 q 退出
git config --global --list
# 查看当前本地全局配置的用户名
git config --global user.name
# 查看当前本地全局配置的邮箱
git config --global user.email
# 本地项目仓库配置
# 修改当前本地全局配置的用户名
git config --global user.name yutu
# 修改当前本地全局配置的邮箱
git config --global user.email yutu@qq.com
6. 要公司的settings.xml 每个公司的配置都不一样
检查文件内容
Default: ${user.home}/.m2/repository 为自己的repository 不需要修改
在idea-Settings 搜索Maven 修改User settings file为最新的settings.xml文件
确认后 加载Maven
7. 启动Spring Boot项目
/Users/qa/Desktop/2024/codenew/xx/src/main/java/com/xx/xx/xxApplication.java
控制台看到端口8090启动成功
8. 在公司配置系统查看/配置项目名称/端口
/Users/qa/Desktop/2024/codenew/xx/src/main/resources/application.yaml
为配置文件
查看 urlpath
/Users/qa/Desktop/2024/codenew/toolkit/src/main/java/com/xx/xx/controller/TrackController.java
接口名=projectname(servlet:context-path)+url commonname+urlpath
9. 在浏览器访问http://127.0.0.1:8090/projectname/urlpath?pageNum=1&pageSize=10
接口正常返回
10. 代码设计流程
step1 定义controller 为QA自己设计的接口:定义请求域名、接口路径,调用自己的接口 传参调用/model/request/的request.java
step2 定义service 为QA自己设计的接口:定义请求接口请求参数和返回,调用自己的接口 返回的数据data有数据不为null调用invokeSilent,返回的数据data无数据为null调用metaResponse
step3 定义client 为要调用RD的接口:定义域名、接口请求路径、传参、返回
step4 运行Application 在控制台Run看到如下图形。意味着Spring Boot应用已经成功运行,并且正在监听8090端口以接受HTTP请求
step5 在浏览器访问 http://127.0.0.1:8090/xx/v1/user/token/invalid?userId=xx&oauthType=all可以看到接口正常返回
11. 重命名方法名 被引用的地方一并修改
右击方法名-Refactor-Rename
右击方法名-Refactor-Rename 修改后回车 select all - ok
12. 编码规范
Controller层:调SpringBoot里的annotation
import org.springframework.web.bind.annotation.*;
// 1强制登出
@GetMapping(Apis.API_USERFORCELOGOUT)
public MetaResponse userForceLogout(UserForceLoginPageRequest userForceLoginPageRequest) {
// 如果不需要对返回的字段判断给前端 则直接return MetaResponse.success();
return MetaResponse.success();
}
// 2账号关联
@GetMapping(Apis.API_USERACCOUNTBH)
public MetaResponse userAccountBindHistory(UserAccountBindHistoryRequest userAccountBindHistoryRequest) {
// 如果需要对返回的字段判断给前端 则需要调用service
return userManageService.accountBindHistory(userAccountBindHistoryRequest);
}
// 3用户中心-查询手机号 get拼接post的部分要@RequestParam("opId") Long opId
// opId必传 其他参数非必传
@PostMapping(Apis.API_USERPHONEQUERY)
public MetaResponse<UserCenterResp> userPhoneQuery(@RequestParam("opId") Long opId,
@RequestParam(required = false) Long id,
@Valid @RequestBody UserPhoneQueryRequest userPhoneQueryRequest) {
return userManageService.userPhoneQuery(opId, id, userPhoneQueryRequest);
}
Service层:传参返参校验
// 5用户管理-账号封禁-列表 get
public MetaResponse userBlockStatus(UserBlockStatusRequest userBlockStatusRequest) {
Util.check(NumberUtil.isPositive(userBlockStatusRequest.getUserId()), "userId不能为空");
log.info("用户id是{}", userBlockStatusRequest.getUserId());
try {
MetaResponse<JSONObject> metaResponse = userManageClient.getUserBlockStatus(userBlockStatusRequest.getUserId()).execute().body();
// System.out.println("账号封禁-列表=" + metaResponse);
return metaResponse;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 6账号封禁-更新核对结果 post 无get传参单独的post传参 需要throws IOException
public void userBlockSet(UserBlockSetRequest userBlockSetRequest) throws IOException {
Util.check(StringUtils.isNotBlank(userBlockSetRequest.getCauseRemarks()), "录入人工核对结果-判定结果不能为空");
Util.check(NumberUtil.isPositive(userBlockSetRequest.getManualDecisionResult()), "录入人工核对结果-原因说明不能为空");
log.info("getCauseRemarks是{}", userBlockSetRequest.getCauseRemarks());
log.info("getManualDecisionResult是{}", userBlockSetRequest.getManualDecisionResult());
// String metaResponse = RetrofitInvokeUtil.invokeSilent(() -> userManageClient.getUserBlockSet(userBlockSetRequest));
// log.error("metaResponse是{}", metaResponse);
JSONObject metaResponse = userManageClient.getUserBlockSet(userBlockSetRequest).execute().body();
System.out.println("账号封禁-更新核对结果-接口metaResponse==" + metaResponse);
// 接口返回字段校验
int errCode = metaResponse.getInteger("errCode");
String data = metaResponse.getString("data");
if (metaResponse == null || errCode != 0 || !"OK".equals(data)) {
log.error("账号封禁-更新核对结果-接口返回为空:{}", metaResponse);
throw new BizException(ErrorCode.ERROR_PARAM, "接口返回错误,请重试");
}
}
}
Client层:调用retrofit2的call
import retrofit2.Call;
import retrofit2.http.*;
@RetrofitService("api-online")
public interface UserManageClient {
// token为Apoll配置中开发写死的值 4个接口一共3个token 登录为用户自己的token 其他token传参为服务间的传参
// 1用户管理-强制登出
@GET("/login/v1/user/token/invalid")
@Headers(value = {"token:xx", "Content-Type: application/json"})
Call<MetaResponse<JSONObject>> getDevUserforcelogoutList(@Query("userId") Long userId, @Query("oauthType") String oauthType);
// 2用户管理-账号关联
// token为Apoll配置中开发写死的值 4个接口一共3个token 登录为用户自己的token 其他token传参为服务间的传参
@GET("/login/v1/internal/account/xx")
@Headers(value = {"token:xx"})
Call<MetaResponse<JSONObject>> getDevUserAccountBindHistoryList(@Query("opId") Long xx, @Query("xx") Long phoneNumber, @Query("userId") Long userId);
// 3用户管理-用户中心-手机号查询
// token为Apoll配置中开发写死的值 4个接口一共3个token 登录为用户自己的token 其他token传参为服务间的传参
@POST("/user_center/v1/db/user")
Call<MetaResponse<JSONObject>> getUserCenterPhoneCheck(@Query("opId") Long opId, @Body UserPhoneQueryRequest userPhoneQueryRequest);
// 4用户管理-用户中心-更新手机号
@PUT("/user_center/v1/user/{userid}")
Call<MetaResponse<JSONObject>> getUserCenterPhoneUpdate(@Path("userid") Long userid,@Query("opId") Long opId, @Body UserPhoneUpdateRequest userPhoneUpdateRequest);
13. 如遇 Web server failed to start. Port 8090 was already in use.
Action:
Identify and stop the process that's listening on port 8090 or configure this application to listen on another port
lsof -i:8090 查找端口占用进程号
sudo kill -9 2848 杀掉进程 重启spring boot
15. 编码规范之方法调用
RetrofitInvokeUtil.invokeSilent(() 里面封装了try catch 不需要在调用的时候捕获异常
MetaResponse<JSONObject> metaResponse 时要加try catch
public JSONObject accountBindHistory(UserAccountBindHistoryRequest userAccountBindHistoryRequest) {
Util.check(NumberUtil.isPositive(userAccountBindHistoryRequest.getOpId()), "opId不能为空");
log.info("当前opId是{},用户id是{}", userAccountBindHistoryRequest.getOpId(), userAccountBindHistoryRequest.getUserId());
// 返回的数据data有数据不为null调用invokeSilent 无数据不可调用该方法
// JSONObject jsOne = RetrofitInvokeUtil.invokeSilent(() -> userForceLogoutClient.getDevuserforcelogoutList(userAccountBindHistoryRequest.getUserId(),userAccountBindHistoryRequest.getOauthType()));
// System.out.println("jsOne="+metaResponse);
// 返回的数据data无数据为null调用metaResponse 无数据调用该方法
try {
// MetaResponse<JSONObject> metaResponse = userManageClient.getDevUserAccountBindHistoryList(userAccountBindHistoryRequest.getOpId(), userAccountBindHistoryRequest.getPhoneNumber(), userAccountBindHistoryRequest.getUserId()).execute().body();
JSONObject metaResponse = RetrofitInvokeUtil.invokeSilent(() -> userManageClient.getDevUserAccountBindHistoryList(userAccountBindHistoryRequest.getOpId(), userAccountBindHistoryRequest.getPhoneNumber(), userAccountBindHistoryRequest.getUserId()));
// System.out.println("账号关联=" + metaResponse);
JSONArray rcords = metaResponse.getJSONArray("rcords");
// for(){
JSONArray records = metaResponse.getJSONArray("records");
// JSONArray jsonArray = new JSONArray();
// for (int i = 0; i < records.size(); i++) {
// UserAccountBindHistoryResp userAccountBindHistoryResp1 = new UserAccountBindHistoryResp();
// BeanUtils.copyProperties(thirdPartyOrder, userAccountBindHistoryResp1);
// userAccountBindHistoryResp.add(userAccountBindHistoryResp1);
// BeanUtils.copyProperties(records.get(i),userAccountBindHistoryResp1);
// jsonArray.add(userAccountBindHistoryResp1);
// }
return rcords;
System.out.println("用户管理-账号管理=" + metaResponse);
System.out.println("用户管理-账号管理records=" + records);
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("records", records);
JSONObject jsonObject = new JSONObject();
jsonObject.put("records", records);
return jsonObject;
} catch (Exception e) {
e.printStackTrace();
}
}
16. 编码规范之注释
1> 单行代码注释不要用//
2> 方法注释不要用
/**
*
* @param userId
*/
统一要用
import io.swagger.annotations.ApiOperation;
@ApiOperation(value = "用户管理-用户信息")
16. 编码规范之方法传参get post put
协议://主机名[:端口号]/路径[?查询参数]
1> get传参为标准的key value格式 接口名?userid=xx
@CheckToken
@ApiOperation(value = "用户管理-用户信息-基本信息查询")
@GetMapping("/xx/xx")
public MetaResponse<List<UserDto>> userInfoList(Long userId) {
return new MetaResponse<>(userManageService.userInfoList(userId));
}
2> put传参为接口名/参数+其他参数在body
get部分的参数要使用注解@PathVariable 定义,body体的参数使用注解@RequestBody定义
@CheckToken
@ApiOperation(value = "用户管理-用户信息-换绑手机号")
@PutMapping("/xx/xx/{userId}")
public MetaResponse userInfoChange(@PathVariable("userId") Long userId, @RequestBody UserUpdateReq req) {
userManageService.userInfoChange(userId, req);
return MetaResponse.success();
}
3> post传参为接口名+所有参数在body
@CheckToken
@ApiOperation(value = "用户管理-账号封禁-更新判定结果")
@PostMapping("/xx/xx")
public MetaResponse userBlockSet(@RequestBody UserBlockSetRequest userBlockSetRequest) {
userManageService.userBlockSet(userBlockSetRequest);
return MetaResponse.success();
}
4> get传参为接口名/所有参数在请求头
<=4个参数使用注解@RequestParam 可以设置默认值 是否必传@RequestParam(value = "version", required = false) String version
请求参数较多时 封装单独的request类 通过new request调用或者Request<requestClassName> reques调用
@CheckToken
@ApiOperation(value = "用户管理-账号封禁-封禁记录历史列表")
@GetMapping("/block/list")
public MetaResponse<List<UserBlockDto>> userBlockList
(@RequestParam("userId") Long userId,
@RequestParam(value = "current", defaultValue = "1") Integer current,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize)
{
return new MetaResponse<>(userManageService.userBlockList(userId, current, pageSize));
}
17. 编码规范之返参Dto
返回的userid有问题
需要对返回的数组单独封装类
格式data.log.userid
"data": {
"logs": [
{
"userId": 40692902,
"manualDecisionResult": 1
}
返参定义在Dto
@Data
public class UserBlockDto {
private Long userId;
private Long userBlockLogId;
private Long ruleId;
private String ruleName;
private String ruleDetailInfo;
private Long ruleCalcFinishTime;
private Long status;
private String statusDesc;
返参数组定义为list
@Data
public class UserBlockLogsDto {
private List<UserBlockDto> logs;
}
public List<UserBlockDto> userBlockList(Long userId, Integer current, Integer pageSize) {
Util.check(NumberUtil.isPositive(userId), "用户Id不能为空");
UserBlockLogsDto respDto = RetrofitInvokeUtil.invokeSilent(() -> userManageClient.getUserBlockList(userId, current, pageSize));
if (Objects.isNull(respDto)) {
throw new BizException(ErrorCode.ERROR_THIRD_SERVER);
}
List<UserBlockDto> respList = respDto.getLogs();
respList.sort(Comparator.comparing(UserBlockDto::getCTime).reversed());
respList.forEach(UserBlockDto::fromUserBlockDto);
return respList;
}
18. 编码规范之前端联调
给前端返回的字段不要封装为JSONObject 否则userid的值会返回科学记数法
改为MetaResponse 单独封装Dto
@ApiOperation(value = "用户管理-用户信息-换绑手机号")
@PUT("/xx/xx/xx/{userId}")
Call<MetaResponse<UserDto>> userInfoChange(@Path("userId") Long userId, @Body UserUpdateReq userUpdateReq);
前端
前端Vue2学习资料
1. 前端环境搭建:
设置npm源
(base) qa@yueyutu: npm config set registry https://npm.xx.xx.com/ 地址为公司私有源
安装依赖 依然报错
(base) qa@yueyutu: npm install
查看npm的用户名
(base) qa@yueyutu: npm whoami
npm ERR! code ENEEDAUTH
npm ERR! need auth This command requires you to be logged in.
npm ERR! need auth You need to authorize this machine using `npm adduser`
npm ERR! A complete log of this run can be found in: /Users/qa/.npm/_logs/2024-07-18T09_57_25_137Z-debug-0.log
(base) qa@yueyutu: npm login
输入域账号 密码
再次查看npm的用户名
(base) qa@yueyutu: npm whoami
显示域账号
2. 如遇npm run serve时报错
error:0308010C:digital envelope routines::unsupported
快速解决Error: error:0308010C:digital envelope routines::unsupported的三种解决方案-CSDN博客
在vscode输入
export NODE_OPTIONS=--openssl-legacy-provider 完美解决