|
@@ -1,11 +1,11 @@
|
|
|
import { Inject, Provide, Config } from '@midwayjs/core';
|
|
|
-import { get } from 'lodash';
|
|
|
+import { get, uniq } from 'lodash';
|
|
|
import { Context } from '@midwayjs/koa';
|
|
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
|
|
import { ServiceError, ErrorCode } from '../error/service.error';
|
|
|
import dayjs = require('dayjs');
|
|
|
import { DictDataService } from './system/dictData.service';
|
|
|
-import { Equal, Repository } from 'typeorm';
|
|
|
+import { Equal, Repository, IsNull } from 'typeorm';
|
|
|
import { Achievement } from '../entity/platform/achievement.entity';
|
|
|
import { Company } from '../entity/users/company.entity';
|
|
|
import { Supply } from '../entity/platform/supply.entity';
|
|
@@ -18,6 +18,10 @@ import * as Path from 'path';
|
|
|
import * as fs from 'fs';
|
|
|
import { User } from '../entity/system/user.entity';
|
|
|
import { CompanyYear } from '../entity/users/companyYear.entity';
|
|
|
+import { Expert } from '../entity/users/expert.entity';
|
|
|
+import { RoleService } from './system/role.service';
|
|
|
+import { Incubator } from '../entity/users/incubator.entity';
|
|
|
+import { SectorService } from './platform/sector.service';
|
|
|
/**
|
|
|
* 工具类服务,为其他地方提供一些通用的函数
|
|
|
*/
|
|
@@ -27,7 +31,6 @@ export class UtilService {
|
|
|
ctx: Context;
|
|
|
@Inject()
|
|
|
userService: UserService;
|
|
|
-
|
|
|
@InjectEntityModel(User)
|
|
|
userModel: Repository<User>;
|
|
|
@InjectEntityModel(Achievement)
|
|
@@ -40,14 +43,722 @@ export class UtilService {
|
|
|
supplyModel: Repository<Supply>;
|
|
|
@InjectEntityModel(Company)
|
|
|
companyModel: Repository<Company>;
|
|
|
+ @InjectEntityModel(Expert)
|
|
|
+ expertModel: Repository<Expert>;
|
|
|
+ @InjectEntityModel(Incubator)
|
|
|
+ incubatorModel: Repository<Incubator>;
|
|
|
@InjectEntityModel(CompanyYear)
|
|
|
yModel: Repository<CompanyYear>;
|
|
|
@Inject()
|
|
|
dictDataService: DictDataService;
|
|
|
+ @Inject()
|
|
|
+ sectorService: SectorService;
|
|
|
+ @Inject()
|
|
|
+ roleService: RoleService;
|
|
|
|
|
|
@Config('PathConfig.path')
|
|
|
path;
|
|
|
|
|
|
+ // 管理端数据看板
|
|
|
+ async oneStatistics(type) {
|
|
|
+ let list = [];
|
|
|
+ // 企业统计数量
|
|
|
+ if (type === 'company') {
|
|
|
+ list = [
|
|
|
+ { name: '企业总数', data: [], percentage: 1 },
|
|
|
+ { name: '高新技术企业', data: [], percentage: 1 },
|
|
|
+ { name: '专精特新企业', data: [], percentage: 1 },
|
|
|
+ { name: '审核成功', data: [], percentage: 1 },
|
|
|
+ ];
|
|
|
+ for (const [index, val] of list.entries()) {
|
|
|
+ let count = 0;
|
|
|
+ if (index === 0) {
|
|
|
+ count = await this.companyModel.count();
|
|
|
+ val.data.push(count);
|
|
|
+ } else if (index === 1) {
|
|
|
+ count = await this.companyModel.count({ where: { is_tech: '0' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.companyModel.count());
|
|
|
+ } else if (index === 2) {
|
|
|
+ count = await this.companyModel.count({ where: { is_new: '0' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.companyModel.count());
|
|
|
+ } else {
|
|
|
+ count = await this.companyModel.count({ where: { status: '1' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.companyModel.count());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 专家统计数量
|
|
|
+ if (type === 'expert') {
|
|
|
+ list = [
|
|
|
+ { name: '专家总数', data: [], percentage: 1 },
|
|
|
+ { name: '高校、科研院所类', data: [], percentage: 1 },
|
|
|
+ { name: '企业类', data: [], percentage: 1 },
|
|
|
+ { name: '审核成功', data: [], percentage: 1 },
|
|
|
+ ];
|
|
|
+ for (const [index, val] of list.entries()) {
|
|
|
+ let count = 0;
|
|
|
+ if (index === 0) {
|
|
|
+ count = await this.expertModel.count();
|
|
|
+ val.data.push(count);
|
|
|
+ } else if (index === 1) {
|
|
|
+ count = await this.expertModel.count({ where: { work_type: '高校、科研院所' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.expertModel.count());
|
|
|
+ } else if (index === 2) {
|
|
|
+ count = await this.expertModel.count({ where: { work_type: '企业' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.expertModel.count());
|
|
|
+ } else {
|
|
|
+ count = await this.expertModel.count({ where: { status: '1' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.expertModel.count());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 需求统计数量
|
|
|
+ if (type === 'demand') {
|
|
|
+ list = [
|
|
|
+ { name: '需求总数', data: [], percentage: 1 },
|
|
|
+ { name: '没有联系方式', data: [], percentage: 1 },
|
|
|
+ { name: '是否公开', data: [], percentage: 1 },
|
|
|
+ { name: '审核成功', data: [], percentage: 1 },
|
|
|
+ ];
|
|
|
+ for (const [index, val] of list.entries()) {
|
|
|
+ let count = 0;
|
|
|
+ if (index === 0) {
|
|
|
+ count = await this.demandModel.count();
|
|
|
+ val.data.push(count);
|
|
|
+ } else if (index === 1) {
|
|
|
+ count = await this.demandModel.count({ where: { tel: IsNull() } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.demandModel.count());
|
|
|
+ } else if (index === 2) {
|
|
|
+ count = await this.demandModel.count({ where: { is_use: '0' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.demandModel.count());
|
|
|
+ } else {
|
|
|
+ count = await this.demandModel.count({ where: { status: '1' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.demandModel.count());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 供给统计数量
|
|
|
+ if (type === 'supply') {
|
|
|
+ list = [
|
|
|
+ { name: '供给总数', data: [], percentage: 1 },
|
|
|
+ { name: '没有价格', data: [], percentage: 1 },
|
|
|
+ { name: '是否公开', data: [], percentage: 1 },
|
|
|
+ { name: '审核成功', data: [], percentage: 1 },
|
|
|
+ ];
|
|
|
+ for (const [index, val] of list.entries()) {
|
|
|
+ let count = 0;
|
|
|
+ if (index === 0) {
|
|
|
+ count = await this.supplyModel.count();
|
|
|
+ val.data.push(count);
|
|
|
+ } else if (index === 1) {
|
|
|
+ count = await this.supplyModel.count({ where: { money: IsNull() } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.supplyModel.count());
|
|
|
+ } else if (index === 2) {
|
|
|
+ count = await this.supplyModel.count({ where: { is_use: '0' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.supplyModel.count());
|
|
|
+ } else {
|
|
|
+ count = await this.supplyModel.count({ where: { status: '1' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.supplyModel.count());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 成果统计数量
|
|
|
+ if (type === 'achievement') {
|
|
|
+ list = [
|
|
|
+ { name: '成果总数', data: [], percentage: 1 },
|
|
|
+ { name: '没有联系方式', data: [], percentage: 1 },
|
|
|
+ { name: '是否公开', data: [], percentage: 1 },
|
|
|
+ { name: '审核成功', data: [], percentage: 1 },
|
|
|
+ ];
|
|
|
+ for (const [index, val] of list.entries()) {
|
|
|
+ let count = 0;
|
|
|
+ if (index === 0) {
|
|
|
+ count = await this.achievementModel.count();
|
|
|
+ val.data.push(count);
|
|
|
+ } else if (index === 1) {
|
|
|
+ count = await this.achievementModel.count({ where: { tel: IsNull() } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.achievementModel.count());
|
|
|
+ } else if (index === 2) {
|
|
|
+ count = await this.achievementModel.count({ where: { is_use: '0' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.achievementModel.count());
|
|
|
+ } else {
|
|
|
+ count = await this.achievementModel.count({ where: { status: '1' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.achievementModel.count());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 项目统计数量
|
|
|
+ if (type === 'project') {
|
|
|
+ list = [
|
|
|
+ { name: '项目总数', data: [], percentage: 1 },
|
|
|
+ { name: '工研院跟踪单位', data: [], percentage: 1 },
|
|
|
+ { name: '是否公开', data: [], percentage: 1 },
|
|
|
+ { name: '审核成功', data: [], percentage: 1 },
|
|
|
+ ];
|
|
|
+ for (const [index, val] of list.entries()) {
|
|
|
+ let count = 0;
|
|
|
+ if (index === 0) {
|
|
|
+ count = await this.projectModel.count();
|
|
|
+ val.data.push(count);
|
|
|
+ } else if (index === 1) {
|
|
|
+ count = await this.projectModel.count({ where: { track_unit: '工研院' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.projectModel.count());
|
|
|
+ } else if (index === 2) {
|
|
|
+ count = await this.projectModel.count({ where: { is_use: '0' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.projectModel.count());
|
|
|
+ } else {
|
|
|
+ count = await this.projectModel.count({ where: { status: '1' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.projectModel.count());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //孵化器统计数量
|
|
|
+ if (type === 'incubate') {
|
|
|
+ list = [
|
|
|
+ { name: '孵化基地总数', data: [], percentage: 1 },
|
|
|
+ { name: '是否具备中试场地', data: [], percentage: 1 },
|
|
|
+ { name: '是否和平台合作标识', data: [], percentage: 1 },
|
|
|
+ { name: '审核成功', data: [], percentage: 1 },
|
|
|
+ ];
|
|
|
+ for (const [index, val] of list.entries()) {
|
|
|
+ let count = 0;
|
|
|
+ if (index === 0) {
|
|
|
+ count = await this.incubatorModel.count();
|
|
|
+ val.data.push(count);
|
|
|
+ } else if (index === 1) {
|
|
|
+ count = await this.incubatorModel.count({ where: { is_have: '0' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.incubatorModel.count());
|
|
|
+ } else if (index === 2) {
|
|
|
+ count = await this.incubatorModel.count({ where: { cooperate: '0' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.incubatorModel.count());
|
|
|
+ } else {
|
|
|
+ count = await this.incubatorModel.count({ where: { status: '1' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.incubatorModel.count());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 用户统计数量
|
|
|
+ if (type === 'user') {
|
|
|
+ list = [
|
|
|
+ { name: '用户总数', data: [], percentage: 1 },
|
|
|
+ { name: '未微信绑定', data: [], percentage: 1 },
|
|
|
+ { name: '未选所属产业', data: [], percentage: 1 },
|
|
|
+ { name: '审核成功', data: [], percentage: 1 },
|
|
|
+ ];
|
|
|
+ for (const [index, val] of list.entries()) {
|
|
|
+ let count = 0;
|
|
|
+ if (index === 0) {
|
|
|
+ count = await this.userModel.count();
|
|
|
+ val.data.push(count);
|
|
|
+ } else if (index === 1) {
|
|
|
+ count = await this.userModel.count({ where: { openid: IsNull() } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.userModel.count());
|
|
|
+ } else if (index === 2) {
|
|
|
+ count = await this.userModel.count({ where: { industry: IsNull() } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.userModel.count());
|
|
|
+ } else {
|
|
|
+ count = await this.userModel.count({ where: { status: '1' } });
|
|
|
+ val.data.push(count);
|
|
|
+ val.percentage = await this.calculatePercentage(count, await this.userModel.count());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ async twoStatistics(type) {
|
|
|
+ let res;
|
|
|
+ let req;
|
|
|
+ const nameList = [];
|
|
|
+ const list = [];
|
|
|
+ // 企业按规模统计
|
|
|
+ if (type === 'company') {
|
|
|
+ res = await this.companyModel.createQueryBuilder('company').select('company.pattern', 'pattern').addSelect('COUNT(company.id)', 'total').groupBy('company.pattern').getRawMany();
|
|
|
+ req = await this.dictDataService.query({ code: 'companyType', is_use: '0' }, {});
|
|
|
+ if (req.data) {
|
|
|
+ for (const val of req.data) {
|
|
|
+ nameList.push(val.label);
|
|
|
+ const select = res.find(f => f.pattern === val.value);
|
|
|
+ if (select) list.push(select.total);
|
|
|
+ else list.push(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 专家按职称统计
|
|
|
+ if (type === 'expert') {
|
|
|
+ res = await this.expertModel.createQueryBuilder('expert').select('expert.title', 'title').addSelect('COUNT(expert.id)', 'total').groupBy('expert.title').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ nameList.push(val.title);
|
|
|
+ list.push(val.total);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 需求按行业领域统计
|
|
|
+ if (type === 'demand') {
|
|
|
+ res = await this.demandModel.createQueryBuilder('demand').select('demand.field', 'field').addSelect('COUNT(demand.id)', 'total').groupBy('demand.field').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.field) {
|
|
|
+ nameList.push(val.field);
|
|
|
+ list.push(val.total);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 供给按行业领域统计
|
|
|
+ if (type === 'supply') {
|
|
|
+ res = await this.supplyModel.createQueryBuilder('supply').select('supply.field', 'field').addSelect('COUNT(supply.id)', 'total').groupBy('supply.field').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.field) {
|
|
|
+ nameList.push(val.field);
|
|
|
+ list.push(val.total);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 项目按来源统计
|
|
|
+ if (type === 'project') {
|
|
|
+ res = await this.projectModel.createQueryBuilder('project').select('project.source', 'source').addSelect('COUNT(project.id)', 'total').groupBy('project.source').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.source) {
|
|
|
+ nameList.push(val.source);
|
|
|
+ list.push(val.total);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 成果按来源统计
|
|
|
+ if (type === 'achievement') {
|
|
|
+ res = await this.achievementModel.createQueryBuilder('achievement').select('achievement.source', 'source').addSelect('COUNT(achievement.id)', 'total').groupBy('achievement.source').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.source) {
|
|
|
+ nameList.push(val.source);
|
|
|
+ list.push(val.total);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //孵化器入驻数量
|
|
|
+ if (type === 'incubate') {
|
|
|
+ res = await this.incubatorModel.createQueryBuilder('incubator').getMany();
|
|
|
+ for (const val of res) {
|
|
|
+ nameList.push(val.name);
|
|
|
+ list.push(parseInt(val.company_num || 0));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //用户所属产业包含总数
|
|
|
+ if (type === 'user') {
|
|
|
+ req = await this.sectorService.query({ is_use: '0' }, {});
|
|
|
+ if (req.data) {
|
|
|
+ for (const val of req.data) {
|
|
|
+ const total = await this.userModel
|
|
|
+ .createQueryBuilder()
|
|
|
+ .where('industry IS NOT NULL') // 确保username字段不为空
|
|
|
+ .andWhere('JSONB_EXISTS(industry, :column)', { column: val.title }) // 使用数组作为查询条件
|
|
|
+ .getCount(); // 获取总数
|
|
|
+ nameList.push(val.title);
|
|
|
+ list.push({ name: val.title, value: total || 0 });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return { nameList, list };
|
|
|
+ }
|
|
|
+
|
|
|
+ async thrStatistics(type) {
|
|
|
+ let nameList = [];
|
|
|
+ let list = [];
|
|
|
+ let res;
|
|
|
+ let req;
|
|
|
+ // 企业行业领域统计
|
|
|
+ if (type === 'company') {
|
|
|
+ res = await this.companyModel.createQueryBuilder('company').select('company.type', 'type').addSelect('COUNT(company.id)', 'total').groupBy('company.type').getRawMany();
|
|
|
+ req = await this.dictDataService.query({ code: 'companyIndustry', is_use: '0' }, {});
|
|
|
+ for (const val of res) {
|
|
|
+ if (req.data) {
|
|
|
+ const select = req.data.find(f => f.value === val.type);
|
|
|
+ if (select) {
|
|
|
+ nameList.push(select.label);
|
|
|
+ list.push({ name: select.label, value: val.total });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 专家行业领域统计
|
|
|
+ if (type === 'expert') {
|
|
|
+ res = await this.expertModel.createQueryBuilder('expert').select('expert.industry_type', 'industry_type').addSelect('COUNT(expert.id)', 'total').groupBy('expert.industry_type').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.industry_type) {
|
|
|
+ nameList.push(val.industry_type);
|
|
|
+ list.push({ name: val.industry_type, value: val.total });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 需求所属产业统计
|
|
|
+ if (type === 'demand') {
|
|
|
+ res = await this.demandModel.createQueryBuilder('demand').select('demand.industry', 'industry').addSelect('COUNT(demand.id)', 'total').groupBy('demand.industry').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.industry) {
|
|
|
+ nameList.push(val.industry);
|
|
|
+ list.push({ name: val.industry, value: val.total });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 供给所属产业统计
|
|
|
+ if (type === 'supply') {
|
|
|
+ res = await this.supplyModel.createQueryBuilder('supply').select('supply.industry', 'industry').addSelect('COUNT(supply.id)', 'total').groupBy('supply.industry').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.industry) {
|
|
|
+ nameList.push(val.industry);
|
|
|
+ list.push({ name: val.industry, value: val.total });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 项目项目进展统计
|
|
|
+ if (type === 'project') {
|
|
|
+ res = await this.projectModel.createQueryBuilder('project').select('project.progress', 'progress').addSelect('COUNT(project.id)', 'total').groupBy('project.progress').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.progress) {
|
|
|
+ nameList.push(val.progress);
|
|
|
+ list.push({ name: val.progress, value: val.total });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 成果行业领域统计
|
|
|
+ if (type === 'achievement') {
|
|
|
+ res = await this.achievementModel.createQueryBuilder('achievement').select('achievement.field', 'field').addSelect('COUNT(achievement.id)', 'total').groupBy('achievement.field').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.field) {
|
|
|
+ nameList.push(val.field);
|
|
|
+ list.push({ name: val.field, value: val.total });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 孵化器市级以上活动数统计数量
|
|
|
+ if (type === 'incubate') {
|
|
|
+ res = await this.incubatorModel.createQueryBuilder('incubator').getMany();
|
|
|
+ for (const val of res) {
|
|
|
+ nameList.push(val.name);
|
|
|
+ list.push({ name: val.name, value: parseInt(val.actCity_num) || 0 });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 用户角色统计
|
|
|
+ if (type === 'user') {
|
|
|
+ res = await this.userModel.createQueryBuilder('expert').select('expert.role', 'role').addSelect('COUNT(expert.id)', 'total').groupBy('expert.role').getRawMany();
|
|
|
+ req = await this.roleService.query({ is_use: '0' }, {});
|
|
|
+ for (const val of res) {
|
|
|
+ if (req.data) {
|
|
|
+ for (const ass of val.role) {
|
|
|
+ if (ass !== 'User') {
|
|
|
+ const select = req.data.find(f => f.code === ass);
|
|
|
+ if (select) {
|
|
|
+ nameList.push(select.name);
|
|
|
+ list.push({ name: select.name, value: parseInt(val.total) });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ nameList = uniq(nameList);
|
|
|
+ list = list.reduce((acc, obj) => {
|
|
|
+ const existingObj = acc.find(item => item.name === obj.name);
|
|
|
+ if (existingObj) {
|
|
|
+ existingObj.value += obj.value;
|
|
|
+ } else {
|
|
|
+ acc.push({ ...obj });
|
|
|
+ }
|
|
|
+ return acc;
|
|
|
+ }, []);
|
|
|
+ }
|
|
|
+ return { nameList, list };
|
|
|
+ }
|
|
|
+
|
|
|
+ async fourStatistics(type) {
|
|
|
+ let list = [];
|
|
|
+ let res;
|
|
|
+ // 企业地区分布
|
|
|
+ if (type === 'company') {
|
|
|
+ res = await this.companyModel.createQueryBuilder('company').select('company.area', 'area').addSelect('COUNT(company.id)', 'total').groupBy('company.area').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.area && val.area.length > 1) {
|
|
|
+ const area = val.area[1];
|
|
|
+ list.push({ name: area, value: parseInt(val.total) });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ list = list.reduce((acc, obj) => {
|
|
|
+ const existingObj = acc.find(item => item.name === obj.name);
|
|
|
+ if (existingObj) {
|
|
|
+ existingObj.value += obj.value;
|
|
|
+ } else {
|
|
|
+ acc.push({ ...obj });
|
|
|
+ }
|
|
|
+ return acc;
|
|
|
+ }, []);
|
|
|
+ }
|
|
|
+ // 专家地区分布
|
|
|
+ if (type === 'expert') {
|
|
|
+ res = await this.expertModel.createQueryBuilder('expert').select('expert.area', 'area').addSelect('COUNT(expert.id)', 'total').groupBy('expert.area').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.area && val.area.length > 1) {
|
|
|
+ const area = val.area[1];
|
|
|
+ list.push({ name: area, value: parseInt(val.total) });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ list = list.reduce((acc, obj) => {
|
|
|
+ const existingObj = acc.find(item => item.name === obj.name);
|
|
|
+ if (existingObj) {
|
|
|
+ existingObj.value += obj.value;
|
|
|
+ } else {
|
|
|
+ acc.push({ ...obj });
|
|
|
+ }
|
|
|
+ return acc;
|
|
|
+ }, []);
|
|
|
+ }
|
|
|
+ // 需求地区分布
|
|
|
+ if (type === 'demand') {
|
|
|
+ res = await this.demandModel.createQueryBuilder('demand').select('demand.area', 'area').addSelect('COUNT(demand.id)', 'total').groupBy('demand.area').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.area && val.area.length > 1) {
|
|
|
+ const area = val.area[1];
|
|
|
+ list.push({ name: area, value: parseInt(val.total) });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ list = list.reduce((acc, obj) => {
|
|
|
+ const existingObj = acc.find(item => item.name === obj.name);
|
|
|
+ if (existingObj) {
|
|
|
+ existingObj.value += obj.value;
|
|
|
+ } else {
|
|
|
+ acc.push({ ...obj });
|
|
|
+ }
|
|
|
+ return acc;
|
|
|
+ }, []);
|
|
|
+ }
|
|
|
+ // 供给地区分布
|
|
|
+ if (type === 'supply') {
|
|
|
+ res = await this.supplyModel.createQueryBuilder('supply').select('supply.area', 'area').addSelect('COUNT(supply.id)', 'total').groupBy('supply.area').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.area && val.area.length > 1) {
|
|
|
+ const area = val.area[1];
|
|
|
+ list.push({ name: area, value: parseInt(val.total) });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ list = list.reduce((acc, obj) => {
|
|
|
+ const existingObj = acc.find(item => item.name === obj.name);
|
|
|
+ if (existingObj) {
|
|
|
+ existingObj.value += obj.value;
|
|
|
+ } else {
|
|
|
+ acc.push({ ...obj });
|
|
|
+ }
|
|
|
+ return acc;
|
|
|
+ }, []);
|
|
|
+ }
|
|
|
+ // 成果地区分布
|
|
|
+ if (type === 'achievement') {
|
|
|
+ res = await this.achievementModel.createQueryBuilder('achievement').select('achievement.area', 'area').addSelect('COUNT(achievement.id)', 'total').groupBy('achievement.area').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.area && val.area.length > 1) {
|
|
|
+ const area = val.area[1];
|
|
|
+ list.push({ name: area, value: parseInt(val.total) });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ list = list.reduce((acc, obj) => {
|
|
|
+ const existingObj = acc.find(item => item.name === obj.name);
|
|
|
+ if (existingObj) {
|
|
|
+ existingObj.value += obj.value;
|
|
|
+ } else {
|
|
|
+ acc.push({ ...obj });
|
|
|
+ }
|
|
|
+ return acc;
|
|
|
+ }, []);
|
|
|
+ }
|
|
|
+ // 项目地区分布
|
|
|
+ if (type === 'project') {
|
|
|
+ res = await this.projectModel.createQueryBuilder('project').select('project.area', 'area').addSelect('COUNT(project.id)', 'total').groupBy('project.area').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.area && val.area.length > 1) {
|
|
|
+ const area = val.area[1];
|
|
|
+ list.push({ name: area, value: parseInt(val.total) });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ list = list.reduce((acc, obj) => {
|
|
|
+ const existingObj = acc.find(item => item.name === obj.name);
|
|
|
+ if (existingObj) {
|
|
|
+ existingObj.value += obj.value;
|
|
|
+ } else {
|
|
|
+ acc.push({ ...obj });
|
|
|
+ }
|
|
|
+ return acc;
|
|
|
+ }, []);
|
|
|
+ }
|
|
|
+ // 孵化基地地区分布
|
|
|
+ if (type === 'incubate') {
|
|
|
+ res = await this.incubatorModel.createQueryBuilder('incubator').select('incubator.area', 'area').addSelect('COUNT(incubator.id)', 'total').groupBy('incubator.area').getRawMany();
|
|
|
+ for (const val of res) {
|
|
|
+ if (val.area && val.area.length > 1) {
|
|
|
+ const area = val.area[1];
|
|
|
+ list.push({ name: area, value: parseInt(val.total) });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ list = list.reduce((acc, obj) => {
|
|
|
+ const existingObj = acc.find(item => item.name === obj.name);
|
|
|
+ if (existingObj) {
|
|
|
+ existingObj.value += obj.value;
|
|
|
+ } else {
|
|
|
+ acc.push({ ...obj });
|
|
|
+ }
|
|
|
+ return acc;
|
|
|
+ }, []);
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ async fiveStatistics(type) {
|
|
|
+ let res;
|
|
|
+ let req;
|
|
|
+ const nameList = [];
|
|
|
+ const list = [];
|
|
|
+ //用户所属产业包含总数
|
|
|
+ if (type === 'user') {
|
|
|
+ req = await this.sectorService.query({ is_use: '0' }, {});
|
|
|
+ if (req.data) {
|
|
|
+ for (const val of req.data) {
|
|
|
+ const total = await this.userModel
|
|
|
+ .createQueryBuilder()
|
|
|
+ .where('industry IS NOT NULL') // 确保username字段不为空
|
|
|
+ .andWhere('JSONB_EXISTS(industry, :column)', { column: val.title }) // 使用数组作为查询条件
|
|
|
+ .getCount(); // 获取总数
|
|
|
+ nameList.push(val.title);
|
|
|
+ list.push({ name: val.title, value: total || 0 });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return { nameList, list };
|
|
|
+ }
|
|
|
+
|
|
|
+ async sixStatistics(type) {
|
|
|
+ let res;
|
|
|
+ let req;
|
|
|
+ const nameList = [];
|
|
|
+ const list = [];
|
|
|
+ let max = [];
|
|
|
+ // 企业按员工人数排序取前8个企业
|
|
|
+ if (type === 'company') {
|
|
|
+ res = await this.companyModel.createQueryBuilder('company').orderBy('company.person', 'DESC').limit(8).getMany();
|
|
|
+ for (const val of res) {
|
|
|
+ nameList.push(val.name);
|
|
|
+ list.push(parseInt(val.person || 0));
|
|
|
+ }
|
|
|
+ max = [1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000];
|
|
|
+ }
|
|
|
+ // 专家按职称统计
|
|
|
+ if (type === 'expert') {
|
|
|
+ res = await this.expertModel.createQueryBuilder('expert').select('expert.title', 'title').addSelect('COUNT(expert.id)', 'total').groupBy('expert.title').getRawMany();
|
|
|
+ res.sort((a, b) => b.total - a.total);
|
|
|
+ for (const val of res.slice(0, 9)) {
|
|
|
+ nameList.push(val.title);
|
|
|
+ list.push(parseInt(val.total || 0));
|
|
|
+ }
|
|
|
+ max = [50, 50, 50, 50, 50, 50, 50, 50];
|
|
|
+ }
|
|
|
+ // 需求按行业领域统计
|
|
|
+ if (type === 'demand') {
|
|
|
+ res = await this.demandModel.createQueryBuilder('demand').select('demand.field', 'field').addSelect('COUNT(demand.id)', 'total').groupBy('demand.field').getRawMany();
|
|
|
+ res.sort((a, b) => b.total - a.total);
|
|
|
+ for (const val of res.slice(0, 9)) {
|
|
|
+ if (val.field) {
|
|
|
+ nameList.push(val.field);
|
|
|
+ list.push({ name: val.field, value: val.total });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ max = [100, 100, 100, 100, 100, 100, 100, 100];
|
|
|
+ }
|
|
|
+ // 供给按行业领域统计
|
|
|
+ if (type === 'supply') {
|
|
|
+ res = await this.supplyModel.createQueryBuilder('supply').select('supply.field', 'field').addSelect('COUNT(supply.id)', 'total').groupBy('supply.field').getRawMany();
|
|
|
+ res.sort((a, b) => b.total - a.total);
|
|
|
+ for (const val of res.slice(0, 9)) {
|
|
|
+ if (val.field) {
|
|
|
+ nameList.push(val.field);
|
|
|
+ list.push({ name: val.field, value: val.total });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ max = [100, 100, 100, 100, 100, 100, 100, 100];
|
|
|
+ }
|
|
|
+ // 项目按来源统计
|
|
|
+ if (type === 'project') {
|
|
|
+ res = await this.projectModel.createQueryBuilder('project').select('project.source', 'source').addSelect('COUNT(project.id)', 'total').groupBy('project.source').getRawMany();
|
|
|
+ res.sort((a, b) => b.total - a.total);
|
|
|
+ for (const val of res.slice(0, 9)) {
|
|
|
+ if (val.source) {
|
|
|
+ nameList.push(val.source);
|
|
|
+ list.push({ name: val.source, value: val.total });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ max = [100, 100, 100, 100, 100, 100, 100, 100];
|
|
|
+ }
|
|
|
+ // 成果按来源统计
|
|
|
+ if (type === 'achievement') {
|
|
|
+ res = await this.achievementModel.createQueryBuilder('achievement').select('achievement.source', 'source').addSelect('COUNT(achievement.id)', 'total').groupBy('achievement.source').getRawMany();
|
|
|
+ res.sort((a, b) => b.total - a.total);
|
|
|
+ for (const val of res.slice(0, 9)) {
|
|
|
+ if (val.source) {
|
|
|
+ nameList.push(val.source);
|
|
|
+ list.push({ name: val.source, value: val.total });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ max = [100, 100, 100, 100, 100, 100, 100, 100];
|
|
|
+ }
|
|
|
+ //孵化器省级以上导师数排名
|
|
|
+ if (type === 'incubate') {
|
|
|
+ res = await this.incubatorModel.createQueryBuilder('incubator').getMany();
|
|
|
+ for (const val of res) {
|
|
|
+ nameList.push(val.name);
|
|
|
+ list.push({ name: val.name, value: parseInt(val.teacher_num) });
|
|
|
+ }
|
|
|
+ list.sort((a, b) => b.value - a.value);
|
|
|
+ max = [100, 100, 100, 100, 100, 100, 100, 100];
|
|
|
+ }
|
|
|
+ //用户男女比例排名
|
|
|
+ if (type === 'user') {
|
|
|
+ res = await this.userModel.createQueryBuilder('user').select('user.gender', 'gender').addSelect('COUNT(user.id)', 'total').groupBy('user.gender').getRawMany();
|
|
|
+ req = await this.dictDataService.query({ code: 'gender', is_use: '0' }, {});
|
|
|
+ res.sort((a, b) => b.total - a.total);
|
|
|
+ for (const val of res) {
|
|
|
+ if (req.data) {
|
|
|
+ const select = req.data.find(f => f.value === val.gender);
|
|
|
+ if (select) {
|
|
|
+ nameList.push(select.label);
|
|
|
+ list.push({ name: select.label, value: val.total });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ max = [100, 100, 100, 100, 100, 100, 100, 100];
|
|
|
+ }
|
|
|
+ return { nameList, list, max };
|
|
|
+ }
|
|
|
+ // 计算百分比
|
|
|
+ calculatePercentage(numerator, denominator) {
|
|
|
+ if (denominator === 0 || isNaN(numerator) || isNaN(denominator)) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return (numerator / denominator).toFixed(1);
|
|
|
+ }
|
|
|
// 统计总数
|
|
|
async toTotal() {
|
|
|
const companyTotal = await this.companyModel.count();
|