diff --git a/nflg-mobilebroken-auth/pom.xml b/nflg-mobilebroken-auth/pom.xml
index 411caf5d..a7e416de 100644
--- a/nflg-mobilebroken-auth/pom.xml
+++ b/nflg-mobilebroken-auth/pom.xml
@@ -16,10 +16,6 @@
com.nflg
nflg-mobilebroken-repository
-
-
-
-
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
@@ -62,6 +58,11 @@
org.springframework.boot
spring-boot-starter-validation
+
+ com.github.binarywang
+ weixin-java-mp
+ 4.7.0
+
diff --git a/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/config/WxMpConfig.java b/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/config/WxMpConfig.java
new file mode 100644
index 00000000..bd91e8e0
--- /dev/null
+++ b/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/config/WxMpConfig.java
@@ -0,0 +1,24 @@
+package com.nflg.mobilebroken.auth.config;
+
+import com.nflg.mobilebroken.auth.weixin.CustomWxMpConfigStorage;
+import com.nflg.mobilebroken.auth.weixin.ExternalTokenService;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.Resource;
+
+@Configuration
+public class WxMpConfig {
+
+ @Resource
+ private ExternalTokenService externalTokenService;
+
+ @Bean
+ public WxMpService wxMpService() {
+ WxMpService service = new WxMpServiceImpl();
+ service.setWxMpConfigStorage(new CustomWxMpConfigStorage(externalTokenService));
+ return service;
+ }
+}
diff --git a/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/controller/WeiXinController.java b/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/controller/WeiXinController.java
new file mode 100644
index 00000000..98a4b1e4
--- /dev/null
+++ b/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/controller/WeiXinController.java
@@ -0,0 +1,174 @@
+package com.nflg.mobilebroken.auth.controller;
+
+import cn.dev33.satoken.stp.SaLoginConfig;
+import cn.dev33.satoken.stp.SaTokenInfo;
+import cn.hutool.core.util.StrUtil;
+import com.nflg.mobilebroken.common.constant.Constant;
+import com.nflg.mobilebroken.common.constant.STATE;
+import com.nflg.mobilebroken.common.exception.NflgException;
+import com.nflg.mobilebroken.common.pojo.ApiResult;
+import com.nflg.mobilebroken.common.pojo.request.UserBindWXRequest;
+import com.nflg.mobilebroken.common.pojo.vo.AppLoginVO;
+import com.nflg.mobilebroken.common.pojo.vo.RoleVO;
+import com.nflg.mobilebroken.common.util.IdUtil;
+import com.nflg.mobilebroken.common.util.SaTokenAdminUtil;
+import com.nflg.mobilebroken.common.util.SaTokenAppUtil;
+import com.nflg.mobilebroken.common.util.VUtils;
+import com.nflg.mobilebroken.repository.entity.AdminUser;
+import com.nflg.mobilebroken.repository.entity.AppUser;
+import com.nflg.mobilebroken.repository.service.IAdminUserRoleMapService;
+import com.nflg.mobilebroken.repository.service.IAdminUserService;
+import com.nflg.mobilebroken.repository.service.IAppUserService;
+import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.api.WxMpService;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * 微信
+ */
+@RestController
+@RequestMapping("/weixin")
+public class WeiXinController extends ControllerBase {
+
+ @Resource
+ private WxMpService wxMpService;
+
+ @Resource
+ private IAppUserService appUserService;
+
+ @Resource
+ private IAdminUserService adminUserService;
+
+ @Resource
+ private IAdminUserRoleMapService adminUserRoleMapService;
+
+ /**
+ * 获取微信授权地址
+ * @param redirectUri 回调地址
+ */
+ @GetMapping("getAuthUrl")
+ public ApiResult getAuthUrl(@Valid @RequestParam @NotBlank String redirectUri) {
+ String url = wxMpService.getOAuth2Service().buildAuthorizationUrl(
+ redirectUri,
+ WxConsts.OAuth2Scope.SNSAPI_BASE,
+ IdUtil.getIdStr()
+ );
+ return ApiResult.success(url);
+ }
+
+ /**
+ * 获取登录token
+ * @param code 微信授权码
+ * @param state state
+ */
+ @GetMapping("getToken")
+ public ApiResult getToken(@Valid @RequestParam @NotBlank String code
+ , @Valid @RequestParam @NotBlank String state) throws WxErrorException {
+ WxOAuth2AccessToken token = wxMpService.getOAuth2Service().getAccessToken(code);
+ String openId = token.getOpenId();
+ AppLoginVO vo = getAppUserToken(openId);
+ vo = Objects.nonNull(vo) ? vo : getAdminUserToken(openId);
+ if (Objects.isNull(vo)) {
+ return ApiResult.success(new AppLoginVO().setWxOpenId(openId));
+ } else {
+ return ApiResult.success(vo);
+ }
+ }
+
+ private AppLoginVO getAppUserToken(String openId) {
+ AppUser user = appUserService.getByWxOpenId(openId);
+ if (Objects.nonNull(user)) {
+ return buildAppLoginVO(user);
+ }
+ return null;
+ }
+
+ private AppLoginVO buildAppLoginVO(AppUser user) {
+ SaTokenAppUtil.login(user.getId(), SaLoginConfig
+ .setExtra("from", Constant.FROM_APP)
+ .setExtra("name", user.getName())
+ .setExtra("email", user.getEmail())
+ .setExtra("companyIds", StrUtil.split(user.getCompanyId(), ",").stream().map(Integer::valueOf).collect(Collectors.toList()))
+ .setExtra("isPrimary", user.getIsPrimary()));
+ user.setLastLoginTime(LocalDateTime.now());
+ appUserService.updateById(user);
+ SaTokenInfo tokenInfo = SaTokenAppUtil.getTokenInfo();
+ return new AppLoginVO()
+ .setUserId(user.getId())
+ .setToken(tokenInfo.getTokenValue())
+ .setExpire(tokenInfo.getTokenTimeout())
+ .setLanguageCode(user.getLanguageCode())
+ .setPlatform(Constant.FROM_APP);
+ }
+
+ private AppLoginVO getAdminUserToken(String openId) {
+ AdminUser adminUser = adminUserService.getByWxOpenId(openId);
+ if (Objects.nonNull(adminUser)) {
+ return buildAdminLoginVO(adminUser);
+ }
+ return null;
+ }
+
+ private AppLoginVO buildAdminLoginVO(AdminUser adminUser) {
+ List roleCodes = adminUserRoleMapService.getRoleList(adminUser.getId());
+ SaTokenAdminUtil.login(adminUser.getId(), SaLoginConfig
+ .setExtra("from", Constant.FROM_ADMIN)
+ .setExtra("name", adminUser.getUserName())
+ .setExtra("code", adminUser.getUserCode())
+ .setExtra("email", adminUser.getEmail())
+ .setExtra("roles", roleCodes.stream().map(RoleVO::getCode).collect(Collectors.toList())));
+ String adminToken = SaTokenAdminUtil.getTokenInfo().getTokenValue();
+ SaTokenAppUtil.login(adminUser.getId(), SaLoginConfig
+ .setExtra("from", Constant.FROM_ADMIN)
+ .setExtra("name", adminUser.getUserName())
+ .setExtra("email", adminUser.getEmail()));
+ SaTokenInfo tokenInfo = SaTokenAppUtil.getTokenInfo();
+ return new AppLoginVO()
+ .setUserId(adminUser.getId())
+ .setToken(tokenInfo.getTokenValue())
+ .setAdminToken(adminToken)
+ .setExpire(tokenInfo.getTokenTimeout())
+ .setLanguageCode(Constant.DEFAULT_LANGUAGE_CODE)
+ .setPlatform(Constant.FROM_ADMIN);
+ }
+
+ /**
+ * 绑定用户
+ * @param request 请求参数
+ */
+ @PostMapping("bindUser")
+ public ApiResult bindUser(@Valid @RequestBody @NotNull UserBindWXRequest request) {
+ AppUser appUser = appUserService.getByWxOpenId(request.getOpenId());
+ AdminUser adminUser = adminUserService.getByWxOpenId(request.getOpenId());
+ VUtils.trueThrowBusinessError(Objects.nonNull(appUser) || Objects.nonNull(adminUser))
+ .throwMessage("请勿重复绑定");
+ appUser = appUserService.getUser(request.getLoginName(), request.getPwd());
+ if (Objects.nonNull(appUser)) {
+ VUtils.trueThrowBusinessError(StrUtil.isNotBlank(appUser.getWxOpenId())).throwMessage("该账号已绑定了微信");
+ appUser.setWxOpenId(request.getOpenId());
+ appUser.setUpdateTime(LocalDateTime.now());
+ return ApiResult.success(buildAppLoginVO(appUser));
+ } else {
+ adminUser = adminUserService.getUser(request.getLoginName(), request.getPwd());
+ if (Objects.nonNull(adminUser)) {
+ VUtils.trueThrowBusinessError(StrUtil.isNotBlank(adminUser.getWxOpenId())).throwMessage("该账号已绑定了微信");
+ adminUser.setWxOpenId(request.getOpenId());
+ adminUser.setUpdateTime(LocalDateTime.now());
+ adminUserService.updateById(adminUser);
+ return ApiResult.success(buildAdminLoginVO(adminUser));
+ }
+ throw new NflgException(STATE.PassportErr, "用户名或密码错误");
+ }
+ }
+}
diff --git a/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/weixin/CustomWxMpConfigStorage.java b/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/weixin/CustomWxMpConfigStorage.java
new file mode 100644
index 00000000..1bccae6e
--- /dev/null
+++ b/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/weixin/CustomWxMpConfigStorage.java
@@ -0,0 +1,27 @@
+package com.nflg.mobilebroken.auth.weixin;
+
+import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
+
+public class CustomWxMpConfigStorage extends WxMpDefaultConfigImpl {
+
+ private final ExternalTokenService externalTokenService;
+
+ public CustomWxMpConfigStorage(ExternalTokenService externalTokenService) {
+ this.externalTokenService = externalTokenService;
+ }
+
+ @Override
+ public String getAccessToken() {
+ return externalTokenService.fetchGlobalAccessToken();
+ }
+
+ @Override
+ public String getAppId() {
+ return externalTokenService.getAppId();
+ }
+
+ @Override
+ public String getSecret() {
+ return externalTokenService.getAppSecret();
+ }
+}
diff --git a/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/weixin/ExternalTokenService.java b/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/weixin/ExternalTokenService.java
new file mode 100644
index 00000000..3d8395f7
--- /dev/null
+++ b/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/weixin/ExternalTokenService.java
@@ -0,0 +1,10 @@
+package com.nflg.mobilebroken.auth.weixin;
+
+public interface ExternalTokenService {
+
+ String fetchGlobalAccessToken();
+
+ String getAppId();
+
+ String getAppSecret();
+}
diff --git a/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/weixin/TokenCache.java b/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/weixin/TokenCache.java
new file mode 100644
index 00000000..cef3e5aa
--- /dev/null
+++ b/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/weixin/TokenCache.java
@@ -0,0 +1,18 @@
+package com.nflg.mobilebroken.auth.weixin;
+
+import cn.hutool.core.annotation.Alias;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+public class TokenCache {
+
+ private String appId;
+
+ @Alias("appSecre")
+ private String appSecret;
+
+ @Alias("token")
+ private String accessToken;
+}
diff --git a/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/weixin/impl/ExternalTokenServiceImpl.java b/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/weixin/impl/ExternalTokenServiceImpl.java
new file mode 100644
index 00000000..be75c1fc
--- /dev/null
+++ b/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/weixin/impl/ExternalTokenServiceImpl.java
@@ -0,0 +1,56 @@
+package com.nflg.mobilebroken.auth.weixin.impl;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.nflg.mobilebroken.auth.weixin.ExternalTokenService;
+import com.nflg.mobilebroken.auth.weixin.TokenCache;
+import com.nflg.mobilebroken.common.constant.STATE;
+import com.nflg.mobilebroken.common.exception.NflgException;
+import com.nflg.mobilebroken.common.util.VUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class ExternalTokenServiceImpl implements ExternalTokenService {
+
+ private TokenCache token;
+
+ @Value("${wx.mp.accessTokenUrl}")
+ private String weixinAccessTokenUrl;
+
+ @Override
+ public String fetchGlobalAccessToken() {
+ refreshToken();
+ return token.getAccessToken();
+ }
+
+ @Override
+ public String getAppId() {
+ refreshToken();
+ return token.getAppId();
+ }
+
+ @Override
+ public String getAppSecret() {
+ refreshToken();
+ return token.getAppSecret();
+ }
+
+ private void refreshToken() {
+ try {
+ String content = HttpUtil.get(weixinAccessTokenUrl, 10000);
+ log.info("获取微信AccessToken结果:{}", content);
+ JSONObject oj = JSONUtil.parseObj(content);
+ VUtils.trueThrowBusinessError(!StrUtil.equals(oj.getStr("status"), "success"))
+ .throwMessage(oj.getStr("message"));
+ token = JSONUtil.toBean(oj.getStr("message"), TokenCache.class);
+ log.debug("Token数据:{}", JSONUtil.toJsonStr(token));
+ } catch (Exception e) {
+ throw new NflgException(STATE.ServiceConnectRefused, "获取微信AccessToken失败:" + e.getMessage());
+ }
+ }
+}
diff --git a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/TicketController.java b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/TicketController.java
index 4588e908..e4148697 100644
--- a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/TicketController.java
+++ b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/TicketController.java
@@ -145,7 +145,7 @@ public class TicketController extends ControllerBase {
* @param request 工单信息
**/
@PostMapping("/addTiket")
- public ApiResult addTiket(@Valid @RequestBody TicketAddRequest request) {
+ public ApiResult addTicket(@Valid @RequestBody TicketAddRequest request) {
Ticket ticket = ticketService.add(request, AppUserUtil.getUserId());
ticketChatService.add(new TicketChatDTO()
.setTicketId(ticket.getId())
diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/TicketAddRequest.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/TicketAddRequest.java
index b6506c68..b1b084b4 100644
--- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/TicketAddRequest.java
+++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/TicketAddRequest.java
@@ -39,4 +39,9 @@ public class TicketAddRequest {
//设备地址
@Size(max = 300, message = "设备地址长度不能超过300")
private String deviceAddress;
+
+ /**
+ * 来源
+ */
+ private String source;
}
\ No newline at end of file
diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/UserBindWXRequest.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/UserBindWXRequest.java
new file mode 100644
index 00000000..7b0f69df
--- /dev/null
+++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/UserBindWXRequest.java
@@ -0,0 +1,27 @@
+package com.nflg.mobilebroken.common.pojo.request;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class UserBindWXRequest {
+
+ /**
+ * 微信openId
+ */
+ @NotBlank
+ private String openId;
+
+ /**
+ * 登录名
+ */
+ @NotBlank
+ private String loginName;
+
+ /**
+ * 密码
+ */
+ @NotBlank
+ private String pwd;
+}
diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AppLoginVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AppLoginVO.java
index 62b110a6..b2a63501 100644
--- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AppLoginVO.java
+++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AppLoginVO.java
@@ -23,4 +23,9 @@ public class AppLoginVO {
//平台,app或者admin
private String platform;
+
+ /**
+ * 微信openId
+ */
+ private String wxOpenId;
}
diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/AdminUser.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/AdminUser.java
index 606e2561..685453e4 100644
--- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/AdminUser.java
+++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/AdminUser.java
@@ -108,4 +108,9 @@ public class AdminUser implements Serializable {
* 删除状态,0:未删除,1:已删除
*/
private Boolean isDel;
+
+ /**
+ * 微信openid
+ */
+ private String wxOpenId;
}
diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/AppUser.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/AppUser.java
index 899408bc..7f1df5da 100644
--- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/AppUser.java
+++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/AppUser.java
@@ -134,4 +134,9 @@ public class AppUser implements Serializable {
* 删除状态,0:未删除,1:已删除
*/
private Boolean isDel;
+
+ /**
+ * 微信openid
+ */
+ private String wxOpenId;
}
diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/Ticket.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/Ticket.java
index eb47663f..9222e196 100644
--- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/Ticket.java
+++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/Ticket.java
@@ -146,4 +146,9 @@ public class Ticket implements Serializable {
* 最后更新时间
*/
private LocalDateTime updateTime;
+
+ /**
+ * 来源
+ */
+ private String source;
}
diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAdminUserService.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAdminUserService.java
index c73930c2..9d66e9fa 100644
--- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAdminUserService.java
+++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAdminUserService.java
@@ -54,4 +54,6 @@ public interface IAdminUserService extends IService {
List getTickerMangagers();
List getCQMIds();
+
+ AdminUser getByWxOpenId(String openId);
}
diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAppUserService.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAppUserService.java
index a29d9a01..13e63806 100644
--- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAppUserService.java
+++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAppUserService.java
@@ -68,4 +68,6 @@ public interface IAppUserService extends IService {
void authorizeRole(@Valid AuthorizeRoleRequest request);
Integer getPrimaryByChild(Integer userId);
+
+ AppUser getByWxOpenId(String openId);
}
diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AdminUserServiceImpl.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AdminUserServiceImpl.java
index 805693db..49bd4263 100644
--- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AdminUserServiceImpl.java
+++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AdminUserServiceImpl.java
@@ -358,6 +358,11 @@ public class AdminUserServiceImpl extends ServiceImpl impl
return primaryUser.getId();
}
+ @Override
+ public AppUser getByWxOpenId(String openId) {
+ return lambdaQuery().eq(AppUser::getWxOpenId, openId).one();
+ }
+
private void bindChildren1(AreaSimpleVO vo) {
List datas = appAreaService.lambdaQuery().eq(AppArea::getParentId, vo.getId()).eq(AppArea::getEnable, true).list();
List vos = datas.stream().map(d -> new AreaSimpleVO().setId(d.getId()).setName(d.getName())).collect(Collectors.toList());
diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketServiceImpl.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketServiceImpl.java
index ec3294e0..38d2e86a 100644
--- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketServiceImpl.java
+++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketServiceImpl.java
@@ -81,6 +81,7 @@ public class TicketServiceImpl extends ServiceImpl impleme
.setTitle(request.getTitle())
.setDescription(request.getDescription())
.setState(TicketState.PendingProcessing.getState())
+ .setSource(request.getSource())
.setUserId(userId)
.setUserPlatform(AppUserUtil.getFrom())
.setCreateTime(LocalDateTime.now());