|
@@ -0,0 +1,217 @@
|
|
|
+import { Provide } from '@midwayjs/core';
|
|
|
+import { InjectEntityModel } from '@midwayjs/typeorm';
|
|
|
+import { Repository } from 'typeorm';
|
|
|
+import { Tags } from '../../entity/system/tags.entity';
|
|
|
+import * as Excel from 'exceljs';
|
|
|
+import * as path from 'path';
|
|
|
+import { Region } from '../../entity/system/region.entity';
|
|
|
+import { get, isArray, isObject, omit, uniq, uniqBy } from 'lodash';
|
|
|
+import { Company } from '../../entity/users/company.entity';
|
|
|
+import dayjs = require('dayjs');
|
|
|
+import { Match } from '../../entity/platform/match.entity';
|
|
|
+import { Sign } from '../../entity/platform/sign.entity';
|
|
|
+@Provide()
|
|
|
+export class initThreeService {
|
|
|
+ tags = ['20240802'];
|
|
|
+ @InjectEntityModel(Tags)
|
|
|
+ tagsModel: Repository<Tags>;
|
|
|
+ @InjectEntityModel(Region)
|
|
|
+ regionModel: Repository<Region>;
|
|
|
+ @InjectEntityModel(Company)
|
|
|
+ companyModel: Repository<Company>;
|
|
|
+ @InjectEntityModel(Match)
|
|
|
+ matchModel: Repository<Match>;
|
|
|
+ @InjectEntityModel(Sign)
|
|
|
+ signModel: Repository<Sign>;
|
|
|
+
|
|
|
+ async initData() {}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取excel表头对应的字段
|
|
|
+ * @returns 表格列对应字段对象
|
|
|
+ */
|
|
|
+ companyMeta() {
|
|
|
+ return {
|
|
|
+ 2: 'area1',
|
|
|
+ 3: 'name',
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ async import2021Company() {
|
|
|
+ const p = path.resolve(__dirname, '../../../importData/20240802', '2021-专精特新-企业.xlsx');
|
|
|
+ const tags = [...this.tags, '2021专精特新'];
|
|
|
+ await this.importCompany(p, tags);
|
|
|
+ await this.addTags(tags);
|
|
|
+ }
|
|
|
+
|
|
|
+ async import2024Company() {
|
|
|
+ const p = path.resolve(__dirname, '../../../importData/20240802', '2024-专精特新-企业.xlsx');
|
|
|
+ const tags = [...this.tags, '2024专精特新'];
|
|
|
+ await this.importCompany(p, tags);
|
|
|
+ await this.addTags(tags);
|
|
|
+ }
|
|
|
+
|
|
|
+ async importCompany(path, tags) {
|
|
|
+ const wb = new Excel.Workbook();
|
|
|
+ await wb.xlsx.readFile(path);
|
|
|
+ const sheet = wb.getWorksheet(1);
|
|
|
+ if (!sheet) return;
|
|
|
+ const meta = this.companyMeta();
|
|
|
+ let allData = [];
|
|
|
+ sheet.eachRow((row, ri) => {
|
|
|
+ if (ri === 1) {
|
|
|
+ // 不处理
|
|
|
+ } else {
|
|
|
+ const obj = {};
|
|
|
+ row.eachCell((cell, ci) => {
|
|
|
+ let val = cell.value;
|
|
|
+ const key = meta[ci];
|
|
|
+ if (key) {
|
|
|
+ if (isObject(val)) {
|
|
|
+ if (isArray(get(val, 'richText'))) {
|
|
|
+ let text = '';
|
|
|
+ const richText = get(val, 'richText', []);
|
|
|
+ for (const t of richText) {
|
|
|
+ text = `${text}${get(t, 'text')}`;
|
|
|
+ }
|
|
|
+ val = text;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ obj[key] = val;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ allData.push(obj);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ for (const i of allData) {
|
|
|
+ // 验重,企业是否存在
|
|
|
+ const result = await this.companyModel.createQueryBuilder().where(`name = :name`, { name: i.name }).getOne();
|
|
|
+ if (result) {
|
|
|
+ i.id = get(result, 'id');
|
|
|
+ // 标签合并,之后有id的修改,没id的添加
|
|
|
+ i.tags = get(result, 'tags', []);
|
|
|
+ if (i.tags === null) i.tags = [];
|
|
|
+ i.tags = uniq([...i.tags, ...tags]);
|
|
|
+ // 有地区之后就不需要处理地区了
|
|
|
+ i.area = get(result, 'area', []);
|
|
|
+ if (i.area.length > 0) continue;
|
|
|
+ }
|
|
|
+ // #region 地区处理
|
|
|
+ i.tags = tags;
|
|
|
+ i.area = ['吉林省'];
|
|
|
+ const builder = this.regionModel.createQueryBuilder();
|
|
|
+ builder.where(`name like '%${i.area1}%'`);
|
|
|
+ builder.andWhere("level = 'city'");
|
|
|
+ builder.andWhere("code like '22%'");
|
|
|
+ const r1 = await builder.getOne();
|
|
|
+ if (r1) i.area.push(r1.name);
|
|
|
+ // 延边州和梅河口需要特殊处理
|
|
|
+ if (i.area1.includes('梅河口')) i.area = ['吉林省', '通化市', '梅河口市'];
|
|
|
+ else if (i.area1.includes('延边')) i.area.push('延边朝鲜族自治州');
|
|
|
+ // 地区处理不通过就不进行处理了
|
|
|
+ if (i.area.length > 1) delete i.area1;
|
|
|
+ else i.noarea = true;
|
|
|
+ }
|
|
|
+ allData = allData.filter(f => !f.noarea);
|
|
|
+ const updateList = allData.filter(f => f.id);
|
|
|
+ const insertList = allData.filter(f => !f.id);
|
|
|
+ await this.companyModel.createQueryBuilder().insert().into(Company).values(insertList).execute();
|
|
|
+ for (const i of updateList) {
|
|
|
+ await this.companyModel.createQueryBuilder().update(Company).set(omit(i, 'id')).where(`id = :id`, { id: i.id }).execute();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ matchingMeta() {
|
|
|
+ return {
|
|
|
+ 2: 'name',
|
|
|
+ 3: 'start_time',
|
|
|
+ 4: 'address',
|
|
|
+ 5: 'sign.name',
|
|
|
+ 6: 'sign.unit',
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ async importMatching() {
|
|
|
+ const p = path.resolve(__dirname, '../../../importData/20240802', '赛事信息.xlsx');
|
|
|
+ const wb = new Excel.Workbook();
|
|
|
+ await wb.xlsx.readFile(p);
|
|
|
+ const sheet = wb.getWorksheet(1);
|
|
|
+ if (!sheet) return;
|
|
|
+ // 导入数据分两个表, 培训名称和培训时间(开始时间),培训地点都属于赛事
|
|
|
+ // 培训人姓名和企业名称(隶属单位)都属于参赛人员部分
|
|
|
+ const meta = this.matchingMeta();
|
|
|
+ let allData = [];
|
|
|
+ sheet.eachRow((row, ri) => {
|
|
|
+ if (ri === 1) {
|
|
|
+ // 不处理
|
|
|
+ } else {
|
|
|
+ const obj = {};
|
|
|
+ row.eachCell((cell, ci) => {
|
|
|
+ let val = cell.value;
|
|
|
+ const key = meta[ci];
|
|
|
+ if (key) {
|
|
|
+ if (isObject(val)) {
|
|
|
+ if (isArray(get(val, 'richText'))) {
|
|
|
+ let text = '';
|
|
|
+ const richText = get(val, 'richText', []);
|
|
|
+ for (const t of richText) {
|
|
|
+ text = `${text}${get(t, 'text')}`;
|
|
|
+ }
|
|
|
+ val = text;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ obj[key] = val;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ allData.push(obj);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ let matchList = allData.map(i => ({ ...omit(i, ['sign.name', 'sign.unit', 'start_time']), start_time: dayjs(i.start_time).format('YYYY-MM-DD') }));
|
|
|
+ matchList = uniqBy(matchList, 'name');
|
|
|
+ for (const m of matchList) {
|
|
|
+ const name = get(m, 'name');
|
|
|
+ const match = await this.matchModel.createQueryBuilder().where('name = :name', { name }).getOne();
|
|
|
+ let mid;
|
|
|
+ // 有赛事,就合并标签
|
|
|
+ if (match) {
|
|
|
+ mid = match.id;
|
|
|
+ let otags = get(match, 'tags', []);
|
|
|
+ if (otags === null) otags = [];
|
|
|
+ const newTags = uniq([...otags, ...this.tags]);
|
|
|
+ const updateData: any = { tags: newTags };
|
|
|
+ await this.matchModel.createQueryBuilder().update(Match).set(updateData).where('id = :id', { id: match.id }).execute();
|
|
|
+ } else {
|
|
|
+ const insertData: any = { ...m, tags: this.tags };
|
|
|
+ const result = await this.matchModel.insert(insertData);
|
|
|
+ mid = get(result, 'identifiers.0.id');
|
|
|
+ }
|
|
|
+ // 已经过滤出赛事数据 m 和 参加该赛事的人员名单 signList.接下来先创建赛事数据,然后再将赛事数据id放到各个参赛人员数据中
|
|
|
+ let signList = allData.filter(f => f.name === name);
|
|
|
+ signList = signList.map(i => ({ ...omit(i, ['name', 'address', 'start_time']), match: mid }));
|
|
|
+ for (const i of signList) {
|
|
|
+ const obj = {};
|
|
|
+ for (const key in i) {
|
|
|
+ const val = i[key];
|
|
|
+ if (key.includes('sign.')) {
|
|
|
+ const nk = key.replace('sign.', '');
|
|
|
+ obj[nk] = val;
|
|
|
+ } else obj[key] = val;
|
|
|
+ }
|
|
|
+ const num = await this.signModel.createQueryBuilder().where('name = :name', { name: i.name }).andWhere('match = :match', { match: i.match }).getCount();
|
|
|
+ if (num <= 0) await this.signModel.insert(obj);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ await this.addTags(this.tags)
|
|
|
+ }
|
|
|
+
|
|
|
+ async addTags(tags: Array<string>) {
|
|
|
+ const arr = [];
|
|
|
+ for (const i of tags) {
|
|
|
+ const num = await this.tagsModel.createQueryBuilder().where(`title = :title`, { title: i }).getCount();
|
|
|
+ if (num > 0) continue;
|
|
|
+ arr.push({ title: i });
|
|
|
+ }
|
|
|
+ if (arr.length <= 0) return;
|
|
|
+ await this.tagsModel.createQueryBuilder().insert().into(Tags).values(arr).updateEntity(false).execute();
|
|
|
+ }
|
|
|
+}
|