123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780 |
- /**
- * icon repo Controller
- *
- */
- let config = require("../config/config");
- let constant = require("../config/constant");
- let responseFormat = require("../util/responseFormat");
- let repoInfoRules = require("../validation/repoInfoRules");
- let validator = require("../util/validator");
- let db = require("../database");
- let log = require("../util/log");
- let path = require("path");
- let fileUtil = require("../util/fileUtil");
- let incUtil = require("../util/incUtil");
- let icon = require("../tool/icon");
- let svgSprite = require("../tool/svgSprite");
- let uploadService = require("../service/upload");
- class RepoController {
- /**
- * add icon repo
- *
- * @param {Object} ctx request object
- * @return {void}
- */
- async addRepo(ctx) {
- let params = ctx.request.body || {};
- let userInfo = ctx.userInfo;
- // validate completely
- validator.validateParamsField(params, repoInfoRules, ctx);
- // validate unique
- await this.iconRepoExist(params, userInfo);
- // get increment repoId
- let repoId = await incUtil.getIncId({ model: "iconRepo", field: "repoId" });
- // build repo data
- Object.assign(params, {
- createTime: global.globalConfig.nowTime,
- updateTime: global.globalConfig.nowTime,
- ownerId: userInfo.userId,
- repoId: repoId,
- });
- log.debug(`add repo data: ${JSON.stringify(params)}`);
- // save icon repo data to database
- await db.iconRepo.add(params);
- // add repoId to owner repos field
- await db.user.update(
- {
- userId: userInfo.userId,
- },
- {
- $push: {
- repos: {
- repoId: repoId,
- repoName: params.repoName,
- },
- },
- }
- );
- ctx.body = responseFormat.responseFormat(200, "save success!", true);
- }
- /**
- * add icon repo
- *
- * @param {Object} ctx request object
- * @return {void}
- */
- async updateRepoInfo(ctx) {
- let data = ctx.request.body || {};
- let params = ctx.params;
- let userInfo = ctx.userInfo;
- // validate completely
- validator.validateParamsField(params, repoInfoRules, ctx);
- // validate privilege, only owner
- let repoItem = await db.iconRepo.findOne({
- ownerId: userInfo.userId,
- repoId: params.repoId,
- });
- if (!repoItem) {
- throw new Error("no privilege!");
- }
- // validate unique
- // await this.iconRepoExist(data, userInfo);
- // build repo data
- data = Object.assign(repoItem, data, {
- updateTime: global.globalConfig.nowTime,
- ownerId: userInfo.userId,
- unSync: true,
- repoId: parseInt(params.repoId),
- });
- log.debug(
- `user ${userInfo.userId} update repo data: ${JSON.stringify(params)}`
- );
- // update icon repo data to database
- await db.iconRepo.update({ repoId: params.repoId }, data);
- // add repoId to owner repos field, todo
- // await db.user.update({
- // userId: userInfo.userId
- // }, {
- // "$set": {
- // "repos.$[element]": {
- // repoId: params.repoId,
- // repoName: data.repoName
- // }
- // }
- // }, {
- // arrayFilters: [{
- // repoId: params.repoId,
- // repoName: repoItem.repoName
- // }]
- // });
- ctx.body = responseFormat.responseFormat(200, "save success!", true);
- }
- /**
- * get repo list
- *
- * @param {Object} ctx request object
- * @return {void}
- */
- async getRepoList(ctx) {
- let params = ctx.params;
- let query = ctx.request.query || {};
- let repoList = [];
- if (parseInt(params.userId)) {
- repoList = await this.getRepoListByUserId(params, query, ctx);
- } else {
- repoList = await this.getAllRepoList(query);
- }
- ctx.body = responseFormat.responseFormatList(200, "", repoList, query);
- }
- /**
- * get all repo list
- *
- * @param {Object} query pagination object
- * @return {void}
- */
- async getAllRepoList(query) {
- let result = await db.iconRepo.find(
- {},
- global.globalConfig.iconRepoExportFields,
- {
- limit: parseInt(query.pageSize),
- skip: parseInt((query.pageIndex - 1) * query.pageSize),
- }
- );
- query.totalCount = await db.iconRepo.count({});
- log.debug(`get all repos and count: ${query.totalCount}`);
- // traverse repo list for finding icon that belong to repo
- for (let i = 0; i < (result || []).length; i++) {
- result[i].icons = [];
- result[i].iconCount = (result[i].iconIds || []).length;
- for (
- let j = 0;
- j <
- Math.min(
- result[i].iconIds.length,
- constant.REPO_LIST_CONTAIN_ICON_COUNT_PER_REPO
- );
- j++
- ) {
- let iconItem = await db.icon.findOne(
- {
- iconId: result[i].iconIds[j].iconId,
- },
- global.globalConfig.iconExportFields
- );
- result[i].icons.push(iconItem || {});
- }
- }
- return result;
- }
- /**
- * get repo list of specific user
- *
- * @param {Object} params query object of url
- * @param {Object} query pagination object
- * @return {void}
- */
- async getRepoListByUserId(params, query) {
- let userItem = await db.user.findOne({
- userId: params.userId,
- });
- query.totalCount = userItem.repos.length;
- log.debug(
- `get user ${params.userId} repo list and count: ${query.totalCount}`
- );
- let repoList = [];
- for (
- let r = (query.pageIndex - 1) * query.pageSize;
- r < Math.min(query.pageIndex * query.pageSize, userItem.repos.length);
- r++
- ) {
- let repoItem = await db.iconRepo.findOne(
- {
- repoId: userItem.repos[r].repoId,
- },
- global.globalConfig.iconRepoExportFields
- );
- // traverse repo list for finding icon that belong to repo
- repoItem.icons = [];
- repoItem.iconCount = (repoItem.iconIds || []).length;
- for (
- let j = 0;
- j <
- Math.min(
- repoItem.iconIds.length,
- constant.REPO_LIST_CONTAIN_ICON_COUNT_PER_REPO
- );
- j++
- ) {
- let iconItem = await db.icon.findOne(
- {
- iconId: repoItem.iconIds[j].iconId,
- },
- global.globalConfig.iconExportFields
- );
- repoItem.icons.push(iconItem || {});
- }
- repoList.push(repoItem);
- }
- return repoList;
- }
- /**
- * get repo info
- *
- * @param {Object} ctx request object
- * @return {void}
- */
- async getRepoInfo(ctx) {
- let userInfo = ctx.userInfo;
- let params = ctx.params;
- // find info first
- let result = await db.iconRepo.findOne({
- repoId: params.repoId,
- });
- // pre login
- if (userInfo.userId) {
- // check user has repoId in repos field
- let userItem = await db.user.findOne({
- userId: userInfo.userId,
- });
- // isMember if exist repoId
- userItem.repos.forEach((item) => {
- if (item.repoId === parseInt(params.repoId)) {
- result.isMember = true;
- }
- });
- // is owner if repo's ownerId equal to userId
- if (result.ownerId === userInfo.userId) {
- result.isOwner = true;
- }
- }
- ctx.body = responseFormat.responseFormat(200, "", result);
- }
- /**
- * get repo css or svg resource
- *
- * @param {Object} ctx request object
- * @return {void}
- */
- async getRepoResource(ctx) {
- let params = ctx.params;
- let type = (ctx.request.query || {}).type;
- // find info first
- let repoItem = await db.iconRepo.findOne({
- repoId: params.repoId,
- });
- // pre login
- let result = null;
- if (repoItem) {
- // type can be cssUrl or cssContent
- if (repoItem[type]) {
- result = repoItem[type];
- } else {
- let iconIds = await this.getRepoIconIds(repoItem.repoId);
- result = [];
- for (let iconId of iconIds) {
- let iconItem = await db.icon.findOne({ iconId: iconId });
- result.push({
- iconId: iconItem.iconId,
- iconContent: iconItem.iconContent,
- iconName: iconItem.iconName,
- });
- }
- }
- }
- ctx.body = responseFormat.responseFormat(200, "", result);
- }
- /**
- * get iconIds that belong to repo
- *
- * @param {Number} repoId repoId
- * @return {Array} all iconIds that belong to repo
- */
- async getRepoIconIds(repoId) {
- let iconRepoItem = await db.iconRepo.findOne({
- repoId: repoId,
- });
- let iconIds = [];
- iconRepoItem.iconIds.map((icon) => {
- iconIds.push(icon.iconId);
- });
- return iconIds;
- }
- /**
- * add iconId to repo's iconIds field
- *
- * @param {Object} ctx request object
- * @return {void}
- */
- async addIcon2Repo(ctx) {
- let params = ctx.request.body || {};
- let userInfo = ctx.userInfo;
- // judge unique from upload icons
- let tmpMap = {};
- for (let icon of params.icons) {
- if (tmpMap[icon.iconName]) {
- throw new Error(`upload repeat icon ${icon.iconName}`);
- }
- tmpMap[icon.iconName] = true;
- }
- // has privilege or not
- let userItem = await db.user.findOne({
- userId: userInfo.userId,
- });
- if (!userItem || !this.hasRepo(userItem.repos, params.repoId)) {
- throw new Error("no privilege!");
- }
- let repoItem = await db.iconRepo.findOne({
- repoId: params.repoId,
- });
- // judge unique to avoid repeat between upload and database
- for (let icon of params.icons) {
- for (let existIcon of repoItem.iconIds) {
- if (
- icon.iconId === existIcon.iconId ||
- icon.iconName === existIcon.iconName
- ) {
- throw new Error(
- `repo ${repoItem.repoName} has contain icon ${icon.iconName}`
- );
- }
- }
- }
- // add many icon one times, need to traverse
- for (let icon of params.icons) {
- await db.iconRepo.update(
- {
- repoId: params.repoId,
- },
- {
- $push: {
- iconIds: {
- iconId: icon.iconId,
- iconName: icon.iconName,
- },
- },
- unSync: true,
- }
- );
- log.debug(
- `user ${userInfo.userId} add icon ${icon.iconId}-${icon.iconName} to repo ${params.repoId}`
- );
- await db.iconBelongToRepo.update(
- {
- iconId: icon.iconId,
- },
- {
- iconId: icon.iconId,
- iconName: icon.iconName,
- $push: {
- repos: {
- repoId: repoItem.repoId,
- repoName: repoItem.repoName,
- },
- },
- },
- {
- upsert: true,
- }
- );
- }
- ctx.body = responseFormat.responseFormat(200, "add success!", true);
- }
- /**
- * is member or master of repoId
- *
- * @param {Array} repos repo array
- * @param {Number} repoId repo id
- * @return {void}
- */
- hasRepo(repos = [], repoId) {
- for (let repo of repos) {
- if (repo.repoId === parseInt(repoId)) {
- return true;
- }
- }
- return false;
- }
- /**
- * delete iconId from repo
- *
- * @param {Object} ctx request object
- * @return {void}
- */
- async deleteIconFromRepo(ctx) {
- let params = ctx.params || {};
- let userInfo = ctx.userInfo;
- let isMember = false;
- // check user has repoId in repos field
- let userItem = await db.user.findOne({
- userId: userInfo.userId,
- });
- // isMember if exist repoId
- userItem.repos.forEach((item) => {
- if (item.repoId === params.repoId) {
- isMember = true;
- }
- });
- if (!isMember) {
- ctx.body = responseFormat.responseFormat(403, "no privilege!", false);
- }
- await db.iconRepo.update(
- {
- repoId: params.repoId,
- },
- {
- $pull: {
- iconIds: {
- iconId: params.iconId,
- },
- },
- unSync: true,
- }
- );
- // remove relationship for delete operation
- await db.iconBelongToRepo.update(
- {
- iconId: params.iconId,
- },
- {
- $pull: {
- repos: {
- repoId: params.repoId,
- },
- },
- }
- );
- // remove svg file from resource
- let repoItem = await db.iconRepo.findOne({
- repoId: params.repoId,
- });
- let iconItem = await db.icon.findOne({
- iconId: params.iconId,
- });
- let iconPath = path.resolve(
- __dirname,
- `../../public/resource/repository/${repoItem.ownerId}-${repoItem.iconPrefix}/svg/${iconItem.iconName}.svg`
- );
- await fileUtil.deleteFile(iconPath);
- log.debug(
- `user ${userInfo.userId} delete icon ${params.iconId} from repo ${params.repoId}`
- );
- ctx.body = responseFormat.responseFormat(200, "delete success!", true);
- }
- /**
- * sync database and generate css files
- *
- * @param {Object} ctx request object
- * @return {void}
- */
- async syncRepo(ctx) {
- let params = ctx.params;
- let userInfo = ctx.userInfo;
- let isRepoMember = false;
- // judge privilege
- let userItem = await db.user.findOne({
- userId: userInfo.userId,
- });
- userItem.repos.map((item) => {
- if (item.userId === params.userId) {
- isRepoMember = true;
- }
- });
- if (!isRepoMember) {
- ctx.body = responseFormat.responseFormat(403, "no privilege!", false);
- return;
- }
- let repoItem = await db.iconRepo.findOne({
- repoId: params.repoId,
- });
- // judge update or not
- if (repoItem.unSync) {
- let repoPath = path.join(
- config.rootRepoPath,
- `./${repoItem.ownerId}-${repoItem.iconPrefix}`
- );
- // clean all svg for avoid cache or change iconPrefix, maintain if default
- // if (config.productType === 'default') {
- // await fileUtil.deleteDirector(repoPath);
- // }
- let repoSvgPath = path.join(repoPath, "./svg/");
- let repoIcons = [];
- await fileUtil.createDirector(repoSvgPath);
- // create svg file recursive
- for (let k = 0; k < repoItem.iconIds.length; k++) {
- let iconItem =
- (await db.icon.findOne({
- iconId: repoItem.iconIds[k].iconId,
- })) || {};
- repoIcons.push(iconItem);
- await fileUtil.createFile(
- path.join(repoSvgPath, iconItem.iconName + ".svg"),
- iconItem.iconContent
- );
- }
- let uploadResult = {};
- let svgSpriteResult = "";
- // must has svg
- if (repoItem.iconIds.length > 0) {
- await icon.compileSvg2Icon(
- repoPath,
- repoItem.iconPrefix,
- repoItem.fontPath
- );
- // output to server and return css url and css content
- uploadResult = await uploadService.upload(repoPath);
- // svg sprite
- svgSpriteResult = svgSprite(repoItem.iconPrefix, repoIcons);
- } else {
- uploadResult = { url: "", cssContent: "" };
- svgSpriteResult = "";
- }
- // update sync status
- await db.iconRepo.update(
- {
- repoId: params.repoId,
- },
- {
- unSync: false,
- cssUrl: uploadResult.url,
- cssContent: uploadResult.cssContent,
- svgSpriteContent: svgSpriteResult,
- }
- );
- log.debug(`user ${userInfo.userId} sync repo ${params.repoId} success`);
- // clean all svg for avoid cache or change iconPrefix, delete if access thirdly upload
- // if (config.productType !== 'default') {
- // await fileUtil.deleteDirector(repoPath);
- // }
- ctx.body = responseFormat.responseFormat(
- 200,
- "update success!",
- uploadResult
- );
- return;
- }
- ctx.body = responseFormat.responseFormat(200, "update success!", true);
- }
- /**
- * judge repo already exist
- *
- * @param {Object} params post request object
- * @param {Object} userInfo userInfo
- * @return {void}
- */
- async iconRepoExist(params, userInfo) {
- let iconLibItem = await db.iconRepo.findOne({
- iconPrefix: params.iconPrefix,
- ownerId: userInfo.userId,
- });
- if (iconLibItem) {
- throw new Error(`${params.iconPrefix} already exist!`);
- }
- }
- /**
- * add member of repo
- *
- * @param {Object} ctx request object
- * @return {void}
- */
- async addMember(ctx) {
- let params = ctx.params;
- let userInfo = ctx.userInfo;
- let data = ctx.request.body || {};
- // only master can add member
- let repo = await db.iconRepo.findOne({
- ownerId: userInfo.userId,
- repoId: params.repoId,
- });
- if (!repo) {
- ctx.body = responseFormat.responseFormat(403, "no privilege!", false);
- return;
- }
- // user exist
- let user = null;
- if (parseInt(data.accountType) === constant.MEMBER_ACCOUNT_TYPE_USER_ID) {
- user = await db.user.findOne({
- userId: data.account,
- });
- } else {
- user = await db.user.findOne({
- userName: data.account,
- });
- }
- if (!user) {
- ctx.body = responseFormat.responseFormat(
- 200,
- "user not exist, make sure has login the site",
- false
- );
- return;
- }
- // add member of repo
- await db.user.update(
- {
- userId: user.userId,
- },
- {
- $push: {
- repos: {
- repoId: repo.repoId,
- repoName: repo.repoName,
- },
- },
- }
- );
- log.debug(
- `user ${userInfo.userId} add member ${user.userId} of repo ${repo.repoId}`
- );
- ctx.body = responseFormat.responseFormat(200, "添加成功!", true);
- }
- /**
- * get recommend repo list
- *
- * @param {Object} ctx request object
- * @return {void}
- */
- async getRecommendRepoList(ctx) {
- let recommendRepos = await db.repoRecommend.find({});
- let result = [];
- let query = ctx.request.query || {};
- // find all recommend repo
- for (let repo of recommendRepos) {
- let repoItem = await db.iconRepo.findOne(
- {
- repoId: repo.repoId,
- },
- global.globalConfig.iconRepoExportFields,
- {
- lean: true,
- }
- );
- // traverse repo list for finding icon that belong to repo
- repoItem.icons = [];
- repoItem.iconCount = (repoItem.iconIds || []).length;
- for (let icon of repoItem.iconIds) {
- if (
- repoItem.icons.length >=
- constant.REPO_LIST_CONTAIN_ICON_COUNT_PER_REPO
- ) {
- break;
- }
- let iconItem =
- (await db.icon.findOne(
- {
- iconId: icon.iconId,
- },
- global.globalConfig.iconExportFields
- )) || {};
- repoItem.icons.push(iconItem);
- }
- result.push(repoItem);
- }
- ctx.body = responseFormat.responseFormatList(200, "", result, query);
- }
- /**
- * add recommend repo
- *
- * @param {Object} ctx request object
- * @return {void}
- */
- async addRecommendRepo(ctx) {
- let params = ctx.request.body || {};
- if (params.key === config.salt) {
- for (let item of params.repos) {
- let repo = await db.iconRepo.findOne({
- repoId: item.repoId,
- });
- if (repo) {
- // get increment repoId
- let id = await incUtil.getIncId({
- model: "repoRecommend",
- field: "id",
- });
- await db.repoRecommend.add({
- id: id,
- repoId: repo.repoId,
- });
- }
- }
- }
- ctx.body = responseFormat.responseFormat(200, "save success!", true);
- }
- /**
- * add recommend repo
- *
- * @param {Object} ctx request object
- * @return {void}
- */
- async deleteRecommendRepo(ctx) {
- let params = ctx.request.body || {};
- if (params.key === config.salt) {
- for (let item of params.repos) {
- await db.repoRecommend.delete({
- repoId: item.repoId,
- });
- }
- }
- ctx.body = responseFormat.responseFormat(200, "delete success!", true);
- }
- }
- module.exports = RepoController;
|