'use strict'; const { CrudService } = require('naf-framework-mongoose-free/lib/service'); const { BusinessError, ErrorCode } = require('naf-core').Error; const { ObjectId } = require('mongoose').Types; const _ = require('lodash'); const assert = require('assert'); // 首页-数据动态统计 class IndexService extends CrudService { constructor(ctx) { super(ctx, 'index'); this.redis = this.app.redis; this.patentModel = this.ctx.model.Dock.Patent; this.code = this.ctx.model.System.Code; this.productModel = this.ctx.model.News.Product; this.expertModel = this.ctx.model.User.Expert; // this.userModel = this.ctx.model.User; this.personalModel = this.ctx.model.User.Personal; this.organizationModel = this.ctx.model.User.Organization; this.surveyModel = this.ctx.model.News.Survey; this.dockUser = this.ctx.model.Dock.DockUser; // 没改 this.tranModel = this.ctx.model.Dock.DockTranscation; // 没改 } /** * 首页专利统计 */ async patent() { const res = await this.patentModel.aggregate([ { $group: { _id: '$apply_personal', value: { $sum: 1 }, }, }, ]); let arr = []; const other = { name: '其他', value: 0 }; for (const i of res) { const { _id, value } = i; const unitList = this.patentUnitList(); const unit = unitList.find(f => (_id && _id.includes(f.name)) || f.name.includes(_id)); if (unit) { // 说明是需要单拎出来的数据,现查arr中是否有该单位:有=>数字合并;没有=>创建条目 const { name } = unit; const arrItem = arr.find(f => f.name === name); if (arrItem) { const index = arr.findIndex(f => f.name === name); arr[index] = { name, value: (arrItem.value || 0) + value }; } else { arr.push({ name, value }); } } else { other.value += value; } } arr = _.orderBy(arr, [ 'value' ], [ 'desc' ]); arr.push(other); return arr; } /** * 首页成果统计 */ async product() { const categroy = await this.code.find({ category: '01' }); const condition = { type: '1', status: '2' }; const arr = []; for (const c of categroy) { const { name } = c; const value = await this.productModel.count({ ...condition, field: name, }); arr.push({ value, name }); } return arr; } /** * 首页统计专家 */ async expert() { const res = await this.expertModel.aggregate([ { $group: { _id: '$company', value: { $sum: 1 }, }, }, ]); let arr = []; const other = { name: '其他', value: 0 }; for (const i of res) { const { _id, value } = i; const unitList = this.expertList(); const unit = unitList.find(f => (_id && _id.includes(f.name)) || f.name.includes(_id)); if (unit) { // 说明是需要单拎出来的数据,现查arr中是否有该单位:有=>数字合并;没有=>创建条目 const { name, sort } = unit; const arrItem = arr.find(f => f.name === name); if (arrItem) { const index = arr.findIndex(f => f.name === name); arr[index] = { ...arr[index], value: (arrItem.value || 0) + value }; } else { arr.push({ name, value, sort }); } } else { other.value += value; } } arr = _.orderBy(arr, [ 'sort' ], [ 'asc' ]); arr.push(other); // 换名 arr.map(i => { const r = this.expertList().find(f => f.name === i.name); if (r && r.alias) i.name = r.alias; return i; }); return arr; } /** * 首页数据统计 */ async circle() { const arr = []; const organization = await this.organizationModel.count({ status: '1' }); arr.push({ name: '企业注册数量', value: organization, }); // TODO:如果需要专家和个人用户区分开,则is_expert:false, 混查则不需要is_expert条件 const user = await this.personalModel.count({ status: '1', is_expert: false, }); arr.push({ name: '个人注册数量', value: user, }); const exports = await this.expertModel.count(); arr.push({ name: '专家注册数量', value: exports, }); const products = await this.productModel.count({ status: '2' }); arr.push({ name: '产品发布数量', value: products, }); const surveys = await this.surveyModel.count(); arr.push({ name: '交流互动', value: surveys, }); const trans = await this.tranModel.aggregate([ { $match: { status: { $in: [ '0', '1', '3' ] } } }, { $group: { _id: '$status', value: { $sum: 1 }, }, }, ]); arr.push({ name: '正在洽谈', value: _.get( trans.find(f => f._id === '0'), 'value', 0 ), }); arr.push({ name: '达成意向', value: _.get( trans.find(f => f._id === '1'), 'value', 0 ), }); arr.push({ name: '对接完成', value: _.get( trans.find(f => f._id === '3'), 'value', 0 ), }); return arr; } /** * 专家列表 */ expertList() { return [ { name: '中科院长春光学精密机械与物理研究所', alias: '光机所', sort: 1 }, { name: '中国科学院长春应用化学研究所', alias: '应化所', sort: 2 }, { name: '中国科学院东北地理与农业生态研究所', alias: '地理所', sort: 3 }, { name: '吉林大学', sort: 4 }, { name: '长春工业大学', sort: 5 }, ]; } /** * 专利单位列表 */ patentUnitList() { return [ { name: '吉林大学' }, { name: '长春理工大学' }, { name: '东北电力大学' }, { name: '吉林工程技术师范学院' }, { name: '长春工业大学' }, { name: '北华大学' }, { name: '吉林农业大学' }, { name: '吉林师范大学' }, { name: '长春工程学院' }, { name: '吉林建筑大学' }, { name: '通化师范学院' }, { name: '长春大学' }, { name: '东北师范大学' }, { name: '吉林农业科技学院' }, ]; } // 展会首页统计 async dockIndex({ dock_id }) { // 同时在线人数(伪) let tszx = _.random(100, 1000); if (this.redis) { tszx = (await this.redis.get('login_number')) || tszx; } // 特邀嘉宾 // const tyjb = await this.personalModel.count({ is_expert: true }); const tyjb = 81; console.log(tyjb); // 洽谈合作 达成意向 交易完成 const trans = await this.tranModel.aggregate([ { $match: { status: { $in: [ '0', '1', '3' ] } } }, { $group: { _id: '$status', value: { $sum: 1 }, }, }, ]); const qthz = _.get( trans.find(f => f._id === '0'), 'value', 0 ); const dcyx = _.get( trans.find(f => f._id === '1'), 'value', 0 ); const jywc = _.get( trans.find(f => f._id === '3'), 'value', 0 ); // 参展项目 const res = await this.dockUser .aggregate() .match({ dock_id: ObjectId(dock_id), 'productList.status': '1', }) .unwind('$productList') .group({ _id: '$dock_id', count: { $sum: 1 }, }); const czxm = _.get(res[0], 'count'); const arr = [ { name: '同时在线', num: tszx, unit: '人' }, { name: '特邀嘉宾', num: tyjb, unit: '人' }, { name: '洽谈合作', num: qthz, unit: '项' }, { name: '达成意向', num: dcyx, unit: '项' }, { name: '交易完成', num: jywc, unit: '项' }, { name: '参展项目', num: czxm, unit: '项' }, ]; return arr; } /** * 高企申报, 兑付成功(is_cashing=='1') * 研发补贴/奖励兑现, 兑付成功(is_cashing==='1'),类型要区分 */ async pac() { const gq = await this.ctx.model.Cysci.Declare.count({ is_cashing: '1' }); const yfjl = await this.ctx.model.Cysci.Reward.aggregate([ { $match: { is_cashing: '1' } }, { $group: { _id: '$type', count: { $sum: 1 }, }, }, ]); const arr = [ { key: '奖励兑现', name: '奖励兑现' }, { key: '研发补贴', name: '研发补贴' }, ]; const obj = this.setData(yfjl, arr); obj.push({ name: '高企申报', value: gq }); return obj; } /** * 高企申报个步骤统计 */ async declare() { const res = await this.ctx.model.Cysci.Declare.aggregate([ { $group: { _id: '$status', count: { $sum: 1 }, }, }, ]); const arr = [ { key: '0', name: '企业信息待审中' }, { key: '1', name: '企业信息审核成功' }, { key: '-1', name: '企业信息审核失败' }, { key: '2', name: '高企申报成功' }, { key: '-2', name: '高企申报失败' }, ]; const obj = this.setData(res, arr); return obj; } /** * 安排返回值 * @param {Array} list 数据[{_id,count}] * @param {*} meta 变换成的另一部信息[{key:_id,name:zh}] */ setData(list, meta) { const obj = []; for (const i of meta) { const { key, name } = i; const r = list.find(f => f._id === key); if (r) { obj.push({ name, value: r.count }); } else { obj.push({ name, value: 0 }); } } return obj; } async dockProduct({ skip = 0, limit = 10, ...query } = {}) { const productQuery = {}; const userQuery = {}; for (const key in query) { if (query[key].length > 12) { if (ObjectId.isValid(query[key])) query[key] = ObjectId(query[key]); } if (key.includes('.')) productQuery[key] = query[key]; else userQuery[key] = query[key]; } const publics = [{ $match: userQuery }, { $project: { productList: 1, _id: 0 } }, { $unwind: '$productList' }, { $match: productQuery }]; const data = await this.ctx.model.Dock.DockUser.aggregate([ ...publics, { $skip: parseInt(skip) }, { $limit: parseInt(limit) }]).replaceRoot('productList'); let total = await this.ctx.model.Dock.DockUser.aggregate([ ...publics, { $group: { _id: null, count: { $sum: 1 }, }, }, ]); if (total && _.isArray(total)) { total = _.get(_.head(total), 'count', 0); } return { data, total }; } async patentUserIndex({ id }) { // 审核通知 const patentExamine = this.ctx.model.Patent.Patentexamine; // 未读消息 const unread = await patentExamine.count({ to: id, is_read: false }); // 通知信息 const patentNotice = this.ctx.model.Patent.Patentnotice; const notice = await patentNotice.count({ to_id: { $elemMatch: { $in: [ ObjectId(id) ] } }, is_read: false }); // 专利申请 const papply = this.ctx.model.Patent.Patentapply; const apply = await papply.count({ status: [ '0', '1', '-1', '2', '3', '4', '-4', '5', '-5', '6', '-6', '7' ], user_id: id, }); // 查询检索 const palysis = this.ctx.model.Patent.Patentanalysis; const analysis = await palysis.count({ status: [ '0', '1', '-1', '2' ], user_id: id }); // 价值评估 const paccess = this.ctx.model.Patent.Patentassess; const access = await paccess.count({ status: [ '0', '1', '-1', '2' ], user_id: id }); // 专利信息 const patentInfo = this.ctx.model.Patent.Patentinfo; const information = await patentInfo.count({ user_id: { $elemMatch: { user_id: id } } }); // 专利维权 const patentsafeg = this.ctx.model.Patent.Patentsafeg; const safeg = await patentsafeg.count({ status: [ '0', '1', '2' ], user_id: id }); // 专利预警 const patentEarly = this.ctx.model.Patent.Patentearly; const early = await patentEarly.count({ user_id: { $elemMatch: { $in: [ ObjectId(id) ] } } }); // 专利交易 const patentTrans = this.ctx.model.Patent.Patenttrans; const trans1 = await patentTrans.count({ type: '转让', user_id: id }); const trans2 = await patentTrans.count({ type: '许可', user_id: id }); const trans3 = await patentTrans.count({ type: '免费许可', user_id: id }); const trans4 = await patentTrans.count({ type: '招商', user_id: id }); const trans5 = await patentTrans.count({ type: '质押', user_id: id }); return { message: { unread, notice }, apply: { apply, analysis, access }, patent: { information, safeg, early }, transaction: { trans1, trans2, trans3, trans4, trans5 }, }; } /** * 根据申请人统计,申请人所在的专利信息数量 */ async patentInfoByApplyPerson() { console.time('p1'); const pImodel = this.ctx.model.Patent.Patentinfo; // const data = await pImodel.find({}, { apply_personal: 1 }); const data = await pImodel.aggregate([{ $project: { apply_personal: 1 } }]); if (data.length <= 0) { return '未找到专利信息相关数据'; } let nameList = data.map(i => i.apply_personal).map(i => i.split(';')); nameList = _.uniq(_.flattenDeep(nameList).map(i => _.trim(i))); const arr = []; for (const i of nameList) { const reg = new RegExp(i); const query = { apply_personal: reg }; const res = await pImodel.aggregate([{ $match: query }, { $count: 'id' }]); if (res) { const head = _.head(res); const num = _.get(head, 'id', 0); arr.push({ name: i, num }); } } return arr; } } module.exports = IndexService;