2021SC@SDUSC


此次分析文件src/model/csmwing/category.js
该文件如其名,主要是对系统中分类信息的操作。

一、info()

此方法用于获取分类详细信息。
此方法有两个参数,第一个参数 id 为分类ID或者标识,第二个参数 field 为查询字段,方法返回值类型为array,为分类信息。
首先判断给的参数是分类id还是标识:若参数 id 为数字,那么给的是分类 id,即数据库表中的id;否则为分类标识,即数据库表中的name。然后在数据库表中查找对应id/标识的字段,返回即可。

async info(id, field) {
    field = think.isEmpty(field) || '';
    const map = {};
    if (think.isNumberString(id)) {
      map.id = id;
    } else {
      map.name = id;
    }
    return await this.field(field).where(map).find();
  }

二、gettree()

此方法用于获取分类树。
此方法有三个参数,第一个参数 id 为分类ID或者标识,第二个参数 field 为查询字段,第三个参数 where 为要获取的树的其他信息。
从方法的第一行可以看出,此方法支持不给定 id 和 field 的查找。若指定分类,方法返回指定分类及其子分类;若不指定分类,方法直接返回所有分类树。

sync gettree(id, field, where = {}) {
    id = id || 0, field = field || true;
    const map = think.extend({'status': {'>': -1}}, where);
    let list = await this.field(field).where(map).order('sort ASC').select();
    for (const v of list) {
      if (!think.isEmpty(v.name)) {
        v.url = `/${v.name}`;
      } else {
        v.url = `/${v.id}`;
      }
    }
    list = get_children(list, id);
    const info = list;

    return info;
  }

三、get_category()

此方法用于获取分类信息并缓存分类。
此方法共有两个参数,第一个参数 id 为分类ID,第二个参数 field 为要获取的字段名,方法返回要获取的分类信息。
在项目中添加 think-cache 扩展后,会注入 think.cache、ctx.cache 和 controller.cache 方法,其中 ctx.cache 和 controller.cache 都是 think.cache 方法的包装,会读取当前请求下对应的缓存配置。该方法就使用了 think.cache 方法,缓存了获取的全部分类信息 。全部分类信息的获取是通过自定义方法 getallcate() 实现的,此方法逻辑比较简单,故在此列出,不再单独进行分析。

async getallcate() {
const lists = {};
const cate = await this.select();
for (const v of cate) {
if (!think.isEmpty(v.name)) {
v.url = /${v.name};
} else {
v.url = /${v.id};
}
lists[v.id] = v;
}
return lists;
}

if 语句判断 id 是否合法。若 id 不合法,直接返回 list ,此时的 list 为全部分类信息缓存。若 id 合法,根据参数 id 和 field 进行查找,返回获取的信息并缓存。

async get_category(id, field) {
    field = field || null;
    const list = await think.cache('sys_category_list', () => {
      return this.getallcate();
    }, {timeout: 365 * 24 * 3600});
    if (think.isEmpty(id) || !think.isNumberString(id)) {
      return list;
    } else if (list[id]) {
      if (think.isEmpty(list) || list[id].status != 1) { /
        return '';
      }
      return think.isEmpty(field) ? list[id] : list[id][field];
    } else {
      return '';
    }
  }

四、check_category()

此方法用于验证分类是否允许发布内容。
此方法只有一个参数 id ,是分类id。方法返回布尔值,返回TRUE意为分类允许发布内容,FALSE意为不允许发布内容。
首先判断参数指定的 id 的 type 是否为空,若为空则设为2。使用上面已经分析过的 get_category() 方法来获取分类的 type ,并通过 split 方法将获取的 type 靠逗号分割开,将获取到的 array 赋值给 type。使用自定义方法 in_array() 方法判断 id 的 type 是否在 array 类型的 type 中。该自定义方法出自文件 src/bootstrap/global.js ,由其他成员进行分析,故只贴出代码不再进行分析。若 id 的 type 在 array 类型的 type 中,说明分类允许发布内容,不在则不允许。

async check_category(id) {
    if (think.isObject(id)) {
      id.type = !think.isEmpty(id.type) ? id.type : 2;
      let type = await this.get_category(id.category_id, 'type');
      type = type.split(',');
      return in_array(id.type, type);
    } else {
      const publish = await this.get_category(id, 'allow_publish');
      return !!publish;
    }
  }

global.in_array = function(stringToSearch, arrayToSearch) {
for (let s = 0; s < arrayToSearch.length; s++) {
const thisEntry = arrayToSearch[s].toString();
if (thisEntry == stringToSearch) {
return true;
}
}
return false;
};

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐