Previously, the role tree has been stored and tree-shaped data can be queried and constructed. This article continues to complete other operations of the role tree, including normal operations such as insertion, deletion and modification.

demand

  • To query no authentication, add, delete or change a token
  • You can query a role by id and return all the role trees under the role.
  • By inserting a new role, you can open another organizational structure, that is, the role has no superiors
  • Modify or delete a role. When modifying or deleting a role, determine whether the role exists.
  • You can modify a role in two ways
    • Change the role name without changing the role structure
    • When the upper ID of the role is changed, the lower id of the role is changed by default.
  • If a role has children, the role is deleted

convention

Description of the positions: ID: role ID PID: upper-level ID of a role Name: role name

  • Query the role tree by ID
    • Parameter: ID (optional). If no transmission is required, all are queried
    • Success returns: character tree, an array in JSON format
    • {code:400, MSG :’ query failed ‘}
  • The new role
    • Parameters: PID (optional), name(mandatory). If PID is empty, the role is a top-level role
    • Return: {code:200, MSG :’ New successfully ‘}
  • Modify the role
    • Parameters: ID (Mandatory), NAME (optional), PID (optional)
    • Return: {code:200, MSG :’ modified successfully ‘}
    • {code:400, MSG :’ failed to modify ‘}
  • Delete the role
    • Parameter: ID (Mandatory)
    • Return: {code:200, MSG :’ delete successfully ‘}
    • {code:400, MSG :’ failed to delete ‘}

implementation

Turning to the role table, the user table and the Config table remain unchanged. It is difficult to delete the subset when querying the role tree with the same ID and deleting the role

  • Database, user name: root, password: 123456, table: test

  • The directory structure

  • app/model/role.js
'use strict';

module.exports = app= > {
  const { INTEGER, STRING } = app.Sequelize;
  const Role = app.model.define('role', {
    id: { type: INTEGER, primaryKey: true.autoIncrement: true },
    name: STRING(50),
    pid: INTEGER,
  }, {
    timestamps: false});return Role;
};
Copy the code

app/controller/role.js

'use strict';

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

class RoleController extends Controller {
  async index() {
    const { ctx } = this;
    ctx.body = await ctx.service.role.getRole();
  }
  async show() {
    const { ctx } = this;
    ctx.body = await ctx.service.role.getRole(ctx.params.id);
  }
  // Insert role
  async create() {
    const { ctx } = this;
    const { name, pid } = ctx.request.body;
    await ctx.service.role.addRole(name, pid);
    ctx.body = { code: 200.msg: 'New added successfully' };
  }
  // Update the role
  async update() {
    const { ctx } = this;
    const { name, pid } = ctx.request.body;
    await ctx.service.role.editRole(ctx.params.id, name, pid);
    if (ctx.status === 404) {
      ctx.body = { code: 400.msg: 'Failed to modify' };
    } else {
      ctx.body = { code: 200.msg: 'Modified successfully'}; }}// Remove the role
  async remove() {
    const { ctx } = this;
    await ctx.service.role.removeRole(ctx.params.id);
    if (ctx.status === 404) {
      ctx.body = { code: 400.msg: 'Deletion failed' };
    } else {
      ctx.body = { code: 200.msg: 'Deletion succeeded'}; }}}module.exports = RoleController;
Copy the code

App /service/ role-js

'use strict';
const Service = require('egg').Service;
function toInt(str) {
  if (typeof str === 'number') return str;
  if(! str)return str;
  return parseInt(str, 10) | |0;
}
class RoleService extends Service {
  // Create a tree structure of data
  // If id is null, all data is built
  // If id is not null, build a tree with id as root
  buildTree(id, data) {
    const res = [];
    if (id) {
      for (const item of data) {
        if(toInt(item.id) === toInt(id)) { item.children = getNode(id); res.push(item); }}}else {
      for (const item of data) {
        if(! item.pid) { item.children = getNode(item.id); res.push(item); }}}// Pass in the root node ID to recursively find all child nodes
    function getNode(id) {
      const node = [];
      for (const item of data) {
        if(toInt(item.pid) === toInt(id)) { item.children = getNode(item.id); node.push(item); }}if (node.length === 0) return;
      return node;
    }
    return res;
  }
  // Get the collection of all child nodes
  getChildrenIds(treeData) {
    const res = [];
    function getIds(treeData, res) {
      for (const item of treeData) {
        res.push(item.id);
        if (item.children) { getIds(item.children, res); }
      }
    }
    getIds(treeData, res);
    return res;
  }
  // Query roles and build a role tree
  async getRole(id) {
    const { ctx } = this;
    const query = { limit: toInt(ctx.query.limit), offset: toInt(ctx.query.offset) };
    const data = await ctx.model.Role.findAll({ query, raw: true });
    return this.buildTree(id, data);
  }
  // Query the role by id
  async getRoleById(id) {
    const { ctx } = this;
    return await ctx.model.Role.findByPk(toInt(id));
  }
  // Insert role
  async addRole(name, pid) {
    const { ctx } = this;
    await ctx.model.Role.create({ name, pid });
  }
  // Modify the role
  async editRole(id, name, pid) {
    const { ctx } = this;
    const role = await this.getRoleById(toInt(id));
    if(! role) { ctx.status =404;
      return;
    }
    await role.update({ name: name || role.name, pid: pid || role.pid });
    ctx.status = 200;
  }
  // Delete the role
  async removeRole(id) {
    const { ctx } = this;
    const roleTree = await this.getRole(toInt(id));
    const role = await this.getRoleById(toInt(id));
    if(! role) { ctx.status =404;
      return;
    }
    const ids = this.getChildrenIds(roleTree);
    for (const i of ids) {
      const r = await this.getRoleById(toInt(i));
      r.destroy();
    }
    ctx.status = 200; }}module.exports = RoleService;
Copy the code

App /router.js (role routing, user related)

'use strict';

/ * * *@param {Egg.Application} app - egg application
 */
module.exports = app= > {
  const { router, controller, jwt } = app;
  router.get('/', controller.home.index);

  router.post('/user/login', controller.user.login);
  // Query the user
  router.get('/user', controller.user.index);
  router.get('/user/:id', jwt, controller.user.show);
  / / new
  router.put('/user', jwt, controller.user.create);
  // Change the password
  router.post('/user/:id', jwt, controller.user.updatePwd);


  // Get the role
  router.get('/role', controller.role.index);
  router.get('/role/:id', jwt, controller.role.show);
  // Insert role
  router.put('/role', jwt, controller.role.create);
  // Modify the role
  router.post('/role/:id', jwt, controller.role.update);
  // Delete the role
  router.delete('/role/:id', jwt, controller.role.remove);
};
Copy the code

test

  • Query a role by ID

  • Querying all Roles

  • Insert the role

  • Modify the role,

  • Delete the role

conclusion

  • Obtain the child node by its ID
  • Traverse the json tree to get a collection of all child node ids
  • Loop through IDS, deleting all children of the current node