Skip to content

Commit

Permalink
feat: 增加站内信,并完成修改任务触发站内信,发送socket;
Browse files Browse the repository at this point in the history
增加站内信,并完成修改任务触发站内信,发送socket;
  • Loading branch information
Imfdj committed Mar 15, 2021
1 parent 84852ef commit c96a652
Show file tree
Hide file tree
Showing 12 changed files with 656 additions and 18 deletions.
75 changes: 75 additions & 0 deletions app/contract/request/message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
'use strict';

const body = {
messageId: {
id: { type: 'number', required: true, description: 'id' },
},
messageBodyReq: {
actor_id: {
type: 'number',
required: true,
min: 1,
example: '1',
description: '发起者ID',
},
receiver_id: {
type: 'number',
required: true,
min: 1,
example: '1',
description: '接受者ID',
},
content: {
type: 'string',
required: true,
min: 1,
max: 700,
trim: true,
example: '1',
description: '内容',
},
is_read: {
type: 'number',
required: false,
min: 0,
max: 1,
example: '0',
description: '是否为已读.1为true,0为false',
},
type: {
type: 'string',
required: true,
min: 1,
max: 30,
trim: true,
example: 'inform',
description: '类型',
},
url: {
type: 'string',
required: false,
min: 1,
max: 255,
trim: true,
example: '',
description: '跳转路径',
},
},
};

module.exports = {
...body,
messagePutBodyReq: {
...body.messageId,
...body.messageBodyReq,
},
messageDelBodyReq: {
ids: {
type: 'array',
required: true,
itemType: 'number',
description: 'ids',
example: [1, 2],
},
},
};
84 changes: 84 additions & 0 deletions app/controller/v1/messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
'use strict';

const Controller = require('egg').Controller;

/**
* @controller 站内信 message
*/

class RoleController extends Controller {
/**
* @apikey
* @summary 获取 站内信
* @description 获取 站内信
* @request query string name message名
* @request query number limit limit
* @request query number offset offset
* @router get /api/v1/messages/list
*/
async findAll() {
const { ctx, service } = this;
const { allRule, query } = ctx.helper.tools.findAllParamsDeal(ctx.rule.messagePutBodyReq, ctx.query);
ctx.validate(allRule, query);
const res = await service.messages.findAll(query);
ctx.helper.body.SUCCESS({ ctx, res });
}

/**
* @apikey
* @summary 获取某个 站内信
* @description 获取某个 站内信
* @router get /api/v1/messages
* @request query number *id eg:1 messageID
*/
async findOne() {
const { ctx, service } = this;
ctx.validate(ctx.rule.messageId, ctx.query);
const res = await service.messages.findOne(ctx.query.id);
res ? ctx.helper.body.SUCCESS({ ctx, res }) : ctx.helper.body.NOT_FOUND({ ctx });
}

/**
* @apikey
* @summary 创建 站内信
* @description 创建 站内信
* @router post /api/v1/messages
* @request body messageBodyReq
*/
async create() {
const ctx = this.ctx;
ctx.validate(ctx.rule.messageBodyReq, ctx.request.body);
await ctx.service.messages.create(ctx.request.body);
ctx.helper.body.CREATED_UPDATE({ ctx });
}

/**
* @apikey
* @summary 更新 站内信
* @description 更新 站内信
* @router put /api/v1/messages
* @request body messagePutBodyReq
*/
async update() {
const { ctx, service } = this;
ctx.validate(ctx.rule.messagePutBodyReq, ctx.request.body);
const res = await service.messages.update(ctx.request.body);
res && res[0] !== 0 ? ctx.helper.body.CREATED_UPDATE({ ctx }) : ctx.helper.body.NOT_FOUND({ ctx });
}

/**
* @apikey
* @summary 批量删除 站内信
* @description 批量删除 站内信
* @router delete /api/v1/messages
* @request body messageDelBodyReq
*/
async destroy() {
const { ctx, service } = this;
ctx.validate(ctx.rule.messageDelBodyReq, ctx.request.body);
const res = await service.messages.destroy(ctx.request.body);
res ? ctx.helper.body.NO_CONTENT({ ctx, res }) : ctx.helper.body.NOT_FOUND({ ctx });
}
}

module.exports = RoleController;
7 changes: 4 additions & 3 deletions app/extend/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,18 @@ module.exports = {
/**
* 发送socket消息给room里的每个连接,并录入redis
*/
sendSocketToClientOfRoom(params, action, project_id = params.project_id, message = 'message', method = 'publish') {
sendSocketToClientOfRoom(params, action, project_id = params.project_id, messageType = 'sync', method = 'publish') {
const { ctx, app, redisKeys } = this;
const nsp = app.io.of('/');
const roomName = `${ this.app.config.socketProjectRoomNamePrefix }${ project_id }`;
nsp.adapter.clients([roomName], (err, clients) => {
clients.forEach(clientId => {
const data = ctx.helper.parseSocketMsg(params, clientId, action, method);
const socket = nsp.to(clientId);
socket.emit(message, data);
const emitData = [messageType, data];
socket.emit(...emitData);
// 存入redis,接收到ACK则删除,否则在 this.app.config.socketRedisExp 时间内多次重发
app.redis.setex(redisKeys.socketBaseSocketId(data.id), this.app.config.socketRedisExp, JSON.stringify(data));
app.redis.setex(redisKeys.socketBaseSocketId(data.id), this.app.config.socketRedisExp, JSON.stringify(emitData));
});
});
},
Expand Down
46 changes: 46 additions & 0 deletions app/model/messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
'use strict';
module.exports = app => {
const Sequelize = app.Sequelize;

const message = app.model.define(
'messages',
{
id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true },
actor_id: Sequelize.INTEGER(11),
receiver_id: Sequelize.INTEGER(11),
content: Sequelize.TEXT,
is_read: Sequelize.TINYINT(1),
type: Sequelize.STRING(30),
url: Sequelize.STRING(255),
},
{}
);

message.addHook('afterCreate', async (message, options) => {
const ctx = await app.createAnonymousContext();
// 发送socket消息
const newMessage = Object.assign({
is_read: 0,
url: '',
}, message.dataValues);
const nsp = app.io.of('/');
const { receiver_id, type } = message;
nsp.clients((error, clients) => {
if (error) throw error;
// 当此用户在线,则发送消息
if (clients.includes(receiver_id.toString())) {
const socket = nsp.to(receiver_id);
const _message = ctx.helper.parseSocketMsg(newMessage, receiver_id, type);
const emitData = ['message', _message];
socket.emit(...emitData);
// 存入redis,接收到ACK则删除,否则在 this.app.config.socketRedisExp 时间内多次重发
app.redis.setex(ctx.helper.redisKeys.socketBaseSocketId(_message.id), app.config.socketRedisExp, JSON.stringify(emitData));
}
});
});

message.associate = function(models) {
// associations can be defined here
};
return message;
};
9 changes: 9 additions & 0 deletions app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,4 +265,13 @@ module.exports = app => {
* 用户-项目-收藏关系表
*/
router.post('/api/v1/user_project_collects/change', controller.v1.userProjectCollects.change);

/**
* 站内信
*/
router.post('/api/v1/messages', controller.v1.messages.create);
router.put('/api/v1/messages', controller.v1.messages.update);
router.get('/api/v1/messages/list', controller.v1.messages.findAll);
router.get('/api/v1/messages', controller.v1.messages.findOne);
router.delete('/api/v1/messages', controller.v1.messages.destroy);
};
10 changes: 7 additions & 3 deletions app/schedule/resend_not_ack_socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@ module.exports = {
// const data = await redis.mget(...intersection);
const nsp = io.of('/');
// console.log(nsp.adapter.rooms);
// nsp.clients((error, clients) => {
// if (error) throw error;
// console.log(clients); // => [PZDoMHjiu8PYfRiKAAAF, Anw2LatarvGVVXEIAAAD]
// });
try {
intersection.forEach(id => {
redis.get(id, (err, data) => {
if (!err) {
const _data = JSON.parse(data);
const socket = nsp.to(_data.clientId);
socket.emit('message', _data);
const emitData = JSON.parse(data);
const socket = nsp.to(emitData[1].clientId);
socket.emit(...emitData);
}
});
});
Expand Down
47 changes: 47 additions & 0 deletions app/service/messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict';

const Service = require('egg').Service;
const { Op } = require('sequelize');

class _objectName_Service extends Service {
async findAll(payload) {
const { ctx } = this;
const { limit, offset, prop_order, order, name } = payload;
const where = payload.where;
const Order = [];
name ? (where.name = { [Op.like]: `%${name}%` }) : null;
prop_order && order ? Order.push([prop_order, order]) : null;
return await ctx.model.Messages.findAndCountAll({
limit,
offset,
where,
order: Order,
});
}

async findOne(id) {
const { ctx } = this;
return await ctx.model.Messages.findOne({ where: { id } });
}

async create(payload) {
const { ctx } = this;
return await ctx.model.Messages.create(payload);
}

async update(payload) {
const { ctx } = this;
return await ctx.model.Messages.update(payload, {
where: { id: payload.id },
});
}

async destroy(payload) {
const { ctx } = this;
return await ctx.model.Messages.destroy({
where: { id: payload.ids },
});
}
}

module.exports = _objectName_Service;
Loading

0 comments on commit c96a652

Please sign in to comment.