瀏覽代碼

导入数据

lrf 10 月之前
父節點
當前提交
dd772abb46

File diff suppressed because it is too large
+ 1313 - 37
package-lock.json


+ 1 - 0
package.json

@@ -17,6 +17,7 @@
     "bcryptjs": "^2.4.3",
     "crypto-js": "^4.2.0",
     "dayjs": "^1.11.11",
+    "exceljs": "^4.4.0",
     "lodash": "^4.17.21",
     "pg": "^8.11.5",
     "typeorm": "^0.3.20"

+ 4 - 3
src/controller/home.controller.ts

@@ -6,10 +6,11 @@ export class HomeController {
   @Inject()
   service: UtilService;
   @Get('/')
-  async home(): Promise<string> {
+  async home(): Promise<any> {
     // const result: any = await this.adminService.create();
-    // await this.service.initData();
-    return 'starting...';
+    const res = await this.service.initData();
+    return res;
+    // return 'starting...';
   }
   // @Get('/:method')
   // async test(@Param('method') method: string, @Query() query: object) {

+ 9 - 1
src/entity/platform/achievement.entity.ts

@@ -1,6 +1,7 @@
 import { Column, Entity } from 'typeorm';
 import { BaseModel } from '../../frame/BaseModel';
 import * as dayjs from 'dayjs';
+// 成果需要与用户连接,否则就只能属于平台的了
 @Entity('achievement')
 export class Achievement extends BaseModel {
   @Column({ type: 'integer', nullable: true, comment: '平台用户id' })
@@ -21,7 +22,7 @@ export class Achievement extends BaseModel {
   technology: string;
   @Column({ type: 'jsonb', nullable: true, comment: '成果地区' })
   area: Array<any>;
-  @Column({ type: 'timestamp without time zone', comment: '发布时间', transformer: { from: value => dayjs(value).format('YYYY-MM-DD HH:mm:ss'), to: value => value } })
+  @Column({ type: 'timestamp without time zone', nullable: true, comment: '发布时间', transformer: { from: value => dayjs(value).format('YYYY-MM-DD HH:mm:ss'), to: value => value } })
   time: Date;
   @Column({ type: 'character varying', nullable: true, comment: '参考价格' })
   money: string;
@@ -35,4 +36,11 @@ export class Achievement extends BaseModel {
   is_use: string;
   @Column({ type: 'character varying', nullable: true, comment: '状态', default: '0' })
   status: string;
+
+  @Column({ type: 'character varying', nullable: true, comment: '项目来源' })
+  source: string;
+  @Column({ type: 'character varying', nullable: true, comment: '负责人' })
+  person: string;
+  @Column({ type: 'character varying', nullable: true, comment: '联系电话' })
+  tel: string;
 }

+ 9 - 0
src/entity/platform/demand.entity.ts

@@ -29,4 +29,13 @@ export class Demand extends BaseModel {
   is_use: string;
   @Column({ type: 'character varying', nullable: true, comment: '状态' })
   status: string;
+
+  @Column({ type: 'character varying', nullable: true, comment: '所属企业' })
+  company: string;
+  @Column({ type: 'character varying', nullable: true, comment: '联系人' })
+  contacts: string;
+  @Column({ type: 'character varying', nullable: true, comment: '联系电话' })
+  tel: string;
+  @Column({ type: 'character varying', nullable: true, comment: '年份' })
+  year: string;
 }

+ 12 - 3
src/entity/users/expert.entity.ts

@@ -1,8 +1,10 @@
 import { Column, Entity } from 'typeorm';
 import { BaseModel } from '../../frame/BaseModel';
+import dayjs = require('dayjs');
+// 导入的数据没有归属,只能不加权限的查询,也无法作为用户的证明
 @Entity('expert')
 export class Expert extends BaseModel {
-  @Column({ type: 'integer', comment: '平台用户id' })
+  @Column({ type: 'integer', nullable: true, comment: '平台用户id' })
   user: number;
   @Column({ type: 'character varying', nullable: true, comment: '专家姓名' })
   name: string;
@@ -10,8 +12,8 @@ export class Expert extends BaseModel {
   icon: Array<any>;
   @Column({ type: 'character varying', nullable: true, comment: '性别' })
   gender: string;
-  @Column({ type: 'character varying', nullable: true, comment: '出生年月' })
-  birth: string;
+  @Column({ type: 'timestamp without time zone', nullable: true, comment: '出生年月', transformer: { from: value => dayjs(value).format('YYYY-MM-DD HH:mm:ss'), to: value => value } })
+  birth: Date;
   @Column({ type: 'character varying', nullable: true, comment: '证件类型' })
   cardType: string;
   @Column({ type: 'character varying', nullable: true, comment: '证件号码' })
@@ -36,4 +38,11 @@ export class Expert extends BaseModel {
   is_show: string;
   @Column({ type: 'character varying', nullable: true, comment: '状态', default: '0' })
   status: string;
+
+  @Column({ type: 'character varying', nullable: true, comment: '产业类型' })
+  industry_type: string;
+  @Column({ type: 'character varying', nullable: true, comment: '产业' })
+  industry: string;
+  @Column({ type: 'character varying', nullable: true, comment: '工作单位类型' })
+  work_type: string;
 }

+ 219 - 307
src/service/util.service.ts

@@ -1,6 +1,6 @@
 import { Inject, Provide } from '@midwayjs/core';
 import * as fs from 'fs';
-import { get, isObject } from 'lodash';
+import { compact, get, isArray, isObject } from 'lodash';
 import path = require('path');
 import { Repository } from 'typeorm';
 // import { Achievement } from '../entity/platform/achievement.entity';
@@ -10,6 +10,8 @@ import { Demand } from '../entity/platform/demand.entity';
 import { Expert } from '../entity/users/expert.entity';
 import { Company } from '../entity/users/company.entity';
 import { Context } from '@midwayjs/koa';
+import * as Excel from 'exceljs';
+import { Achievement } from '../entity/platform/achievement.entity';
 // import { upperFirst } from 'lodash';
 
 // import { User } from '../entity/system/user.entity';
@@ -33,316 +35,226 @@ export class UtilService {
     // }
   }
 
-  @InjectEntityModel(Company)
-  model: Repository<Company>;
+  @InjectEntityModel(Demand)
+  model: Repository<Demand>;
   async initData() {
-    // company
-    const d: any = {
-      user: 5,
-      name: '长春市福瑞科技有限公司',
-      logo: [
-        {
-          id: 'company',
-          name: '2.jpg',
-          uri: '/files/web/template/company.jpg',
-          url: 'http://192.168.1.197/files/web/template/company.jpg',
-          uid: 1712632020400,
-          status: 'success',
-        },
-      ],
-      code: '1234567890',
-      pattern: '0',
-      scale: '0',
-      phone: '18843520013',
-      type: '3',
-      area: ['山西省', '阳泉市'],
-      representative: '张三',
-      email: 'email1233@.com',
-      person: 100,
-      register: '100',
-      create_time: '2024-04-09',
-      address: '吉林省长春市力旺广场',
-      brief: '简介',
-      is_show: '0',
-      companyStatus: '0',
-      status: '1',
-    };
-    await this.model.insert(d);
+    console.log('in initData');
+    return this.importRequirementFromExcel();
+  }
+  async importRequirementFromExcel() {
+    const path = 'E:/workspace/产学研用/项目数据资料/项目数据资料/需求库.xlsx';
+    const wb = new Excel.Workbook();
+    await wb.xlsx.readFile(path);
+    const sheet = wb.getWorksheet(1);
+    const meta = this.requirementMeta();
+    const allData = [];
+    const cityArr = ['长春', '吉林', '通化', '白山', '辽源', '四平', '白城', '松原', '延边州', '延边'];
+    const areaArr = [
+      '五棵树经济开发区',
+      '南关区',
+      '宽城区',
+      '朝阳区',
+      '二道区',
+      '绿园区',
+      '双阳区',
+      '九台区',
+      '公主岭市',
+      '榆树市',
+      '德惠市',
+      '农安县',
+      '昌邑区',
+      '龙潭区',
+      '船营区',
+      '丰满区',
+      '蛟河市',
+      '桦甸市',
+      '舒兰市',
+      '磐石市',
+      '永吉县',
+      '东昌区',
+      '二道江区',
+      '集安市',
+      '梅河口市',
+      '通化县',
+      '辉南县',
+      '柳河县',
+      '浑江区',
+      '江源区',
+      '临江市',
+      '抚松县',
+      '靖宇县',
+      '长白朝鲜族自治县',
+      '龙山区',
+      '西安区',
+      '东丰县',
+      '东辽县',
+      '铁西区',
+      '铁东区',
+      '双辽市',
+      '梨树县',
+      '伊通满族自治县',
+      '洮北区',
+      '洮南市',
+      '大安市',
+      '镇赉县',
+      '通榆县',
+      '宁江区',
+      '扶余市',
+      '长岭县',
+      '乾安县',
+      '前郭尔罗斯蒙古族自治县',
+      '延吉市',
+      '图们市',
+      '敦化市',
+      '珲春市',
+      '龙井市',
+      '和龙市',
+      '汪清县',
+      '安图县',
+    ];
+    const specialList = [
+      { e: '高新区', to: '高新技术产业开发区' },
+      { e: '高新', to: '高新技术产业开发区' },
+      { e: '经开', to: '经济技术开发区' },
+      { e: '五棵树', to: '五棵树经济开发区' },
+      { e: '北湖', to: '北湖科技开发区' },
+      { e: '净月', to: '净月高新技术产业开发区' },
+      { e: '绿园经济', to: '绿园经济开发区' },
+    ];
+    const ignoreArea = ['吉林', '长春', '白城'];
+    const specialAreaList = [
+      { e: '梅河口', to: ['吉林省', '通化市', '梅河口市'] },
+      { e: '德惠', to: ['吉林省', '长春市', '德惠市'] },
+      { e: '敦化', to: ['吉林省', '延边州', '敦化市'] },
+      { e: '延吉', to: ['吉林省', '延边州', '延吉市'] },
+      { e: '柳河', to: ['吉林省', '通化市', '柳河县'] },
+    ];
+    sheet.eachRow((row, ri) => {
+      if (ri === 1 || ri === 2) {
+        // 不处理
+      } else {
+        const obj = {};
+        row.eachCell((cell, ci) => {
+          const val = cell.value as string;
+          const key = meta[ci];
+          if (ci === 3) {
+            let area = ['吉林省'];
+            // 处理地区
+            const res = cityArr.find(f => val.includes(f));
+            if (res) {
+              // 有市级关键词的, 延边州不需要处理
+              if (res === '延边') area.push('延边州');
+              else if (res !== '延边州') area.push(`${res}市`);
+              else area.push(res);
+              const elseStr = val.replace(res, '');
+              if (elseStr !== '' && !ignoreArea.includes(elseStr)) {
+                const areaVal = areaArr.find(f => f.includes(elseStr));
+                if (areaVal) area.push(areaVal);
+                else {
+                  const rs = specialList.find(f => elseStr.includes(f.e));
+                  if (rs) area.push(rs.to);
+                }
+              }
+            } else {
+              const res = specialAreaList.find(f => val.includes(f.e));
+              if (res) area = res.to;
+              else obj['no_area'] = true;
+            }
+            obj[key] = area;
+          } else if (ci === 6) {
+            // 分离人员和电话
+            const strReg = /([\u4e00-\u9fa5]{3}|[\u4e00-\u9fa5]{2})/g;
+            const strRes = val.match(strReg);
+            const numRes = val.replace(strReg, '').replace('\n', '');
+            if (isArray(strRes)) obj['contacts'] = strRes.join(';');
+            if (isArray(numRes)) obj['tel'] = numRes.join(';');
+            if (numRes) obj['tel'] = numRes;
+          } else if (key) obj[key] = val;
+        });
+        allData.push(obj);
+      }
+    });
+    const res = await this.model.insert(allData);
+    return res;
+  }
 
-    //expert
-    // const data = {
-    //   user: '4',
-    //   name: '专家名称',
-    //   birth: '1981-04-01',
-    //   cardType: '0',
-    //   card: '220581200003302462',
-    //   field: '9',
-    //   direction: '大豆分子育种',
-    //   education: '2',
-    //   brief: '简介',
-    //   area: ['吉林省', '长春市'],
-    //   is_show: '0',
-    //   status: '1',
-    //   icon: [
-    //     {
-    //       id: '20240412143738',
-    //       name: '2.jpg',
-    //       uri: '/files/web/template/expert/20240412143738.jpg',
-    //       url: 'http://192.168.1.197/files/web/template/expert/20240412143738.jpg',
-    //       uid: 1712903858560,
-    //       status: 'success',
-    //     },
-    //   ],
-    //   work: '吉林大学',
-    // };
-    // await this.model.insert(data);
-    //user
-    // const place = path.resolve(__dirname, 'C:\\workspace\\cxyy\\user.json');
-    // let list: any = fs.readFileSync(place, 'utf8');
-    // if (!list) return;
-    // list = JSON.parse(list);
-    // list = get(list, 'RECORDS');
-    // let id = 1;
-    // for (const i of list) {
-    //   i.id = id;
-    //   if (i.role && i.role !== '') i.role = JSON.parse(get(i, 'role'));
-    //   if (i.icon && i.icon !== '') i.icon = JSON.parse(get(i, 'icon'));
-    //   if (i.password && i.password !== '') {
-    //     let password = JSON.parse(get(i, 'password'));
-    //     if (isObject(password)) {
-    //       password = get(password, 'secret');
-    //       i.password = password;
-    //     }
-    //   }
-    //   id++;
-    //   delete i._id;
-    // }
-    // for (const i of list) {
-    //   for (const key in i) {
-    //     const val = i[key];
-    //     if (val === '') {
-    //       delete i[key];
-    //     }
-    //   }
-    // }
-    // const res = await this.model.insert(list);
-    // console.log(res);
+  requirementMeta() {
+    return {
+      2: 'field',
+      3: 'area',
+      4: 'company',
+      5: 'brief',
+      6: 'contacts',
+      7: 'year',
+    };
+  }
 
-    //demand
-    // const place = path.resolve(__dirname, 'C:\\workspace\\cxyy\\demand.json');
-    // let list: any = fs.readFileSync(place, 'utf8');
-    // if (!list) return;
-    // list = JSON.parse(list);
-    // list = get(list, 'RECORDS');
-    // let id = 1;
-    // for (const i of list) {
-    //   i.id = id;
-    //   if (i.time && i.time !== '') i.time = JSON.parse(get(i, 'time'));
-    //   if (i.area && i.area !== '') i.area = JSON.parse(get(i, 'area'));
-    //   // if (i.file && i.file !== '') i.file = JSON.parse(get(i, 'file'));
-    //   id++;
-    //   delete i._id;
-    // }
-    // for (const i of list) {
-    //   for (const key in i) {
-    //     const val = i[key];
-    //     if (val === '') {
-    //       delete i[key];
-    //     }
-    //   }
-    // }
-    // const res = await this.model.insert(list);
-    // console.log(res);
-    // news
-    // const place = path.resolve(__dirname, 'C:\\workspace\\cxyy\\news.json');
-    // let list: any = fs.readFileSync(place, 'utf8');
-    // if (!list) return;
-    // list = JSON.parse(list);
-    // list = get(list, 'RECORDS');
-    // let id = 1;
-    // for (const i of list) {
-    //   i.id = id;
-    //   if (i.logo && i.logo !== '') i.logo = JSON.parse(get(i, 'logo'));
-    //   // if (i.rules && i.rules !== '') i.rules = JSON.parse(get(i, 'rules'));
-    //   // if (i.file && i.file !== '') i.file = JSON.parse(get(i, 'file'));
-    //   id++;
-    //   delete i._id;
-    // }
-    // for (const i of list) {
-    //   for (const key in i) {
-    //     const val = i[key];
-    //     if (val === '') {
-    //       delete i[key];
-    //     }
-    //   }
-    // }
-    // const res = await this.model.insert(list);
-    // console.log(res);
+  async importAchieveFromExcel() {
+    const path = 'E:/workspace/产学研用/项目数据资料/项目数据资料/成果库.xlsx';
+    const wb = new Excel.Workbook();
+    await wb.xlsx.readFile(path);
+    const sheet = wb.getWorksheet(1);
+    const meta = this.achieveMeta();
+    const allData = [];
+    sheet.eachRow((row, ri) => {
+      if (ri === 1 || ri === 2) {
+        // 不处理
+      } else {
+        const obj = {};
+        row.eachCell((cell, ci) => {
+          const val = cell.value;
+          const key = meta[ci];
+          if (key) obj[key] = val;
+        });
+        allData.push(obj);
+      }
+    });
+    return await this.model.insert(allData);
+  }
+  achieveMeta() {
+    return {
+      2: 'field',
+      3: 'name',
+      4: 'brief',
+      5: 'source',
+      6: 'person',
+      7: 'tel',
+    };
+  }
 
-    //dictData
-    // const place = path.resolve(__dirname, 'C:\\workspace\\cxyy\\dictData.json');
-    // let list: any = fs.readFileSync(place, 'utf8');
-    // if (!list) return;
-    // list = JSON.parse(list);
-    // list = get(list, 'RECORDS');
-    // let id = 1;
-    // for (const i of list) {
-    //   i.id = id;
-    //   // if (i.time && i.time !== '') i.time = JSON.parse(get(i, 'time'));
-    //   // if (i.rules && i.rules !== '') i.rules = JSON.parse(get(i, 'rules'));
-    //   // if (i.file && i.file !== '') i.file = JSON.parse(get(i, 'file'));
-    //   id++;
-    //   delete i._id;
-    // }
-    // for (const i of list) {
-    //   for (const key in i) {
-    //     const val = i[key];
-    //     if (val === '') {
-    //       delete i[key];
-    //     }
-    //   }
-    // }
-    // const res = await this.model.insert(list);
-    // console.log(res);
+  async importExportFromExcel() {
+    const path = 'E:/workspace/产学研用/项目数据资料/项目数据资料/专家库docx.xlsx';
+    const wb = new Excel.Workbook();
+    await wb.xlsx.readFile(path);
+    const sheet = wb.getWorksheet(1);
+    const rows = sheet.getRows(3, 200);
+    const meta = this.exportsMeta();
+    const allData = [];
+    for (const row of rows) {
+      const obj = {};
+      row.eachCell((cell, index) => {
+        let val = cell.value as string;
+        if (index === 4) {
+          const varr = val.split('').filter(f => f !== ' ');
+          val = varr.join('');
+        }
+        const key = meta[index];
+        obj[key] = val;
+      });
+      allData.push(obj);
+    }
+    const res = await this.model.insert(allData);
+    return res;
+  }
 
-    // dictType
-    // const place = path.resolve(__dirname, 'C:\\workspace\\cxyy\\dictType.json');
-    // let list: any = fs.readFileSync(place, 'utf8');
-    // if (!list) return;
-    // list = JSON.parse(list);
-    // list = get(list, 'RECORDS');
-    // let id = 1;
-    // for (const i of list) {
-    //   i.id = id;
-    //   // if (i.time && i.time !== '') i.time = JSON.parse(get(i, 'time'));
-    //   // if (i.rules && i.rules !== '') i.rules = JSON.parse(get(i, 'rules'));
-    //   // if (i.file && i.file !== '') i.file = JSON.parse(get(i, 'file'));
-    //   id++;
-    //   delete i._id;
-    // }
-    // for (const i of list) {
-    //   for (const key in i) {
-    //     const val = i[key];
-    //     if (val === '') {
-    //       delete i[key];
-    //     }
-    //   }
-    // }
-    // const res = await this.model.insert(list);
-    // console.log(res);
-    // match
-    // const place = path.resolve(__dirname, 'C:\\workspace\\cxyy\\match.json');
-    // let list: any = fs.readFileSync(place, 'utf8');
-    // if (!list) return;
-    // list = JSON.parse(list);
-    // list = get(list, 'RECORDS');
-    // let id = 1;
-    // for (const i of list) {
-    //   i.id = id;
-    //   if (i.time && i.time !== '') i.time = JSON.parse(get(i, 'time'));
-    //   if (i.rules && i.rules !== '') i.rules = JSON.parse(get(i, 'rules'));
-    //   if (i.file && i.file !== '') i.file = JSON.parse(get(i, 'file'));
-    //   id++;
-    //   delete i._id;
-    // }
-    // for (const i of list) {
-    //   for (const key in i) {
-    //     const val = i[key];
-    //     if (val === '') {
-    //       delete i[key];
-    //     }
-    //   }
-    // }
-    // const res = await this.model.insert(list);
-    // console.log(res);
-    // project
-    // const place = path.resolve(__dirname, 'C:\\workspace\\cxyy\\project.json');
-    // let list: any = fs.readFileSync(place, 'utf8');
-    // if (!list) return;
-    // list = JSON.parse(list);
-    // list = get(list, 'RECORDS');
-    // let id = 1;
-    // for (const i of list) {
-    //   i.id = id;
-    //   if (i.area !== '') i.area = JSON.parse(get(i, 'area'));
-    //   id++;
-    //   delete i._id;
-    // }
-    // for (const i of list) {
-    //   for (const key in i) {
-    //     const val = i[key];
-    //     if (val === '') {
-    //       delete i[key];
-    //     }
-    //   }
-    // }
-    // const res = await this.model.insert(list);
-    // console.log(res);
-    //role
-    // const place = path.resolve(__dirname, 'C:\\workspace\\cxyy\\role.json');
-    // let list: any = fs.readFileSync(place, 'utf8');
-    // if (!list) return;
-    // list = JSON.parse(list);
-    // list = get(list, 'RECORDS');
-    // let id = 1;
-    // for (const i of list) {
-    //   i.id = id;
-    //   i.menu = JSON.parse(get(i, 'menu'));
-    //   id++;
-    // }
-    // for (const i of list) {
-    //   for (const key in i) {
-    //     const val = i[key];
-    //     if (val === '') {
-    //       delete i[key];
-    //     }
-    //   }
-    // }
-    // const res = await this.model.insert(list);
-    // console.log(res);
-    // desing
-    // const data = {
-    //   zhTitle: '产学研用平台',
-    //   zhEnglish: 'Information Technology Incubation Platform',
-    //   zhBrief: '方寸心间 创新无限',
-    //   logoUrl: [],
-    //   videoUrl: [],
-    //   footInfo: {
-    //     Phone: '0431-81165166',
-    //     Email: 'jlpstm@126.com',
-    //     Address: '吉林省长春市硅谷西街156号',
-    //     Copyright: 'Copyright©2007-2024 吉林省华欣数字科技股份有限公司 │ 吉ICP备14005689号',
-    //     Company: '吉林省华欣数字科技股份有限公司',
-    //   },
-    //   agreement: '<h1 style="text-align: center;">使用协议</h1>',
-    //   brief: '<h1 style="text-align: center;"><sup>关于我们</sup></h1>',
-    // };
-    // const res = await this.model.insert(data);
-    // console.log(res);
-    // achievement
-    // const place = path.resolve(__dirname, 'C:\\workspace\\cxyy\\achievement.json');
-    // let list: any = fs.readFileSync(place, 'utf8');
-    // if (!list) return;
-    // list = JSON.parse(list);
-    // list = get(list, 'RECORDS');
-    // let id = 1;
-    // for (const i of list) {
-    //   i.id = id;
-    //   i.area = JSON.parse(get(i, 'area'));
-    //   i.file = JSON.parse(get(i, 'file'));
-    //   id++;
-    // }
-    // for (const i of list) {
-    //   for (const key in i) {
-    //     const val = i[key];
-    //     if (val === '') {
-    //       console.log(key);
-    //       delete i[key];
-    //     }
-    //   }
-    // }
-    // // console.log(list);
-    // const res = await this.model.insert(list);
-    // console.log(res);
+  exportsMeta() {
+    return {
+      1: 'industry_type',
+      2: 'industry',
+      3: 'work_type',
+      4: 'name',
+      5: 'work',
+      6: 'title',
+    };
   }
 }