Browse Source

系统消息推送任务

master
xsx 1 year ago
parent
commit
1e6d61d3df
  1. 34
      db/im-admin.sql
  2. 28
      im-admin-ui/src/api/im/smPushTask/index.ts
  3. 22
      im-admin-ui/src/api/im/smPushTask/types.ts
  4. 12
      im-admin-ui/src/api/im/systemMessage/index.ts
  5. 2
      im-admin-ui/src/api/im/user/index.ts
  6. 3
      im-admin-ui/src/components/Editor/index.vue
  7. 90
      im-admin-ui/src/components/ImageUpload/index.vue
  8. 51
      im-admin-ui/src/components/im/ImSysMsgSelect/index.vue
  9. 4
      im-admin-ui/src/components/im/ImUserSelect/index.vue
  10. 34
      im-admin-ui/src/views/im/message/system/index.vue
  11. 276
      im-admin-ui/src/views/im/message/task/index.vue
  12. 2
      im-admin/ruoyi-admin/src/main/resources/application-dev.yml
  13. 37
      im-admin/ruoyi-im/src/main/java/org/dromara/im/controller/ImSmPushTaskController.java
  14. 30
      im-admin/ruoyi-im/src/main/java/org/dromara/im/controller/ImSystemMessageController.java
  15. 13
      im-admin/ruoyi-im/src/main/java/org/dromara/im/controller/ImUserController.java
  16. 57
      im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/ImBaseEntity.java
  17. 26
      im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/ImSmPushTask.java
  18. 28
      im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/ImSystemMessage.java
  19. 32
      im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/bo/ImSmPushTaskBo.java
  20. 48
      im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/vo/ImSmPushTaskVo.java
  21. 34
      im-admin/ruoyi-im/src/main/java/org/dromara/im/enums/ImSmPushStatus.java
  22. 9
      im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImGroupMemberService.java
  23. 10
      im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImGroupMessageService.java
  24. 10
      im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImPrivateMessageService.java
  25. 17
      im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImSmPushTaskService.java
  26. 8
      im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImSystemMessageService.java
  27. 7
      im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImUserService.java
  28. 14
      im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImGroupMemberServiceImpl.java
  29. 12
      im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImGroupMessageServiceImpl.java
  30. 12
      im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImPrivateMessageServiceImpl.java
  31. 8
      im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImSensitiveWordServiceImpl.java
  32. 115
      im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImSmPushTaskServiceImpl.java
  33. 30
      im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImSystemMessageServiceImpl.java
  34. 7
      im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImUserServiceImpl.java
  35. 98
      im-admin/ruoyi-im/src/main/java/org/dromara/im/util/CommaTextUtils.java

34
db/im-admin.sql

@ -31,7 +31,7 @@ create table sys_social
create_time datetime comment '创建时间', create_time datetime comment '创建时间',
update_by bigint(20) comment '更新者', update_by bigint(20) comment '更新者',
update_time datetime comment '更新时间', update_time datetime comment '更新时间',
del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', del_flag char(1) default '0' comment '删除标志(0代表存在 1代表删除)',
PRIMARY KEY (id) PRIMARY KEY (id)
) engine=innodb comment = '社会化关系表'; ) engine=innodb comment = '社会化关系表';
@ -55,7 +55,7 @@ create table sys_tenant
expire_time datetime comment '过期时间', expire_time datetime comment '过期时间',
account_count int default -1 comment '用户数量(-1不限制)', account_count int default -1 comment '用户数量(-1不限制)',
status char(1) default '0' comment '租户状态(0正常 1停用)', status char(1) default '0' comment '租户状态(0正常 1停用)',
del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', del_flag char(1) default '0' comment '删除标志(0代表存在 1代表删除)',
create_dept bigint(20) comment '创建部门', create_dept bigint(20) comment '创建部门',
create_by bigint(20) comment '创建者', create_by bigint(20) comment '创建者',
create_time datetime comment '创建时间', create_time datetime comment '创建时间',
@ -75,7 +75,7 @@ create table sys_tenant_package (
remark varchar(200) comment '备注', remark varchar(200) comment '备注',
menu_check_strictly tinyint(1) default 1 comment '菜单树选择项是否关联显示', menu_check_strictly tinyint(1) default 1 comment '菜单树选择项是否关联显示',
status char(1) default '0' comment '状态(0正常 1停用)', status char(1) default '0' comment '状态(0正常 1停用)',
del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', del_flag char(1) default '0' comment '删除标志(0代表存在 1代表删除)',
create_dept bigint(20) comment '创建部门', create_dept bigint(20) comment '创建部门',
create_by bigint(20) comment '创建者', create_by bigint(20) comment '创建者',
create_time datetime comment '创建时间', create_time datetime comment '创建时间',
@ -100,7 +100,7 @@ create table sys_dept (
phone varchar(11) default null comment '联系电话', phone varchar(11) default null comment '联系电话',
email varchar(50) default null comment '邮箱', email varchar(50) default null comment '邮箱',
status char(1) default '0' comment '部门状态(0正常 1停用)', status char(1) default '0' comment '部门状态(0正常 1停用)',
del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', del_flag char(1) default '0' comment '删除标志(0代表存在 1代表删除)',
create_dept bigint(20) default null comment '创建部门', create_dept bigint(20) default null comment '创建部门',
create_by bigint(20) default null comment '创建者', create_by bigint(20) default null comment '创建者',
create_time datetime comment '创建时间', create_time datetime comment '创建时间',
@ -133,7 +133,7 @@ create table sys_user (
avatar varchar(256) comment '头像地址', avatar varchar(256) comment '头像地址',
password varchar(100) default '' comment '密码', password varchar(100) default '' comment '密码',
status char(1) default '0' comment '帐号状态(0正常 1停用)', status char(1) default '0' comment '帐号状态(0正常 1停用)',
del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', del_flag char(1) default '0' comment '删除标志(0代表存在 1代表删除)',
login_ip varchar(128) default '' comment '最后登录IP', login_ip varchar(128) default '' comment '最后登录IP',
login_date datetime comment '最后登录时间', login_date datetime comment '最后登录时间',
create_dept bigint(20) default null comment '创建部门', create_dept bigint(20) default null comment '创建部门',
@ -187,7 +187,7 @@ create table sys_role (
menu_check_strictly tinyint(1) default 1 comment '菜单树选择项是否关联显示', menu_check_strictly tinyint(1) default 1 comment '菜单树选择项是否关联显示',
dept_check_strictly tinyint(1) default 1 comment '部门树选择项是否关联显示', dept_check_strictly tinyint(1) default 1 comment '部门树选择项是否关联显示',
status char(1) not null comment '角色状态(0正常 1停用)', status char(1) not null comment '角色状态(0正常 1停用)',
del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', del_flag char(1) default '0' comment '删除标志(0代表存在 1代表删除)',
create_dept bigint(20) default null comment '创建部门', create_dept bigint(20) default null comment '创建部门',
create_by bigint(20) default null comment '创建者', create_by bigint(20) default null comment '创建者',
create_time datetime comment '创建时间', create_time datetime comment '创建时间',
@ -238,7 +238,7 @@ insert into sys_menu values('2', '系统监控', '0', '13', 'monitor',
insert into sys_menu values('3', '系统工具', '0', '14', 'tool', null, '', 1, 0, 'M', '0', '0', '', 'tool', 103, 1, sysdate(), null, null, '系统工具目录'); insert into sys_menu values('3', '系统工具', '0', '14', 'tool', null, '', 1, 0, 'M', '0', '0', '', 'tool', 103, 1, sysdate(), null, null, '系统工具目录');
-- 二级菜单 -- 二级菜单
insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 103, 1, sysdate(), null, null, '用户管理菜单'); insert into sys_menu values('100', '系统用户', '1', '1', 'user', 'system/user/index', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 103, 1, sysdate(), null, null, '用户管理菜单');
insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 103, 1, sysdate(), null, null, '角色管理菜单'); insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 103, 1, sysdate(), null, null, '角色管理菜单');
insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 103, 1, sysdate(), null, null, '菜单管理菜单'); insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 103, 1, sysdate(), null, null, '菜单管理菜单');
insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 103, 1, sysdate(), null, null, '部门管理菜单'); insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 103, 1, sysdate(), null, null, '部门管理菜单');
@ -354,11 +354,19 @@ insert into sys_menu values('61', '群聊消息', '6', '2', 'group', 'i
insert into sys_menu values('6101', '群聊消息查询', '61', '1', '#', '', '', 1, 0, 'F', '0', '0', 'im:groupMessage:query', '#', 103, 1, sysdate(), null, null, ''); insert into sys_menu values('6101', '群聊消息查询', '61', '1', '#', '', '', 1, 0, 'F', '0', '0', 'im:groupMessage:query', '#', 103, 1, sysdate(), null, null, '');
-- IM-系统消息 -- IM-系统消息
insert into sys_menu values('62', '系统消息', '6', '4', 'system', 'im/message/system/index', '', 1, 0, 'C', '0', '0', 'im:systemMessage:list', 'category', 103, 1, sysdate(), null, null, 'IM系统消息'); insert into sys_menu values('62', '系统消息', '6', '4', 'system', 'im/message/system/index', '', 1, 0, 'C', '0', '0', 'im:systemMessage:list', 'druid', 103, 1, sysdate(), null, null, 'IM系统消息');
insert into sys_menu values('6201', '系统消息查询', '6', '1', '#', '', '', 1, 0, 'F', '0', '0', 'im:systemMessage:query', '#', 103, 1, sysdate(), null, null, ''); insert into sys_menu values('6201', '系统消息查询', '62', '1', '#', '', '', 1, 0, 'F', '0', '0', 'im:systemMessage:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('6202', '系统消息添加', '6', '2', '#', '', '', 1, 0, 'F', '0', '0', 'im:systemMessage:add', '#', 103, 1, sysdate(), null, null, ''); insert into sys_menu values('6202', '系统消息添加', '62', '2', '#', '', '', 1, 0, 'F', '0', '0', 'im:systemMessage:add', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('6203', '系统消息删除', '6', '3', '#', '', '', 1, 0, 'F', '0', '0', 'im:systemMessage:remove', '#', 103, 1, sysdate(), null, null, ''); insert into sys_menu values('6203', '系统消息删除', '62', '3', '#', '', '', 1, 0, 'F', '0', '0', 'im:systemMessage:remove', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('6204', '系统消息修改', '6', '4', '#', '', '', 1, 0, 'F', '0', '0', 'im:systemMessage:edit', '#', 103, 1, sysdate(), null, null, ''); insert into sys_menu values('6204', '系统消息修改', '62', '4', '#', '', '', 1, 0, 'F', '0', '0', 'im:systemMessage:edit', '#', 103, 1, sysdate(), null, null, '');
-- IM-推送任务
insert into sys_menu values('63', '推送任务', '6', '4', 'task', 'im/message/task/index', '', 1, 0, 'C', '0', '0', 'im:smPushTask:list', 'my-task', 103, 1, sysdate(), null, null, 'IM推送任务');
insert into sys_menu values('6301', '推送任务查询', '63', '1', '#', '', '', 1, 0, 'F', '0', '0', 'im:smPushTask:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('6302', '推送任务添加', '63', '2', '#', '', '', 1, 0, 'F', '0', '0', 'im:smPushTask:add', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('6303', '推送任务删除', '63', '3', '#', '', '', 1, 0, 'F', '0', '0', 'im:smPushTask:remove', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('6304', '推送任务修改', '63', '3', '#', '', '', 1, 0, 'F', '0', '0', 'im:smPushTask:edit', '#', 103, 1, sysdate(), null, null, '');
-- IM-敏感词管理 -- IM-敏感词管理
insert into sys_menu values('7', '敏感词管理', '0', '2', 'im/sensitiveWord', 'im/sensitiveWord/index', '', 1, 0, 'C', '0', '0', 'im:sensitiveWord:list', 'documentation', 103, 1, sysdate(), null, null, 'IM敏感词管理'); insert into sys_menu values('7', '敏感词管理', '0', '2', 'im/sensitiveWord', 'im/sensitiveWord/index', '', 1, 0, 'C', '0', '0', 'im:sensitiveWord:list', 'documentation', 103, 1, sysdate(), null, null, 'IM敏感词管理');
@ -705,7 +713,7 @@ create table sys_client (
active_timeout int(11) default 1800 comment 'token活跃超时时间', active_timeout int(11) default 1800 comment 'token活跃超时时间',
timeout int(11) default 604800 comment 'token固定超时', timeout int(11) default 604800 comment 'token固定超时',
status char(1) default '0' comment '状态(0正常 1停用)', status char(1) default '0' comment '状态(0正常 1停用)',
del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', del_flag char(1) default '0' comment '删除标志(0代表存在 1代表删除)',
create_dept bigint(20) default null comment '创建部门', create_dept bigint(20) default null comment '创建部门',
create_by bigint(20) default null comment '创建者', create_by bigint(20) default null comment '创建者',
create_time datetime default null comment '创建时间', create_time datetime default null comment '创建时间',

28
im-admin-ui/src/api/im/smPushTask/index.ts

@ -20,7 +20,7 @@ export const listSmPushTask = (query?: SmPushTaskQuery): AxiosPromise<SmPushTask
* *
* @param id * @param id
*/ */
export const getSmPushTask = (id: string | number): AxiosPromise<SmPushTaskVO> => { export const getSmPushTask = (id: number): AxiosPromise<SmPushTaskVO> => {
return request({ return request({
url: '/im/smPushTask/' + id, url: '/im/smPushTask/' + id,
method: 'get' method: 'get'
@ -55,9 +55,33 @@ export const updateSmPushTask = (data: SmPushTaskForm) => {
* *
* @param id * @param id
*/ */
export const delSmPushTask = (id: string | number | Array<string | number>) => { export const delSmPushTask = (id: number | Array< number>) => {
return request({ return request({
url: '/im/smPushTask/' + id, url: '/im/smPushTask/' + id,
method: 'delete' method: 'delete'
}); });
}; };
/**
*
* @param id
*/
export const cancelSmPushTask = (id: number) => {
return request({
url: '/im/smPushTask/cancel?id=' + id,
method: 'put'
});
};
/**
*
* @param id
*/
export const openSmPushTask = (id: number) => {
return request({
url: '/im/smPushTask/open?id=' + id,
method: 'put'
});
};

22
im-admin-ui/src/api/im/smPushTask/types.ts

@ -2,12 +2,12 @@ export interface SmPushTaskVO {
/** /**
* id * id
*/ */
id: string | number; id: number;
/** /**
* id * id
*/ */
messageId: string | number; messageId: number;
/** /**
* *
@ -27,12 +27,12 @@ export interface SmPushTaskVO {
/** /**
* *
*/ */
sendToAll: number; sendToAll: boolean;
/** /**
* id,,send_to_all为false时有效 * id,,send_to_all为false时有效
*/ */
recvIds: string | number; recvIds: string;
/** /**
* 0 1 * 0 1
@ -55,12 +55,12 @@ export interface SmPushTaskForm extends BaseEntity {
/** /**
* id * id
*/ */
id?: string | number; id?: number;
/** /**
* id * id
*/ */
messageId?: string | number; messageId?: number;
/** /**
* *
@ -80,12 +80,12 @@ export interface SmPushTaskForm extends BaseEntity {
/** /**
* *
*/ */
sendToAll?: number; sendToAll?: boolean;
/** /**
* id,,send_to_all为false时有效 * id,,send_to_all为false时有效
*/ */
recvIds?: string | number; recvIds?: string;
/** /**
* 0 1 * 0 1
@ -109,7 +109,7 @@ export interface SmPushTaskQuery extends PageQuery {
/** /**
* id * id
*/ */
messageId?: string | number; messageId?: number;
/** /**
* *
@ -129,12 +129,12 @@ export interface SmPushTaskQuery extends PageQuery {
/** /**
* *
*/ */
sendToAll?: number; sendToAll?: boolean;
/** /**
* id,,send_to_all为false时有效 * id,,send_to_all为false时有效
*/ */
recvIds?: string | number; recvIds?: string;
/** /**
* 0 1 * 0 1

12
im-admin-ui/src/api/im/systemMessage/index.ts

@ -61,3 +61,15 @@ export const delSystemMessage = (id: string | number | Array<string | number>) =
method: 'delete' method: 'delete'
}); });
}; };
/**
*
* @param title
*/
export const findSystemMessageByTitle = (title?: String): AxiosPromise<SystemMessageVO[]> => {
return request({
url: '/im/systemMessage/findByTitle?title=' + title,
method: 'get'
});
};

2
im-admin-ui/src/api/im/user/index.ts

@ -56,7 +56,7 @@ export const unban = (data: UserUnbanDTO) => {
export const findUserByName = (name?: String): AxiosPromise<UserVO[]> => { export const findUserByName = (name?: String): AxiosPromise<UserVO[]> => {
return request({ return request({
url: '/im/user/findByName?name='+name, url: '/im/user/findByName?name=' + name,
method: 'get' method: 'get'
}); });
}; };

3
im-admin-ui/src/components/Editor/index.vue

@ -55,7 +55,7 @@ const editorConfig: Partial<IEditorConfig> = {
console.log(file) console.log(file)
const fd = new FormData() const fd = new FormData()
fd.append('file', file) fd.append('file', file)
let url = import.meta.env.VITE_APP_BASE_API + '/image/upload'; let url = import.meta.env.VITE_APP_BASE_API + '/system/image/upload';
let headers = globalHeaders(); let headers = globalHeaders();
headers['Content-Type'] = 'multipart/form-data'; headers['Content-Type'] = 'multipart/form-data';
let res = await axios.post(url, fd, { headers }) let res = await axios.post(url, fd, { headers })
@ -72,7 +72,6 @@ onBeforeUnmount(() => {
if (editor == null) { if (editor == null) {
return return
} }
console.log("onBeforeUnmount")
editor.destroy() editor.destroy()
}) })

90
im-admin-ui/src/components/ImageUpload/index.vue

@ -1,10 +1,9 @@
<template> <template>
<div class="component-upload-image"> <div class="component-upload-image">
<el-upload class="upload" ref="imageUpload" :action="uploadImgUrl" list-type="picture-card" <el-upload class="upload" ref="imageUpload" :action="uploadImgUrl" list-type="picture-card" :style="style"
:style="style" :on-success="handleUploadSuccess" :before-upload="handleBeforeUpload" :on-error="handleUploadError"
:on-success="handleUploadSuccess" :before-upload="handleBeforeUpload" :show-file-list="false" :accept="acceptType" :headers="headers"
:on-error="handleUploadError" :show-file-list="false" :on-preview="handlePictureCardPreview">
:headers="headers" :on-preview="handlePictureCardPreview">
<img v-if="modelValue" :src="modelValue" class="avatar"> <img v-if="modelValue" :src="modelValue" class="avatar">
<el-icon v-else class="avatar-uploader-icon"> <el-icon v-else class="avatar-uploader-icon">
<plus /> <plus />
@ -29,12 +28,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { propTypes } from '@/utils/propTypes'; import { propTypes } from '@/utils/propTypes';
import { globalHeaders } from '@/utils/request'; import { globalHeaders } from '@/utils/request';
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
type: [String, Object, Array], type: String,
default: '' default: ''
}, },
width: { width: {
@ -50,26 +49,27 @@
// (MB) // (MB)
fileSize: propTypes.number.def(5), fileSize: propTypes.number.def(5),
// , ['png', 'jpg', 'jpeg'] // , ['png', 'jpg', 'jpeg']
fileType: propTypes.array.def(['png', 'jpg', 'jpeg']), fileType: propTypes.array.def(['png', 'jpg', 'jpeg', 'webp', 'gif']),
// //
isShowTip: { isShowTip: {
type: Boolean, type: Boolean,
default: false default: false
} }
});
const { proxy } = getCurrentInstance() as ComponentInternalInstance; });
const emit = defineEmits(['update:modelValue']);
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const emit = defineEmits(['update:modelValue']);
const dialogImageUrl = ref(''); const dialogImageUrl = ref('');
const dialogVisible = ref(false); const dialogVisible = ref(false);
const baseUrl = import.meta.env.VITE_APP_BASE_API; const baseUrl = import.meta.env.VITE_APP_BASE_API;
const uploadImgUrl = ref(baseUrl + '/system/image/upload'); // const uploadImgUrl = ref(baseUrl + '/system/image/upload'); //
const headers = ref(globalHeaders()); const headers = ref(globalHeaders());
const showTip = computed(() => props.isShowTip && (props.fileType || props.fileSize)); const showTip = computed(() => props.isShowTip && (props.fileType || props.fileSize));
/** 上传前loading加载 */ /** 上传前loading加载 */
const handleBeforeUpload = (file: any) => { const handleBeforeUpload = (file: any) => {
let isImg = false; let isImg = false;
if (props.fileType.length) { if (props.fileType.length) {
let fileExtension = ''; let fileExtension = '';
@ -95,51 +95,55 @@
return false; return false;
} }
} }
}; };
// //
const handleUploadSuccess = (res: any) => { const handleUploadSuccess = (res: any) => {
if (res.code === 200) { if (res.code === 200) {
emit('update:modelValue', res.data.originUrl); emit('update:modelValue', res.data.originUrl);
} else { } else {
emit('update:modelValue', ''); emit('update:modelValue', '');
} }
}; };
// //
const handleUploadError = () => { const handleUploadError = () => {
proxy?.$modal.msgError('上传图片失败'); proxy?.$modal.msgError('上传图片失败');
proxy?.$modal.closeLoading(); proxy?.$modal.closeLoading();
}; };
// //
const handlePictureCardPreview = (file: any) => { const handlePictureCardPreview = (file: any) => {
dialogImageUrl.value = file.url; dialogImageUrl.value = file.url;
dialogVisible.value = true; dialogVisible.value = true;
}; };
const style = computed(() => { const style = computed(() => {
return `width:${props.width}px;height: ${props.height}px;` return `width:${props.width}px;height: ${props.height}px;`
}) })
const acceptType = computed( ()=>{
return props.fileType.map(ft=>'image/'+ft).join(',')
})
</script> </script>
<style lang="scss"> <style lang="scss">
//.el-upload--picture-card //.el-upload--picture-card
:deep(.hide .el-upload--picture-card) { :deep(.hide .el-upload--picture-card) {
display: none; display: none;
} }
.upload { .upload {
width: 300px ; width: 300px;
height: 200px; height: 200px;
} }
.el-upload--picture-card { .el-upload--picture-card {
width: 100% !important; width: 100% !important;
height: 100% !important; height: 100% !important;
} }
.avatar { .avatar {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
</style> </style>

51
im-admin-ui/src/components/im/ImSysMsgSelect/index.vue

@ -1,51 +0,0 @@
<template>
<el-select v-model="messageIds" :multiple="multiple" filterable remote clearable
:placeholder="placeholder" :remote-method="handleRemote" :loading="loading">
<el-option v-for="message in options" :key="message.id" :label="message.title" :value="message.id" />
</el-select>
</template>
<script setup lang="ts" name="ImSmSelect">
import { computed } from 'vue'
import { ref } from 'vue'
import { listSystemMessage } from '@/api/im/systemMessage'
const props = defineProps({
multiple: {
type: Boolean,
required: false,
default: () => false
},
placeholder: {
type: String,
required: false,
default: () => ''
}
})
const loading = ref(false)
const options = ref()
const model = defineModel<number | Array<Number> | string | Array<String>>()
const messageIds = computed({
get() {
if(model.value != undefined){
return model.value
}else if(props.multiple){
return []
}
},
set(value) {
model.value = value
}
})
const handleRemote = (name: string)=>{
loading.value = true
listSystemMessage().then((res) => {
loading.value = false;
options.value = res.data;
});
}
</script>

4
im-admin-ui/src/components/im/ImUserSelect/index.vue

@ -9,7 +9,7 @@
import { computed } from 'vue' import { computed } from 'vue'
import { ref } from 'vue' import { ref } from 'vue'
import { findUserByName } from '@/api/im/user' import { findUserByName,findUserByIds } from '@/api/im/user'
const props = defineProps({ const props = defineProps({
multiple: { multiple: {
@ -26,7 +26,7 @@ const props = defineProps({
const loading = ref(false) const loading = ref(false)
const options = ref() const options = ref()
const model = defineModel<number | Array<Number> | string | Array<String>>() const model = defineModel<number | Array<Number>>()
const userIds = computed({ const userIds = computed({
get() { get() {
if(model.value != undefined){ if(model.value != undefined){

34
im-admin-ui/src/views/im/message/system/index.vue

@ -25,10 +25,6 @@
<el-button type="primary" plain icon="Plus" @click="handleAdd" <el-button type="primary" plain icon="Plus" @click="handleAdd"
v-hasPermi="['im:systemMessage:add']">新增</el-button> v-hasPermi="['im:systemMessage:add']">新增</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()"
v-hasPermi="['im:systemMessage:edit']">修改</el-button>
</el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
v-hasPermi="['im:systemMessage:remove']">删除</el-button> v-hasPermi="['im:systemMessage:remove']">删除</el-button>
@ -57,14 +53,12 @@
<el-table-column label="创建者" align="center" prop="creatorName" /> <el-table-column label="创建者" align="center" prop="creatorName" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-tooltip content="修改" placement="top"> <el-button link type="primary" @click="handleSend(scope.row)"
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['im:smPushTask:add']">推送</el-button>
v-hasPermi="['im:systemMessage:edit']"></el-button> <el-button link type="primary" @click="handleUpdate(scope.row)"
</el-tooltip> v-hasPermi="['im:systemMessage:edit']">修改</el-button>
<el-tooltip content="删除" placement="top"> <el-button link type="danger" @click="handleDelete(scope.row)"
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['im:systemMessage:remove']">删除</el-button>
v-hasPermi="['im:systemMessage:remove']"></el-button>
</el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -79,17 +73,18 @@
<el-input v-model="form.title" placeholder="请输入标题" /> <el-input v-model="form.title" placeholder="请输入标题" />
</el-form-item> </el-form-item>
<el-form-item label="封面" prop="coverUrl"> <el-form-item label="封面" prop="coverUrl">
<image-upload v-model="form.coverUrl" width="200" height="150"></image-upload> <image-upload v-model="form.coverUrl" :width="200" :height="150"></image-upload>
</el-form-item> </el-form-item>
<el-form-item label="简介" prop="intro"> <el-form-item label="简介" prop="intro">
<el-input v-model="form.intro" placeholder="请输入简介" /> <el-input v-model="form.intro" placeholder="请输入简介" />
</el-form-item> </el-form-item>
<el-form-item label="类型" prop="contentType"> <el-form-item label="类型" prop="contentType">
<el-radio-group v-model="form.contentType"> <el-radio-group v-model="form.contentType">
<el-radio v-for="dict in im_sm_content_type" :key="dict.value" :value="parseInt(dict.value)">{{ dict.label }}</el-radio> <el-radio v-for="dict in im_sm_content_type" :key="dict.value" :value="parseInt(dict.value)">{{ dict.label
}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item v-if="form.contentType==0" label="富文本内容" prop="richText"> <el-form-item v-if="form.contentType == 0" label="富文本内容" prop="richText">
<editor v-model="richText" placeholder="请输入内容" /> <editor v-model="richText" placeholder="请输入内容" />
</el-form-item> </el-form-item>
<el-form-item v-else label="外部链接" prop="externLink"> <el-form-item v-else label="外部链接" prop="externLink">
@ -103,13 +98,16 @@
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
<sm-task-info ref="taskInfoRef"></sm-task-info>
</div> </div>
</template> </template>
<script setup name="SystemMessage" lang="ts"> <script setup name="SystemMessage" lang="ts">
import { listSystemMessage, getSystemMessage, delSystemMessage, addSystemMessage, updateSystemMessage } from '@/api/im/systemMessage'; import { listSystemMessage, getSystemMessage, delSystemMessage, addSystemMessage, updateSystemMessage } from '@/api/im/systemMessage';
import { SystemMessageVO, SystemMessageQuery, SystemMessageForm } from '@/api/im/systemMessage/types'; import { SystemMessageVO, SystemMessageQuery, SystemMessageForm } from '@/api/im/systemMessage/types';
import { Base64 } from 'js-base64'; import { Base64 } from 'js-base64';
import SmTaskInfo from '../task/SmTaskInfo.vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@ -124,6 +122,7 @@ const total = ref(0);
const queryFormRef = ref<ElFormInstance>(); const queryFormRef = ref<ElFormInstance>();
const systemMessageFormRef = ref<ElFormInstance>(); const systemMessageFormRef = ref<ElFormInstance>();
const taskInfoRef = ref();
const dialog = reactive<DialogOption>({ const dialog = reactive<DialogOption>({
visible: false, visible: false,
@ -265,6 +264,11 @@ const handleExport = () => {
}, `systemMessage_${new Date().getTime()}.xlsx`) }, `systemMessage_${new Date().getTime()}.xlsx`)
} }
const handleSend = (row?: SystemMessageVO) =>{
taskInfoRef.value.initByMessage(row.id);
}
onMounted(() => { onMounted(() => {
getList(); getList();
}); });

276
im-admin-ui/src/views/im/message/task/index.vue

@ -1,37 +1,12 @@
<template> <template>
<div class="p-2"> <div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> <transition :enter-active-class="proxy?.animate.searchAnimate.enter"
:leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]"> <div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover"> <el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> <el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="系统消息id" prop="messageId"> <el-form-item label="推送消息" prop="messageId">
<el-input v-model="queryParams.messageId" placeholder="请输入系统消息id" clearable @keyup.enter="handleQuery" /> <im-sm-select v-model="queryParams.messageId" placeholder="请输入系统消息" clearable ></im-sm-select>
</el-form-item>
<el-form-item label="发送序列号" prop="seqNo">
<el-input v-model="queryParams.seqNo" placeholder="请输入发送序列号" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="推送时间" prop="sendTime">
<el-date-picker clearable
v-model="queryParams.sendTime"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择推送时间"
/>
</el-form-item>
<el-form-item label="是否发送给全体用户" prop="sendToAll">
<el-input v-model="queryParams.sendToAll" placeholder="请输入是否发送给全体用户" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="接收用户id,逗号分隔,send_to_all为false时有效" prop="recvIds">
<el-input v-model="queryParams.recvIds" placeholder="请输入接收用户id,逗号分隔,send_to_all为false时有效" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="删除标识 0:正常 1:已删除" prop="deleted">
<el-input v-model="queryParams.deleted" placeholder="请输入删除标识 0:正常 1:已删除" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="创建者" prop="creator">
<el-input v-model="queryParams.creator" placeholder="请输入创建者" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="更新者" prop="updater">
<el-input v-model="queryParams.updater" placeholder="请输入更新者" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
@ -46,16 +21,12 @@
<template #header> <template #header>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['im:smPushTask:add']">新增</el-button> <el-button type="primary" plain icon="Plus" @click="handleAdd"
</el-col> v-hasPermi="['im:smPushTask:add']">新增</el-button>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['im:smPushTask:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['im:smPushTask:remove']">删除</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['im:smPushTask:export']">导出</el-button> <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
v-hasPermi="['im:smPushTask:remove']">删除</el-button>
</el-col> </el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
@ -63,189 +34,86 @@
<el-table v-loading="loading" :data="smPushTaskList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="smPushTaskList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="id" align="center" prop="id" v-if="true" /> <el-table-column label="推送消息" align="center" prop="messageTitle" />
<el-table-column label="系统消息id" align="center" prop="messageId" />
<el-table-column label="发送序列号" align="center" prop="seqNo" />
<el-table-column label="推送时间" align="center" prop="sendTime" width="180"> <el-table-column label="推送时间" align="center" prop="sendTime" width="180">
<template #default="scope"> <template #default="scope">
<span>{{ parseTime(scope.row.sendTime, '{y}-{m}-{d}') }}</span> <span>{{ parseTime(scope.row.sendTime, '{y}-{m}-{d}') }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="状态 1:待发送 2:发送中 3:已发送 4:已取消" align="center" prop="status" /> <el-table-column label="推送状态" align="center" prop="status">
<el-table-column label="是否发送给全体用户" align="center" prop="sendToAll" /> <template #default="scope">
<el-table-column label="接收用户id,逗号分隔,send_to_all为false时有效" align="center" prop="recvIds" /> <dict-tag :options="im_sm_push_status" :value="scope.row.status" />
<el-table-column label="删除标识 0:正常 1:已删除" align="center" prop="deleted" /> </template>
<el-table-column label="创建者" align="center" prop="creator" /> </el-table-column>>
<el-table-column label="更新者" align="center" prop="updater" /> <el-table-column label="接收用户" align="center" prop="recvIds">
<template #default="scope">
<span>{{ scope.row.sendToAll ? '全体用户' : `${scope.row.recvIds.split(',').length}个用户` }}</span>
</template>
</el-table-column>
<el-table-column label="创建者" align="center" prop="creatorName" />
<el-table-column label="创建时间" align="center" prop="createTime" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-tooltip content="修改" placement="top"> <el-button v-if="scope.row.status == 1" v-hasPermi="['im:smPushTask:edit']" type="primary" link
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['im:smPushTask:edit']"></el-button> @click="handleUpdate(scope.row)">修改</el-button>
</el-tooltip> <el-button v-hasPermi="['im:smPushTask:remove']" type="danger" link
<el-tooltip content="删除" placement="top"> @click="handleDelete(scope.row)">删除</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['im:smPushTask:remove']"></el-button> <el-button v-if="scope.row.status == 1" v-hasPermi="['im:smPushTask:edit']" type="danger" link
</el-tooltip> @click="handleCancel(scope.row.id)">取消</el-button>
<el-button v-if="scope.row.status == 4" v-hasPermi="['im:smPushTask:edit']" type="primary" link
@click="handleOpen(scope.row.id)">开启</el-button>
<el-button v-if="scope.row.status == 3" v-hasPermi="['im:smPushTask:add']" type="primary" link
@click="handleResend(scope.row.id)">再次推送</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card> </el-card>
<!-- 添加或修改系统消息推送任务对话框 --> <sm-task-info ref="taskInfoRef" @refreshDataList="getList"></sm-task-info>
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="smPushTaskFormRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="系统消息id" prop="messageId">
<el-input v-model="form.messageId" placeholder="请输入系统消息id" />
</el-form-item>
<el-form-item label="发送序列号" prop="seqNo">
<el-input v-model="form.seqNo" placeholder="请输入发送序列号" />
</el-form-item>
<el-form-item label="推送时间" prop="sendTime">
<el-date-picker clearable
v-model="form.sendTime"
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择推送时间">
</el-date-picker>
</el-form-item>
<el-form-item label="是否发送给全体用户" prop="sendToAll">
<el-input v-model="form.sendToAll" placeholder="请输入是否发送给全体用户" />
</el-form-item>
<el-form-item label="接收用户id,逗号分隔,send_to_all为false时有效" prop="recvIds">
<el-input v-model="form.recvIds" placeholder="请输入接收用户id,逗号分隔,send_to_all为false时有效" />
</el-form-item>
<el-form-item label="删除标识 0:正常 1:已删除" prop="deleted">
<el-input v-model="form.deleted" placeholder="请输入删除标识 0:正常 1:已删除" />
</el-form-item>
<el-form-item label="创建者" prop="creator">
<el-input v-model="form.creator" placeholder="请输入创建者" />
</el-form-item>
<el-form-item label="更新者" prop="updater">
<el-input v-model="form.updater" placeholder="请输入更新者" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div> </div>
</template> </template>
<script setup name="SmPushTask" lang="ts"> <script setup name="SmPushTask" lang="ts">
import { listSmPushTask, getSmPushTask, delSmPushTask, addSmPushTask, updateSmPushTask } from '@/api/im/smPushTask'; import { listSmPushTask, getSmPushTask, delSmPushTask, cancelSmPushTask, openSmPushTask } from '@/api/im/smPushTask';
import { SmPushTaskVO, SmPushTaskQuery, SmPushTaskForm } from '@/api/im/smPushTask/types'; import { SmPushTaskVO, SmPushTaskQuery } from '@/api/im/smPushTask/types';
import SmTaskInfo from './SmTaskInfo.vue'
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const smPushTaskList = ref<SmPushTaskVO[]>([]); const smPushTaskList = ref<SmPushTaskVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true); const loading = ref(true);
const showSearch = ref(true); const showSearch = ref(true);
const ids = ref<Array<string | number>>([]); const ids = ref<Array<number>>([]);
const single = ref(true); const single = ref(true);
const multiple = ref(true); const multiple = ref(true);
const total = ref(0); const total = ref(0);
const queryFormRef = ref<ElFormInstance>(); const queryFormRef = ref<ElFormInstance>();
const smPushTaskFormRef = ref<ElFormInstance>(); const taskInfoRef = ref();
const dialog = reactive<DialogOption>({ const queryParams = reactive<SmPushTaskQuery>({
visible: false,
title: ''
});
const initFormData: SmPushTaskForm = {
id: undefined,
messageId: undefined,
seqNo: undefined,
sendTime: undefined,
status: undefined,
sendToAll: undefined,
recvIds: undefined,
deleted: undefined,
creator: undefined,
updater: undefined,
}
const data = reactive<PageData<SmPushTaskForm, SmPushTaskQuery>>({
form: {...initFormData},
queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
messageId: undefined, messageId: undefined,
seqNo: undefined, })
sendTime: undefined, const { im_sm_push_status } = toRefs<any>(proxy?.useDict('im_sm_push_status'));
status: undefined,
sendToAll: undefined,
recvIds: undefined,
deleted: undefined,
creator: undefined,
updater: undefined,
params: {
}
},
rules: {
id: [
{ required: true, message: "id不能为空", trigger: "blur" }
],
messageId: [
{ required: true, message: "系统消息id不能为空", trigger: "blur" }
],
seqNo: [
{ required: true, message: "发送序列号不能为空", trigger: "blur" }
],
sendTime: [
{ required: true, message: "推送时间不能为空", trigger: "blur" }
],
status: [
{ required: true, message: "状态 1:待发送 2:发送中 3:已发送 4:已取消不能为空", trigger: "change" }
],
sendToAll: [
{ required: true, message: "是否发送给全体用户不能为空", trigger: "blur" }
],
recvIds: [
{ required: true, message: "接收用户id,逗号分隔,send_to_all为false时有效不能为空", trigger: "blur" }
],
deleted: [
{ required: true, message: "删除标识 0:正常 1:已删除不能为空", trigger: "blur" }
],
creator: [
{ required: true, message: "创建者不能为空", trigger: "blur" }
],
updater: [
{ required: true, message: "更新者不能为空", trigger: "blur" }
],
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询系统消息推送任务列表 */ /** 查询系统消息推送任务列表 */
const getList = async () => { const getList = async () => {
loading.value = true; loading.value = true;
const res = await listSmPushTask(queryParams.value); const res = await listSmPushTask(queryParams);
smPushTaskList.value = res.rows; smPushTaskList.value = res.rows;
total.value = res.total; total.value = res.total;
loading.value = false; loading.value = false;
} }
/** 取消按钮 */
const cancel = () => {
reset();
dialog.visible = false;
}
/** 表单重置 */
const reset = () => {
form.value = {...initFormData};
smPushTaskFormRef.value?.resetFields();
}
/** 搜索按钮操作 */ /** 搜索按钮操作 */
const handleQuery = () => { const handleQuery = () => {
queryParams.value.pageNum = 1; queryParams.pageNum = 1;
getList(); getList();
} }
@ -264,52 +132,42 @@ const handleSelectionChange = (selection: SmPushTaskVO[]) => {
/** 新增按钮操作 */ /** 新增按钮操作 */
const handleAdd = () => { const handleAdd = () => {
reset(); console.log(taskInfoRef.value)
dialog.visible = true; taskInfoRef.value.init()
dialog.title = "添加系统消息推送任务";
} }
/** 修改按钮操作 */ /** 修改按钮操作 */
const handleUpdate = async (row?: SmPushTaskVO) => { const handleUpdate = async (row: SmPushTaskVO) => {
reset(); taskInfoRef.value.init(row.id);
const _id = row?.id || ids.value[0]
const res = await getSmPushTask(_id);
Object.assign(form.value, res.data);
dialog.visible = true;
dialog.title = "修改系统消息推送任务";
} }
/** 提交按钮 */
const submitForm = () => {
smPushTaskFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
if (form.value.id) {
await updateSmPushTask(form.value).finally(() => buttonLoading.value = false);
} else {
await addSmPushTask(form.value).finally(() => buttonLoading.value = false);
}
proxy?.$modal.msgSuccess("操作成功");
dialog.visible = false;
await getList();
}
});
}
/** 删除按钮操作 */ /** 删除按钮操作 */
const handleDelete = async (row?: SmPushTaskVO) => { const handleDelete = async (row?: SmPushTaskVO) => {
const _ids = row?.id || ids.value; const _ids = row?.id || ids.value;
await proxy?.$modal.confirm('是否确认删除系统消息推送任务编号为"' + _ids + '"的数据项?').finally(() => loading.value = false); await proxy?.$modal.confirm('是否确认删除?').finally(() => loading.value = false);
await delSmPushTask(_ids); await delSmPushTask(_ids);
proxy?.$modal.msgSuccess("删除成功"); proxy?.$modal.msgSuccess("删除成功");
await getList(); await getList();
} }
/** 导出按钮操作 */ const handleCancel = (id: number) => {
const handleExport = () => { cancelSmPushTask(id).then(() => {
proxy?.download('im/smPushTask/export', { getList()
...queryParams.value ElMessage.success('任务取消成功')
}, `smPushTask_${new Date().getTime()}.xlsx`) })
}
const handleOpen = (id: number) => {
openSmPushTask(id).then(() => {
getList();
ElMessage.success('任务开启成功')
})
}
const handleResend = async(id: number) => {
const res = await getSmPushTask(id);
taskInfoRef.value.initByTask(res.data);
} }
onMounted(() => { onMounted(() => {

2
im-admin/ruoyi-admin/src/main/resources/application-dev.yml

@ -48,7 +48,7 @@ spring.data:
# 端口,默认为6379 # 端口,默认为6379
port: 6379 port: 6379
# 数据库索引 # 数据库索引
database: 4 database: 1
# redisson 配置 # redisson 配置
redisson: redisson:

37
im-admin/ruoyi-im/src/main/java/org/dromara/im/controller/ImSmPushTaskController.java

@ -1,14 +1,12 @@
package org.dromara.im.controller; package org.dromara.im.controller;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup; import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit; import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType; import org.dromara.common.log.enums.BusinessType;
@ -46,17 +44,6 @@ public class ImSmPushTaskController extends BaseController {
return imSmPushTaskService.queryPageList(bo, pageQuery); return imSmPushTaskService.queryPageList(bo, pageQuery);
} }
/**
* 导出系统消息推送任务列表
*/
@SaCheckPermission("im:smPushTask:export")
@Log(title = "系统消息推送任务", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ImSmPushTaskBo bo, HttpServletResponse response) {
List<ImSmPushTaskVo> list = imSmPushTaskService.queryList(bo);
ExcelUtil.exportExcel(list, "系统消息推送任务", ImSmPushTaskVo.class, response);
}
/** /**
* 获取系统消息推送任务详细信息 * 获取系统消息推送任务详细信息
* *
@ -64,8 +51,7 @@ public class ImSmPushTaskController extends BaseController {
*/ */
@SaCheckPermission("im:smPushTask:query") @SaCheckPermission("im:smPushTask:query")
@GetMapping("/{id}") @GetMapping("/{id}")
public R<ImSmPushTaskVo> getInfo(@NotNull(message = "主键不能为空") public R<ImSmPushTaskVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
@PathVariable Long id) {
return R.ok(imSmPushTaskService.queryById(id)); return R.ok(imSmPushTaskService.queryById(id));
} }
@ -99,8 +85,23 @@ public class ImSmPushTaskController extends BaseController {
@SaCheckPermission("im:smPushTask:remove") @SaCheckPermission("im:smPushTask:remove")
@Log(title = "系统消息推送任务", businessType = BusinessType.DELETE) @Log(title = "系统消息推送任务", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空") public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
@PathVariable Long[] ids) { return toAjax(imSmPushTaskService.deleteByIds(List.of(ids), true));
return toAjax(imSmPushTaskService.deleteWithValidByIds(List.of(ids), true)); }
@PutMapping("cancel")
@Log(title = "取消推送任务", businessType = BusinessType.UPDATE)
@SaCheckPermission("im:smPushTask:edit")
public R<Void> cancel(@RequestParam("id") Long id) {
imSmPushTaskService.cancel(id);
return R.ok();
}
@PutMapping("open")
@Log(title = "开启推送任务", businessType = BusinessType.UPDATE)
@SaCheckPermission("im:smPushTask:edit")
public R<Void> open(@RequestParam("id") Long id) {
imSmPushTaskService.open(id);
return R.ok();
} }
} }

30
im-admin/ruoyi-im/src/main/java/org/dromara/im/controller/ImSystemMessageController.java

@ -1,14 +1,12 @@
package org.dromara.im.controller; package org.dromara.im.controller;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup; import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit; import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType; import org.dromara.common.log.enums.BusinessType;
@ -35,7 +33,7 @@ import java.util.List;
@RequestMapping("/im/systemMessage") @RequestMapping("/im/systemMessage")
public class ImSystemMessageController extends BaseController { public class ImSystemMessageController extends BaseController {
private final IImSystemMessageService imSystemMessageService; private final IImSystemMessageService systemMessageService;
/** /**
* 查询系统消息列表 * 查询系统消息列表
@ -43,19 +41,9 @@ public class ImSystemMessageController extends BaseController {
@SaCheckPermission("im:systemMessage:list") @SaCheckPermission("im:systemMessage:list")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo<ImSystemMessageVo> list(ImSystemMessageBo bo, PageQuery pageQuery) { public TableDataInfo<ImSystemMessageVo> list(ImSystemMessageBo bo, PageQuery pageQuery) {
return imSystemMessageService.queryPageList(bo, pageQuery); return systemMessageService.queryPageList(bo, pageQuery);
} }
/**
* 导出系统消息列表
*/
@SaCheckPermission("im:systemMessage:export")
@Log(title = "系统消息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ImSystemMessageBo bo, HttpServletResponse response) {
List<ImSystemMessageVo> list = imSystemMessageService.queryList(bo);
ExcelUtil.exportExcel(list, "系统消息", ImSystemMessageVo.class, response);
}
/** /**
* 获取系统消息详细信息 * 获取系统消息详细信息
@ -66,7 +54,7 @@ public class ImSystemMessageController extends BaseController {
@GetMapping("/{id}") @GetMapping("/{id}")
public R<ImSystemMessageVo> getInfo(@NotNull(message = "主键不能为空") public R<ImSystemMessageVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) { @PathVariable Long id) {
return R.ok(imSystemMessageService.queryById(id)); return R.ok(systemMessageService.queryById(id));
} }
/** /**
@ -77,7 +65,7 @@ public class ImSystemMessageController extends BaseController {
@RepeatSubmit() @RepeatSubmit()
@PostMapping() @PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody ImSystemMessageBo bo) { public R<Void> add(@Validated(AddGroup.class) @RequestBody ImSystemMessageBo bo) {
return toAjax(imSystemMessageService.insertByBo(bo)); return toAjax(systemMessageService.insertByBo(bo));
} }
/** /**
@ -88,7 +76,7 @@ public class ImSystemMessageController extends BaseController {
@RepeatSubmit() @RepeatSubmit()
@PutMapping() @PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ImSystemMessageBo bo) { public R<Void> edit(@Validated(EditGroup.class) @RequestBody ImSystemMessageBo bo) {
return toAjax(imSystemMessageService.updateByBo(bo)); return toAjax(systemMessageService.updateByBo(bo));
} }
/** /**
@ -101,6 +89,12 @@ public class ImSystemMessageController extends BaseController {
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空") public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) { @PathVariable Long[] ids) {
return toAjax(imSystemMessageService.deleteWithValidByIds(List.of(ids), true)); return toAjax(systemMessageService.deleteWithValidByIds(List.of(ids), true));
}
@GetMapping("findByTitle")
@SaCheckPermission("im:systemMessage:list")
public R<List<ImSystemMessageVo>> findByTitle(@RequestParam String title) {
return R.ok(systemMessageService.findByTitle(title));
} }
} }

13
im-admin/ruoyi-im/src/main/java/org/dromara/im/controller/ImUserController.java

@ -18,10 +18,12 @@ import org.dromara.im.domain.dto.ImUserBanDto;
import org.dromara.im.domain.dto.ImUserUnbanDto; import org.dromara.im.domain.dto.ImUserUnbanDto;
import org.dromara.im.domain.vo.ImUserVo; import org.dromara.im.domain.vo.ImUserVo;
import org.dromara.im.service.IImUserService; import org.dromara.im.service.IImUserService;
import org.dromara.im.util.CommaTextUtils;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* 用户 * 用户
@ -85,11 +87,18 @@ public class ImUserController extends BaseController {
@GetMapping("/findByName") @GetMapping("/findByName")
@Operation(summary = "根据用户名查找用户",description = "用于下拉框选择用户") @Operation(summary = "根据用户名查找用户",description = "用于下拉框选择用户")
@SaCheckPermission("im:user:info") @SaCheckPermission("im:user:list")
public R<List<ImUserVo>> findByName(@RequestParam String name){ public R<List<ImUserVo>> findByName(@RequestParam String name){
List<ImUserVo> vos = userService.findByName(name); List<ImUserVo> vos = userService.findByName(name);
return R.ok(vos); return R.ok(vos);
} }
@GetMapping("/findByIds")
@Operation(summary = "根据id列表查找用户")
@SaCheckPermission("im:user:list")
public R<List<ImUserVo>> findByIds(@RequestParam String ids){
List<Long> arrIds = CommaTextUtils.asList(ids).stream().map(Long::parseLong).collect(Collectors.toList());
List<ImUserVo> vos = userService.findByIds(arrIds);
return R.ok(vos);
}
} }

57
im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/ImBaseEntity.java

@ -1,57 +0,0 @@
package org.dromara.im.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author Blue
* @date 2024-12-29
* @version 1.0
*/
@Data
public class ImBaseEntity {
/**
* id
*/
@TableId
private Long id;
/**
* 创建者
*/
@TableField(fill = FieldFill.INSERT)
private Long creator;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新者
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updater;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
/**
* 删除标记
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer deleted;
}

26
im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/ImSmPushTask.java

@ -1,8 +1,8 @@
package org.dromara.im.domain; package org.dromara.im.domain;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data; import lombok.Data;
import java.util.Date; import java.util.Date;
@ -42,38 +42,32 @@ public class ImSmPushTask {
/** /**
* 状态 1:待发送 2:发送中 3:已发送 4:已取消 * 状态 1:待发送 2:发送中 3:已发送 4:已取消
*/ */
private Long status; private Integer status;
/** /**
* 是否发送给全体用户 * 是否发送给全体用户
*/ */
private Long sendToAll; private Boolean sendToAll;
/** /**
* 接收用户id,逗号分隔,send_to_all为false时有效 * 接收用户id,逗号分隔,send_to_all为false时有效
*/ */
private String recvIds; private String recvIds;
/**
* 版本号
*/
@Version
private Long version;
/**
* 删除标识 0正常 1已删除
*/
private Long deleted;
/** /**
* 创建者 * 创建者
*/ */
private Long creator; private Long creator;
/** /**
* 更新者 * 创建时间
*/ */
private Long updater; private Date createTime;
/**
* 删除标记
*/
@TableLogic
private Boolean deleted;
} }

28
im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/ImSystemMessage.java

@ -1,8 +1,12 @@
package org.dromara.im.domain; package org.dromara.im.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.fhs.core.trans.vo.TransPojo;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
/** /**
* 系统消息对象 im_system_message * 系统消息对象 im_system_message
@ -11,10 +15,14 @@ import lombok.EqualsAndHashCode;
* @date 2024-12-22 * @date 2024-12-22
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true)
@TableName("im_system_message") @TableName("im_system_message")
public class ImSystemMessage extends ImBaseEntity { public class ImSystemMessage implements TransPojo {
/**
* id
*/
@TableId
private Long id;
/** /**
* 标题 * 标题
*/ */
@ -45,5 +53,19 @@ public class ImSystemMessage extends ImBaseEntity {
*/ */
private String externLink; private String externLink;
/**
* 创建者
*/
private Long creator;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除标记
*/
@TableLogic
private Boolean deleted;
} }

32
im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/bo/ImSmPushTaskBo.java

@ -1,7 +1,6 @@
package org.dromara.im.domain.bo; package org.dromara.im.domain.bo;
import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -23,6 +22,7 @@ import java.util.Date;
@AutoMapper(target = ImSmPushTask.class, reverseConvertGenerate = false) @AutoMapper(target = ImSmPushTask.class, reverseConvertGenerate = false)
public class ImSmPushTaskBo extends BaseEntity { public class ImSmPushTaskBo extends BaseEntity {
/** /**
* id * id
*/ */
@ -38,50 +38,26 @@ public class ImSmPushTaskBo extends BaseEntity {
/** /**
* 发送序列号 * 发送序列号
*/ */
@NotNull(message = "发送序列号不能为空", groups = { AddGroup.class, EditGroup.class })
private Long seqNo; private Long seqNo;
/** /**
* 推送时间 * 推送时间
*/ */
@NotNull(message = "推送时间不能为空", groups = { AddGroup.class, EditGroup.class })
private Date sendTime; private Date sendTime;
/** /**
* 状态 1:待发送 2:发送中 3:已发送 4:已取消 * 状态 1:待发送 2:发送中 3:已发送 4:已取消
*/ */
@NotNull(message = "状态 1:待发送 2:发送中 3:已发送 4:已取消不能为空", groups = { AddGroup.class, EditGroup.class }) private Integer status;
private Long status;
/** /**
* 是否发送给全体用户 * 是否发送给全体用户
*/ */
@NotNull(message = "是否发送给全体用户不能为空", groups = { AddGroup.class, EditGroup.class }) private Boolean sendToAll;
private Long sendToAll;
/** /**
* 接收用户id,逗号分隔,send_to_all为false时有效 * 接收用户id,逗号分隔
*/ */
@NotBlank(message = "接收用户id,逗号分隔,send_to_all为false时有效不能为空", groups = { AddGroup.class, EditGroup.class })
private String recvIds; private String recvIds;
/**
* 删除标识 0正常 1已删除
*/
@NotNull(message = "删除标识 0:正常 1:已删除不能为空", groups = { AddGroup.class, EditGroup.class })
private Long deleted;
/**
* 创建者
*/
@NotNull(message = "创建者不能为空", groups = { AddGroup.class, EditGroup.class })
private Long creator;
/**
* 更新者
*/
@NotNull(message = "更新者不能为空", groups = { AddGroup.class, EditGroup.class })
private Long updater;
} }

48
im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/vo/ImSmPushTaskVo.java

@ -1,15 +1,18 @@
package org.dromara.im.domain.vo; package org.dromara.im.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import com.fhs.core.trans.anno.Trans;
import com.fhs.core.trans.constant.TransType;
import com.fhs.core.trans.vo.TransPojo;
import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data; import lombok.Data;
import org.dromara.im.constant.ImConstant;
import org.dromara.im.domain.ImSmPushTask; import org.dromara.im.domain.ImSmPushTask;
import org.dromara.im.domain.ImSystemMessage;
import org.dromara.system.domain.SysUser;
import java.util.Date; import java.util.Date;
/** /**
* 系统消息推送任务视图对象 im_sm_push_task * 系统消息推送任务视图对象 im_sm_push_task
* *
@ -19,67 +22,64 @@ import java.util.Date;
@Data @Data
@ExcelIgnoreUnannotated @ExcelIgnoreUnannotated
@AutoMapper(target = ImSmPushTask.class) @AutoMapper(target = ImSmPushTask.class)
public class ImSmPushTaskVo { public class ImSmPushTaskVo implements TransPojo {
/** /**
* id * id
*/ */
@ExcelProperty(value = "id")
private Long id; private Long id;
/** /**
* 系统消息id * 系统消息id
*/ */
@ExcelProperty(value = "系统消息id") @Trans(type = TransType.SIMPLE, dataSource = ImConstant.DS_IM_PLATFORM, target = ImSystemMessage.class,
fields = "title", ref = "messageTitle")
private Long messageId; private Long messageId;
/**
* 消息标题
*/
private String messageTitle;
/** /**
* 发送序列号 * 发送序列号
*/ */
@ExcelProperty(value = "发送序列号")
private Long seqNo; private Long seqNo;
/** /**
* 推送时间 * 推送时间
*/ */
@ExcelProperty(value = "推送时间")
private Date sendTime; private Date sendTime;
/** /**
* 状态 1:待发送 2:发送中 3:已发送 4:已取消 * 状态 1:待发送 2:发送中 3:已发送 4:已取消
*/ */
@ExcelProperty(value = "状态 1:待发送 2:发送中 3:已发送 4:已取消") private Integer status;
private Long status;
/** /**
* 是否发送给全体用户 * 是否发送给全体用户
*/ */
@ExcelProperty(value = "是否发送给全体用户") private Boolean sendToAll;
private Long sendToAll;
/** /**
* 接收用户id,逗号分隔,send_to_all为false时有效 * 接收用户id
*/ */
@ExcelProperty(value = "接收用户id,逗号分隔,send_to_all为false时有效")
private String recvIds; private String recvIds;
/**
* 删除标识 0正常 1已删除
*/
@ExcelProperty(value = "删除标识 0:正常 1:已删除")
private Long deleted;
/** /**
* 创建者 * 创建者
*/ */
@ExcelProperty(value = "创建者") @Trans(type = TransType.SIMPLE, target = SysUser.class, fields = "userName", ref = "creatorName")
private Long creator; private Long creator;
/** /**
* 更新者 * 创建者名称
*/ */
@ExcelProperty(value = "更新者") private String creatorName;
private Long updater;
/**
* 创建时间
*/
private Date createTime;
} }

34
im-admin/ruoyi-im/src/main/java/org/dromara/im/enums/ImSmPushStatus.java

@ -0,0 +1,34 @@
package org.dromara.im.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author: Blue
* @date: 2024-09-06
* @version: 1.0
*/
@Getter
@AllArgsConstructor
public enum ImSmPushStatus {
/**
* 待发送
*/
WAIT_SEND(1),
/**
* 发送中
*/
SENDING(2),
/**
* 已取消
*/
SENDED(3),
/**
* 已取消
*/
CANCEL(4);
private final Integer value;
}

9
im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImGroupMemberService.java

@ -5,8 +5,6 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.im.domain.bo.ImGroupMemberBo; import org.dromara.im.domain.bo.ImGroupMemberBo;
import org.dromara.im.domain.vo.ImGroupMemberVo; import org.dromara.im.domain.vo.ImGroupMemberVo;
import java.util.List;
/** /**
* 群成员Service接口 * 群成员Service接口
* *
@ -32,13 +30,6 @@ public interface IImGroupMemberService {
*/ */
TableDataInfo<ImGroupMemberVo> queryPageList(ImGroupMemberBo bo, PageQuery pageQuery); TableDataInfo<ImGroupMemberVo> queryPageList(ImGroupMemberBo bo, PageQuery pageQuery);
/**
* 查询符合条件的群成员列表
*
* @param bo 查询条件
* @return 群成员列表
*/
List<ImGroupMemberVo> queryList(ImGroupMemberBo bo);
/** /**

10
im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImGroupMessageService.java

@ -5,8 +5,6 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.im.domain.bo.ImGroupMessageBo; import org.dromara.im.domain.bo.ImGroupMessageBo;
import org.dromara.im.domain.vo.ImGroupMessageVo; import org.dromara.im.domain.vo.ImGroupMessageVo;
import java.util.List;
/** /**
* 群消息Service接口 * 群消息Service接口
* *
@ -32,14 +30,6 @@ public interface IImGroupMessageService {
*/ */
TableDataInfo<ImGroupMessageVo> queryPageList(ImGroupMessageBo bo, PageQuery pageQuery); TableDataInfo<ImGroupMessageVo> queryPageList(ImGroupMessageBo bo, PageQuery pageQuery);
/**
* 查询符合条件的群消息列表
*
* @param bo 查询条件
* @return 群消息列表
*/
List<ImGroupMessageVo> queryList(ImGroupMessageBo bo);
} }

10
im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImPrivateMessageService.java

@ -5,8 +5,6 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.im.domain.bo.ImPrivateMessageBo; import org.dromara.im.domain.bo.ImPrivateMessageBo;
import org.dromara.im.domain.vo.ImPrivateMessageVo; import org.dromara.im.domain.vo.ImPrivateMessageVo;
import java.util.List;
/** /**
* 私聊消息Service接口 * 私聊消息Service接口
* *
@ -32,13 +30,7 @@ public interface IImPrivateMessageService {
*/ */
TableDataInfo<ImPrivateMessageVo> queryPageList(ImPrivateMessageBo bo, PageQuery pageQuery); TableDataInfo<ImPrivateMessageVo> queryPageList(ImPrivateMessageBo bo, PageQuery pageQuery);
/**
* 查询符合条件的私聊消息列表
*
* @param bo 查询条件
* @return 私聊消息列表
*/
List<ImPrivateMessageVo> queryList(ImPrivateMessageBo bo);
} }

17
im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImSmPushTaskService.java

@ -6,7 +6,6 @@ import org.dromara.im.domain.bo.ImSmPushTaskBo;
import org.dromara.im.domain.vo.ImSmPushTaskVo; import org.dromara.im.domain.vo.ImSmPushTaskVo;
import java.util.Collection; import java.util.Collection;
import java.util.List;
/** /**
* 系统消息推送任务Service接口 * 系统消息推送任务Service接口
@ -33,13 +32,6 @@ public interface IImSmPushTaskService {
*/ */
TableDataInfo<ImSmPushTaskVo> queryPageList(ImSmPushTaskBo bo, PageQuery pageQuery); TableDataInfo<ImSmPushTaskVo> queryPageList(ImSmPushTaskBo bo, PageQuery pageQuery);
/**
* 查询符合条件的系统消息推送任务列表
*
* @param bo 查询条件
* @return 系统消息推送任务列表
*/
List<ImSmPushTaskVo> queryList(ImSmPushTaskBo bo);
/** /**
* 新增系统消息推送任务 * 新增系统消息推送任务
@ -64,5 +56,12 @@ public interface IImSmPushTaskService {
* @param isValid 是否进行有效性校验 * @param isValid 是否进行有效性校验
* @return 是否删除成功 * @return 是否删除成功
*/ */
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); Boolean deleteByIds(Collection<Long> ids, Boolean isValid);
void cancel(Long id);
void open(Long id);
boolean isExistTask(Collection<Long> messageIds);
} }

8
im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImSystemMessageService.java

@ -33,13 +33,7 @@ public interface IImSystemMessageService {
*/ */
TableDataInfo<ImSystemMessageVo> queryPageList(ImSystemMessageBo bo, PageQuery pageQuery); TableDataInfo<ImSystemMessageVo> queryPageList(ImSystemMessageBo bo, PageQuery pageQuery);
/**
* 查询符合条件的系统消息列表
*
* @param bo 查询条件
* @return 系统消息列表
*/
List<ImSystemMessageVo> queryList(ImSystemMessageBo bo);
/** /**
* 新增系统消息 * 新增系统消息

7
im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImUserService.java

@ -63,4 +63,11 @@ public interface IImUserService {
*/ */
List<ImUserVo> findByName(String name); List<ImUserVo> findByName(String name);
/**
* 根据用户id查找
*
* @param ids 用户id
*/
List<ImUserVo> findByIds(List<Long> ids);
} }

14
im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImGroupMemberServiceImpl.java

@ -17,8 +17,6 @@ import org.dromara.im.mapper.ImGroupMemberMapper;
import org.dromara.im.service.IImGroupMemberService; import org.dromara.im.service.IImGroupMemberService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
/** /**
* 群成员Service业务层处理 * 群成员Service业务层处理
* *
@ -61,18 +59,6 @@ public class ImGroupMemberServiceImpl implements IImGroupMemberService {
return TableDataInfo.build(result); return TableDataInfo.build(result);
} }
/**
* 查询符合条件的群成员列表
*
* @param bo 查询条件
* @return 群成员列表
*/
@Override
public List<ImGroupMemberVo> queryList(ImGroupMemberBo bo) {
LambdaQueryWrapper<ImGroupMember> wrapper = buildQueryWrapper(bo);
return baseMapper.selectVoList(wrapper);
}
@Override @Override
public Long findCountByGroupId(Long groupId) { public Long findCountByGroupId(Long groupId) {

12
im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImGroupMessageServiceImpl.java

@ -16,7 +16,6 @@ import org.dromara.im.mapper.ImGroupMessageMapper;
import org.dromara.im.service.IImGroupMessageService; import org.dromara.im.service.IImGroupMessageService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -57,17 +56,6 @@ public class ImGroupMessageServiceImpl implements IImGroupMessageService {
return TableDataInfo.build(result); return TableDataInfo.build(result);
} }
/**
* 查询符合条件的群消息列表
*
* @param bo 查询条件
* @return 群消息列表
*/
@Override
public List<ImGroupMessageVo> queryList(ImGroupMessageBo bo) {
LambdaQueryWrapper<ImGroupMessage> wrapper = buildQueryWrapper(bo);
return baseMapper.selectVoList(wrapper);
}
private LambdaQueryWrapper<ImGroupMessage> buildQueryWrapper(ImGroupMessageBo bo) { private LambdaQueryWrapper<ImGroupMessage> buildQueryWrapper(ImGroupMessageBo bo) {
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();

12
im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImPrivateMessageServiceImpl.java

@ -16,7 +16,6 @@ import org.dromara.im.mapper.ImPrivateMessageMapper;
import org.dromara.im.service.IImPrivateMessageService; import org.dromara.im.service.IImPrivateMessageService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -57,17 +56,6 @@ public class ImPrivateMessageServiceImpl implements IImPrivateMessageService {
return TableDataInfo.build(result); return TableDataInfo.build(result);
} }
/**
* 查询符合条件的私聊消息列表
*
* @param bo 查询条件
* @return 私聊消息列表
*/
@Override
public List<ImPrivateMessageVo> queryList(ImPrivateMessageBo bo) {
LambdaQueryWrapper<ImPrivateMessage> wrapper = buildQueryWrapper(bo);
return baseMapper.selectVoList(wrapper);
}
private LambdaQueryWrapper<ImPrivateMessage> buildQueryWrapper(ImPrivateMessageBo bo) { private LambdaQueryWrapper<ImPrivateMessage> buildQueryWrapper(ImPrivateMessageBo bo) {
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();

8
im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImSensitiveWordServiceImpl.java

@ -87,8 +87,8 @@ public class ImSensitiveWordServiceImpl implements IImSensitiveWordService {
*/ */
@Override @Override
public Boolean insertByBo(ImSensitiveWordBo bo) { public Boolean insertByBo(ImSensitiveWordBo bo) {
ImSensitiveWord add = MapstructUtils.convert(bo, ImSensitiveWord.class); ImSensitiveWord word = MapstructUtils.convert(bo, ImSensitiveWord.class);
return baseMapper.insert(add) > 0; return baseMapper.insert(word) > 0;
} }
/** /**
@ -99,8 +99,8 @@ public class ImSensitiveWordServiceImpl implements IImSensitiveWordService {
*/ */
@Override @Override
public Boolean updateByBo(ImSensitiveWordBo bo) { public Boolean updateByBo(ImSensitiveWordBo bo) {
ImSensitiveWord update = MapstructUtils.convert(bo, ImSensitiveWord.class); ImSensitiveWord word = MapstructUtils.convert(bo, ImSensitiveWord.class);
return baseMapper.updateById(update) > 0; return baseMapper.updateById(word) > 0;
} }

115
im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImSmPushTaskServiceImpl.java

@ -2,24 +2,30 @@ package org.dromara.im.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.logging.log4j.util.Strings;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.im.constant.ImConstant; import org.dromara.im.constant.ImConstant;
import org.dromara.im.domain.ImSmPushTask; import org.dromara.im.domain.ImSmPushTask;
import org.dromara.im.domain.bo.ImSmPushTaskBo; import org.dromara.im.domain.bo.ImSmPushTaskBo;
import org.dromara.im.domain.vo.ImSmPushTaskVo; import org.dromara.im.domain.vo.ImSmPushTaskVo;
import org.dromara.im.enums.ImSmPushStatus;
import org.dromara.im.mapper.ImSmPushTaskMapper; import org.dromara.im.mapper.ImSmPushTaskMapper;
import org.dromara.im.service.IImSmPushTaskService; import org.dromara.im.service.IImSmPushTaskService;
import org.dromara.im.util.CommaTextUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.Date;
import java.util.Map; import java.util.Objects;
import java.util.Set;
/** /**
* 系统消息推送任务Service业务层处理 * 系统消息推送任务Service业务层处理
@ -59,30 +65,12 @@ public class ImSmPushTaskServiceImpl implements IImSmPushTaskService {
return TableDataInfo.build(result); return TableDataInfo.build(result);
} }
/**
* 查询符合条件的系统消息推送任务列表
*
* @param bo 查询条件
* @return 系统消息推送任务列表
*/
@Override
public List<ImSmPushTaskVo> queryList(ImSmPushTaskBo bo) {
LambdaQueryWrapper<ImSmPushTask> wrapper = buildQueryWrapper(bo);
return baseMapper.selectVoList(wrapper);
}
private LambdaQueryWrapper<ImSmPushTask> buildQueryWrapper(ImSmPushTaskBo bo) { private LambdaQueryWrapper<ImSmPushTask> buildQueryWrapper(ImSmPushTaskBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<ImSmPushTask> wrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<ImSmPushTask> wrapper = Wrappers.lambdaQuery();
wrapper.eq(bo.getMessageId() != null, ImSmPushTask::getMessageId, bo.getMessageId()); wrapper.eq(bo.getMessageId() != null, ImSmPushTask::getMessageId, bo.getMessageId());
wrapper.eq(bo.getSeqNo() != null, ImSmPushTask::getSeqNo, bo.getSeqNo()); wrapper.orderByDesc(ImSmPushTask::getId);
wrapper.eq(bo.getSendTime() != null, ImSmPushTask::getSendTime, bo.getSendTime());
wrapper.eq(bo.getStatus() != null, ImSmPushTask::getStatus, bo.getStatus());
wrapper.eq(bo.getSendToAll() != null, ImSmPushTask::getSendToAll, bo.getSendToAll());
wrapper.eq(StringUtils.isNotBlank(bo.getRecvIds()), ImSmPushTask::getRecvIds, bo.getRecvIds());
wrapper.eq(bo.getDeleted() != null, ImSmPushTask::getDeleted, bo.getDeleted());
wrapper.eq(bo.getCreator() != null, ImSmPushTask::getCreator, bo.getCreator());
wrapper.eq(bo.getUpdater() != null, ImSmPushTask::getUpdater, bo.getUpdater());
return wrapper; return wrapper;
} }
@ -94,15 +82,16 @@ public class ImSmPushTaskServiceImpl implements IImSmPushTaskService {
*/ */
@Override @Override
public Boolean insertByBo(ImSmPushTaskBo bo) { public Boolean insertByBo(ImSmPushTaskBo bo) {
ImSmPushTask add = MapstructUtils.convert(bo, ImSmPushTask.class); ImSmPushTask task = valid(MapstructUtils.convert(bo, ImSmPushTask.class));
validEntityBeforeSave(add); task.setDeleted(false);
boolean flag = baseMapper.insert(add) > 0; task.setCreator(LoginHelper.getUserId());
if (flag) { task.setCreateTime(new Date());
bo.setId(add.getId()); return baseMapper.insert(task) > 0;
}
return flag;
} }
/** /**
* 修改系统消息推送任务 * 修改系统消息推送任务
* *
@ -111,18 +100,15 @@ public class ImSmPushTaskServiceImpl implements IImSmPushTaskService {
*/ */
@Override @Override
public Boolean updateByBo(ImSmPushTaskBo bo) { public Boolean updateByBo(ImSmPushTaskBo bo) {
ImSmPushTask update = MapstructUtils.convert(bo, ImSmPushTask.class); ImSmPushTask task = this.baseMapper.selectById(bo.getId());
validEntityBeforeSave(update); if (!ImSmPushStatus.WAIT_SEND.getValue().equals(task.getStatus())) {
return baseMapper.updateById(update) > 0; throw new ServiceException("只允许修改未发送的任务");
} }
task = valid(MapstructUtils.convert(bo, ImSmPushTask.class));
/** return baseMapper.updateById(task) > 0;
* 保存前的数据校验
*/
private void validEntityBeforeSave(ImSmPushTask entity){
//TODO 做一些数据校验,如唯一约束
} }
/** /**
* 校验并批量删除系统消息推送任务信息 * 校验并批量删除系统消息推送任务信息
* *
@ -131,10 +117,53 @@ public class ImSmPushTaskServiceImpl implements IImSmPushTaskService {
* @return 是否删除成功 * @return 是否删除成功
*/ */
@Override @Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { public Boolean deleteByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0; return baseMapper.deleteByIds(ids) > 0;
} }
@Override
public void cancel(Long id) {
LambdaUpdateWrapper<ImSmPushTask> wrapper = Wrappers.lambdaUpdate();
wrapper.eq(ImSmPushTask::getId, id);
wrapper.set(ImSmPushTask::getStatus, ImSmPushStatus.CANCEL.getValue());
this.baseMapper.update(wrapper);
}
@Override
public void open(Long id) {
LambdaUpdateWrapper<ImSmPushTask> wrapper = Wrappers.lambdaUpdate();
wrapper.eq(ImSmPushTask::getId, id);
wrapper.set(ImSmPushTask::getStatus, ImSmPushStatus.WAIT_SEND.getValue());
this.baseMapper.update(wrapper);
}
@Override
public boolean isExistTask(Collection<Long> messageIds) {
LambdaQueryWrapper<ImSmPushTask> wrapper = Wrappers.lambdaQuery();
wrapper.in(ImSmPushTask::getMessageId, messageIds);
return this.baseMapper.exists(wrapper);
}
private ImSmPushTask valid(ImSmPushTask task){
// 校验接收用户
if(task.getSendToAll()){
task.setRecvIds(Strings.EMPTY);
}else {
// 去重
Set<String> recvIds = CommaTextUtils.asSet(task.getRecvIds());
if(recvIds.isEmpty()){
throw new ServiceException("请选择接收用户");
}
if(recvIds.size() > 20){
throw new ServiceException("接收用户最多选择20人");
}
task.setRecvIds(CommaTextUtils.asText(recvIds));
}
// 校验时间:小于当前时间,修正为当前时间,表示立即发送
if (Objects.isNull(task.getSendTime()) || task.getSendTime().compareTo(new Date()) < 0) {
task.setSendTime(new Date());
}
return task;
}
} }

30
im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImSystemMessageServiceImpl.java

@ -6,19 +6,23 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.im.constant.ImConstant; import org.dromara.im.constant.ImConstant;
import org.dromara.im.domain.ImSystemMessage; import org.dromara.im.domain.ImSystemMessage;
import org.dromara.im.domain.bo.ImSystemMessageBo; import org.dromara.im.domain.bo.ImSystemMessageBo;
import org.dromara.im.domain.vo.ImSystemMessageVo; import org.dromara.im.domain.vo.ImSystemMessageVo;
import org.dromara.im.mapper.ImSystemMessageMapper; import org.dromara.im.mapper.ImSystemMessageMapper;
import org.dromara.im.service.IImSmPushTaskService;
import org.dromara.im.service.IImSystemMessageService; import org.dromara.im.service.IImSystemMessageService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Collection; import java.util.Collection;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
@ -34,6 +38,7 @@ public class ImSystemMessageServiceImpl implements IImSystemMessageService {
private final ImSystemMessageMapper baseMapper; private final ImSystemMessageMapper baseMapper;
private final IImSmPushTaskService smPushTaskService;
/** /**
* 查询系统消息 * 查询系统消息
* *
@ -59,17 +64,6 @@ public class ImSystemMessageServiceImpl implements IImSystemMessageService {
return TableDataInfo.build(result); return TableDataInfo.build(result);
} }
/**
* 查询符合条件的系统消息列表
*
* @param bo 查询条件
* @return 系统消息列表
*/
@Override
public List<ImSystemMessageVo> queryList(ImSystemMessageBo bo) {
LambdaQueryWrapper<ImSystemMessage> wrapper = buildQueryWrapper(bo);
return baseMapper.selectVoList(wrapper);
}
private LambdaQueryWrapper<ImSystemMessage> buildQueryWrapper(ImSystemMessageBo bo) { private LambdaQueryWrapper<ImSystemMessage> buildQueryWrapper(ImSystemMessageBo bo) {
LambdaQueryWrapper<ImSystemMessage> wrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<ImSystemMessage> wrapper = Wrappers.lambdaQuery();
@ -87,8 +81,11 @@ public class ImSystemMessageServiceImpl implements IImSystemMessageService {
*/ */
@Override @Override
public Boolean insertByBo(ImSystemMessageBo bo) { public Boolean insertByBo(ImSystemMessageBo bo) {
ImSystemMessage add = MapstructUtils.convert(bo, ImSystemMessage.class); ImSystemMessage message = MapstructUtils.convert(bo, ImSystemMessage.class);
return baseMapper.insert(add) > 0; message.setDeleted(false);
message.setCreator(LoginHelper.getUserId());
message.setCreateTime(new Date());
return baseMapper.insert(message) > 0;
} }
/** /**
@ -99,8 +96,8 @@ public class ImSystemMessageServiceImpl implements IImSystemMessageService {
*/ */
@Override @Override
public Boolean updateByBo(ImSystemMessageBo bo) { public Boolean updateByBo(ImSystemMessageBo bo) {
ImSystemMessage update = MapstructUtils.convert(bo, ImSystemMessage.class); ImSystemMessage message = MapstructUtils.convert(bo, ImSystemMessage.class);
return baseMapper.updateById(update) > 0; return baseMapper.updateById(message) > 0;
} }
@ -113,6 +110,9 @@ public class ImSystemMessageServiceImpl implements IImSystemMessageService {
*/ */
@Override @Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(smPushTaskService.isExistTask(ids)){
throw new ServiceException("部分消息存在关联任务,删除失败");
}
return baseMapper.deleteByIds(ids) > 0; return baseMapper.deleteByIds(ids) > 0;
} }

7
im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImUserServiceImpl.java

@ -118,4 +118,11 @@ public class ImUserServiceImpl implements IImUserService {
return baseMapper.selectVoList(queryWrapper); return baseMapper.selectVoList(queryWrapper);
} }
@Override
public List<ImUserVo> findByIds(List<Long> ids) {
// 取出用户名或昵称匹配的前10条
LambdaQueryWrapper<ImUser> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.in(ImUser::getId, ids);
return baseMapper.selectVoList(queryWrapper);
}
} }

98
im-admin/ruoyi-im/src/main/java/org/dromara/im/util/CommaTextUtils.java

@ -0,0 +1,98 @@
package org.dromara.im.util;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import java.util.*;
import java.util.stream.Collectors;
/**
* 逗号分格文本处理工具类
*
* @author: blue
* @date: 2023-11-09 09:52:49
* @version: 1.0
*/
public class CommaTextUtils {
/**
* 文本转列表
*
* @param strText 文件
* @return 列表
*/
public static List<String> asList(String strText) {
if (StrUtil.isEmpty(strText)) {
return new LinkedList<>();
}
return new LinkedList<>(Arrays.asList(strText.split(",")));
}
/**
* 文本转列表
*
* @param strText 文件
* @return 列表
*/
public static Set<String> asSet(String strText) {
if (StrUtil.isEmpty(strText)) {
return new HashSet<>();
}
return Arrays.stream((strText.split(","))).collect(Collectors.toSet());
}
/**
* 列表转字符串并且自动清空去重排序
*
* @param texts 列表
* @return 文本
*/
public static <T> String asText(Collection<T> texts) {
if (CollUtil.isEmpty(texts)) {
return StrUtil.EMPTY;
}
return texts.stream().map(text -> StrUtil.toString(text)).filter(StrUtil::isNotEmpty).distinct().sorted().collect(Collectors.joining(","));
}
/**
* 追加一个单词
*
* @param strText 文本
* @param word 单词
* @return 文本
*/
public static <T> String appendWord(String strText, T word) {
List<String> texts = asList(strText);
texts.add(StrUtil.toString(word));
return asText(texts);
}
/**
* 删除一个单词
*
* @param strText 文本
* @param word 单词
* @return 文本
*/
public static <T> String removeWord(String strText, T word) {
List<String> texts = asList(strText);
texts.remove(StrUtil.toString(word));
return asText(texts);
}
/**
* 合并
*
* @param strText1 文本1
* @param strText2 文本2
* @return 文本
*/
public static String merge(String strText1, String strText2) {
List<String> texts = asList(strText1);
texts.addAll(asList(strText2));
return asText(texts);
}
}
Loading…
Cancel
Save