|
@@ -5,6 +5,7 @@ const { ObjectId } = require('mongoose').Types;
|
|
|
const _ = require('lodash');
|
|
|
const jwt = require('jsonwebtoken');
|
|
|
const assert = require('assert');
|
|
|
+const Excel = require('exceljs');
|
|
|
|
|
|
// 个人用户
|
|
|
class PersonalService extends CrudService {
|
|
@@ -48,7 +49,7 @@ class PersonalService extends CrudService {
|
|
|
const { secret } = op;
|
|
|
if (status !== '1') throw new BusinessError(ErrorCode.ACCESS_DENIED, '拒绝访问!');
|
|
|
if (secret !== password) throw new BusinessError(ErrorCode.BAD_PASSWORD, '密码错误');
|
|
|
- const data = _.omit(JSON.parse(JSON.stringify(object)), [ 'meta', 'password', '__v' ]);
|
|
|
+ const data = _.omit(JSON.parse(JSON.stringify(object)), ['meta', 'password', '__v']);
|
|
|
const { secret: secrets } = this.config.jwt;
|
|
|
const token = jwt.sign(data, secrets);
|
|
|
// 记录登陆
|
|
@@ -73,7 +74,7 @@ class PersonalService extends CrudService {
|
|
|
assert(id, '缺少个人用户ID');
|
|
|
const user = await this.model.findOne({ _id: ObjectId(id) }, '+password');
|
|
|
if (!user) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到用户的信息');
|
|
|
- data = _.omit(data, [ 'meta', '__v' ]);
|
|
|
+ data = _.omit(data, ['meta', '__v']);
|
|
|
data.user_id = id;
|
|
|
// 创建专家
|
|
|
const is_expert = await this.ctx.model.Expert.count({ user_id: ObjectId(id) });
|
|
@@ -82,6 +83,77 @@ class PersonalService extends CrudService {
|
|
|
user.is_expert = true;
|
|
|
await user.save();
|
|
|
}
|
|
|
+
|
|
|
+ async import({ uri }) {
|
|
|
+ assert(uri, '未获取到文件地址');
|
|
|
+ let domain = 'http://127.0.0.1';
|
|
|
+ const file = await this.ctx.curl(`${domain}${uri}`);
|
|
|
+ if (!(file && file.data)) {
|
|
|
+ throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到指定文件');
|
|
|
+ }
|
|
|
+ const workbook = new Excel.Workbook();
|
|
|
+ await workbook.xlsx.load(file.data);
|
|
|
+ const sheet = workbook.getWorksheet(1);
|
|
|
+ let meta = this.importMeta();
|
|
|
+ // 根据excel,将列序号加入meta中
|
|
|
+ const head = sheet.getRow(1)?.values;
|
|
|
+ for (let i = 0; i < head.length; i++) {
|
|
|
+ const e = head[i];
|
|
|
+ if (!e) continue;
|
|
|
+ const r = meta.find((f) => f.column === e);
|
|
|
+ if (r) r.index = i;
|
|
|
+ }
|
|
|
+ // 过滤出列表中不必要且不存在的字段
|
|
|
+ meta = meta.filter((f) => f.required || f.index);
|
|
|
+ const errorList = [];
|
|
|
+ const dataList = [];
|
|
|
+ sheet.eachRow(async (row, index) => {
|
|
|
+ if (index !== 1) {
|
|
|
+ const values = row.values;
|
|
|
+ const obj = {};
|
|
|
+ for (const m of meta) {
|
|
|
+ const { required, key, index, method } = m;
|
|
|
+ const value = values[index];
|
|
|
+ if (required && !value) {
|
|
|
+ // 必填且没值的情况
|
|
|
+ errorList.push({ message: `第${index}行数据,缺少必填项;` });
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (_.isFunction(method)) obj[key] = method(value);
|
|
|
+ else obj[key] = value;
|
|
|
+ }
|
|
|
+ dataList.push(obj);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (errorList.length > 0) return errorList;
|
|
|
+ for (const i of dataList) {
|
|
|
+ try {
|
|
|
+ await this.create(i);
|
|
|
+ } catch (error) {
|
|
|
+ errorList.push(error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return errorList;
|
|
|
+ }
|
|
|
+
|
|
|
+ importMeta() {
|
|
|
+ return [
|
|
|
+ { required: true, column: '用户名', key: 'name' },
|
|
|
+ { required: true, column: '手机号', key: 'phone' },
|
|
|
+ { required: true, column: '登录密码', key: 'password' },
|
|
|
+ { required: true, column: '邀请码', key: 'code' },
|
|
|
+ { required: true, column: '身份证号', key: 'card' },
|
|
|
+ { column: '电子邮箱', key: 'email' },
|
|
|
+ { column: '联系地址', key: 'addr' },
|
|
|
+ { column: '办公电话', key: 'office_phone' },
|
|
|
+ { column: '所属辖区', key: 'juris' },
|
|
|
+ { column: '院校', key: 'school' },
|
|
|
+ { column: '专业', key: 'major' },
|
|
|
+ { column: '职务职称', key: 'zwzc' },
|
|
|
+ { column: '审核状态', key: 'status' },
|
|
|
+ ];
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
module.exports = PersonalService;
|