iconController.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /**
  2. * 字体图标CURD Controller
  3. *
  4. */
  5. let responseFormat = require("../util/responseFormat");
  6. let db = require("../database");
  7. let log = require("../util/log");
  8. let incUtil = require("../util/incUtil");
  9. class IconController {
  10. constructor(config) {
  11. this.config = config;
  12. }
  13. /**
  14. * 保存字体图标到数据库
  15. *
  16. * @param {String} iconName 字体图标名称
  17. * @param {String} iconContent svg的xml内容字符串
  18. * @param {Object} userInfo 用户基本信息
  19. * @return {Object} 字体图标完整信息对象
  20. */
  21. async saveIcon(iconName, iconContent, userInfo) {
  22. // 获取唯一自增Id
  23. let iconId = await incUtil.getIncId({ model: "icon", field: "iconId" });
  24. // 构建完整数据
  25. let iconData = {
  26. iconName: iconName.replace(".svg", ""),
  27. iconContent: iconContent,
  28. createTime: global.globalConfig.nowTime,
  29. updateTime: global.globalConfig.nowTime,
  30. ownerId: userInfo.userId,
  31. iconId: iconId,
  32. };
  33. let iconAddResult = await db.icon.add(iconData);
  34. return iconAddResult.toObject();
  35. }
  36. /**
  37. * 获取各种条件下的字体图标列表
  38. *
  39. * @param {Object} ctx 请求对象
  40. * @return {void}
  41. */
  42. async getIconList(ctx) {
  43. let params = ctx.params;
  44. let query = Object.assign(
  45. {
  46. pageIndex: 1,
  47. pageSize: 20,
  48. },
  49. ctx.request.query
  50. );
  51. let iconIds = [];
  52. let result = [];
  53. query.q = new RegExp(`.*${query.q || ""}.*`);
  54. // 获取仓库下的字体图标Id数组, 倒序
  55. if (query.repoId) {
  56. iconIds = (
  57. (await this.getRepoIconIds(query, query.unique)) || []
  58. ).reverse();
  59. }
  60. if (!query.unique && !query.repoId) {
  61. // 获取用户的所有字体图标列表
  62. if (params.userId === "all") {
  63. result = await this.getAllIconList(query);
  64. } else {
  65. result = await this.getIconListByUserId(params, query);
  66. }
  67. } else if (query.unique) {
  68. // 判断当前用户不起作用
  69. // await auth();
  70. // 获取用户的所有字体图标列表,过滤掉当前图标库已经有的
  71. result = await this.getIconListNotInRepoByUnique(params, query, iconIds);
  72. } else {
  73. // 获取该图标库下的所有字体图标列表
  74. result = await this.getIconListByRepoId(query.repoId, query, iconIds);
  75. }
  76. ctx.body = responseFormat.responseFormatList(200, "", result, query);
  77. }
  78. /**
  79. * 获取该仓库下所有字体图标的iconId数组
  80. *
  81. * @param {Object} query request query
  82. * @param {Boolean} notFilter get all icons of repoId
  83. * @return {Array} 字体图标数组
  84. */
  85. async getRepoIconIds(query, notFilter) {
  86. let iconRepoItem = await db.iconRepo.findOne({
  87. repoId: query.repoId,
  88. });
  89. if (!notFilter) {
  90. iconRepoItem.iconIds = iconRepoItem.iconIds.filter((icon) => {
  91. return icon.iconName.match(query.q);
  92. });
  93. }
  94. return iconRepoItem.iconIds.map((icon) => {
  95. return icon.iconId;
  96. });
  97. }
  98. /**
  99. * 获取当前用户的字体图标列表
  100. *
  101. * @param {Object} userInfo 用户基本信息
  102. * @param {Object} query 请求参数对象
  103. * @return {Array} 字体图标对象数组
  104. */
  105. async getIconListByUserId(userInfo, query) {
  106. let result = await db.icon.find(
  107. {
  108. ownerId: userInfo.userId,
  109. iconName: query.q,
  110. },
  111. global.globalConfig.iconExportFields,
  112. {
  113. limit: parseInt(query.pageSize),
  114. skip: parseInt((query.pageIndex - 1) * query.pageSize),
  115. sort: {
  116. createTime: -1,
  117. },
  118. }
  119. );
  120. query.totalCount = await db.icon.count({
  121. ownerId: userInfo.userId,
  122. iconName: query.q,
  123. });
  124. return result;
  125. }
  126. /**
  127. * 获取当前用户的字体图标列表
  128. *
  129. * @param {Object} userInfo 用户基本信息
  130. * @param {Object} query 请求参数对象
  131. * @return {Array} 字体图标对象数组
  132. */
  133. async getAllIconList(query) {
  134. let result = await db.icon.find(
  135. {
  136. iconName: query.q,
  137. },
  138. global.globalConfig.iconExportFields,
  139. {
  140. limit: parseInt(query.pageSize),
  141. skip: parseInt((query.pageIndex - 1) * query.pageSize),
  142. sort: {
  143. createTime: -1,
  144. },
  145. }
  146. );
  147. query.totalCount = await db.icon.count({
  148. iconName: query.q,
  149. });
  150. return result;
  151. }
  152. /**
  153. * 获取当前图标库下的字体图标列表
  154. *
  155. * @param {Number} repoId 图标库Id
  156. * @param {Object} query 请求参数对象
  157. * @param {Array} iconIds 字体图标id数组
  158. * @return {Array} 字体图标对象数组
  159. */
  160. async getIconListByRepoId(repoId, query, iconIds) {
  161. let result = [];
  162. for (
  163. let i = (query.pageIndex - 1) * query.pageSize || 0;
  164. i < Math.min(iconIds.length, query.pageIndex * query.pageSize);
  165. i++
  166. ) {
  167. let iconItem = await db.icon.findOne(
  168. {
  169. iconId: iconIds[i],
  170. },
  171. global.globalConfig.iconExportFields
  172. );
  173. result.push(iconItem);
  174. }
  175. query.totalCount = iconIds.length;
  176. return result;
  177. }
  178. /**
  179. * 获取当前用户的字体图标列表
  180. *
  181. * @param {Object} userInfo 用户基本信息
  182. * @param {Object} query 请求参数对象
  183. * @param {Array} iconIds 字体图标id数组
  184. * @return {Array} 字体图标对象数组
  185. */
  186. async getIconListNotInRepoByUnique(userInfo, query, iconIds) {
  187. let result = await db.icon.find(
  188. {
  189. ownerId: userInfo.userId,
  190. iconId: {
  191. $nin: iconIds,
  192. },
  193. iconName: query.q,
  194. },
  195. global.globalConfig.iconExportFields,
  196. {
  197. limit: parseInt(query.pageSize),
  198. skip: parseInt((query.pageIndex - 1) * query.pageSize),
  199. sort: {
  200. createTime: -1,
  201. },
  202. }
  203. );
  204. query.totalCount = await db.icon.count({
  205. ownerId: userInfo.userId,
  206. iconId: {
  207. $nin: iconIds,
  208. },
  209. iconName: query.q,
  210. });
  211. return result;
  212. }
  213. /**
  214. * 删除字体图标
  215. *
  216. * @param {Object} ctx 请求对象
  217. * @return {void}
  218. */
  219. async deleteIcon(ctx) {
  220. let userInfo = ctx.userInfo;
  221. let params = ctx.params;
  222. let iconItem = await db.icon.findOne({
  223. iconId: params.iconId,
  224. });
  225. if (!iconItem) {
  226. ctx.body = responseFormat.responseFormat(500, "无此图标!", false);
  227. return;
  228. }
  229. // check privilege
  230. if (userInfo.userId !== iconItem.ownerId) {
  231. ctx.body = responseFormat.responseFormat(403, "无权限", false);
  232. return;
  233. }
  234. // check dependence
  235. let iconRelationshipItem = await db.iconBelongToRepo.findOne({
  236. iconId: params.iconId,
  237. });
  238. if (iconRelationshipItem && iconRelationshipItem.repos.length > 0) {
  239. let message = "该图标已经加入图标库: ";
  240. for (let repo of iconRelationshipItem.repos) {
  241. message += repo.repoName + "、";
  242. }
  243. message += ", 请移除后再删除!";
  244. ctx.body = responseFormat.responseFormat(500, message, false);
  245. return;
  246. }
  247. // delete icon
  248. await db.icon.delete({
  249. ownerId: userInfo.userId,
  250. iconId: params.iconId,
  251. });
  252. log.debug(`user ${userInfo.userId} delete icon ${params.iconId}`);
  253. ctx.body = responseFormat.responseFormat(200, "删除成功!", false);
  254. }
  255. /**
  256. * 下载字体图标
  257. *
  258. * @param {Object} ctx 请求对象
  259. * @return {void}
  260. */
  261. async downloadIcon(ctx) {
  262. let params = ctx.params || {};
  263. let iconItem = await db.icon.findOne({
  264. iconId: params.iconId,
  265. });
  266. if (!iconItem) {
  267. ctx.body = responseFormat.responseFormat(200, "无此图标!", false);
  268. return;
  269. }
  270. // 强制客户端直接下载svg headers
  271. ctx.set("Content-Type", "application/force-download");
  272. ctx.set(
  273. "Content-disposition",
  274. "attachment; filename=" + iconItem.iconName + ".svg"
  275. );
  276. ctx.body = iconItem.iconContent;
  277. }
  278. }
  279. module.exports = IconController;