index.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. 'use strict';
  2. const { CrudService } = require('naf-framework-mongoose/lib/service');
  3. const { BusinessError, ErrorCode } = require('naf-core').Error;
  4. const { ObjectId } = require('mongoose').Types;
  5. const _ = require('lodash');
  6. const assert = require('assert');
  7. // 首页-数据动态统计
  8. class IndexService extends CrudService {
  9. constructor(ctx) {
  10. super(ctx, 'index');
  11. this.redis = this.app.redis;
  12. this.patentModel = this.ctx.model.Dock.Patent;
  13. this.code = this.ctx.model.Code;
  14. this.productModel = this.ctx.model.Product;
  15. this.expertModel = this.ctx.model.Expert;
  16. // this.userModel = this.ctx.model.User;
  17. this.personalModel = this.ctx.model.Personal;
  18. this.organizationModel = this.ctx.model.Organization;
  19. this.surveyModel = this.ctx.model.Survey;
  20. this.dockUser = this.ctx.model.Dock.DockUser; // 没改
  21. this.tranModel = this.ctx.model.Dock.DockTranscation;// 没改
  22. }
  23. /**
  24. * 首页专利统计
  25. */
  26. async patent() {
  27. const res = await this.patentModel.aggregate([
  28. {
  29. $group: {
  30. _id: '$apply_personal',
  31. value: { $sum: 1 },
  32. },
  33. },
  34. ]);
  35. let arr = [];
  36. const other = { name: '其他', value: 0 };
  37. for (const i of res) {
  38. const { _id, value } = i;
  39. const unitList = this.patentUnitList();
  40. const unit = unitList.find(
  41. f => (_id && _id.includes(f.name)) || f.name.includes(_id)
  42. );
  43. if (unit) {
  44. // 说明是需要单拎出来的数据,现查arr中是否有该单位:有=>数字合并;没有=>创建条目
  45. const { name } = unit;
  46. const arrItem = arr.find(f => f.name === name);
  47. if (arrItem) {
  48. const index = arr.findIndex(f => f.name === name);
  49. arr[index] = { name, value: (arrItem.value || 0) + value };
  50. } else {
  51. arr.push({ name, value });
  52. }
  53. } else {
  54. other.value += value;
  55. }
  56. }
  57. arr = _.orderBy(arr, [ 'value' ], [ 'desc' ]);
  58. arr.push(other);
  59. return arr;
  60. }
  61. /**
  62. * 首页成果统计
  63. */
  64. async product() {
  65. const categroy = await this.code.find({ category: '01' });
  66. const condition = { type: '1', status: '2' };
  67. const arr = [];
  68. for (const c of categroy) {
  69. const { name } = c;
  70. const value = await this.productModel.count({
  71. ...condition,
  72. field: name,
  73. });
  74. arr.push({ value, name });
  75. }
  76. return arr;
  77. }
  78. /**
  79. * 首页统计专家
  80. */
  81. async expert() {
  82. const res = await this.expertModel.aggregate([
  83. {
  84. $group: {
  85. _id: '$company',
  86. value: { $sum: 1 },
  87. },
  88. },
  89. ]);
  90. let arr = [];
  91. const other = { name: '其他', value: 0 };
  92. for (const i of res) {
  93. const { _id, value } = i;
  94. const unitList = this.expertList();
  95. const unit = unitList.find(
  96. f => (_id && _id.includes(f.name)) || f.name.includes(_id)
  97. );
  98. if (unit) {
  99. // 说明是需要单拎出来的数据,现查arr中是否有该单位:有=>数字合并;没有=>创建条目
  100. const { name, sort } = unit;
  101. const arrItem = arr.find(f => f.name === name);
  102. if (arrItem) {
  103. const index = arr.findIndex(f => f.name === name);
  104. arr[index] = { ...arr[index], value: (arrItem.value || 0) + value };
  105. } else {
  106. arr.push({ name, value, sort });
  107. }
  108. } else {
  109. other.value += value;
  110. }
  111. }
  112. arr = _.orderBy(arr, [ 'sort' ], [ 'asc' ]);
  113. arr.push(other);
  114. // 换名
  115. arr.map(i => {
  116. const r = this.expertList().find(f => f.name === i.name);
  117. if (r && r.alias) i.name = r.alias;
  118. return i;
  119. });
  120. return arr;
  121. }
  122. /**
  123. * 首页数据统计
  124. */
  125. async circle() {
  126. const arr = [];
  127. const organization = await this.organizationModel.count({ status: '1' });
  128. arr.push({
  129. name: '企业注册数量',
  130. value: organization,
  131. });
  132. // TODO:如果需要专家和个人用户区分开,则is_expert:false, 混查则不需要is_expert条件
  133. const user = await this.personalModel.count({
  134. status: '1',
  135. is_expert: false,
  136. });
  137. arr.push({
  138. name: '个人注册数量',
  139. value: user,
  140. });
  141. const exports = await this.expertModel.count();
  142. arr.push({
  143. name: '专家注册数量',
  144. value: exports,
  145. });
  146. const products = await this.productModel.count({ status: '2' });
  147. arr.push({
  148. name: '产品发布数量',
  149. value: products,
  150. });
  151. const surveys = await this.surveyModel.count();
  152. arr.push({
  153. name: '交流互动',
  154. value: surveys,
  155. });
  156. const trans = await this.tranModel.aggregate([
  157. { $match: { status: { $in: [ '0', '1', '3' ] } } },
  158. {
  159. $group: {
  160. _id: '$status',
  161. value: { $sum: 1 },
  162. },
  163. },
  164. ]);
  165. arr.push({
  166. name: '正在洽谈',
  167. value: _.get(
  168. trans.find(f => f._id === '0'),
  169. 'value',
  170. 0
  171. ),
  172. });
  173. arr.push({
  174. name: '达成意向',
  175. value: _.get(
  176. trans.find(f => f._id === '1'),
  177. 'value',
  178. 0
  179. ),
  180. });
  181. arr.push({
  182. name: '对接完成',
  183. value: _.get(
  184. trans.find(f => f._id === '3'),
  185. 'value',
  186. 0
  187. ),
  188. });
  189. return arr;
  190. }
  191. /**
  192. * 专家列表
  193. */
  194. expertList() {
  195. return [
  196. { name: '中科院长春光学精密机械与物理研究所', alias: '光机所', sort: 1 },
  197. { name: '中国科学院长春应用化学研究所', alias: '应化所', sort: 2 },
  198. { name: '中国科学院东北地理与农业生态研究所', alias: '地理所', sort: 3 },
  199. { name: '吉林大学', sort: 4 },
  200. { name: '长春工业大学', sort: 5 },
  201. ];
  202. }
  203. /**
  204. * 专利单位列表
  205. */
  206. patentUnitList() {
  207. return [
  208. { name: '吉林大学' },
  209. { name: '长春理工大学' },
  210. { name: '东北电力大学' },
  211. { name: '吉林工程技术师范学院' },
  212. { name: '长春工业大学' },
  213. { name: '北华大学' },
  214. { name: '吉林农业大学' },
  215. { name: '吉林师范大学' },
  216. { name: '长春工程学院' },
  217. { name: '吉林建筑大学' },
  218. { name: '通化师范学院' },
  219. { name: '长春大学' },
  220. { name: '东北师范大学' },
  221. { name: '吉林农业科技学院' },
  222. ];
  223. }
  224. // 展会首页统计
  225. async dockIndex({ dock_id }) {
  226. // 同时在线人数(伪)
  227. const tszx = await this.redis.get('login_number');
  228. // 特邀嘉宾
  229. // const tyjb = await this.personalModel.count({ is_expert: true });
  230. const tyjb = 81;
  231. console.log(tyjb);
  232. // 洽谈合作 达成意向 交易完成
  233. const trans = await this.tranModel.aggregate([
  234. { $match: { status: { $in: [ '0', '1', '3' ] } } },
  235. {
  236. $group: {
  237. _id: '$status',
  238. value: { $sum: 1 },
  239. },
  240. },
  241. ]);
  242. const qthz = _.get(
  243. trans.find(f => f._id === '0'),
  244. 'value',
  245. 0
  246. );
  247. const dcyx = _.get(
  248. trans.find(f => f._id === '1'),
  249. 'value',
  250. 0
  251. );
  252. const jywc = _.get(
  253. trans.find(f => f._id === '3'),
  254. 'value',
  255. 0
  256. );
  257. // 参展项目
  258. const res = await this.dockUser
  259. .aggregate()
  260. .match({
  261. dock_id: ObjectId(dock_id),
  262. 'productList.status': '1',
  263. })
  264. .unwind('$productList')
  265. .group({
  266. _id: '$dock_id',
  267. count: { $sum: 1 },
  268. });
  269. const czxm = _.get(res[0], 'count');
  270. const arr = [
  271. { name: '同时在线', num: tszx, unit: '人' },
  272. { name: '特邀嘉宾', num: tyjb, unit: '人' },
  273. { name: '洽谈合作', num: qthz, unit: '项' },
  274. { name: '达成意向', num: dcyx, unit: '项' },
  275. { name: '交易完成', num: jywc, unit: '项' },
  276. { name: '参展项目', num: czxm, unit: '项' },
  277. ];
  278. return arr;
  279. }
  280. /**
  281. * 高企申报, 兑付成功(is_cashing=='1')
  282. * 研发补贴/奖励兑现, 兑付成功(is_cashing==='1'),类型要区分
  283. */
  284. async pac() {
  285. const gq = await this.ctx.model.Declare.count({ is_cashing: '1' });
  286. const yfjl = await this.ctx.model.Reward.aggregate([
  287. { $match: { is_cashing: '1' } },
  288. { $group: {
  289. _id: '$type',
  290. count: { $sum: 1 },
  291. } },
  292. ]);
  293. const arr = [
  294. { key: '奖励兑现', name: '奖励兑现' },
  295. { key: '研发补贴', name: '研发补贴' },
  296. ];
  297. const obj = this.setData(yfjl, arr);
  298. obj.push({ name: '高企申报', value: gq });
  299. return obj;
  300. }
  301. /**
  302. * 高企申报个步骤统计
  303. */
  304. async declare() {
  305. const res = await this.ctx.model.Declare.aggregate([
  306. { $group: {
  307. _id: '$status',
  308. count: { $sum: 1 },
  309. } },
  310. ]);
  311. const arr = [
  312. { key: '0', name: '企业信息待审中' },
  313. { key: '1', name: '企业信息审核成功' },
  314. { key: '-1', name: '企业信息审核失败' },
  315. { key: '2', name: '高企申报成功' },
  316. { key: '-2', name: '高企申报失败' },
  317. ];
  318. const obj = this.setData(res, arr);
  319. return obj;
  320. }
  321. /**
  322. * 安排返回值
  323. * @param {Array} list 数据[{_id,count}]
  324. * @param {*} meta 变换成的另一部信息[{key:_id,name:zh}]
  325. */
  326. setData(list, meta) {
  327. const obj = [];
  328. for (const i of meta) {
  329. const { key, name } = i;
  330. const r = list.find(f => f._id === key);
  331. if (r) {
  332. obj.push({ name, value: r.count });
  333. } else {
  334. obj.push({ name, value: 0 });
  335. }
  336. }
  337. return obj;
  338. }
  339. async dockProduct({ skip = 0, limit = 10, ...query } = {}) {
  340. const productQuery = {};
  341. const userQuery = {};
  342. for (const key in query) {
  343. if (query[key].length > 12) {
  344. if (ObjectId.isValid(query[key])) query[key] = ObjectId(query[key]);
  345. }
  346. if (key.includes('.')) productQuery[key] = query[key];
  347. else userQuery[key] = query[key];
  348. }
  349. const publics = [
  350. { $match: userQuery },
  351. { $project: { productList: 1, _id: 0 } },
  352. { $unwind: '$productList' },
  353. { $match: productQuery },
  354. ];
  355. const data = await this.ctx.model.Dock.DockUser.aggregate([
  356. ...publics,
  357. { $skip: parseInt(skip) },
  358. { $limit: parseInt(limit) },
  359. ]).replaceRoot('productList');
  360. let total = await this.ctx.model.Dock.DockUser.aggregate([
  361. ...publics,
  362. { $group: {
  363. _id: null,
  364. count: { $sum: 1 },
  365. } },
  366. ]);
  367. if (total && _.isArray(total)) {
  368. total = _.get(_.head(total), 'count', 0);
  369. }
  370. return { data, total };
  371. }
  372. async patentUserIndex({ id }) {
  373. const patentExamine = this.ctx.service.patent.patentexamine;
  374. const unread = await patentExamine.count({ id, is_read: false });
  375. const papply = this.ctx.patent.patentapply;
  376. const apply = await papply.count({ status: [ '0', '1', '-1', '2' ], user_id: id });
  377. const palysis = this.ctx.patent.patentanalysis;
  378. const analysis = await palysis.count({ status: [ '0', '-1' ], user_id: id });
  379. const paccess = this.ctx.patent.patentassess;
  380. const access = await paccess.count({ status: [ '0', '-1' ], user_id: id });
  381. const patentInfo = this.ctx.patent.patentinfo;
  382. const information = await patentInfo.count({ user_id: [ id ] });
  383. const patentEarly = this.ctx.patent.patentearly;
  384. const early = await patentEarly.count({ user_id: [ id ] });
  385. const patentTrans = this.ctx.patent.patenttrans;
  386. const trans1 = await patentTrans.count({ type: '转让', user_id: id });
  387. const trans2 = await patentTrans.count({ type: '合作', user_id: id });
  388. const trans3 = await patentTrans.count({ type: '招商', user_id: id });
  389. return { unread, apply, analysis, access, information, early, trans1, trans2, trans3 };
  390. }
  391. }
  392. module.exports = IndexService;