|
@@ -0,0 +1,246 @@
|
|
|
+import { Inject, Provide } from '@midwayjs/core';
|
|
|
+import { InjectDataSource, InjectEntityModel } from '@midwayjs/typeorm';
|
|
|
+import { Tags } from '../../entity/system/tags.entity';
|
|
|
+import { DataSource, Repository } from 'typeorm';
|
|
|
+import { Demand } from '../../entity/platform/demand.entity';
|
|
|
+import * as Excel from 'exceljs';
|
|
|
+import * as path from 'path';
|
|
|
+import { get, isArray, isObject, isString, replace, trim } from 'lodash';
|
|
|
+import { Support } from '../../entity/platform/support.entity';
|
|
|
+import { ESService } from '../elasticsearch/es.service';
|
|
|
+
|
|
|
+@Provide()
|
|
|
+export class InitFourService {
|
|
|
+ tags = ['20240930'];
|
|
|
+ @InjectEntityModel(Tags)
|
|
|
+ tagsModel: Repository<Tags>;
|
|
|
+ @InjectEntityModel(Demand)
|
|
|
+ demandModel: Repository<Demand>;
|
|
|
+ @InjectEntityModel(Support)
|
|
|
+ supportModel: Repository<Support>;
|
|
|
+ @InjectDataSource('default')
|
|
|
+ defaultDataSource: DataSource;
|
|
|
+ @Inject()
|
|
|
+ esService: ESService;
|
|
|
+ async initData() {
|
|
|
+ await this.addDemand();
|
|
|
+ await this.addSupport();
|
|
|
+ }
|
|
|
+
|
|
|
+ async addSupport() {
|
|
|
+ const p = path.resolve(__dirname, '../../../importData/20240930', '服务支撑数据.xlsx');
|
|
|
+ const wb = new Excel.Workbook();
|
|
|
+ await wb.xlsx.readFile(p);
|
|
|
+ const sheet = wb.getWorksheet('Sheet1');
|
|
|
+ if (!sheet) return;
|
|
|
+ const meta = this.supportMeta();
|
|
|
+ const allData: any = [];
|
|
|
+ sheet.eachRow((row, ri) => {
|
|
|
+ if (ri === 1) {
|
|
|
+ // 不处理
|
|
|
+ } else {
|
|
|
+ const obj = {};
|
|
|
+ row.eachCell((cell, ci) => {
|
|
|
+ const val = this.correctData(cell.value);
|
|
|
+ const key = meta[ci];
|
|
|
+ if (key) obj[key] = val;
|
|
|
+ });
|
|
|
+ allData.push(obj);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ for (const i of allData) {
|
|
|
+ const fiedls = i.field.split(',');
|
|
|
+ i.field = fiedls;
|
|
|
+ }
|
|
|
+ await this.clearTable('support');
|
|
|
+ await this.supportModel.insert(allData);
|
|
|
+ await this.esService.initESOneIndex('support')
|
|
|
+ // return allData;
|
|
|
+ }
|
|
|
+
|
|
|
+ supportMeta() {
|
|
|
+ return {
|
|
|
+ 1: 'name',
|
|
|
+ 2: 'field',
|
|
|
+ 3: 'brief',
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ async addDemand() {
|
|
|
+ const p = path.resolve(__dirname, '../../../importData/20240930', '需求库.xlsx');
|
|
|
+ const wb = new Excel.Workbook();
|
|
|
+ await wb.xlsx.readFile(p);
|
|
|
+ const sheet = wb.getWorksheet('Sheet1');
|
|
|
+ if (!sheet) return;
|
|
|
+ const meta = this.demandMeta();
|
|
|
+ const allData: any = [];
|
|
|
+ sheet.eachRow((row, ri) => {
|
|
|
+ if (ri === 1 || ri === 2) {
|
|
|
+ // 不处理
|
|
|
+ } else {
|
|
|
+ const obj = {};
|
|
|
+ row.eachCell((cell, ci) => {
|
|
|
+ const val = this.correctData(cell.value);
|
|
|
+ const key = meta[ci];
|
|
|
+ if (key) obj[key] = val;
|
|
|
+ });
|
|
|
+ allData.push(obj);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 需要处理area和contacts
|
|
|
+ for (const i of allData) {
|
|
|
+ i.name = trim(i.name);
|
|
|
+ // 处理联系人
|
|
|
+ const { contacts, tel } = this.dealContacts(i.contacts);
|
|
|
+ if (contacts) i.contacts = contacts;
|
|
|
+ if (tel) i.tel = tel;
|
|
|
+ // 处理地区
|
|
|
+ const area = this.dealArea(i.area);
|
|
|
+ if (area) i.area1 = area;
|
|
|
+ }
|
|
|
+
|
|
|
+ // return JSON.stringify(allData, null, 2);
|
|
|
+ await this.clearTable('demand');
|
|
|
+ await this.demandModel.insert(allData)
|
|
|
+ await this.esService.initESOneIndex('demand')
|
|
|
+ }
|
|
|
+
|
|
|
+ demandMeta() {
|
|
|
+ return {
|
|
|
+ 2: 'field',
|
|
|
+ 3: 'area',
|
|
|
+ 4: 'company',
|
|
|
+ 5: 'name',
|
|
|
+ 6: 'brief',
|
|
|
+ 7: 'contacts', //tel
|
|
|
+ 8: 'year',
|
|
|
+ };
|
|
|
+ }
|
|
|
+ // 处理地区
|
|
|
+ dealArea(area) {
|
|
|
+ let correctArea = ['吉林省'];
|
|
|
+ const cityArr = ['长春', '吉林', '通化', '白山', '辽源', '四平', '白城', '松原', '延边州', '延边'];
|
|
|
+ const specialAreaList = [
|
|
|
+ { e: '梅河口', to: ['吉林省', '通化市', '梅河口市'] },
|
|
|
+ { e: '德惠', to: ['吉林省', '长春市', '德惠市'] },
|
|
|
+ { e: '敦化', to: ['吉林省', '延边朝鲜族自治州', '敦化市'] },
|
|
|
+ { e: '延吉', to: ['吉林省', '延边朝鲜族自治州', '延吉市'] },
|
|
|
+ { e: '柳河', to: ['吉林省', '通化市', '柳河县'] },
|
|
|
+ ];
|
|
|
+ const hasSpecial = specialAreaList.find(f => area.includes(f.e));
|
|
|
+ if (hasSpecial) {
|
|
|
+ correctArea = hasSpecial.to;
|
|
|
+ return correctArea;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (const i of cityArr) {
|
|
|
+ if (area.includes(i)) {
|
|
|
+ if (i === '延边州') correctArea.push(`延边朝鲜族自治州`);
|
|
|
+ else correctArea.push(`${i}市`);
|
|
|
+ area = trim(replace(area, i, ' '));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const areaArr = [
|
|
|
+ '五棵树经济开发区',
|
|
|
+ '南关区',
|
|
|
+ '宽城区',
|
|
|
+ '朝阳区',
|
|
|
+ '二道区',
|
|
|
+ '绿园区',
|
|
|
+ '双阳区',
|
|
|
+ '九台区',
|
|
|
+ '公主岭市',
|
|
|
+ '榆树市',
|
|
|
+ '德惠市',
|
|
|
+ '农安县',
|
|
|
+ '昌邑区',
|
|
|
+ '龙潭区',
|
|
|
+ '船营区',
|
|
|
+ '丰满区',
|
|
|
+ '蛟河市',
|
|
|
+ '桦甸市',
|
|
|
+ '舒兰市',
|
|
|
+ '磐石市',
|
|
|
+ '永吉县',
|
|
|
+ '东昌区',
|
|
|
+ '二道江区',
|
|
|
+ '集安市',
|
|
|
+ '梅河口市',
|
|
|
+ '通化县',
|
|
|
+ '辉南县',
|
|
|
+ '柳河县',
|
|
|
+ '浑江区',
|
|
|
+ '江源区',
|
|
|
+ '临江市',
|
|
|
+ '抚松县',
|
|
|
+ '靖宇县',
|
|
|
+ '长白朝鲜族自治县',
|
|
|
+ '龙山区',
|
|
|
+ '西安区',
|
|
|
+ '东丰县',
|
|
|
+ '东辽县',
|
|
|
+ '铁西区',
|
|
|
+ '铁东区',
|
|
|
+ '双辽市',
|
|
|
+ '梨树县',
|
|
|
+ '伊通满族自治县',
|
|
|
+ '洮北区',
|
|
|
+ '洮南市',
|
|
|
+ '大安市',
|
|
|
+ '镇赉县',
|
|
|
+ '通榆县',
|
|
|
+ '宁江区',
|
|
|
+ '扶余市',
|
|
|
+ '长岭县',
|
|
|
+ '乾安县',
|
|
|
+ '前郭尔罗斯蒙古族自治县',
|
|
|
+ '延吉市',
|
|
|
+ '图们市',
|
|
|
+ '敦化市',
|
|
|
+ '珲春市',
|
|
|
+ '龙井市',
|
|
|
+ '和龙市',
|
|
|
+ '汪清县',
|
|
|
+ '安图县',
|
|
|
+ ];
|
|
|
+ if (area && area !== '') {
|
|
|
+ const nextLevel = areaArr.find(f => f.includes(area));
|
|
|
+ if (nextLevel) correctArea.push(nextLevel);
|
|
|
+ }
|
|
|
+ return correctArea;
|
|
|
+ }
|
|
|
+ // 处理联系人
|
|
|
+ dealContacts(contacts) {
|
|
|
+ const obj: any = {};
|
|
|
+ const strReg = /([\u4e00-\u9fa5]{3}|[\u4e00-\u9fa5]{2})/g;
|
|
|
+ const strRes = contacts.match(strReg);
|
|
|
+ let numRes = contacts.replace(strReg, '');
|
|
|
+ while (numRes.includes('\n')) numRes = numRes.replace('\n', ' ');
|
|
|
+ numRes = trim(numRes);
|
|
|
+ if (isArray(strRes)) obj['contacts'] = strRes.join(';');
|
|
|
+ if (isArray(numRes)) obj['tel'] = numRes.join(';');
|
|
|
+ else if (isString(numRes)) obj['tel'] = numRes;
|
|
|
+ return obj;
|
|
|
+ }
|
|
|
+ correctData(data) {
|
|
|
+ if (!data) return data;
|
|
|
+ if (isString(data) && data.includes('richText')) {
|
|
|
+ const obj = JSON.parse(data);
|
|
|
+ const str = obj.richText.reduce((p, n) => `${p}${n.text}`, '');
|
|
|
+ return str;
|
|
|
+ } else if (isObject(data)) {
|
|
|
+ return get(data, 'text');
|
|
|
+ }
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 清空表与id序列
|
|
|
+ * @param tableName 表名 小驼峰
|
|
|
+ */
|
|
|
+ private async clearTable(tableName: string) {
|
|
|
+ await this.defaultDataSource.query(`TRUNCATE TABLE "public"."${tableName}" RESTART IDENTITY RESTRICT;`);
|
|
|
+ await this.defaultDataSource.query(`SELECT setval('"${tableName}_id_seq"', (SELECT max(id) FROM "${tableName}"));`);
|
|
|
+ }
|
|
|
+}
|