Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
I
im-common
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
陈永峰
im-common
Commits
e6c090eb
Commit
e6c090eb
authored
Nov 28, 2021
by
chenyongfeng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
初始化
parent
1c96c19a
Pipeline
#20392
failed with stages
in 59 seconds
Changes
42
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
1980 additions
and
81 deletions
+1980
-81
pom.xml
pom.xml
+0
-0
ClientConfiguration.java
src/main/java/io/github/doocs/im/ClientConfiguration.java
+9
-0
ImClient.java
src/main/java/io/github/doocs/im/ImClient.java
+109
-37
QcloudImApplication.java
src/main/java/io/github/doocs/im/QcloudImApplication.java
+32
-0
BusinessException.java
...ain/java/io/github/doocs/im/config/BusinessException.java
+20
-0
CommonError.java
src/main/java/io/github/doocs/im/config/CommonError.java
+21
-0
CommonResult.java
src/main/java/io/github/doocs/im/config/CommonResult.java
+49
-0
ErrorEnum.java
src/main/java/io/github/doocs/im/config/ErrorEnum.java
+74
-0
ExecutorConfig.java
src/main/java/io/github/doocs/im/config/ExecutorConfig.java
+37
-0
GlobalExceptionAdvice.java
...java/io/github/doocs/im/config/GlobalExceptionAdvice.java
+150
-0
HttpClientPoolConfig.java
.../java/io/github/doocs/im/config/HttpClientPoolConfig.java
+53
-0
MongoConfig.java
src/main/java/io/github/doocs/im/config/MongoConfig.java
+220
-0
MyBatisFillConfig.java
...ain/java/io/github/doocs/im/config/MyBatisFillConfig.java
+31
-0
MybatisPlusConfig.java
...ain/java/io/github/doocs/im/config/MybatisPlusConfig.java
+28
-0
RestTemplateConfig.java
...in/java/io/github/doocs/im/config/RestTemplateConfig.java
+0
-0
ValidatorConfig.java
src/main/java/io/github/doocs/im/config/ValidatorConfig.java
+24
-0
ValidatorUtil.java
src/main/java/io/github/doocs/im/config/ValidatorUtil.java
+64
-0
WebConfig.java
src/main/java/io/github/doocs/im/config/WebConfig.java
+37
-0
ActionStatus.java
src/main/java/io/github/doocs/im/constant/ActionStatus.java
+3
-0
MongoAccoutStatus.java
...n/java/io/github/doocs/im/constant/MongoAccoutStatus.java
+8
-0
AccountController.java
...java/io/github/doocs/im/controller/AccountController.java
+47
-0
GroupController.java
...n/java/io/github/doocs/im/controller/GroupController.java
+113
-0
MessageController.java
...java/io/github/doocs/im/controller/MessageController.java
+37
-0
Account.java
src/main/java/io/github/doocs/im/core/Account.java
+1
-1
Group.java
src/main/java/io/github/doocs/im/core/Group.java
+1
-1
Message.java
src/main/java/io/github/doocs/im/core/Message.java
+1
-1
CreateGroupRequest.java
.../io/github/doocs/im/model/request/CreateGroupRequest.java
+4
-0
AccountEntity.java
src/main/java/io/github/doocs/im/mongo/AccountEntity.java
+31
-0
AccountService.java
src/main/java/io/github/doocs/im/servie/AccountService.java
+145
-0
GeneraService.java
src/main/java/io/github/doocs/im/servie/GeneraService.java
+22
-0
GroupService.java
src/main/java/io/github/doocs/im/servie/GroupService.java
+174
-0
MessageService.java
src/main/java/io/github/doocs/im/servie/MessageService.java
+65
-0
HttpUtil.java
src/main/java/io/github/doocs/im/util/HttpUtil.java
+5
-1
RandomUtil.java
src/main/java/io/github/doocs/im/util/RandomUtil.java
+167
-0
AccountVO.java
src/main/java/io/github/doocs/im/vo/AccountVO.java
+22
-0
QueryOnlineStatusRequestVO.java
...ava/io/github/doocs/im/vo/QueryOnlineStatusRequestVO.java
+16
-0
SimpleMessageVO.java
src/main/java/io/github/doocs/im/vo/SimpleMessageVO.java
+27
-0
application.yml
src/main/resources/application.yml
+50
-0
rebel.xml
src/main/resources/rebel.xml
+16
-0
AccountTest.java
src/test/java/io/github/doocs/im/AccountTest.java
+27
-17
GroupTest.java
src/test/java/io/github/doocs/im/GroupTest.java
+1
-1
MessageTest.java
src/test/java/io/github/doocs/im/MessageTest.java
+39
-22
No files found.
pom.xml
View file @
e6c090eb
This diff is collapsed.
Click to expand it.
src/main/java/io/github/doocs/im/ClientConfiguration.java
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
;
import
org.springframework.context.annotation.Configuration
;
import
io.github.doocs.im.util.VersionInfoUtil
;
/**
* @author bingo
* @since 2021/11/2 14:17
*/
@Configuration
public
class
ClientConfiguration
{
private
static
final
String
DEFAULT_USER_AGENT
=
VersionInfoUtil
.
getDefaultUserAgent
();
private
static
final
int
DEFAULT_MAX_RETRIES
=
3
;
...
...
@@ -22,6 +25,12 @@ public class ClientConfiguration {
*/
private
static
final
long
DEFAULT_EXPIRE_TIME
=
24
*
60
*
60L
;
//------------------------------------------------------------------------------
private
int
maxRetries
=
DEFAULT_MAX_RETRIES
;
private
long
connectTimeout
=
DEFAULT_CONNECT_TIMEOUT
;
private
long
readTimeout
=
DEFAULT_READ_TIMEOUT
;
...
...
src/main/java/io/github/doocs/im/ImClient.java
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
;
import
io.github.doocs.im.core.*
;
import
io.github.doocs.im.util.SigUtil
;
import
java.util.concurrent.ThreadLocalRandom
;
import
javax.annotation.PostConstruct
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
io.github.doocs.im.core.Account
;
import
io.github.doocs.im.core.Group
;
import
io.github.doocs.im.core.Member
;
import
io.github.doocs.im.core.Message
;
import
io.github.doocs.im.core.Operation
;
import
io.github.doocs.im.core.Profile
;
import
io.github.doocs.im.core.RecentContact
;
import
io.github.doocs.im.core.Sns
;
import
io.github.doocs.im.util.SigUtil
;
/**
* @author hyh
* @since 2021/07/29 16:11
*/
@Component
public
class
ImClient
{
private
final
long
sdkAppId
;
private
final
String
key
;
private
final
String
userId
;
private
final
ClientConfiguration
config
;
@Value
(
"${sdkAppId}"
)
private
Long
sdkAppId
;
@Value
(
"${key}"
)
private
String
key
;
@Value
(
"${userId}"
)
private
String
userId
;
@Autowired
private
ClientConfiguration
config
;
private
String
userSig
;
private
long
userSigExpireTs
;
private
static
final
String
VERSION
=
"v4"
;
private
static
final
String
FORMAT_URL
=
"https://console.tim.qq.com/%s/%s/%s?sdkappid=%d&identifier=%s&usersig=%s&random=%d&contenttype=json"
;
public
final
Account
account
;
public
final
Message
message
;
public
final
Member
member
;
public
final
Profile
profile
;
public
final
Group
group
;
public
final
Sns
sns
;
public
final
Operation
operation
;
public
final
RecentContact
recentContact
;
private
static
final
ClientConfiguration
DEFAULT_CONFIG
=
new
ClientConfiguration
();
public
static
ImClient
getInstance
(
long
sdkAppId
,
String
userId
,
String
key
)
{
return
new
ImClient
(
sdkAppId
,
userId
,
key
);
}
public
static
ImClient
getInstance
(
long
sdkAppId
,
String
userId
,
String
key
,
ClientConfiguration
config
)
{
return
new
ImClient
(
sdkAppId
,
userId
,
key
,
config
);
private
static
final
String
FORMAT_URL
=
"https://console.tim.qq.com/%s/%s/%s?sdkappid=%d&identifier=%s&usersig=%s&random=%d&contenttype=json"
;
public
Account
account
;
public
Message
message
;
public
Member
member
;
public
Profile
profile
;
public
Group
group
;
public
Sns
sns
;
public
Operation
operation
;
public
RecentContact
recentContact
;
// public ImClient(long sdkAppId, String userId, String key) {
//
//
// }
// private static final ClientConfiguration DEFAULT_CONFIG = new ClientConfiguration();
public
static
ImClient
getInstance
(
long
sdkAppId
,
String
userId
,
String
key
)
{
// return new ImClient(sdkAppId, userId, key);
return
null
;
}
//
// public static ImClient getInstance(long sdkAppId, String userId, String key, ClientConfiguration config) {
// return new ImClient(sdkAppId, userId, key, config);
// }
//
// public ImClient(long sdkAppId, String userId, String key) {
// this(sdkAppId, userId, key, DEFAULT_CONFIG);
// }
// public ImClient(long sdkAppId, String userId, String key, ClientConfiguration config) {
// this.sdkAppId = sdkAppId;
// this.userId = userId;
// this.key = key;
// this.config = config;
// this.userSig = SigUtil.genUserSig(sdkAppId, key, userId, config.getExpireTime());
// this.userSigExpireTs = System.currentTimeMillis() / 1000 + config.getExpireTime() - 100;
//
// account = new Account(this);
// message = new Message(this);
// member = new Member(this);
// profile = new Profile(this);
// group = new Group(this);
// operation = new Operation(this);
// sns = new Sns(this);
// recentContact = new RecentContact(this);
// }
@PostConstruct
public
void
initMethod
()
{
public
ImClient
(
long
sdkAppId
,
String
userId
,
String
key
)
{
this
(
sdkAppId
,
userId
,
key
,
DEFAULT_CONFIG
);
}
public
ImClient
(
long
sdkAppId
,
String
userId
,
String
key
,
ClientConfiguration
config
)
{
this
.
sdkAppId
=
sdkAppId
;
this
.
userId
=
userId
;
this
.
key
=
key
;
this
.
config
=
config
;
this
.
userSig
=
SigUtil
.
genUserSig
(
sdkAppId
,
key
,
userId
,
config
.
getExpireTime
());
this
.
userSigExpireTs
=
System
.
currentTimeMillis
()
/
1000
+
config
.
getExpireTime
()
-
100
;
...
...
@@ -85,7 +126,38 @@ public class ImClient {
public
String
getUrl
(
String
serviceName
,
String
command
)
{
String
sig
=
getUserSig
();
long
random
=
ThreadLocalRandom
.
current
().
nextLong
(
0
,
0x100000000
L
);
return
String
.
format
(
FORMAT_URL
,
VERSION
,
serviceName
,
command
,
sdkAppId
,
userId
,
sig
,
random
);
return
String
.
format
(
FORMAT_URL
,
VERSION
,
serviceName
,
command
,
sdkAppId
,
userId
,
sig
,
random
);
}
public
Account
getAccount
()
{
return
account
;
}
public
Message
getMessage
()
{
return
message
;
}
public
Member
getMember
()
{
return
member
;
}
public
Profile
getProfile
()
{
return
profile
;
}
public
Group
getGroup
()
{
return
group
;
}
public
Sns
getSns
()
{
return
sns
;
}
public
Operation
getOperation
()
{
return
operation
;
}
public
RecentContact
getRecentContact
()
{
return
recentContact
;
}
}
src/main/java/io/github/doocs/im/QcloudImApplication.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
;
import
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration
;
import
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
;
import
com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
;
@SpringBootApplication
(
exclude
=
{
DataSourceAutoConfiguration
.
class
,
DataSourceTransactionManagerAutoConfiguration
.
class
,
DruidDataSourceAutoConfigure
.
class
,
HibernateJpaAutoConfiguration
.
class
})
public
class
QcloudImApplication
{
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
QcloudImApplication
.
class
,
args
);
}
}
src/main/java/io/github/doocs/im/config/BusinessException.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
config
;
import
lombok.Data
;
@Data
public
class
BusinessException
extends
RuntimeException
{
private
CommonError
commonError
;
public
BusinessException
(
ErrorEnum
errorEnum
)
{
super
();
this
.
commonError
=
new
CommonError
(
errorEnum
);
}
public
BusinessException
(
CommonError
commonError
)
{
super
();
this
.
commonError
=
commonError
;
}
}
src/main/java/io/github/doocs/im/config/CommonError.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
config
;
import
lombok.Data
;
@Data
public
class
CommonError
{
private
String
code
;
private
String
msg
;
public
CommonError
(
String
code
,
String
msg
)
{
this
.
code
=
code
;
this
.
msg
=
msg
;
}
public
CommonError
(
ErrorEnum
errorEnum
)
{
this
.
code
=
errorEnum
.
getCode
();
this
.
msg
=
errorEnum
.
getMsg
();
}
}
src/main/java/io/github/doocs/im/config/CommonResult.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
config
;
import
com.alibaba.fastjson.JSONObject
;
import
lombok.Data
;
@Data
public
class
CommonResult
{
private
String
status
;
private
Object
data
;
public
static
CommonResult
success
()
{
CommonResult
commonResult
=
new
CommonResult
();
commonResult
.
setStatus
(
"success"
);
commonResult
.
setData
(
"操作成功!"
);
return
commonResult
;
}
public
static
CommonResult
success
(
Object
data
)
{
CommonResult
success
=
success
();
if
(
data
==
null
)
{
success
.
setData
(
new
JSONObject
());
return
success
;
}
success
.
setData
(
data
);
return
success
;
}
public
static
CommonResult
fail
(
ErrorEnum
errorEnum
)
{
CommonResult
commonResult
=
new
CommonResult
();
commonResult
.
setStatus
(
"fail"
);
CommonError
commonError
=
new
CommonError
(
errorEnum
);
commonResult
.
setData
(
commonError
);
return
commonResult
;
}
public
static
CommonResult
fail
(
CommonError
commonError
)
{
CommonResult
commonResult
=
new
CommonResult
();
commonResult
.
setStatus
(
"fail"
);
commonResult
.
setData
(
commonError
);
return
commonResult
;
}
}
src/main/java/io/github/doocs/im/config/ErrorEnum.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
config
;
public
enum
ErrorEnum
{
UNKNOWN_ERROR
(
"10001"
,
"未知错误!"
),
REQUEST_ERROR
(
"10002"
,
"请求qcloud失败!"
),
ACCOUNT_KILLED
(
"1000"
,
"账号已被失效!"
),
ACCOUNT_DELETE
(
"1001"
,
"账号已被删除!"
),
E404_ERROR
(
"10003"
,
"请求不存在!"
),
BIND_ERROR
(
"10004"
,
"请求参数不存在"
),
PARAM_ERROR_4
(
"10005"
,
"请求参数错误"
),
METHOD_ERROR
(
"10006"
,
"请求方式get/post错误!"
),
SAVE_ERROR
(
"10008"
,
"保存失败!"
),
DEL_ERROR
(
"10007"
,
"删除数量为0!"
),
EXISTS_ERROR
(
"20001"
,
"名称已存在!"
),
EXCEL_ERROR
(
"30001"
,
"excel文件内容不能为空!"
),
EXCEL_PARSE_ERROR
(
"30002"
,
"excel文件内容解析失败!"
),
EMAIL_ERROR
(
"30003"
,
"与预留邮箱不一致!"
),
EMAIL_FAIL_ERROR
(
"30004"
,
"邮件发送失败!"
),
CODE_ERROR
(
"30005"
,
"验证码不正确!"
),
CODE_CREATE_ERROR
(
"30006"
,
"验证码生成失败!"
),
CODE_EFFECT_ERROR
(
"30007"
,
"验证码已经失效!"
),
USERNAME_ERROR
(
"30008"
,
"用户邮箱不能为空!"
),
PASSWORD_ERROR
(
"30009"
,
"密码不能为空!"
),
USERNOTEXISTS_ERROR
(
"30010"
,
"用户不存在!"
),
PASSWORDFAIL_ERROR
(
"30011"
,
"密码不正确!"
),
PARAMVALUE_ERROR
(
"30012"
,
"参数值错误!"
),
PARAMLOSE_ERROR
(
"30013"
,
"参数缺失!"
),
LOGIN_ERROR
(
"30014"
,
"请重新登陆!"
),
PHONEVERIFY_ERROR
(
"30015"
,
"手机号未注册!"
),
IDNULL_ERROR
(
"30016"
,
"id不能为空!"
),
NO_AUTH_ERROR
(
"10000"
,
"没有权限,请联系管理员授权"
),
NOTALL_ERROR
(
"30017"
,
"开始结束时间必须同时存在!"
)
,
VERIFY_CODE_ERROR
(
"30018"
,
"手机验证码错误!"
)
,
BIND_CHILDREN_ERROR
(
"30019"
,
"请绑定孩子!"
),
RESERVE_COURSE_ERROR
(
"30020"
,
"暂未约课!"
),
REQUEST_FAILED
(
"30021"
,
"request failed!"
),
RESERVE_FULL
(
"30022"
,
"课程已约满"
),
RESERVE_ABOVE
(
"30023"
,
"约课已超出剩余"
),
RESERVE_DATE_ERROR
(
"30024"
,
"约课日期有过去的时间请重新约课"
),
USERCOUNT_ERROR
(
"30025"
,
"账户已失效!"
),
USERBLOCK_ERROR
(
"30026"
,
"账户已冻结!"
),
BINDTYPE_ERROR
(
"30027"
,
"已绑定身份!"
),
PAYMENT_ERROR
(
"30028"
,
"订单已确认收款,不能重复提交!"
),
RESERVE_ERROR
(
"30029"
,
"您已在该时段预约,不能重复提交!"
),
NULL_TIMEZONE_ERROR
(
"30030"
,
"时区不可为空!!"
);
private
String
code
;
private
String
msg
;
ErrorEnum
(
String
code
,
String
msg
)
{
this
.
code
=
code
;
this
.
msg
=
msg
;
}
public
String
getCode
()
{
return
code
;
}
public
void
setCode
(
String
code
)
{
this
.
code
=
code
;
}
public
String
getMsg
()
{
return
msg
;
}
public
void
setMsg
(
String
msg
)
{
this
.
msg
=
msg
;
}
}
src/main/java/io/github/doocs/im/config/ExecutorConfig.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
config
;
/**
* @Auther chenyongfeng
* @Date 2021/5/28
*/
import
java.util.concurrent.Executor
;
import
java.util.concurrent.ThreadPoolExecutor
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
;
@Configuration
public
class
ExecutorConfig
{
@Bean
(
name
=
"mypool"
)
public
Executor
asyncServiceExecutor
()
{
ThreadPoolTaskExecutor
executor
=
new
ThreadPoolTaskExecutor
();
// 配置核心线程数
executor
.
setCorePoolSize
(
20
);
// 配置最大线程数
executor
.
setMaxPoolSize
(
30
);
// 配置队列大小
executor
.
setQueueCapacity
(
5
);
// 配置线程池中的线程的名称前缀
executor
.
setThreadNamePrefix
(
"Thread-"
);
executor
.
setAwaitTerminationSeconds
(
10000
);
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
executor
.
setRejectedExecutionHandler
(
new
ThreadPoolExecutor
.
CallerRunsPolicy
());
// 执行初始化
executor
.
initialize
();
return
executor
;
}
}
src/main/java/io/github/doocs/im/config/GlobalExceptionAdvice.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
config
;
import
java.util.stream.Collectors
;
import
javax.validation.ConstraintViolation
;
import
javax.validation.ConstraintViolationException
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.converter.HttpMessageNotReadableException
;
import
org.springframework.web.HttpRequestMethodNotSupportedException
;
import
org.springframework.web.bind.MethodArgumentNotValidException
;
import
org.springframework.web.bind.ServletRequestBindingException
;
import
org.springframework.web.bind.annotation.ControllerAdvice
;
import
org.springframework.web.bind.annotation.ExceptionHandler
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
org.springframework.web.bind.annotation.ResponseStatus
;
import
org.springframework.web.servlet.NoHandlerFoundException
;
import
lombok.extern.slf4j.Slf4j
;
@ControllerAdvice
@Slf4j
public
class
GlobalExceptionAdvice
{
@ExceptionHandler
(
Exception
.
class
)
@ResponseBody
public
CommonResult
exceptionHandler
(
Exception
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
return
CommonResult
.
fail
(
new
CommonError
(
ErrorEnum
.
UNKNOWN_ERROR
));
}
/**
* 自定义异常
*
* @param e
* @return
*/
@ExceptionHandler
(
BusinessException
.
class
)
@ResponseBody
public
CommonResult
exceptionHandler
(
BusinessException
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
return
CommonResult
.
fail
(
e
.
getCommonError
());
}
/**
* 参数转换错误
*
* @param e
* @return
*/
@ExceptionHandler
(
HttpMessageNotReadableException
.
class
)
@ResponseBody
public
CommonResult
handleConstraintViolationException
(
HttpMessageNotReadableException
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
return
CommonResult
.
fail
(
ErrorEnum
.
PARAM_ERROR_4
);
}
/**
* 404
*
* @param e
* @return
*/
@ResponseBody
@ExceptionHandler
(
NoHandlerFoundException
.
class
)
@ResponseStatus
(
HttpStatus
.
NOT_FOUND
)
public
CommonResult
handleConstraintViolationException
(
NoHandlerFoundException
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
return
CommonResult
.
fail
(
ErrorEnum
.
E404_ERROR
);
}
/**
* 参数校验失败 在方法内的参数
*
* @param e
* @return
*/
@ResponseBody
@ExceptionHandler
(
ConstraintViolationException
.
class
)
public
CommonResult
handleConstraintViolationException
(
ConstraintViolationException
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
return
CommonResult
.
fail
(
new
CommonError
(
"10009"
,
e
.
getConstraintViolations
().
stream
().
map
(
ConstraintViolation:
:
getMessage
).
collect
(
Collectors
.
joining
())));
}
/**
* 参数绑定错误 id ids
*
* @param e
* @return
*/
@ResponseBody
@ExceptionHandler
(
ServletRequestBindingException
.
class
)
public
CommonResult
handleConstraintViolationException
(
ServletRequestBindingException
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
return
CommonResult
.
fail
(
ErrorEnum
.
BIND_ERROR
);
}
@ResponseBody
@ExceptionHandler
(
MethodArgumentNotValidException
.
class
)
public
CommonResult
handleConstraintViolationException
(
MethodArgumentNotValidException
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
return
CommonResult
.
fail
(
new
CommonError
(
"10009"
,
e
.
getBindingResult
().
getFieldError
().
getDefaultMessage
()));
}
@ResponseBody
@ExceptionHandler
(
HttpRequestMethodNotSupportedException
.
class
)
public
CommonResult
handleConstraintViolationException
(
HttpRequestMethodNotSupportedException
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
return
CommonResult
.
fail
(
ErrorEnum
.
METHOD_ERROR
);
}
// @ResponseBody
// @ExceptionHandler(AccessDeniedException.class)
// public CommonResult handleAuthorizationException(AccessDeniedException e) {
// log.error(e.getMessage(), e);
// return CommonResult.fail(ErrorEnum.NO_AUTH_ERROR);
// }
/**
* 文件上传异常处理
*
* @param e
* @return
*/
// @ResponseBody
// @ExceptionHandler(MultipartException.class)
// public CommonResult exception(MaxUploadSizeExceededException e) {
// if (e.getCause().getCause() instanceof FileUploadBase.FileSizeLimitExceededException) {
// log.error("message异常信息为=========》" + e.getMessage());
// log.error("cause异常信息为=========》" + e.getCause().getCause());
// String s = "单个上传文件大小不能超过20MB";
// return CommonResult.fail(new CommonError("40001","单个上传文件大小不能超过20MB"));
//
// } else if (e.getCause().getCause() instanceof FileUploadBase.SizeLimitExceededException) {
// log.error("message异常信息为=========》" + e.getMessage());
// log.error("cause异常信息为=========》" + e.getCause().getCause());
// return CommonResult.fail(new CommonError("40002","总上传文件大小不能超过100MB"));
//
// }
// return CjwommonResult.fail(new CommonError("40000","文件上传异常!"));
//
// }
}
src/main/java/io/github/doocs/im/config/HttpClientPoolConfig.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
config
;
import
java.util.Map
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.stereotype.Component
;
import
lombok.Data
;
@Component
@ConfigurationProperties
(
prefix
=
"spring.http-client.pool"
)
@Data
public
class
HttpClientPoolConfig
{
/**
* java配置的优先级低于yml配置;如果yml配置不存在,会采用java配置
*/
/**
* 连接池的最大连接数
*/
private
int
maxTotalConnect
;
/**
* 同路由的并发数
*/
private
int
maxConnectPerRoute
;
/**
* 客户端和服务器建立连接超时,默认2s
*/
private
int
connectTimeout
=
2
*
1000
;
/**
* 指客户端从服务器读取数据包的间隔超时时间,不是总读取时间,默认30s
*/
private
int
readTimeout
=
30
*
1000
;
private
String
charset
=
"UTF-8"
;
/**
* 重试次数,默认2次
*/
private
int
retryTimes
=
2
;
/**
* 从连接池获取连接的超时时间,不宜过长,单位ms
*/
private
int
connectionRequestTimout
=
200
;
/**
* 针对不同的地址,特别设置不同的长连接保持时间
*/
private
Map
<
String
,
Integer
>
keepAliveTargetHost
;
/**
* 针对不同的地址,特别设置不同的长连接保持时间,单位 s
*/
private
int
keepAliveTime
=
60
;
}
src/main/java/io/github/doocs/im/config/MongoConfig.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
config
;
import
java.util.ArrayList
;
import
java.util.List
;
import
javax.validation.constraints.Min
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.mongodb.MongoDbFactory
;
import
org.springframework.data.mongodb.core.MongoTemplate
;
import
org.springframework.data.mongodb.core.SimpleMongoDbFactory
;
import
org.springframework.data.mongodb.core.convert.DbRefResolver
;
import
org.springframework.data.mongodb.core.convert.DefaultDbRefResolver
;
import
org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper
;
import
org.springframework.data.mongodb.core.convert.MappingMongoConverter
;
import
org.springframework.data.mongodb.core.convert.MongoCustomConversions
;
import
org.springframework.data.mongodb.core.mapping.MongoMappingContext
;
import
org.springframework.util.StringUtils
;
import
org.springframework.validation.annotation.Validated
;
import
com.mongodb.MongoClient
;
import
com.mongodb.MongoClientOptions
;
import
com.mongodb.MongoCredential
;
import
com.mongodb.ReadPreference
;
import
com.mongodb.ServerAddress
;
import
lombok.Getter
;
import
lombok.Setter
;
/**
* @Description mongo配置类
* @Author Mr.nobody
* @Date 2020/11/7
* @Version 1.0
*/
@Configuration
// 将带有@ConfigurationProperties注解的类注入为Spring容器的Bean,
// 任何被@ConfigurationProperties注解的beans将自动被Environment属性配置。
@EnableConfigurationProperties
(
MongoConfig
.
MongoClientOptionProperties
.
class
)
public
class
MongoConfig
{
/**
* 此Bean也是可以不显示定义的,如果我们没有显示定义生成MongoTemplate实例, SpringBoot利用我们配置好的MongoDbFactory在配置类中生成一个MongoTemplate,
* 之后我们就可以在项目代码中直接@Autowired了。因为用于生成MongoTemplate 的MongoDbFactory是我们自己在MongoConfig配置类中生成的,所以我们自定义的连接池参数也就生效了。
*
* @param mongoDbFactory
* mongo工厂
* @param converter
* 转换器
* @return MongoTemplate实例
*/
@Bean
public
MongoTemplate
mongoTemplate
(
MongoDbFactory
mongoDbFactory
,
MappingMongoConverter
converter
)
{
MongoTemplate
mongoTemplate
=
new
MongoTemplate
(
mongoDbFactory
,
converter
);
// 设置读从库优先
mongoTemplate
.
setReadPreference
(
ReadPreference
.
secondaryPreferred
());
return
mongoTemplate
;
}
/**
* 转换器 MappingMongoConverter可以自定义mongo转换器,主要自定义存取mongo数据时的一些操作,例如 mappingConverter.setTypeMapper(new
* DefaultMongoTypeMapper(null)) 方法会将mongo数据中的_class字段去掉。
*
* @param factory
* mongo工厂
* @param context
* 上下文
* @param conversions
* 自定义转换器
* @return 转换器对象
*/
@Bean
public
MappingMongoConverter
mappingMongoConverter
(
MongoDbFactory
factory
,
MongoMappingContext
context
,
MongoCustomConversions
conversions
)
{
DbRefResolver
dbRefResolver
=
new
DefaultDbRefResolver
(
factory
);
MappingMongoConverter
mappingConverter
=
new
MappingMongoConverter
(
dbRefResolver
,
context
);
mappingConverter
.
setCustomConversions
(
conversions
);
// remove _class field
mappingConverter
.
setTypeMapper
(
new
DefaultMongoTypeMapper
(
null
));
return
mappingConverter
;
}
/**
* 自定义mongo连接池
*
* @param properties
* 属性配置类
* @return MongoDbFactory对象
*/
@Bean
public
MongoDbFactory
mongoDbFactory
(
MongoClientOptionProperties
properties
)
{
MongoClient
mongoClient
;
// 创建客户端参数
MongoClientOptions
mongoClientOptions
=
mongoClientOptions
(
properties
);
// 解析获取mongo服务地址
List
<
ServerAddress
>
serverAddressList
=
getServerAddress
(
properties
.
getAddress
());
// 创建认证
MongoCredential
mongoCredential
=
getCredential
(
properties
);
// 创建客户端
if
(
null
==
mongoCredential
)
{
mongoClient
=
new
MongoClient
(
serverAddressList
,
mongoClientOptions
);
}
else
{
mongoClient
=
new
MongoClient
(
serverAddressList
,
mongoCredential
,
mongoClientOptions
);
}
return
new
SimpleMongoDbFactory
(
mongoClient
,
properties
.
getDatabase
());
}
/**
* 创建认证
*
* @param properties
* 属性配置类
* @return 认证对象
*/
private
MongoCredential
getCredential
(
MongoClientOptionProperties
properties
)
{
if
(!
StringUtils
.
isEmpty
(
properties
.
getUsername
())
&&
!
StringUtils
.
isEmpty
(
properties
.
getPassword
()))
{
// 没有专用认证数据库则取当前数据库
String
database
=
StringUtils
.
isEmpty
(
properties
.
getAuthenticationDatabase
())
?
properties
.
getDatabase
()
:
properties
.
getAuthenticationDatabase
();
return
MongoCredential
.
createCredential
(
properties
.
getUsername
(),
database
,
properties
.
getPassword
().
toCharArray
());
}
return
null
;
}
/**
* 获取数据库服务地址
*
* @param mongoAddress
* 地址字符串
* @return 服务地址数组
*/
private
List
<
ServerAddress
>
getServerAddress
(
String
mongoAddress
)
{
String
[]
mongoAddressArray
=
mongoAddress
.
trim
().
split
(
","
);
List
<
ServerAddress
>
serverAddressList
=
new
ArrayList
<>(
4
);
for
(
String
address
:
mongoAddressArray
)
{
String
[]
hostAndPort
=
address
.
split
(
":"
);
serverAddressList
.
add
(
new
ServerAddress
(
hostAndPort
[
0
],
Integer
.
parseInt
(
hostAndPort
[
1
])));
}
return
serverAddressList
;
}
/**
* mongo客户端参数配置
*
* @param properties
* 属性配置类
* @return mongo客户端参数配置对象
*/
private
MongoClientOptions
mongoClientOptions
(
MongoClientOptionProperties
properties
)
{
return
MongoClientOptions
.
builder
().
applicationName
(
properties
.
getClientName
())
.
connectTimeout
(
properties
.
getConnectionTimeoutMs
())
.
maxConnectionIdleTime
(
properties
.
getMaxConnectionIdleTimeMs
())
.
maxConnectionLifeTime
(
properties
.
getMaxConnectionLifeTimeMs
()).
socketTimeout
(
properties
.
getReadTimeoutMs
())
.
maxWaitTime
(
properties
.
getMaxWaitTimeMs
()).
heartbeatFrequency
(
properties
.
getHeartbeatFrequencyMs
())
.
minHeartbeatFrequency
(
properties
.
getMinHeartbeatFrequencyMs
())
.
heartbeatConnectTimeout
(
properties
.
getHeartbeatConnectionTimeoutMs
())
.
heartbeatSocketTimeout
(
properties
.
getHeartbeatReadTimeoutMs
())
.
connectionsPerHost
(
properties
.
getConnectionsPerHost
())
.
minConnectionsPerHost
(
properties
.
getMinConnectionsPerHost
())
.
threadsAllowedToBlockForConnectionMultiplier
(
properties
.
getThreadsAllowedToBlockForConnectionMultiplier
())
// .readPreference(ReadPreference.secondaryPreferred()).sslEnabled(true).build();
.
readPreference
(
ReadPreference
.
secondaryPreferred
()).
build
();
}
@Getter
@Setter
@Validated
@ConfigurationProperties
(
prefix
=
"mongodb"
)
public
static
class
MongoClientOptionProperties
{
/**
* 基础连接参数
*/
private
String
database
;
// 要连接的数据库
private
String
username
;
// 用户名
private
String
password
;
// 密码
private
String
address
;
// IP和端口(host:port),例如127.0.0.1:27017。集群模式用,分隔开,例如host1:port1,host2:port2
private
String
authenticationDatabase
;
// 设置认证数据库,如果有的话
/**
* 客户端连接池参数
*/
private
String
clientName
;
// 客户端的标识,用于定位请求来源等,一般用程序名
@Min
(
value
=
1
)
private
int
connectionTimeoutMs
;
// TCP(socket)连接超时时间,毫秒
@Min
(
value
=
1
)
private
int
maxConnectionIdleTimeMs
;
// TCP(socket)连接闲置时间,毫秒
@Min
(
value
=
1
)
private
int
maxConnectionLifeTimeMs
;
// TCP(socket)连接最多可以使用多久,毫秒
@Min
(
value
=
1
)
private
int
readTimeoutMs
;
// TCP(socket)读取超时时间,毫秒
@Min
(
value
=
1
)
private
int
maxWaitTimeMs
;
// 当连接池无可用连接时客户端阻塞等待的最大时长,毫秒
@Min
(
value
=
2000
)
private
int
heartbeatFrequencyMs
;
// 心跳检测发送频率,毫秒
@Min
(
value
=
300
)
private
int
minHeartbeatFrequencyMs
;
// 最小的心跳检测发送频率,毫秒
@Min
(
value
=
200
)
private
int
heartbeatConnectionTimeoutMs
;
// 心跳检测连接超时时间,毫秒
@Min
(
value
=
200
)
private
int
heartbeatReadTimeoutMs
;
// 心跳检测读取超时时间,毫秒
@Min
(
value
=
1
)
private
int
connectionsPerHost
;
// 线程池允许的最大连接数
@Min
(
value
=
1
)
private
int
minConnectionsPerHost
;
// 线程池空闲时保持的最小连接数
@Min
(
value
=
1
)
// 计算允许多少个线程阻塞等待时的乘数,算法:threadsAllowedToBlockForConnectionMultiplier*maxConnectionsPerHost
private
int
threadsAllowedToBlockForConnectionMultiplier
;
}
}
src/main/java/io/github/doocs/im/config/MyBatisFillConfig.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
config
;
import
java.util.Date
;
import
org.apache.ibatis.reflection.MetaObject
;
import
org.springframework.context.annotation.Configuration
;
import
com.baomidou.mybatisplus.core.handlers.MetaObjectHandler
;
/**
* @Auther chenyongfeng
* @Date 2021/7/30
*/
@Configuration
public
class
MyBatisFillConfig
implements
MetaObjectHandler
{
// 使用mp实现添加操作,这个方法会执行,metaObject元数据(表中的名字,表中的字段)
@Override
public
void
insertFill
(
MetaObject
metaObject
)
{
// 根据名称设置属性值
this
.
setFieldValByName
(
"createTime"
,
new
Date
(),
metaObject
);
this
.
setFieldValByName
(
"updateTime"
,
new
Date
(),
metaObject
);
this
.
setFieldValByName
(
"applyTime"
,
new
Date
(),
metaObject
);
}
// 使用mp实现修改操作,这个方法会执行
@Override
public
void
updateFill
(
MetaObject
metaObject
)
{
this
.
setFieldValByName
(
"updateTime"
,
new
Date
(),
metaObject
);
}
}
src/main/java/io/github/doocs/im/config/MybatisPlusConfig.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
config
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.transaction.annotation.EnableTransactionManagement
;
import
com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor
;
/**
* mybatis-plus分页配置
*
* @author muxh
* @date 2021/10/18 16:46
*/
@EnableTransactionManagement
@Configuration
public
class
MybatisPlusConfig
{
/**
* 分页插件*/
@Bean
public
PaginationInterceptor
paginationInterceptor
()
{
return
new
PaginationInterceptor
();
}
}
src/main/java/io/github/doocs/im/config/RestTemplateConfig.java
0 → 100644
View file @
e6c090eb
This diff is collapsed.
Click to expand it.
src/main/java/io/github/doocs/im/config/ValidatorConfig.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
config
;
import
javax.validation.Validation
;
import
javax.validation.Validator
;
import
javax.validation.ValidatorFactory
;
import
org.hibernate.validator.HibernateValidator
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
/**
* 配置校验快速失败
*/
@Configuration
public
class
ValidatorConfig
{
@Bean
public
Validator
validator
()
{
ValidatorFactory
validatorFactory
=
Validation
.
byProvider
(
HibernateValidator
.
class
).
configure
().
failFast
(
true
).
buildValidatorFactory
();
return
validatorFactory
.
getValidator
();
}
}
\ No newline at end of file
src/main/java/io/github/doocs/im/config/ValidatorUtil.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
config
;
/**
* @Auther chenyongfeng
* @Date 2021/5/26
*/
import
java.util.Iterator
;
import
java.util.Set
;
import
javax.validation.ConstraintViolation
;
import
javax.validation.Validation
;
import
javax.validation.Validator
;
import
org.hibernate.validator.HibernateValidator
;
public
class
ValidatorUtil
{
private
static
Validator
validatorFast
=
Validation
.
byProvider
(
HibernateValidator
.
class
).
configure
().
failFast
(
true
)
.
buildValidatorFactory
().
getValidator
();
private
static
Validator
validatorAll
=
Validation
.
byProvider
(
HibernateValidator
.
class
).
configure
().
failFast
(
false
)
.
buildValidatorFactory
().
getValidator
();
/**
* 校验遇到第一个不合法的字段直接返回不合法字段,后续字段不再校验
*
* @param <T>
* @param domain
* @throws Exception
* @Time 2020年6月22日 上午11:36:13
*/
public
static
<
T
>
void
validateFast
(
T
domain
)
{
Set
<
ConstraintViolation
<
T
>>
validateResult
=
validatorFast
.
validate
(
domain
);
if
(
validateResult
.
size
()
>
0
)
{
// System.out.println(validateResult.iterator().next().getPropertyPath() +":"+
// validateResult.iterator().next().getMessage());
throw
new
BusinessException
(
new
CommonError
(
"10009"
,
validateResult
.
iterator
().
next
().
getPropertyPath
()
+
":"
+
validateResult
.
iterator
().
next
().
getMessage
()));
}
}
/**
* 校验所有字段并返回不合法字段
*
* @param <T>
* @param domain
* @return
* @throws Exception
* @Time 2020年6月22日 上午11:36:55
*/
public
static
<
T
>
Set
<
ConstraintViolation
<
T
>>
validateAll
(
T
domain
)
throws
Exception
{
Set
<
ConstraintViolation
<
T
>>
validateResult
=
validatorAll
.
validate
(
domain
);
if
(
validateResult
.
size
()
>
0
)
{
Iterator
<
ConstraintViolation
<
T
>>
it
=
validateResult
.
iterator
();
while
(
it
.
hasNext
())
{
ConstraintViolation
<
T
>
cv
=
it
.
next
();
System
.
out
.
println
(
cv
.
getPropertyPath
()
+
":"
+
cv
.
getMessage
());
}
}
return
validateResult
;
}
}
src/main/java/io/github/doocs/im/config/WebConfig.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
config
;
import
java.text.SimpleDateFormat
;
import
java.util.TimeZone
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
;
import
com.fasterxml.jackson.databind.DeserializationFeature
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.SerializationFeature
;
/**
* WebJsonConverterConfig
*
* @author WebJsonConverterConfig
*/
// @Configuration
public
class
WebConfig
implements
WebMvcConfigurer
{
@Bean
public
MappingJackson2HttpMessageConverter
mappingJackson2HttpMessageConverter
()
{
MappingJackson2HttpMessageConverter
jackson2HttpMessageConverter
=
new
MappingJackson2HttpMessageConverter
();
ObjectMapper
objectMapper
=
new
ObjectMapper
();
objectMapper
.
setDateFormat
(
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
));
objectMapper
.
setTimeZone
(
TimeZone
.
getTimeZone
(
"GMT+8"
));
objectMapper
.
configure
(
DeserializationFeature
.
FAIL_ON_UNKNOWN_PROPERTIES
,
false
);
objectMapper
.
configure
(
SerializationFeature
.
FAIL_ON_EMPTY_BEANS
,
false
);
jackson2HttpMessageConverter
.
setObjectMapper
(
objectMapper
);
return
jackson2HttpMessageConverter
;
}
}
src/main/java/io/github/doocs/im/constant/ActionStatus.java
View file @
e6c090eb
...
...
@@ -17,6 +17,9 @@ public class ActionStatus {
*/
public
static
final
String
FAIL
=
"FAIL"
;
public
static
final
String
SOMEERROR
=
"SomeError"
;
private
ActionStatus
()
{
}
...
...
src/main/java/io/github/doocs/im/constant/MongoAccoutStatus.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
constant
;
public
class
MongoAccoutStatus
{
public
static
final
int
EFFECTIVED
=
1
;
public
static
final
int
KILLED
=
2
;
public
static
final
int
DELETEED
=
3
;
}
src/main/java/io/github/doocs/im/controller/AccountController.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
controller
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.validation.annotation.Validated
;
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
io.github.doocs.im.config.CommonResult
;
import
io.github.doocs.im.servie.AccountService
;
import
io.github.doocs.im.vo.AccountVO
;
import
io.github.doocs.im.vo.QueryOnlineStatusRequestVO
;
@RestController
@RequestMapping
(
"/account"
)
public
class
AccountController
{
@Autowired
AccountService
accountService
;
/**
* 生成im账号 有会从当前服务返回,没有会请求腾讯im获取返回 也可用于户账号查询 生成的imid 规则为source_originalId
*
* @param accountVO
* @return
*/
@PostMapping
(
"/accountImport"
)
public
CommonResult
accountImport
(
@Validated
@RequestBody
AccountVO
accountVO
)
{
return
accountService
.
accountImport
(
accountVO
);
}
/**
* 查询账号在线状态
*
* @param
* @return
*/
@PostMapping
(
"/queryOnlineStatus"
)
public
CommonResult
queryOnlineStatus
(
@Validated
@RequestBody
QueryOnlineStatusRequestVO
queryOnlineStatusRequest
)
{
return
accountService
.
queryOnlineStatus
(
queryOnlineStatusRequest
);
}
}
src/main/java/io/github/doocs/im/controller/GroupController.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
controller
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
io.github.doocs.im.config.CommonResult
;
import
io.github.doocs.im.model.request.AddGroupMemberRequest
;
import
io.github.doocs.im.model.request.CreateGroupRequest
;
import
io.github.doocs.im.model.request.DeleteGroupMemberRequest
;
import
io.github.doocs.im.model.request.DestroyGroupRequest
;
import
io.github.doocs.im.model.request.GroupMsgRecallRequest
;
import
io.github.doocs.im.model.request.ModifyGroupBaseInfoRequest
;
import
io.github.doocs.im.model.request.SetUnreadMsgNumRequest
;
import
io.github.doocs.im.servie.GroupService
;
@RestController
@RequestMapping
(
"/group"
)
public
class
GroupController
{
@Autowired
GroupService
groupService
;
/**
* 创建群组
*
* @param createGroupRequest
* @return
*/
@RequestMapping
(
"/createGroup"
)
public
CommonResult
createGroup
(
@RequestBody
CreateGroupRequest
createGroupRequest
)
{
return
groupService
.
createGroup
(
createGroupRequest
);
}
/**
* 添加群成员
*
* @param addGroupMemberRequest
* @return
*/
@RequestMapping
(
"/addGroupMember"
)
public
CommonResult
addGroupMember
(
@RequestBody
AddGroupMemberRequest
addGroupMemberRequest
)
{
return
groupService
.
addGroupMember
(
addGroupMemberRequest
);
}
/**
* 删除群成员
*
* @param addGroupMemberRequest
* @return
*/
@RequestMapping
(
"/deleteGroupMember"
)
public
CommonResult
deleteGroupMember
(
@RequestBody
DeleteGroupMemberRequest
addGroupMemberRequest
)
{
return
groupService
.
deleteGroupMember
(
addGroupMemberRequest
);
}
/**
* 解散群组
*
* @param destroyGroupRequest
* @return
*/
@RequestMapping
(
"/destroyGroup"
)
public
CommonResult
destroyGroup
(
@RequestBody
DestroyGroupRequest
destroyGroupRequest
)
{
return
groupService
.
destroyGroup
(
destroyGroupRequest
);
}
/**
* 修改群基础信息
*
* @param modifyGroupBaseInfoRequest
* @return
*/
@RequestMapping
(
"/modifyGroupBaseInfo"
)
public
CommonResult
modifyGroupBaseInfo
(
@RequestBody
ModifyGroupBaseInfoRequest
modifyGroupBaseInfoRequest
)
{
return
groupService
.
modifyGroupBaseInfo
(
modifyGroupBaseInfoRequest
);
}
/**
* 设置群成员消息未读数
*
* @param setUnreadMsgNumRequest
* @return
*/
@RequestMapping
(
"/setUnreadMsgNum"
)
public
CommonResult
setUnreadMsgNum
(
@RequestBody
SetUnreadMsgNumRequest
setUnreadMsgNumRequest
)
{
return
groupService
.
setUnreadMsgNum
(
setUnreadMsgNumRequest
);
}
/**
* 管理员撤回群消息
* @param groupMsgRecallRequest
* @return
*/
@RequestMapping
(
"/groupMsgRecall"
)
public
CommonResult
groupMsgRecall
(
@RequestBody
GroupMsgRecallRequest
groupMsgRecallRequest
)
{
return
groupService
.
groupMsgRecall
(
groupMsgRecallRequest
);
}
}
src/main/java/io/github/doocs/im/controller/MessageController.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
controller
;
import
com.fasterxml.jackson.core.JsonProcessingException
;
import
io.github.doocs.im.servie.MessageService
;
import
org.springframework.beans.factory.annotation.Autowired
;
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
io.github.doocs.im.config.CommonResult
;
import
io.github.doocs.im.vo.SimpleMessageVO
;
@RestController
@RequestMapping
(
"/message"
)
public
class
MessageController
{
@Autowired
MessageService
messageService
;
@PostMapping
(
"/sendMessage"
)
public
CommonResult
sendMessage
(
@RequestBody
SimpleMessageVO
simpleMessageVO
)
throws
JsonProcessingException
{
return
messageService
.
sendMessage
(
simpleMessageVO
);
}
// public static void main(String[] args) {
// String a = "https://img14.360buyimg.com/pop/jfs/t1/181251/30/8749/184198/60c32b0bEbe5d7052/dc859b8261fb7c8b.jpg";
// int length = a.length();
// System.out.println(length);
// }
}
src/main/java/io/github/doocs/im/core/Account.java
View file @
e6c090eb
...
...
@@ -43,7 +43,7 @@ public class Account {
* @return 结果
* @throws IOException 异常
*/
public
AccountImportResult
accountImport
(
AccountImportRequest
accountImportRequest
)
throws
IO
Exception
{
public
AccountImportResult
accountImport
(
AccountImportRequest
accountImportRequest
)
throws
Exception
{
String
url
=
imClient
.
getUrl
(
SERVICE_NAME
,
ACCOUNT_IMPORT_COMMAND
);
return
HttpUtil
.
post
(
url
,
accountImportRequest
,
AccountImportResult
.
class
,
imClient
.
getConfig
());
}
...
...
src/main/java/io/github/doocs/im/core/Group.java
View file @
e6c090eb
...
...
@@ -72,7 +72,7 @@ public class Group {
* @return 结果
* @throws IOException 异常
*/
public
CreateGroupResult
createGroup
(
CreateGroupRequest
createGroupRequest
)
throws
IO
Exception
{
public
CreateGroupResult
createGroup
(
CreateGroupRequest
createGroupRequest
)
throws
Exception
{
String
url
=
imClient
.
getUrl
(
SERVICE_NAME
,
CREATE_GROUP_COMMAND
);
return
HttpUtil
.
post
(
url
,
createGroupRequest
,
CreateGroupResult
.
class
,
imClient
.
getConfig
());
}
...
...
src/main/java/io/github/doocs/im/core/Message.java
View file @
e6c090eb
...
...
@@ -43,7 +43,7 @@ public class Message {
* @return 结果
* @throws IOException 异常
*/
public
SendMsgResult
sendMsg
(
SendMsgRequest
sendMsgRequest
)
throws
IO
Exception
{
public
SendMsgResult
sendMsg
(
SendMsgRequest
sendMsgRequest
)
throws
Exception
{
String
url
=
imClient
.
getUrl
(
SERVICE_NAME
,
SEND_MSG_COMMAND
);
return
HttpUtil
.
post
(
url
,
sendMsgRequest
,
SendMsgResult
.
class
,
imClient
.
getConfig
());
}
...
...
src/main/java/io/github/doocs/im/model/request/CreateGroupRequest.java
View file @
e6c090eb
...
...
@@ -17,6 +17,10 @@ public class CreateGroupRequest extends GroupInfo {
super
(
builder
);
}
public
CreateGroupRequest
()
{
}
public
static
class
Builder
extends
GroupInfo
.
Builder
<
CreateGroupRequest
.
Builder
>
{
@Override
public
CreateGroupRequest
build
()
{
...
...
src/main/java/io/github/doocs/im/mongo/AccountEntity.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
mongo
;
import
lombok.ToString
;
import
org.springframework.data.mongodb.core.mapping.Document
;
import
lombok.Data
;
@Data
@Document
(
collection
=
"im_account"
)
@ToString
public
class
AccountEntity
{
// 来源
private
String
id
;
// 昵称
private
String
nick
;
// 头像
private
String
faceUrl
;
// 状态 1-正常 2-封号 3-删除
private
int
status
;
// 时间
private
long
updateTime
=
System
.
currentTimeMillis
();
public
AccountEntity
(
String
id
,
String
nick
,
String
faceUrl
,
int
status
)
{
this
.
id
=
id
;
this
.
nick
=
nick
;
this
.
faceUrl
=
faceUrl
;
this
.
status
=
status
;
}
}
src/main/java/io/github/doocs/im/servie/AccountService.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
servie
;
import
java.util.HashMap
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.mongodb.core.query.Criteria
;
import
org.springframework.data.mongodb.core.query.Query
;
import
org.springframework.stereotype.Service
;
import
com.alibaba.fastjson.JSON
;
import
com.google.common.collect.Maps
;
import
io.github.doocs.im.ImClient
;
import
io.github.doocs.im.config.BusinessException
;
import
io.github.doocs.im.config.CommonError
;
import
io.github.doocs.im.config.CommonResult
;
import
io.github.doocs.im.config.ErrorEnum
;
import
io.github.doocs.im.constant.ActionStatus
;
import
io.github.doocs.im.constant.MongoAccoutStatus
;
import
io.github.doocs.im.core.Account
;
import
io.github.doocs.im.model.request.AccountImportRequest
;
import
io.github.doocs.im.model.request.QueryOnlineStatusRequest
;
import
io.github.doocs.im.model.response.AccountImportResult
;
import
io.github.doocs.im.model.response.QueryOnlineStatusResult
;
import
io.github.doocs.im.mongo.AccountEntity
;
import
io.github.doocs.im.vo.AccountVO
;
import
io.github.doocs.im.vo.QueryOnlineStatusRequestVO
;
import
lombok.extern.slf4j.Slf4j
;
@Service
@Slf4j
public
class
AccountService
extends
GeneraService
{
@Autowired
ImClient
imClient
;
public
CommonResult
accountImport
(
AccountVO
accountVO
)
{
// 先从mongo获取 有直接返回成功
String
id
=
accountVO
.
getSource
()
+
"_"
+
accountVO
.
getOriginalId
();
AccountEntity
accountEntity
=
mongoTemplate
.
findOne
(
Query
.
query
(
Criteria
.
where
(
"_id"
).
is
(
id
)),
AccountEntity
.
class
);
if
(
accountEntity
!=
null
)
{
if
(
accountEntity
.
getStatus
()
==
MongoAccoutStatus
.
EFFECTIVED
)
{
return
CommonResult
.
success
(
id
);
}
if
(
accountEntity
.
getStatus
()
==
MongoAccoutStatus
.
KILLED
)
{
return
CommonResult
.
fail
(
ErrorEnum
.
ACCOUNT_KILLED
);
}
if
(
accountEntity
.
getStatus
()
==
MongoAccoutStatus
.
DELETEED
)
{
return
CommonResult
.
fail
(
ErrorEnum
.
ACCOUNT_DELETE
);
}
}
Account
account
=
imClient
.
getAccount
();
AccountImportRequest
accountImportRequest
=
new
AccountImportRequest
();
accountImportRequest
.
setIdentifier
(
id
);
accountImportRequest
.
setFaceUrl
(
accountVO
.
getFaceUrl
());
accountImportRequest
.
setNick
(
accountVO
.
getNick
());
AccountImportResult
accountImportResult
;
try
{
accountImportResult
=
account
.
accountImport
(
accountImportRequest
);
log
.
info
(
"腾讯result:{}"
,
accountImportResult
.
toString
());
}
catch
(
Exception
e
)
{
log
.
error
(
"请求qcloud失败,参数:{}"
,
accountVO
.
toString
());
throw
new
BusinessException
(
ErrorEnum
.
REQUEST_ERROR
);
}
return
conver
(
accountImportResult
,
accountVO
);
}
/**
* 注册账号结果转换
*
* @param accountImportResult
* @param accountVO
* @return
*/
public
CommonResult
conver
(
AccountImportResult
accountImportResult
,
AccountVO
accountVO
)
{
String
actionStatus
=
accountImportResult
.
getActionStatus
();
if
(
ActionStatus
.
OK
.
equalsIgnoreCase
(
actionStatus
))
{
saveToMongo
(
accountVO
);
return
CommonResult
.
success
(
accountVO
.
getSource
()
+
"_"
+
accountVO
.
getOriginalId
());
}
return
CommonResult
.
fail
(
new
CommonError
(
String
.
valueOf
(
accountImportResult
.
getErrorCode
()),
accountImportResult
.
getErrorInfo
()));
}
/**
* 账号信息保存到mongo
*
* @param accountVO
*/
public
void
saveToMongo
(
AccountVO
accountVO
)
{
executor
.
execute
(()
->
{
// int i = 2 / 0; 异步线程的异常不会在主线程被捕获
AccountEntity
accountEntity
=
new
AccountEntity
(
accountVO
.
getSource
()
+
"_"
+
accountVO
.
getOriginalId
(),
accountVO
.
getNick
(),
accountVO
.
getFaceUrl
(),
1
);
// 有效
try
{
mongoTemplate
.
save
(
accountEntity
);
log
.
info
(
"保存im_account成功:{}"
,
accountEntity
.
toString
());
}
catch
(
Exception
e
)
{
log
.
error
(
"保存im_account失败:{}"
,
accountEntity
.
toString
());
}
});
}
/**
* 查询账号在线状态 个别账号无效返回someError 全部无效返回fali
*
* @param
* @return
*/
public
CommonResult
queryOnlineStatus
(
QueryOnlineStatusRequestVO
queryOnlineStatusRequestVO
)
{
Account
account
=
imClient
.
getAccount
();
QueryOnlineStatusRequest
queryOnlineStatusRequest
=
new
QueryOnlineStatusRequest
();
BeanUtils
.
copyProperties
(
queryOnlineStatusRequestVO
,
queryOnlineStatusRequest
);
QueryOnlineStatusResult
queryOnlineStatusResult
;
try
{
queryOnlineStatusResult
=
account
.
queryOnlineStatus
(
queryOnlineStatusRequest
);
}
catch
(
Exception
e
)
{
log
.
error
(
"请求qcloud失败,参数:{}"
,
JSON
.
toJSONString
(
queryOnlineStatusRequest
));
throw
new
BusinessException
(
ErrorEnum
.
REQUEST_ERROR
);
}
log
.
info
(
"结果:{}"
,
queryOnlineStatusResult
.
toString
());
String
actionStatus
=
queryOnlineStatusResult
.
getActionStatus
();
if
(
ActionStatus
.
OK
.
equalsIgnoreCase
(
actionStatus
)
||
ActionStatus
.
SOMEERROR
.
equalsIgnoreCase
(
actionStatus
))
{
HashMap
<
String
,
Object
>
result
=
Maps
.
newHashMap
();
result
.
put
(
"queryResult"
,
queryOnlineStatusResult
.
getQueryResult
());
result
.
put
(
"errorList"
,
queryOnlineStatusResult
.
getErrorList
());
return
CommonResult
.
success
(
result
);
}
return
CommonResult
.
fail
(
new
CommonError
(
String
.
valueOf
(
queryOnlineStatusResult
.
getErrorCode
()),
queryOnlineStatusResult
.
getErrorInfo
()));
}
}
src/main/java/io/github/doocs/im/servie/GeneraService.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
servie
;
import
java.util.concurrent.Executor
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.data.mongodb.core.MongoTemplate
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
public
abstract
class
GeneraService
{
@Autowired
MongoTemplate
mongoTemplate
;
@Qualifier
(
"mypool"
)
@Autowired
Executor
executor
;
ObjectMapper
mapper
=
new
ObjectMapper
();
}
src/main/java/io/github/doocs/im/servie/GroupService.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
servie
;
import
java.util.HashMap
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
com.alibaba.fastjson.JSON
;
import
com.google.common.collect.Maps
;
import
io.github.doocs.im.ImClient
;
import
io.github.doocs.im.config.BusinessException
;
import
io.github.doocs.im.config.CommonError
;
import
io.github.doocs.im.config.CommonResult
;
import
io.github.doocs.im.config.ErrorEnum
;
import
io.github.doocs.im.constant.ActionStatus
;
import
io.github.doocs.im.core.Group
;
import
io.github.doocs.im.model.request.AddGroupMemberRequest
;
import
io.github.doocs.im.model.request.CreateGroupRequest
;
import
io.github.doocs.im.model.request.DeleteGroupMemberRequest
;
import
io.github.doocs.im.model.request.DestroyGroupRequest
;
import
io.github.doocs.im.model.request.GroupMsgRecallRequest
;
import
io.github.doocs.im.model.request.ModifyGroupBaseInfoRequest
;
import
io.github.doocs.im.model.request.SetUnreadMsgNumRequest
;
import
io.github.doocs.im.model.response.AddGroupMemberResult
;
import
io.github.doocs.im.model.response.CreateGroupResult
;
import
io.github.doocs.im.model.response.DeleteGroupMemberResult
;
import
io.github.doocs.im.model.response.DestroyGroupResult
;
import
io.github.doocs.im.model.response.GroupMsgRecallResult
;
import
io.github.doocs.im.model.response.ModifyGroupBaseInfoResult
;
import
io.github.doocs.im.model.response.SetUnreadMsgNumResult
;
import
lombok.extern.slf4j.Slf4j
;
@Service
@Slf4j
public
class
GroupService
extends
GeneraService
{
@Autowired
ImClient
imClient
;
public
CommonResult
createGroup
(
CreateGroupRequest
createGroupRequest
)
{
Group
group
=
imClient
.
getGroup
();
CreateGroupResult
groupResult
;
try
{
groupResult
=
group
.
createGroup
(
createGroupRequest
);
}
catch
(
Exception
e
)
{
log
.
error
(
"请求qcloud失败,参数:{}"
,
JSON
.
toJSONString
(
createGroupRequest
));
throw
new
BusinessException
(
ErrorEnum
.
REQUEST_ERROR
);
}
String
actionStatus
=
groupResult
.
getActionStatus
();
if
(
ActionStatus
.
OK
.
equalsIgnoreCase
(
actionStatus
))
{
HashMap
<
String
,
Object
>
result
=
Maps
.
newHashMap
();
result
.
put
(
"groupId"
,
groupResult
.
getGroupId
());
return
CommonResult
.
success
(
result
);
}
return
CommonResult
.
fail
(
new
CommonError
(
String
.
valueOf
(
groupResult
.
getErrorCode
()),
groupResult
.
getErrorInfo
()));
}
public
CommonResult
addGroupMember
(
AddGroupMemberRequest
addGroupMemberRequest
)
{
Group
group
=
imClient
.
getGroup
();
AddGroupMemberResult
addGroupMemberResult
;
try
{
addGroupMemberResult
=
group
.
addGroupMember
(
addGroupMemberRequest
);
}
catch
(
Exception
e
)
{
log
.
error
(
"请求qcloud失败,参数:{}"
,
JSON
.
toJSONString
(
addGroupMemberRequest
));
throw
new
BusinessException
(
ErrorEnum
.
REQUEST_ERROR
);
}
String
actionStatus
=
addGroupMemberResult
.
getActionStatus
();
if
(
ActionStatus
.
OK
.
equalsIgnoreCase
(
actionStatus
))
{
HashMap
<
String
,
Object
>
result
=
Maps
.
newHashMap
();
result
.
put
(
"MemberList"
,
addGroupMemberResult
.
getMemberList
());
return
CommonResult
.
success
(
result
);
}
return
CommonResult
.
fail
(
new
CommonError
(
String
.
valueOf
(
addGroupMemberResult
.
getErrorCode
()),
addGroupMemberResult
.
getErrorInfo
()));
}
public
CommonResult
deleteGroupMember
(
DeleteGroupMemberRequest
addGroupMemberRequest
)
{
Group
group
=
imClient
.
getGroup
();
DeleteGroupMemberResult
deleteGroupMemberResult
;
try
{
deleteGroupMemberResult
=
group
.
deleteGroupMember
(
addGroupMemberRequest
);
}
catch
(
Exception
e
)
{
log
.
error
(
"请求qcloud失败,参数:{}"
,
JSON
.
toJSONString
(
addGroupMemberRequest
));
throw
new
BusinessException
(
ErrorEnum
.
REQUEST_ERROR
);
}
String
actionStatus
=
deleteGroupMemberResult
.
getActionStatus
();
if
(
ActionStatus
.
OK
.
equalsIgnoreCase
(
actionStatus
))
{
return
CommonResult
.
success
();
}
return
CommonResult
.
fail
(
new
CommonError
(
String
.
valueOf
(
deleteGroupMemberResult
.
getErrorCode
()),
deleteGroupMemberResult
.
getErrorInfo
()));
}
public
CommonResult
destroyGroup
(
DestroyGroupRequest
destroyGroupRequest
)
{
Group
group
=
imClient
.
getGroup
();
DestroyGroupResult
destroyGroupResult
;
try
{
destroyGroupResult
=
group
.
destroyGroup
(
destroyGroupRequest
);
}
catch
(
Exception
e
)
{
log
.
error
(
"请求qcloud失败,参数:{}"
,
JSON
.
toJSONString
(
destroyGroupRequest
));
throw
new
BusinessException
(
ErrorEnum
.
REQUEST_ERROR
);
}
String
actionStatus
=
destroyGroupResult
.
getActionStatus
();
if
(
ActionStatus
.
OK
.
equalsIgnoreCase
(
actionStatus
))
{
return
CommonResult
.
success
();
}
return
CommonResult
.
fail
(
new
CommonError
(
String
.
valueOf
(
destroyGroupResult
.
getErrorCode
()),
destroyGroupResult
.
getErrorInfo
()));
}
public
CommonResult
modifyGroupBaseInfo
(
ModifyGroupBaseInfoRequest
modifyGroupBaseInfoRequest
)
{
Group
group
=
imClient
.
getGroup
();
ModifyGroupBaseInfoResult
modifyGroupBaseInfoResult
;
try
{
modifyGroupBaseInfoResult
=
group
.
modifyGroupBaseInfo
(
modifyGroupBaseInfoRequest
);
}
catch
(
Exception
e
)
{
log
.
error
(
"请求qcloud失败,参数:{}"
,
JSON
.
toJSONString
(
modifyGroupBaseInfoRequest
));
throw
new
BusinessException
(
ErrorEnum
.
REQUEST_ERROR
);
}
String
actionStatus
=
modifyGroupBaseInfoResult
.
getActionStatus
();
if
(
ActionStatus
.
OK
.
equalsIgnoreCase
(
actionStatus
))
{
return
CommonResult
.
success
();
}
return
CommonResult
.
fail
(
new
CommonError
(
String
.
valueOf
(
modifyGroupBaseInfoResult
.
getErrorCode
()),
modifyGroupBaseInfoResult
.
getErrorInfo
()));
}
public
CommonResult
setUnreadMsgNum
(
SetUnreadMsgNumRequest
setUnreadMsgNumRequest
)
{
Group
group
=
imClient
.
getGroup
();
SetUnreadMsgNumResult
setUnreadMsgNumResult
;
try
{
setUnreadMsgNumResult
=
group
.
setUnreadMsgNum
(
setUnreadMsgNumRequest
);
}
catch
(
Exception
e
)
{
log
.
error
(
"请求qcloud失败,参数:{}"
,
JSON
.
toJSONString
(
setUnreadMsgNumRequest
));
throw
new
BusinessException
(
ErrorEnum
.
REQUEST_ERROR
);
}
String
actionStatus
=
setUnreadMsgNumResult
.
getActionStatus
();
if
(
ActionStatus
.
OK
.
equalsIgnoreCase
(
actionStatus
))
{
return
CommonResult
.
success
();
}
return
CommonResult
.
fail
(
new
CommonError
(
String
.
valueOf
(
setUnreadMsgNumResult
.
getErrorCode
()),
setUnreadMsgNumResult
.
getErrorInfo
()));
}
public
CommonResult
groupMsgRecall
(
GroupMsgRecallRequest
groupMsgRecallRequest
)
{
Group
group
=
imClient
.
getGroup
();
GroupMsgRecallResult
groupMsgRecallResult
;
try
{
groupMsgRecallResult
=
group
.
groupMsgRecall
(
groupMsgRecallRequest
);
}
catch
(
Exception
e
)
{
log
.
error
(
"请求qcloud失败,参数:{}"
,
JSON
.
toJSONString
(
groupMsgRecallRequest
));
throw
new
BusinessException
(
ErrorEnum
.
REQUEST_ERROR
);
}
log
.
info
(
"返回结果:{}"
,
groupMsgRecallResult
.
toString
());
String
actionStatus
=
groupMsgRecallResult
.
getActionStatus
();
if
(
ActionStatus
.
OK
.
equalsIgnoreCase
(
actionStatus
))
{
return
CommonResult
.
success
(
groupMsgRecallResult
.
getRecallRetList
());
}
return
CommonResult
.
fail
(
new
CommonError
(
String
.
valueOf
(
groupMsgRecallResult
.
getErrorCode
()),
groupMsgRecallResult
.
getErrorInfo
()));
}
}
src/main/java/io/github/doocs/im/servie/MessageService.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
servie
;
import
java.util.HashMap
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
com.fasterxml.jackson.core.JsonProcessingException
;
import
com.google.common.collect.Maps
;
import
io.github.doocs.im.ImClient
;
import
io.github.doocs.im.config.BusinessException
;
import
io.github.doocs.im.config.CommonError
;
import
io.github.doocs.im.config.CommonResult
;
import
io.github.doocs.im.config.ErrorEnum
;
import
io.github.doocs.im.constant.ActionStatus
;
import
io.github.doocs.im.core.Message
;
import
io.github.doocs.im.model.request.SendMsgRequest
;
import
io.github.doocs.im.model.response.SendMsgResult
;
import
io.github.doocs.im.util.JsonUtil
;
import
io.github.doocs.im.util.RandomUtil
;
import
io.github.doocs.im.vo.SimpleMessageVO
;
import
lombok.extern.slf4j.Slf4j
;
@Service
@Slf4j
public
class
MessageService
extends
GeneraService
{
@Autowired
ImClient
imClient
;
public
CommonResult
sendMessage
(
SimpleMessageVO
simpleMessageVO
)
throws
JsonProcessingException
{
Message
message
=
imClient
.
getMessage
();
// 组装数据
SendMsgRequest
sendMsgRequest
=
new
SendMsgRequest
();
sendMsgRequest
.
setFromAccount
(
simpleMessageVO
.
getFromAccount
());
sendMsgRequest
.
setToAccount
(
simpleMessageVO
.
getToAccount
());
sendMsgRequest
.
setMsgBody
(
simpleMessageVO
.
getMsgBody
());
sendMsgRequest
.
setMsgRandom
(
RandomUtil
.
getRandomLong
());
// 同步到发送方
sendMsgRequest
.
setSyncOtherMachine
(
1
);
SendMsgResult
sendMsgResult
;
try
{
sendMsgResult
=
message
.
sendMsg
(
sendMsgRequest
);
log
.
info
(
"结果:{}"
,
sendMsgResult
.
toString
());
}
catch
(
Exception
e
)
{
log
.
error
(
"请求qcloud失败,参数:{}"
,
JsonUtil
.
obj2Str
(
sendMsgRequest
));
throw
new
BusinessException
(
ErrorEnum
.
REQUEST_ERROR
);
}
String
actionStatus
=
sendMsgResult
.
getActionStatus
();
if
(
ActionStatus
.
OK
.
equalsIgnoreCase
(
actionStatus
))
{
HashMap
<
String
,
Object
>
result
=
Maps
.
newHashMap
();
result
.
put
(
"msgTime"
,
sendMsgResult
.
getMsgTime
());
result
.
put
(
"msgKey"
,
sendMsgResult
.
getMsgKey
());
return
CommonResult
.
success
(
result
);
}
return
CommonResult
.
fail
(
new
CommonError
(
String
.
valueOf
(
sendMsgResult
.
getErrorCode
()),
sendMsgResult
.
getErrorInfo
()));
}
}
src/main/java/io/github/doocs/im/util/HttpUtil.java
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
util
;
import
io.github.doocs.im.ClientConfiguration
;
import
lombok.extern.slf4j.Slf4j
;
import
okhttp3.*
;
import
java.io.IOException
;
...
...
@@ -15,6 +16,7 @@ import java.util.concurrent.TimeUnit;
* @author bingo
* @since 2021/10/31 15:57
*/
@Slf4j
public
class
HttpUtil
{
private
static
final
MediaType
JSON
=
MediaType
.
get
(
"application/json; charset=utf-8"
);
...
...
@@ -66,7 +68,9 @@ public class HttpUtil {
}
public
static
<
T
>
T
post
(
String
url
,
Object
data
,
Class
<
T
>
cls
,
ClientConfiguration
config
)
throws
IOException
{
String
result
=
post
(
url
,
JsonUtil
.
obj2Str
(
data
),
config
);
String
param
=
JsonUtil
.
obj2Str
(
data
);
log
.
info
(
"请求参数:{}"
,
param
);
String
result
=
post
(
url
,
param
,
config
);
return
JsonUtil
.
str2Obj
(
result
,
cls
);
}
...
...
src/main/java/io/github/doocs/im/util/RandomUtil.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
util
;
import
java.text.DateFormat
;
import
java.text.SimpleDateFormat
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Random
;
public
class
RandomUtil
{
/**
* 生成一个n位的随机数字符串
*
* @param n
* @return
*/
public
static
String
getRandomNum
(
int
length
)
{
String
str
=
"0123456789"
;
Random
random
=
new
Random
();
StringBuffer
sb
=
new
StringBuffer
();
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
int
number
=
random
.
nextInt
(
9
);
// [1,9)
sb
.
append
(
str
.
charAt
(
number
+
1
));
}
return
sb
.
toString
();
}
/**
* 生成一个n位的随机字符串
*
* @param length
* @return
*/
public
static
String
getRandomString
(
int
length
)
{
String
str
=
"abcdefghijklmnopqrstuvwxyz0123456789"
;
Random
random
=
new
Random
();
StringBuffer
sb
=
new
StringBuffer
();
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
int
number
=
random
.
nextInt
(
36
);
// [0,36)
sb
.
append
(
str
.
charAt
(
number
));
}
return
sb
.
toString
();
}
/**
* 获取当前时间,年月日时
*
* @return
*/
public
static
String
getDate
()
{
String
str
=
""
;
DateFormat
df
=
new
SimpleDateFormat
(
"yyyyMMddHH"
);
Date
date
=
new
Date
();
str
=
df
.
format
(
date
);
return
str
;
}
/**
* 生成用户id,10位,纯数字
*
* @return
*/
public
static
String
userId
()
{
String
userId
=
""
;
userId
=
getRandomNum
(
10
);
return
userId
;
}
/**
* 生成订单号,13位,纯数字
*
* @return
*/
public
static
String
orderId
()
{
String
orderId
=
""
;
String
date
=
getDate
();
String
rand
=
getRandomNum
(
13
);
orderId
=
date
+
rand
;
return
orderId
;
}
/**
* 生成商品id,10位,纯数字
*
* @return
*/
public
static
String
proId
()
{
String
userId
=
""
;
userId
=
getRandomNum
(
10
);
return
userId
;
}
/**
* 随机取list数据
*
* @param list
* @param n
* 取几条
* @return
*/
@SuppressWarnings
({
"rawtypes"
,
"unused"
,
"unchecked"
})
public
static
List
getRandomList
(
List
list
,
int
n
)
{
Map
map
=
new
HashMap
();
List
listNew
=
new
ArrayList
();
if
(
list
.
size
()
<=
n
)
{
return
list
;
}
else
{
while
(
map
.
size
()
<
n
)
{
int
random
=
(
int
)(
Math
.
random
()
*
list
.
size
());
if
(!
map
.
containsKey
(
random
))
{
map
.
put
(
random
,
""
);
listNew
.
add
(
list
.
get
(
random
));
}
}
return
listNew
;
}
}
/**
* 获取随机数字
* @return
*/
public
static
Long
getRandomLong
()
{
return
Long
.
parseLong
(
getRandomNum
((
9
)));
}
/**
* 取数组随机数
*
* @param arr
* @param n
* @return
*/
@SuppressWarnings
({
"unused"
,
"unchecked"
})
public
static
Long
[]
createRandomArray
(
Long
[]
arr
,
int
n
)
{
// TODO Auto-generated method stub
@SuppressWarnings
(
"rawtypes"
)
Map
map
=
new
HashMap
();
Long
[]
arrNew
=
new
Long
[
n
];
if
(
arr
.
length
<=
n
)
{
return
arr
;
}
else
{
int
count
=
0
;
// 新数组下标计数
while
(
map
.
size
()
<
n
)
{
int
random
=
(
int
)(
Math
.
random
()
*
arr
.
length
);
if
(!
map
.
containsKey
(
random
))
{
map
.
put
(
random
,
""
);
arrNew
[
count
++]
=
arr
[
random
];
}
}
return
arrNew
;
}
}
public
static
void
main
(
String
[]
args
)
{
String
randomNum
=
getRandomNum
(
10
);
System
.
out
.
println
(
randomNum
);
}
}
src/main/java/io/github/doocs/im/vo/AccountVO.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
vo
;
import
lombok.Data
;
import
lombok.ToString
;
import
javax.validation.constraints.NotBlank
;
@Data
@ToString
public
class
AccountVO
{
// 来源
@NotBlank
(
message
=
"应用名称不可为空!"
)
private
String
source
;
// 原id
@NotBlank
(
message
=
"应用用户id不可为空!"
)
private
String
originalId
;
// 昵称
private
String
nick
;
// 头像
private
String
faceUrl
;
}
src/main/java/io/github/doocs/im/vo/QueryOnlineStatusRequestVO.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
vo
;
import
lombok.Data
;
import
javax.validation.Valid
;
import
javax.validation.constraints.NotEmpty
;
import
java.util.List
;
@Data
public
class
QueryOnlineStatusRequestVO
{
private
Integer
isNeedDetail
;
@NotEmpty
(
message
=
"im_id不可为空!"
)
private
List
<
@Valid
String
>
toAccount
;
}
\ No newline at end of file
src/main/java/io/github/doocs/im/vo/SimpleMessageVO.java
0 → 100644
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
.
vo
;
import
java.util.List
;
import
io.github.doocs.im.model.message.TIMMsgElement
;
import
lombok.Data
;
@Data
public
class
SimpleMessageVO
{
// 发送方
private
String
fromAccount
;
// 接收方
private
String
toAccount
;
// 消息
List
<
TIMMsgElement
>
msgBody
;
}
src/main/resources/application.yml
0 → 100644
View file @
e6c090eb
sdkAppId
:
1400599792
key
:
cacfa51c0e3789a34b322fd1209f237ba363b8279f3ad483a302804b4e9fcab8
userId
:
administrator
mongodb
:
address
:
10.244.4.39:27017
authenticationDatabase
:
admin
clientName
:
${spring.application.name}
connectionTimeoutMs
:
5000
connectionsPerHost
:
30
database
:
im
heartbeatConnectionTimeoutMs
:
10000
heartbeatFrequencyMs
:
20000
heartbeatReadTimeoutMs
:
15000
maxConnectionIdleTimeMs
:
60000
maxConnectionLifeTimeMs
:
300000
maxWaitTimeMs
:
5000
minConnectionsPerHost
:
2
minHeartbeatFrequencyMs
:
8000
password
:
readTimeoutMs
:
15000
threadsAllowedToBlockForConnectionMultiplier
:
5
username
:
spring
:
application
:
name
:
im
# yml配置的优先级高于java配置;如果yml配置和java配置同时存在,则yml配置会覆盖java配置
http-client
:
pool
:
#连接池的最大连接数,0代表不限;如果取0,需要考虑连接泄露导致系统崩溃的后果
maxTotalConnect
:
1000
#每个路由的最大连接数,如果只调用一个地址,可以将其设置为最大连接数
maxConnectPerRoute
:
200
# 指客户端和服务器建立连接的超时时间,ms , 最大约21秒,因为内部tcp在进行三次握手建立连接时,默认tcp超时时间是20秒
connectTimeout
:
3000
# 指客户端从服务器读取数据包的间隔超时时间,不是总读取时间,也就是socket timeout,ms
readTimeout
:
5000
# 从连接池获取连接的timeout,不宜过大,ms
connectionRequestTimout
:
200
# 重试次数
retryTimes
:
3
charset
:
UTF-8
# 长连接保持时间 单位s,不宜过长
keepAliveTime
:
10
# 针对不同的网址,长连接保持的存活时间,单位s,如果是频繁而持续的请求,可以设置小一点,不建议设置过大,避免大量无用连接占用内存资源
keepAliveTargetHost
:
www.baidu.com
:
5
\ No newline at end of file
src/main/resources/rebel.xml
0 → 100644
View file @
e6c090eb
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application
generated-by=
"intellij"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns=
"http://www.zeroturnaround.com"
xsi:schemaLocation=
"http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd"
>
<id>
im-server-sdk-java
</id>
<classpath>
<dir
name=
"D:/ideaproject/qcloud-im-server-sdk-java/target/classes"
>
</dir>
</classpath>
</application>
src/test/java/io/github/doocs/im/AccountTest.java
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
;
import
io.github.doocs.im.constant.ActionStatus
;
import
io.github.doocs.im.constant.IsNeedDetail
;
import
io.github.doocs.im.model.request.*
;
import
io.github.doocs.im.model.response.*
;
import
org.junit.Assert
;
import
org.junit.Test
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.util.ArrayList
;
...
...
@@ -14,6 +7,23 @@ import java.util.Arrays;
import
java.util.List
;
import
java.util.Properties
;
import
org.junit.Assert
;
import
org.junit.Test
;
import
io.github.doocs.im.constant.ActionStatus
;
import
io.github.doocs.im.model.request.AccountCheckItem
;
import
io.github.doocs.im.model.request.AccountCheckRequest
;
import
io.github.doocs.im.model.request.AccountDeleteItem
;
import
io.github.doocs.im.model.request.AccountDeleteRequest
;
import
io.github.doocs.im.model.request.AccountImportRequest
;
import
io.github.doocs.im.model.request.KickRequest
;
import
io.github.doocs.im.model.request.MultiAccountImportRequest
;
import
io.github.doocs.im.model.response.AccountCheckResult
;
import
io.github.doocs.im.model.response.AccountDeleteResult
;
import
io.github.doocs.im.model.response.AccountImportResult
;
import
io.github.doocs.im.model.response.KickResult
;
import
io.github.doocs.im.model.response.MultiAccountImportResult
;
/**
* @author bingo
* @since 2021/7/30 16:17
...
...
@@ -37,7 +47,7 @@ public class AccountTest {
@Test
public
void
testAccountImport
()
throws
IO
Exception
{
public
void
testAccountImport
()
throws
Exception
{
AccountImportRequest
request
=
AccountImportRequest
.
builder
()
.
identifier
(
"admin"
)
.
faceUrl
(
"https://avatars.githubusercontent.com/u/43716716?s=200&v=4"
)
...
...
@@ -96,14 +106,14 @@ public class AccountTest {
@Test
public
void
testQueryOnlineStatus
()
throws
IOException
{
List
<
String
>
toAccount
=
Arrays
.
asList
(
"user1"
,
"user2"
);
QueryOnlineStatusRequest
request
=
QueryOnlineStatusRequest
.
builder
()
.
toAccount
(
toAccount
)
.
isNeedDetail
(
IsNeedDetail
.
YES
)
.
build
();
QueryOnlineStatusResult
result
=
client
.
account
.
queryOnlineStatus
(
request
);
System
.
out
.
println
(
result
);
Assert
.
assertEquals
(
ActionStatus
.
OK
,
result
.
getActionStatus
());
//
List<String> toAccount = Arrays.asList("user1", "user2");
//
QueryOnlineStatusRequest request = QueryOnlineStatusRequest.builder()
//
.toAccount(toAccount)
//
.isNeedDetail(IsNeedDetail.YES)
//
.build();
//
//
QueryOnlineStatusResult result = client.account.queryOnlineStatus(request);
//
System.out.println(result);
//
Assert.assertEquals(ActionStatus.OK, result.getActionStatus());
}
}
src/test/java/io/github/doocs/im/GroupTest.java
View file @
e6c090eb
...
...
@@ -49,7 +49,7 @@ public class GroupTest {
}
@Test
public
void
testCreateGroup
()
throws
IO
Exception
{
public
void
testCreateGroup
()
throws
Exception
{
CreateGroupRequest
request
=
CreateGroupRequest
.
builder
()
.
type
(
GroupType
.
PUBLIC
)
.
name
(
"TestGroup"
)
...
...
src/test/java/io/github/doocs/im/MessageTest.java
View file @
e6c090eb
package
io
.
github
.
doocs
.
im
;
import
java.io.IOException
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.Properties
;
import
org.junit.Assert
;
import
org.junit.Test
;
import
io.github.doocs.im.constant.ActionStatus
;
import
io.github.doocs.im.constant.MsgType
;
import
io.github.doocs.im.constant.SyncOtherMachine
;
import
io.github.doocs.im.model.message.TIMCustomMsgElement
;
import
io.github.doocs.im.model.message.TIMMsgElement
;
import
io.github.doocs.im.model.message.TIMTextMsgElement
;
import
io.github.doocs.im.model.request.*
;
import
io.github.doocs.im.model.response.*
;
import
org.junit.Assert
;
import
org.junit.Test
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.util.*
;
import
io.github.doocs.im.model.request.AdminGetRoamMsgRequest
;
import
io.github.doocs.im.model.request.AdminMsgWithdrawRequest
;
import
io.github.doocs.im.model.request.AdminSetMsgReadRequest
;
import
io.github.doocs.im.model.request.BatchSendMsgRequest
;
import
io.github.doocs.im.model.request.GetC2cUnreadMsgRequest
;
import
io.github.doocs.im.model.request.ImportMsgRequest
;
import
io.github.doocs.im.model.request.SendMsgRequest
;
import
io.github.doocs.im.model.response.AdminMsgWithdrawResult
;
import
io.github.doocs.im.model.response.AdminRoamMsgResult
;
import
io.github.doocs.im.model.response.AdminSetMsgReadResult
;
import
io.github.doocs.im.model.response.BatchSendMsgResult
;
import
io.github.doocs.im.model.response.C2cUnreadMsgNumResult
;
import
io.github.doocs.im.model.response.ImportMsgResult
;
import
io.github.doocs.im.model.response.MsgListItem
;
import
io.github.doocs.im.model.response.SendMsgResult
;
/**
* @author bingo
...
...
@@ -21,23 +38,23 @@ import java.util.*;
*/
public
class
MessageTest
{
private
static
final
Properties
properties
=
new
Properties
();
private
static
final
ImClient
client
;
private
static
final
ImClient
client
=
null
;
static
{
InputStream
resourceAsStream
=
MessageTest
.
class
.
getClassLoader
().
getResourceAsStream
(
"app.properties"
);
try
{
properties
.
load
(
resourceAsStream
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
String
key
=
properties
.
getProperty
(
"key"
);
String
userId
=
properties
.
getProperty
(
"userId"
);
Long
appId
=
Long
.
parseLong
(
properties
.
getProperty
(
"appId"
));
client
=
ImClient
.
getInstance
(
appId
,
userId
,
key
);
}
//
static {
//
InputStream resourceAsStream = MessageTest.class.getClassLoader().getResourceAsStream("app.properties");
//
try {
//
properties.load(resourceAsStream);
//
} catch (IOException e) {
//
e.printStackTrace();
//
}
//
String key = properties.getProperty("key");
//
String userId = properties.getProperty("userId");
//
Long appId = Long.parseLong(properties.getProperty("appId"));
//
client = ImClient.getInstance(appId, userId, key);
//
}
@Test
public
void
testSendMsg
()
throws
IO
Exception
{
public
void
testSendMsg
()
throws
Exception
{
TIMTextMsgElement
msg
=
new
TIMTextMsgElement
(
"hello world"
);
List
<
TIMMsgElement
>
msgBody
=
Collections
.
singletonList
(
msg
);
SendMsgRequest
request
=
SendMsgRequest
.
builder
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment