|
@@ -1845,26 +1845,52 @@ module.exports = app => {
|
|
|
const result = [];
|
|
const result = [];
|
|
|
const contractIds = new Set((await this._loadContracts(scope)).map(item => String(item.id)));
|
|
const contractIds = new Set((await this._loadContracts(scope)).map(item => String(item.id)));
|
|
|
for (const source of this._attachmentSources()) {
|
|
for (const source of this._attachmentSources()) {
|
|
|
- const where = { [source.tenderField]: tenderId };
|
|
|
|
|
- if (source.notDeleted) where.is_deleted = 0;
|
|
|
|
|
- const rows = await this.ctx.service[source.service].getAllDataByCondition({ where });
|
|
|
|
|
|
|
+ let rows = [];
|
|
|
|
|
+ if (source.parent) {
|
|
|
|
|
+ const parents = source.parent.permission === 'financialPay'
|
|
|
|
|
+ ? await this.ctx.service.financialPay.getListByStatus(scope.subProjects[0].id, null, null, 0, [tenderId])
|
|
|
|
|
+ : await this.ctx.service[source.parent.service].getAllDataByCondition({ where: { tid: tenderId } });
|
|
|
|
|
+ for (const parent of parents) {
|
|
|
|
|
+ rows.push(...await this.ctx.service[source.service].getAllDataByCondition({
|
|
|
|
|
+ where: { [source.parent.foreignKey]: parent.id },
|
|
|
|
|
+ }));
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const where = { [source.tenderField]: tenderId };
|
|
|
|
|
+ if (source.notDeleted) where.is_deleted = 0;
|
|
|
|
|
+ rows = await this.ctx.service[source.service].getAllDataByCondition({ where });
|
|
|
|
|
+ }
|
|
|
for (const row of rows) {
|
|
for (const row of rows) {
|
|
|
if (source.contractScoped && !contractIds.has(String(row.cid))) continue;
|
|
if (source.contractScoped && !contractIds.has(String(row.cid))) continue;
|
|
|
- const filename = String(row.file_name || row.filename || '').trim();
|
|
|
|
|
- const fileext = String(row.fileext || '').trim();
|
|
|
|
|
- const fullName = filename && fileext && !filename.toLowerCase().endsWith(fileext.toLowerCase())
|
|
|
|
|
- ? filename + fileext : filename;
|
|
|
|
|
- if (!fullName || !row.filepath) continue;
|
|
|
|
|
- if (keyword && `${fullName} ${source.label}`.toLowerCase().indexOf(keyword) === -1) continue;
|
|
|
|
|
- const uploadTime = row.create_time || row.upload_time || row.update_time || row.in_time || '';
|
|
|
|
|
- result.push({
|
|
|
|
|
- source: source.key,
|
|
|
|
|
- id: String(row.id),
|
|
|
|
|
- filename: fullName,
|
|
|
|
|
- module: source.label,
|
|
|
|
|
- uploadTime,
|
|
|
|
|
- filesize: row.filesize || row.file_size || '',
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ let files = [row];
|
|
|
|
|
+ if (source.embedded) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const attachment = JSON.parse(row.attachment || '[]');
|
|
|
|
|
+ files = Array.isArray(attachment) ? attachment.map(file => Object.assign({}, file, {
|
|
|
|
|
+ id: `${row.id}:${file.file_id || file.id}`,
|
|
|
|
|
+ create_time: file.in_time || row.in_time,
|
|
|
|
|
+ })) : [];
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ files = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ for (const file of files) {
|
|
|
|
|
+ const filename = String(file.file_name || file.filename || '').trim();
|
|
|
|
|
+ const fileext = String(file.fileext || '').trim();
|
|
|
|
|
+ const fullName = filename && fileext && !filename.toLowerCase().endsWith(fileext.toLowerCase())
|
|
|
|
|
+ ? filename + fileext : filename;
|
|
|
|
|
+ if (!fullName || !file.filepath) continue;
|
|
|
|
|
+ if (keyword && `${fullName} ${source.label}`.toLowerCase().indexOf(keyword) === -1) continue;
|
|
|
|
|
+ const uploadTime = file.create_time || file.upload_time || file.update_time || file.in_time || '';
|
|
|
|
|
+ result.push({
|
|
|
|
|
+ source: source.key,
|
|
|
|
|
+ id: String(file.id),
|
|
|
|
|
+ filename: fullName,
|
|
|
|
|
+ module: source.label,
|
|
|
|
|
+ uploadTime,
|
|
|
|
|
+ filesize: file.filesize || file.file_size || '',
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
result.sort((a, b) => new Date(b.uploadTime || 0).getTime() - new Date(a.uploadTime || 0).getTime());
|
|
result.sort((a, b) => new Date(b.uploadTime || 0).getTime() - new Date(a.uploadTime || 0).getTime());
|
|
@@ -1891,10 +1917,35 @@ module.exports = app => {
|
|
|
async getAttachmentFile(sourceKey, id) {
|
|
async getAttachmentFile(sourceKey, id) {
|
|
|
const source = this._attachmentSources().find(item => item.key === sourceKey);
|
|
const source = this._attachmentSources().find(item => item.key === sourceKey);
|
|
|
if (!source || !id) throw '附件参数不正确';
|
|
if (!source || !id) throw '附件参数不正确';
|
|
|
- const file = await this.ctx.service[source.service].getDataById(id);
|
|
|
|
|
|
|
+ let file;
|
|
|
|
|
+ let tenderId;
|
|
|
|
|
+ if (source.embedded) {
|
|
|
|
|
+ const separator = id.indexOf(':');
|
|
|
|
|
+ if (separator <= 0) throw '附件参数不正确';
|
|
|
|
|
+ const row = await this.ctx.service[source.service].getDataById(id.slice(0, separator));
|
|
|
|
|
+ let attachment = [];
|
|
|
|
|
+ try {
|
|
|
|
|
+ attachment = row && JSON.parse(row.attachment || '[]');
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ attachment = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ file = Array.isArray(attachment) ? attachment.find(item => String(item.file_id || item.id) === id.slice(separator + 1)) : null;
|
|
|
|
|
+ tenderId = row && String(row.tid || '');
|
|
|
|
|
+ } else {
|
|
|
|
|
+ file = await this.ctx.service[source.service].getDataById(id);
|
|
|
|
|
+ if (file && source.parent) {
|
|
|
|
|
+ const parent = await this.ctx.service[source.parent.service].getDataById(file[source.parent.foreignKey]);
|
|
|
|
|
+ tenderId = parent && String(parent.tid || '');
|
|
|
|
|
+ if (parent && source.parent.permission === 'financialPay') {
|
|
|
|
|
+ const allowed = await this.ctx.service.financialPay.getListByStatus(parent.spid, null, null, 0, [parent.tid]);
|
|
|
|
|
+ if (!allowed.some(item => String(item.id) === String(parent.id))) throw '您无权查看该附件';
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ tenderId = file && String(file[source.tenderField] || '');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
if (!file || (source.notDeleted && Number(file.is_deleted) !== 0) || !file.filepath) throw '附件不存在或已删除';
|
|
if (!file || (source.notDeleted && Number(file.is_deleted) !== 0) || !file.filepath) throw '附件不存在或已删除';
|
|
|
const scope = await this._loadScope('', {});
|
|
const scope = await this._loadScope('', {});
|
|
|
- const tenderId = String(file[source.tenderField] || '');
|
|
|
|
|
const tender = scope.tenders.find(item => String(item.id) === tenderId);
|
|
const tender = scope.tenders.find(item => String(item.id) === tenderId);
|
|
|
if (!tenderId || !tender) throw '您无权查看该附件';
|
|
if (!tenderId || !tender) throw '您无权查看该附件';
|
|
|
if (source.contractScoped) {
|
|
if (source.contractScoped) {
|
|
@@ -1921,6 +1972,7 @@ module.exports = app => {
|
|
|
return [
|
|
return [
|
|
|
{ key: 'ledger', service: 'ledgerAtt', tenderField: 'tid', label: '台账' },
|
|
{ key: 'ledger', service: 'ledgerAtt', tenderField: 'tid', label: '台账' },
|
|
|
{ key: 'stage', service: 'stageAtt', tenderField: 'tid', label: '计量' },
|
|
{ key: 'stage', service: 'stageAtt', tenderField: 'tid', label: '计量' },
|
|
|
|
|
+ { key: 'stage_detail', service: 'stageDetailAtt', tenderField: 'tid', label: '计量清单附件', embedded: true },
|
|
|
{ key: 'stage_shoufang', service: 'stageShoufangAtt', tenderField: 'tid', label: '收方记录' },
|
|
{ key: 'stage_shoufang', service: 'stageShoufangAtt', tenderField: 'tid', label: '收方记录' },
|
|
|
{ key: 'material', service: 'materialFile', tenderField: 'tid', label: '材料调差' },
|
|
{ key: 'material', service: 'materialFile', tenderField: 'tid', label: '材料调差' },
|
|
|
{ key: 'advance', service: 'advanceFile', tenderField: 'tid', label: '预付款' },
|
|
{ key: 'advance', service: 'advanceFile', tenderField: 'tid', label: '预付款' },
|
|
@@ -1935,6 +1987,7 @@ module.exports = app => {
|
|
|
{ key: 'contract_supplement', service: 'contractSupplementAtt', tenderField: 'tid', label: '合同补充协议', contractScoped: true },
|
|
{ key: 'contract_supplement', service: 'contractSupplementAtt', tenderField: 'tid', label: '合同补充协议', contractScoped: true },
|
|
|
{ key: 'contract_pay', service: 'contractPayAtt', tenderField: 'tid', label: '合同支付', contractScoped: true },
|
|
{ key: 'contract_pay', service: 'contractPayAtt', tenderField: 'tid', label: '合同支付', contractScoped: true },
|
|
|
{ key: 'construction', service: 'constructionAtt', tenderField: 'tid', label: '施工日志' },
|
|
{ key: 'construction', service: 'constructionAtt', tenderField: 'tid', label: '施工日志' },
|
|
|
|
|
+ { key: 'financial_pay', service: 'financialPayAtt', label: '资金支付', parent: { service: 'financialPay', foreignKey: 'fpid', permission: 'financialPay' } },
|
|
|
{ key: 'cost', service: 'costStageFile', tenderField: 'tid', label: '成本管理', notDeleted: true },
|
|
{ key: 'cost', service: 'costStageFile', tenderField: 'tid', label: '成本管理', notDeleted: true },
|
|
|
{ key: 'quality', service: 'qualityFile', tenderField: 'tid', label: '质量管理', notDeleted: true },
|
|
{ key: 'quality', service: 'qualityFile', tenderField: 'tid', label: '质量管理', notDeleted: true },
|
|
|
{ key: 'quality_inspection', service: 'qualityInspectionAtt', tenderField: 'tid', label: '质量巡检' },
|
|
{ key: 'quality_inspection', service: 'qualityInspectionAtt', tenderField: 'tid', label: '质量巡检' },
|