✨ [2025-06-17] 添加门户网站使用说明
All checks were successful
Publish to Confluence / confluence (push) Successful in 1m12s
All checks were successful
Publish to Confluence / confluence (push) Successful in 1m12s
This commit is contained in:
parent
f69e5f7a4f
commit
0b2c794413
78
教程/工具/20250617-门户网站使用教程.md
Normal file
78
教程/工具/20250617-门户网站使用教程.md
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<!-- Space: qifu -->
|
||||||
|
<!-- Parent: 后端技术&知识&规范 -->
|
||||||
|
<!-- Parent: 技术方案 -->
|
||||||
|
<!-- Parent: 基建 -->
|
||||||
|
<!-- Parent: 04-使用教程 -->
|
||||||
|
<!-- Title: 20250617-门户网站使用教程 -->
|
||||||
|
|
||||||
|
<!-- Macro: :anchor\((.*)\):
|
||||||
|
Template: ac:anchor
|
||||||
|
Anchor: ${1} -->
|
||||||
|
<!-- Macro: \!\[.*\]\((.+)\)\<\!\-\- width=(.*) \-\-\>
|
||||||
|
Template: ac:image
|
||||||
|
Url: ${1}
|
||||||
|
Width: ${2} -->
|
||||||
|
<!-- Macro: \<\!\-\- :toc: \-\-\>
|
||||||
|
Template: ac:toc
|
||||||
|
Printable: 'false'
|
||||||
|
MinLevel: 2
|
||||||
|
MaxLevel: 4 -->
|
||||||
|
<!-- Include: 杂项/声明文件.md -->
|
||||||
|
|
||||||
|
<!-- :toc: -->
|
||||||
|
|
||||||
|
# 门户网站使用教程
|
||||||
|
|
||||||
|
## 解决问题
|
||||||
|
|
||||||
|
- 公司各种工具和环境混杂
|
||||||
|
- 许多工具开发无法很好的感知
|
||||||
|
- 统一书签管理
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 快速使用
|
||||||
|
|
||||||
|
1. 打开 http://menhu.qifu.com
|
||||||
|
2. 选择企微登录
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 附加说明
|
||||||
|
|
||||||
|
### 修改密码
|
||||||
|
|
||||||
|
- 修改密码之后,可以用账户和密码登录,而不需要企微登录
|
||||||
|
- 打开设置 (头像 -> 设置)
|
||||||
|
- 选择左侧 `密码` 选项
|
||||||
|
- 填入新密码,点击 `保存修改`。旧密码默认为空
|
||||||
|
|
||||||
|
### 扩展使用
|
||||||
|
|
||||||
|
- 使用扩展可以快速添加自己的链接到自定义收藏夹
|
||||||
|
|
||||||
|
#### 浏览器安装扩展程序
|
||||||
|
|
||||||
|
- [Chrome/Edge地址](https://chromewebstore.google.com/detail/linkwarden/pnidmkljnhbjfffciajlcpeldoljnidn)
|
||||||
|
- 
|
||||||
|
- [Firefox地址](https://chromewebstore.google.com/detail/linkwarden/pnidmkljnhbjfffciajlcpeldoljnidn)
|
||||||
|
- 
|
||||||
|
- 如果网络不方便的可以使用下面的压缩包,扩展解压缩后,在扩展界面添加已解压的扩展进行安装
|
||||||
|
- [扩展包下载](https://drive.weixin.qq.com/s?k=AE0Auwd4ACg2LReqE1)
|
||||||
|
- 
|
||||||
|
|
||||||
|
#### 配置服务信息
|
||||||
|
|
||||||
|
- 新建 AccessToken(头像 -> 设置)
|
||||||
|
- 
|
||||||
|
- 浏览器插件配置
|
||||||
|
- 
|
||||||
|
- URL:http://menhu.qifu.com
|
||||||
|
- API Key:第一步创建的 AccessToken
|
||||||
|
- 在需要收藏的界面点击插件图标,保存到自己的文件夹下(官方文件夹无权限收藏)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 参考
|
||||||
|
|
||||||
|
- [官方说明文档](https://docs.linkwarden.app/getting-started/browser-extension)
|
34
文档/基础组件/01-元盟核心包变更记录.md
Normal file
34
文档/基础组件/01-元盟核心包变更记录.md
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<!-- Space: qifu -->
|
||||||
|
<!-- Parent: 后端技术&知识&规范 -->
|
||||||
|
<!-- Parent: 技术方案 -->
|
||||||
|
<!-- Parent: 基建 -->
|
||||||
|
<!-- Parent: 00-基础组件 -->
|
||||||
|
<!-- Title: 20250000-元盟核心包变更记录 -->
|
||||||
|
|
||||||
|
<!-- Macro: :anchor\((.*)\):
|
||||||
|
Template: ac:anchor
|
||||||
|
Anchor: ${1} -->
|
||||||
|
<!-- Macro: \!\[.*\]\((.+)\)\<\!\-\- width=(.*) \-\-\>
|
||||||
|
Template: ac:image
|
||||||
|
Url: ${1}
|
||||||
|
Width: ${2} -->
|
||||||
|
<!-- Macro: \<\!\-\- :toc: \-\-\>
|
||||||
|
Template: ac:toc
|
||||||
|
Printable: 'false'
|
||||||
|
MinLevel: 2
|
||||||
|
MaxLevel: 4 -->
|
||||||
|
<!-- Include: 杂项/声明文件.md -->
|
||||||
|
|
||||||
|
<!-- :toc: -->
|
||||||
|
|
||||||
|
# 元盟核心包变更记录
|
||||||
|
## 2.0.2
|
||||||
|
- 修复脚手架扫描路径导致的问题
|
||||||
|
- 自动填充工具类多层级支持
|
||||||
|
|
||||||
|
## 2.0.1(Deprecated)
|
||||||
|
- 用户重构兼容
|
||||||
|
|
||||||
|
## 2.0.0
|
||||||
|
- 重构核心包结构
|
||||||
|
- 抽离兼容包
|
400
文档/基础组件/web/20250617-engine-starter-web-2.0.2.md
Normal file
400
文档/基础组件/web/20250617-engine-starter-web-2.0.2.md
Normal file
@ -0,0 +1,400 @@
|
|||||||
|
<!-- Space: qifu -->
|
||||||
|
<!-- Parent: 后端技术&知识&规范 -->
|
||||||
|
<!-- Parent: 技术方案 -->
|
||||||
|
<!-- Parent: 基建 -->
|
||||||
|
<!-- Parent: 00-基础组件 -->
|
||||||
|
<!-- Parent: 00-EngineStarterWeb使用指南 -->
|
||||||
|
<!-- Title: 20250605-engine-starter-web-2.0.1 -->
|
||||||
|
|
||||||
|
<!-- Macro: :anchor\((.*)\):
|
||||||
|
Template: ac:anchor
|
||||||
|
Anchor: ${1} -->
|
||||||
|
<!-- Macro: \!\[.*\]\((.+)\)\<\!\-\- width=(.*) \-\-\>
|
||||||
|
Template: ac:image
|
||||||
|
Url: ${1}
|
||||||
|
Width: ${2} -->
|
||||||
|
<!-- Macro: \<\!\-\- :toc: \-\-\>
|
||||||
|
Template: ac:toc
|
||||||
|
Printable: 'false'
|
||||||
|
MinLevel: 2
|
||||||
|
MaxLevel: 4 -->
|
||||||
|
<!-- Include: 杂项/声明文件.md -->
|
||||||
|
|
||||||
|
<!-- :toc: -->
|
||||||
|
|
||||||
|
# engine-starter-web 使用教程
|
||||||
|
|
||||||
|
> 基于 web 的各种工具封装
|
||||||
|
> 具体使用可参考 [engine-sample > engine-sample-starter-web](../engine-sample/engine-sample-starter-web)
|
||||||
|
|
||||||
|
## 功能特性
|
||||||
|
|
||||||
|
- [X] `YmAutofillResponseAdvice`: 全局返回结果填充处理
|
||||||
|
- [X] `@YmAutoFill` 和 `@YmAutoFillResp`: 结果自动填充
|
||||||
|
- 多层级填充实现,[使用样例](#结果自动填充)
|
||||||
|
- 多层级字段需要使用 `@YmAutofillResp` 标识
|
||||||
|
- [X] `@YmIgnoreResultWrapper`: 忽略 `Result` 结果包装
|
||||||
|
- [X] `YmResponseAdvice`: 全局结果封装
|
||||||
|
- [X] `YmGlobalExceptionHandlerAdvice`: 全局异常拦截处理
|
||||||
|
- [X] `YmI18nResponseAdvice`: I18n全局处理
|
||||||
|
- [X] `@YmIgnoreI18n`: 忽略I18n
|
||||||
|
- [X] `YmHealthCheckFilter`: 全局健康检查接口
|
||||||
|
- [X] `YmRequestBodyWrapperFilter`: request 和 response 可重复读封装
|
||||||
|
- [X] `YmRequestPrintFilter`: 请求日志打印
|
||||||
|
- [X] `YmThreadLocalFilter`: 登录用户信息解析存储(兼容新网关)
|
||||||
|
- [X] `YmUserLoginFilter`: 用户登录校验(后续会迁移到网关,默认关闭)
|
||||||
|
- [X] `YmThreadLocalUtils`: 获取当前线程中的上下文信息
|
||||||
|
|
||||||
|
-------
|
||||||
|
|
||||||
|
## 快速使用
|
||||||
|
|
||||||
|
- **注意:** `qifu-saas-parent >= 2.0.1-SNAPSHOT`
|
||||||
|
- **注意:** 启动类 `@ComponentScan` 需要变更为如下形式
|
||||||
|
- ```java
|
||||||
|
@ComponentScan(value = "com.yuanmeng.*",
|
||||||
|
excludeFilters = {
|
||||||
|
@ComponentScan.Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
|
||||||
|
@ComponentScan.Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)
|
||||||
|
})
|
||||||
|
@SpringBootApplication
|
||||||
|
public class SampleStarterWebApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SampleStarterWebApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 添加依赖
|
||||||
|
|
||||||
|
```xml
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.yuanmeng.engine</groupId>
|
||||||
|
<artifactId>engine-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 添加兼容包(可选)
|
||||||
|
|
||||||
|
- 项目中存在 `web-core` 或者 `oauth2-core` 时需要添加兼容包
|
||||||
|
|
||||||
|
```xml
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.yuanmeng.engine</groupId>
|
||||||
|
<artifactId>engine-starter-compatible-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
## 使用工具
|
||||||
|
|
||||||
|
### 忽略结果封装
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class Usage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试忽略包装
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@YmIgnoreResultWrapper
|
||||||
|
@GetMapping("/ignore-result-wrapper")
|
||||||
|
public String ignoreResultWrapper() {
|
||||||
|
return "ignore-result-wrapper success";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 全局异常拦截
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class Usage {
|
||||||
|
|
||||||
|
@GetMapping("/exception")
|
||||||
|
public String exception() {
|
||||||
|
// 打印error日志,触发告警
|
||||||
|
throw new RuntimeException("exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/ym-exception")
|
||||||
|
public String ymException() {
|
||||||
|
// 打印error日志,触发告警
|
||||||
|
throw new YmException("ym exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/ym-biz-exception")
|
||||||
|
public String ymBizException() {
|
||||||
|
// 打印 warning 日志
|
||||||
|
throw new YmBizException(YmResultCode.BASE_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/ym-biz-data-exception")
|
||||||
|
public String ymBizDataException() {
|
||||||
|
// 打印 info 日志
|
||||||
|
throw new YmBizDataException(YmResultCode.BASE_ERROR,
|
||||||
|
new TestData(TestStatusEnum.SUCCESS.getCode(), "1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@YmAutofillResp
|
||||||
|
@GetMapping("/ym-biz-data-exception-fill")
|
||||||
|
public String ymBizDataExceptionFill() {
|
||||||
|
// 触发结果数据自动填充
|
||||||
|
throw new YmBizDataException(YmResultCode.BASE_ERROR,
|
||||||
|
new TestData(TestStatusEnum.SUCCESS.getCode(), "1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 国际化支持
|
||||||
|
|
||||||
|
- 开启国际化支撑
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
yuanmeng:
|
||||||
|
web:
|
||||||
|
i18n:
|
||||||
|
enable: true
|
||||||
|
```
|
||||||
|
|
||||||
|
- 添加国际化文件
|
||||||
|
- 默认 `resources > i18n > messages_zh_CN.properties`
|
||||||
|
|
||||||
|
```properties
|
||||||
|
Base\ Error=服务端错误
|
||||||
|
```
|
||||||
|
|
||||||
|
- 编写代码
|
||||||
|
|
||||||
|
```java
|
||||||
|
|
||||||
|
@GetMapping("/i18n")
|
||||||
|
public String i18n() {
|
||||||
|
return "test success";
|
||||||
|
}
|
||||||
|
|
||||||
|
@YmIgnoreI18n
|
||||||
|
@GetMapping("/i18n-ignore")
|
||||||
|
public String i18nIgnore() {
|
||||||
|
return "i18n ignore";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/i18n-error")
|
||||||
|
public String i18nError() {
|
||||||
|
// 触发国际化配置
|
||||||
|
throw new YmBizException(YmResultCode.BASE_ERROR);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **自定义国际化处理类(可选)**
|
||||||
|
|
||||||
|
```java
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class CustomI18nMessageHandler implements YmI18nMessageHandler {
|
||||||
|
|
||||||
|
private final MessageSource messageSource;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale) {
|
||||||
|
return messageSource.getMessage(code, args, defaultMessage, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException {
|
||||||
|
return messageSource.getMessage(code, args, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
|
||||||
|
return messageSource.getMessage(resolvable, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class YmI18nConfiguration {
|
||||||
|
|
||||||
|
public static final String I18N_MESSAGE_SOURCE = "ymI18nMessageSource";
|
||||||
|
public static final String I18N_MESSAGE_HANDLER = "ymI18nMessageHandler";
|
||||||
|
|
||||||
|
@Bean(I18N_MESSAGE_SOURCE)
|
||||||
|
@ConditionalOnMissingBean(name = I18N_MESSAGE_SOURCE)
|
||||||
|
public MessageSource messageSource() {
|
||||||
|
log.info("[WEB_STARTER_INIT]: CUSTOM I18N_MESSAGE_SOURCE init");
|
||||||
|
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
|
||||||
|
messageSource.setBasename("i18n/test");
|
||||||
|
messageSource.setDefaultEncoding(StandardCharsets.UTF_8.toString());
|
||||||
|
return messageSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(I18N_MESSAGE_HANDLER)
|
||||||
|
@ConditionalOnMissingBean(name = I18N_MESSAGE_HANDLER)
|
||||||
|
public YmI18nMessageHandler ymI18nMessageHandler(@Qualifier(I18N_MESSAGE_SOURCE) MessageSource messageSource) {
|
||||||
|
log.info("[WEB_STARTER_INIT]: CUSTOM YmI18nMessageHandler init");
|
||||||
|
return new CustomI18nMessageHandler(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 结果自动填充
|
||||||
|
|
||||||
|
```java
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum TestStatusEnum implements YmBaseEnum<String> {
|
||||||
|
|
||||||
|
SUCCESS("SUCCESS", "成功"),
|
||||||
|
FAIL("FAIL", "失败"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String desc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class TestAutoFillHandler implements YmAutofillHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<?, ?> handle(Collection<?> ids, YmAutofillInfo autofill) {
|
||||||
|
Collection<String> string = (Collection<String>) ids;
|
||||||
|
Map<String, String> result = new HashMap<>();
|
||||||
|
string.forEach(k -> result.put(k, k + "value"));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class TestData {
|
||||||
|
|
||||||
|
@YmAutofill(enumCls = TestStatusEnum.class)
|
||||||
|
private String statusName;
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
@YmAutofill(from = "code", type = YmAutofillType.BEAN, handler = TestAutoFillHandler.class)
|
||||||
|
private String msg;
|
||||||
|
|
||||||
|
@YmAutofillResp
|
||||||
|
private List<TestDataSecond> secondList;
|
||||||
|
@YmAutofillResp
|
||||||
|
private List<TestData> childList;
|
||||||
|
|
||||||
|
public TestData(String status, String code) {
|
||||||
|
this.status = status;
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class TestDataSecond {
|
||||||
|
|
||||||
|
private String statusName;
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
private String msg;
|
||||||
|
|
||||||
|
@YmAutofillResp
|
||||||
|
private TestData testData;
|
||||||
|
|
||||||
|
public TestDataSecond(String status, String code) {
|
||||||
|
this.status = status;
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class Usage {
|
||||||
|
|
||||||
|
@YmAutofillResp
|
||||||
|
@GetMapping("/autofill")
|
||||||
|
public List<TestData> autofill() {
|
||||||
|
List<TestData> list = new ArrayList<>();
|
||||||
|
list.add(new TestData(TestStatusEnum.SUCCESS.getCode(), "1"));
|
||||||
|
list.add(new TestData(TestStatusEnum.FAIL.getCode(), "2"));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@YmAutofillResp({
|
||||||
|
@YmAutofill(from = "status", target = "statusName", enumCls = TestStatusEnum.class),
|
||||||
|
@YmAutofill(from = "code", target = "msg", type = YmAutofillType.BEAN, handler = TestAutoFillHandler.class)
|
||||||
|
})
|
||||||
|
@GetMapping("/autofill-second")
|
||||||
|
public List<TestDataSecond> autofillSecond() {
|
||||||
|
List<TestDataSecond> list = new ArrayList<>();
|
||||||
|
list.add(new TestDataSecond(TestStatusEnum.SUCCESS.getCode(), "1"));
|
||||||
|
list.add(new TestDataSecond(TestStatusEnum.FAIL.getCode(), "2"));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
## 完整默认配置文件
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
yuanmeng:
|
||||||
|
web:
|
||||||
|
#- 开启starter
|
||||||
|
enable: true
|
||||||
|
#- 开启兼容排除
|
||||||
|
enable-ignore: true
|
||||||
|
#- 开启返回结果填充
|
||||||
|
enable-audit-handler: true
|
||||||
|
#- 开启返回结果自动封装 YmResult
|
||||||
|
enable-result-wrapper: true
|
||||||
|
#- 开启全局异常拦截
|
||||||
|
enable-exception-handler: true
|
||||||
|
filter:
|
||||||
|
#- 开启健康检查接口
|
||||||
|
enable-health-check: true
|
||||||
|
#- 开启上下文信息解析
|
||||||
|
enable-thread-local: true
|
||||||
|
#- 开启登录拦截器(token校验)
|
||||||
|
enable-user-login: false
|
||||||
|
#- 需要跳过的路径
|
||||||
|
skip-path:
|
||||||
|
- "/test"
|
||||||
|
#- 可重复读请求封装
|
||||||
|
request-body:
|
||||||
|
enable: true
|
||||||
|
filter-uris:
|
||||||
|
- "/test1"
|
||||||
|
#- 请求日志打印封装
|
||||||
|
track:
|
||||||
|
enable: true
|
||||||
|
filter-uris:
|
||||||
|
- "/test2"
|
||||||
|
sensitive-keys:
|
||||||
|
- "password"
|
||||||
|
print-type: 2
|
||||||
|
#- 打印请求体
|
||||||
|
print-request-body: true
|
||||||
|
#- 打印返回体
|
||||||
|
print-response-body: true
|
||||||
|
external-url-list:
|
||||||
|
- "/external/test"
|
||||||
|
#- i18n全局拦截
|
||||||
|
i18n:
|
||||||
|
enable: false
|
||||||
|
```
|
383
杂项/test1.json
383
杂项/test1.json
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user