'use strict'; const archiver = require('archiver'); const path = require('path'); const fs = require('fs'); /** * 附件表 数据模型 * @author LanJianRong * @date 2020/6/30 * @version */ module.exports = app => { class ChangePlanFile extends app.BaseService { /** * 构造函数 * * @param {Object} ctx - egg全局变量 * @return {void} */ constructor(ctx) { super(ctx); this.tableName = 'change_plan_attachment'; } /** * 获取当前标段(期)所有上传的附件 * @param {Number} tid 标段id * @param {Number?} mid 期id * @return {Promise} 数据库查询实例 */ async getAllChangePlanAtt(tid, cpid) { const { ctx } = this; // const where = { tid }; // if (cpid) where.cpid = cpid; const sql = 'SELECT a.*,b.name as username FROM ?? as a LEFT JOIN ?? as b ON a.uid = b.id WHERE a.tid = ? AND a.cpid = ? ORDER BY upload_time DESC'; const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tid, cpid]; const result = await this.db.query(sql, sqlParam); // const result = await this.db.select(this.tableName, { // where, // orders: [['upload_time', 'desc']], // }); // for (const r of result) { // const userInfo = await this.ctx.service.projectAccount.getDataById(r.uid); // r.username = userInfo ? userInfo.name : ''; // } return result.map(item => { item.orginpath = this.ctx.app.config.fujianOssPath + item.filepath; if (!ctx.helper.canPreview(item.fileext)) { item.filepath = `/tender/${ctx.tender.id}/change/plan/${item.cpid}/information/file/${item.id}/download`; } else { item.filepath = this.ctx.app.config.fujianOssPath + item.filepath; } return item; }); } /** * 存储上传的文件信息至数据库 * @param {Array} payload 载荷 * @return {Promise} 数据库插入执行实例 */ async saveFileMsgToDb(payload) { return await this.db.insert(this.tableName, payload); } /** * 获取单个文件信息 * @param {Number} id 文件id * @return {Promise} 数据库查询实例 */ async getMaterialFileById(id) { return await this.getDataByCondition({ id }); } /** * 删除附件 * @param {Number} id - 附件id * @return {void} */ async delete(id) { return await this.deleteById(id); } /** * 将文件压缩成zip,并返回zip文件的路径 * @param {array} fileIds - 文件数组id * @param {string} zipPath - 压缩文件存储路径 * @return {string} 压缩后的zip文件路径 */ async compressedFile(fileIds, zipPath) { this.initSqlBuilder(); this.sqlBuilder.setAndWhere('id', { value: fileIds, operate: 'in', }); const [sql, sqlParam] = this.sqlBuilder.build(this.tableName); const files = await this.db.query(sql, sqlParam); // const paths = files.map(item => { // return { name: item.filename + item.fileext, path: item.filepath } // }) return new Promise((resolve, reject) => { // 每次开一个新的archiver const ziparchiver = archiver('zip'); const outputPath = fs.createWriteStream(path.resolve(this.app.baseDir, zipPath)); outputPath.on('error', err => { return reject(err); }); ziparchiver.pipe(outputPath); files.forEach(item => { ziparchiver.file(path.resolve(this.app.baseDir, 'app', item.filepath), { name: item.file_name }); }); // 存档警告 ziparchiver.on('warning', function(err) { // if (err.code === 'ENOENT') { // console.warn('stat故障和其他非阻塞错误'); // } return reject(err); }); // 存档出错 ziparchiver.on('error', function(err) { // console.log(err); return reject(err); }); ziparchiver.finalize(); outputPath.on('close', () => { return resolve(ziparchiver.pointer()); }); }); } } return ChangePlanFile; };