无尘阁日记

无尘阁日记

跟AI协作完成下载接口
2025-04-22

问:

/**

* @route   v1/domain-version/download

* @name    获取下载文件

* @uses    fetch download file

* @parameter integer   UserId 用户id

* @parameter string    TokenId  token

* @parameter integer   ProjectId 项目id

* @parameter integer   EevaluationMethodType 评估方法 1收益法,2市场法

* @method    GET, HEAD

* @author    J.T

* @author    FYH 于20210427改成zip格式下载并返回FileId

* @return  array

*/

public function actionDownload()

{

$params = Yii::$app->request->get();

$params['MethodType'] = 0;

$data = ['FileId' => '', 'Url' => '', 'isAttachment' => 0, 'Files' => []]; // 返回结果

$result = $this->checkParams($params);

Yii::info($params);

if ($result !== true) return $result;

// 调用错误日志code

$log = ErrorLogModel::getLogCode($params['ProjectId'], $params['EevaluationMethodType'], ErrorLogModel::PROJECT_TYPE);

if ($log != false) return ['IsSuccess' => 0, 'ErrMsg' => $log['Code'] . ':' . unserialize($log['Content']), 'Data' => json_encode($data, JSON_UNESCAPED_UNICODE)];

$model = TJProjectStatistics::getProject($params['ProjectId'], $params['EevaluationMethodType']);

if (empty($model)) return ['IsSuccess' => 0, 'ErrMsg' => '项目不存在', 'Data' => json_encode($data, JSON_UNESCAPED_UNICODE)];

switch ($params['EevaluationMethodType']) {

case 2:

$method = "MarketApproach";

$field = "Market" . ($model['CurrentStep1'] - 10);

/** @var TJProjectStatistics $file */

$file = $model[$field];

break;

case 3:

$method = "ForcostApproach";

$file = $model['ForcostManuscriptFile'];

break;

default:

$method = "IncomeApproach";

$field = "ManuscriptFile";

/** @var TJProjectStatistics $file */

$file = $model[$field];

}

// 刚刚新建的项目还未上传过底稿时 及未保存在file表中的项目老项目

$fileHistoryMode = TJFileHistory::find()

->where([

'ProjectId' => $params['ProjectId'],

'EvaluationMethodType' => $params['EevaluationMethodType']])

->orderBy(['Id' => SORT_DESC])

->one();

yii::error($fileHistoryMode);

yii::error($model['GZ_ID']);

// 数据库存储的文件路径

if (empty($fileHistoryMode) && empty($model['GZ_ID'])) {

return ['IsSuccess' => 0, 'ErrMsg' => '底稿生成中,请稍后下载', 'Data' => json_encode($data, JSON_UNESCAPED_UNICODE)];

}

$manuscriptFileId = '';

$fileVersion = '';

if ($fileHistoryMode) {

$manuscriptFileId = $fileHistoryMode->FileId;

$fileVersion = $fileHistoryMode->Id;

}

if (empty($manuscriptFileId)) {   // zip 文件不存在时 读取excel 文件并加密压缩下载

if ($fileHistoryMode) {

$writeHistoryRes = TJFileHistory::zipToFileAndWriteBackHistoryFile($fileHistoryMode, TJFiles::MANUSCRIPT_FILE_TYPE);

if ($writeHistoryRes && isset($writeHistoryRes['IsSuccess']) && $writeHistoryRes['IsSuccess'] == 0) return $writeHistoryRes;

}

if (empty($fileHistoryMode) && $model['GZ_ID']) { // 只针对广州项目组

if (empty($file)) return ['IsSuccess' => 0, 'ErrMsg' => '历史期模板生成中'];

$writeHistoryRes = TJFileHistory::zipToFileFromProjects($file, TJFiles::MANUSCRIPT_FILE_TYPE, $params['EevaluationMethodType']);

}

if (!$writeHistoryRes) {

Yii::error("历史版本源文件不存在");

return ['IsSuccess' => 0, 'ErrMsg' => '历史版本源文件不存在', 'Data' => json_encode($data, JSON_UNESCAPED_UNICODE)];

}

$manuscriptFileId = $writeHistoryRes->Uuid;

}

$data['FileId'] = $manuscriptFileId;

$data['Version'] = $fileVersion;

//查找是否上传过附件文件 第一步 先从项目附件关联表中查找

$attachmentModel = HistoryAttachment::getAttachment($params['ProjectId'], $params['EevaluationMethodType']);

$fileAttachmentId = '';

if ($attachmentModel) {

$fileAttachmentId = $attachmentModel->FileId;

} else { // 第二步 从项目主体的上传的附件文件路径 保存附件文件

// 目前仅限于收益法能上传附件

if ($params['EevaluationMethodType'] == 1) {

$time = time();

$attachmentSrc = HistoryAttachment::projectAttachmentPath($params['ProjectId'], $params['EevaluationMethodType']);

$attachmentFileSrc = Yii::$app->basePath . $attachmentSrc;

yii::error($attachmentSrc);

if (file_exists($attachmentFileSrc) && $attachmentSrc) { // 将原先附件保存

// rename($attachmentFileSrc, $attachmentTemp = $attachmentFileSrc . "_temp_" . time());

$attachmentPath = TJFileHistory::copyVersionFile($attachmentFileSrc, $method, $model, $time, $type = TJFiles::ATTACHMENT_FILE_TYPE);

//   unlink($attachmentTemp);

$transaction = Yii::$app->db->beginTransaction();

if ($attachmentPath) {

$fileAttachmentData = [

'ZipPath' => str_replace(Yii::$app->basePath, '', $attachmentPath),

'UserId' => $params['UserId'],

'Type' => TJFiles::ATTACHMENT_FILE_TYPE,

'Remark' => '附件',

'CreatedAt' => time(),

'UpdatedAt' => time()

];

$fileModel = TJFiles::insertFile($fileAttachmentData); // 附件入文件库

Yii::error($fileModel);

if (!$fileModel) {

$data['ErrMsg'] = "附件保存入库失败";

Yii::error($data['ErrMsg']);

}

// 写入附件项目关联表

$attachmentData = [

'ProjectId' => $params['ProjectId'],

'FileId' => $fileModel->Uuid,

'EvaluationMethodType' => $params['EevaluationMethodType'],

'Uuid' => LibSnowflake::getNext(),

'UserId' => $params['UserId'],

'Remark' => '附件',

'CreatedAt' => time(),

'UpdatedAt' => time()

];

$attachmentModel = HistoryAttachment::insertAttachment($attachmentData);

Yii::error($attachmentModel);

if (!$attachmentModel) {

$data['ErrMsg'] = "附件项目关联入库失败";

Yii::error($data['ErrMsg']);

return ['IsSuccess' => 0, 'ErrMsg' => '附件项目关联入库失败', 'Data' => json_encode($data, JSON_UNESCAPED_UNICODE)];

}

$fileAttachmentId = $fileModel->Uuid;

$transaction->commit();

}

}

}

}

if ($fileAttachmentId) {

$data['isAttachment'] = 1;

$data['Files'] = [['FileId' => $fileAttachmentId, 'Url' => '']];

}

Yii::error($params);

if (!$this->switchProjectStatus($params['ProjectId'], $params['EevaluationMethodType'], 2)) return ['IsSuccess' => 0, 'ErrMsg' => '更新项目状态失败', 'Data' => json_encode($data, JSON_UNESCAPED_UNICODE)];

// 更新分发消息数据状态

$taskId = $fileHistoryMode->TaskId;

if ($taskId) {

MessageSummary::updateMessageSummary($params['ProjectId'], $params['EevaluationMethodType'], $params['UserId'], $taskId);

}

// 标记三种方法底稿是否成功下载过,2023年6月25日增加

TJProjectStatistics::markDownloaded($params['ProjectId'], $params['EevaluationMethodType']);

return ['IsSuccess' => 1, 'ErrMsg' => '获取文件成功!', 'Data' => json_encode($data, JSON_UNESCAPED_UNICODE)];

}


在这个方法开头我将加入一个逻辑分支。

1. 先判断当前项目是否单项资产,在TJProjectStatistics这个模型中查到ProjectType=2,这个也是一个枚举,如下:

// 普通项目

const PROJECT_TYPE_COMMON = 1;

// 单项资产项目

const PROJECT_TYPE_SINGLE_ASSET = 2;

如果是单项资产,则走新分支。新分支将写一个独立的方法,在以上api里调用一下。

2. 这个方法要实现的功能包括:

a)上面那个逻辑中查询表改为TJFilehistorySingleAsset这个模型,逻辑是查这个表指定项目id最新的版本,如果FileId存在,则返回结构跟上面那个api一样。如果FileId不存在,则报错,底稿生成中,请稍后下载。开始吧。

答:

我们将分两部分完成你说的需求:


✅ 一、在原方法中添加判断逻辑,判断是否是“单项资产项目”

插入到 actionDownload() 方法前半部分,在 $model = TJProjectStatistics::getProject(...) 获取之后:

$model = TJProjectStatistics::getProject($params['ProjectId'], $params['EevaluationMethodType']);

if (empty($model)) {
    return ['IsSuccess' => 0, 'ErrMsg' => '项目不存在', 'Data' => json_encode($data, JSON_UNESCAPED_UNICODE)];
}

// 新增:判断是否为单项资产项目,直接走新分支
if ((int)$model['ProjectType'] === TJProjectStatistics::PROJECT_TYPE_SINGLE_ASSET) {
    return $this->handleSingleAssetDownload($model, $params, $data);
}

✅ 二、实现新方法 handleSingleAssetDownload

/**
 * 处理单项资产项目的下载逻辑
 */
private function handleSingleAssetDownload($model, $params, &$data)
{
    $fileHistory = TJFileHistorySingleAsset::find()
        ->where(['ProjectId' => $params['ProjectId']])
        ->orderBy(['Id' => SORT_DESC])
        ->one();

    Yii::error(['single-asset-fileHistory' => $fileHistory]);

    if (empty($fileHistory)) {
        return ['IsSuccess' => 0, 'ErrMsg' => '底稿生成中,请稍后下载', 'Data' => json_encode($data, JSON_UNESCAPED_UNICODE)];
    }

    if (empty($fileHistory->FileId)) {
        return ['IsSuccess' => 0, 'ErrMsg' => '底稿生成中,请稍后下载', 'Data' => json_encode($data, JSON_UNESCAPED_UNICODE)];
    }

    // 返回结构统一
    $data['FileId'] = $fileHistory->FileId;
    $data['Version'] = $fileHistory->Id;

    // 如果未来支持附件功能可补充此处逻辑,现在保持空即可
    $data['isAttachment'] = 0;
    $data['Files'] = [];

    // 可加:标记下载记录或更新状态
    TJProjectStatistics::markDownloaded($params['ProjectId'], $params['EevaluationMethodType']);

    return ['IsSuccess' => 1, 'ErrMsg' => '获取文件成功!', 'Data' => json_encode($data, JSON_UNESCAPED_UNICODE)];
}

这样结构是清晰的:

  • 主逻辑中增加类型判断

  • 单项资产项目 被分流处理

  • 独立封装逻辑后续更容易拓展(比如判断版本类型、返回不同文件等)