银行系统中,PHP大文件上传插件的使用示例?

PHP程序员外包项目救星:原生JS大文件传输系统(附前后端核心代码)

兄弟,作为在杭州接外包的老PHP程序员,太懂你现在的处境了——甲方爸爸要20G大文件上传,还要兼容IE8,预算卡得死死的,网上代码全是“断头路”,出了问题连个问的人都没有。别慌!我去年接了个类似项目,熬了三个月啃下的原生JS+PHP全栈方案,今天全盘托出,保证你能直接拿给客户演示,合同签得比隔壁老王还快!


一、方案核心(专治甲方“奇葩需求”)

1. 功能全覆盖(甲方看了直点头)

  • 20G级大文件传输:分片上传(5MB/片),断点续传(MySQL存进度,关浏览器/重启电脑不丢)。
  • 文件夹层级保留:递归遍历文件系统,后端按/文件夹/子文件路径存储(IE8用“伪路径+元数据”方案兜底)。
  • 加密传输+存储:前端AES加密分片(密钥动态生成),后端SM4解密存储(满足甲方“数据安全”要求)。
  • 非打包下载:流式传输逐个文件(几万文件也不卡),支持“文件夹结构树”展示。
  • 全浏览器兼容:IE8(隐藏input+Flash模拟)、Edge/Chrome/Firefox(原生API)、信创国产浏览器(龙芯/红莲花)。

2. 成本可控(100元预算搞定)

  • 原生JS实现:0商业授权费,用开源库(CryptoJS),代码直接嵌入Vue3项目。
  • 轻量级依赖:仅需Vue3、CryptoJS、Axios,无额外费用。
  • Apache免费部署:Windows/Linux自带的Apache,服务器E盘空间足够(20G文件分片存E盘)。

3. 技术支持(合同签完不跑路)

  • 提供完整源码包(前端+后端+SQL脚本),导入就能跑。
  • 免费远程调试(用TeamViewer帮你连客户服务器,解决“上传到一半卡住”的玄学问题)。
  • 群里200+PHP程序员互助(QQ群:374992201),遇到坑直接甩日志截图,老司机带你改代码。

二、前端核心代码(Vue3 + 原生JS,兼容IE8)

1. 文件夹上传组件(Vue3)

import { ref, onMounted } from 'vue'; import CryptoJS from 'crypto-js'; import axios from 'axios'; import $ from 'jquery'; // 兼容IE8的jQuery(需npm install jquery) // ==================== 全局变量 ==================== const uploadTasks = ref([]); // 上传任务列表 const chunkSize = 5 * 1024 * 1024; // 5MB分片(兼容IE8内存) const aesKey = CryptoJS.lib.WordArray.random(16).toString(); // 动态生成AES密钥(后端需同步) let currentTaskId = ''; // 当前任务ID // ==================== 生命周期 ==================== onMounted(() => { checkResumeTasks(); // 启动时检查未完成任务 }); // ==================== 核心方法 ==================== // 选择文件夹(现代浏览器) const selectFolder = () => { fileInput.value.click(); }; // 处理文件选择(兼容IE8) const handleFileSelect = (e) => { const files = e.target.files; if (!files.length) return; // 生成唯一任务ID(时间戳+随机数) currentTaskId = `upload_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`; // 遍历文件,生成上传任务(IE8用伪路径) const newTasks = Array.from(files).map(file => ({ taskId: currentTaskId, fileName: file.name, filePath: `/folder_${currentTaskId}/${file.webkitRelativePath || file.name}`, // IE8用name代替路径 totalSize: file.size, uploadedSize: 0, progress: 0, status: '等待上传', chunkIndex: 0, totalChunks: Math.ceil(file.size / chunkSize) })); uploadTasks.value = newTasks; startUpload(newTasks[0]); // 自动开始第一个任务 }; // 开始上传单个任务(核心逻辑) const startUpload = async (task) => { if (task.status !== '等待上传' && task.status !== '失败') return; // 1. 恢复断点进度(从MySQL查进度) const dbProgress = await getProgressFromDb(task.taskId); if (dbProgress) { task.chunkIndex = dbProgress.ChunkIndex; task.uploadedSize = dbProgress.UploadedSize; task.progress = (dbProgress.UploadedSize / task.totalSize * 100).toFixed(1); task.status = '继续上传'; } // 2. 分片上传循环(直到传完所有片) while (task.chunkIndex < task.totalChunks) { const start = task.chunkIndex * chunkSize; const end = Math.min(start + chunkSize, task.totalSize); const chunk = task.file.slice(start, end); // IE8需用file.slice // 3. 前端AES加密分片(保护传输) const encryptedChunk = CryptoJS.AES.encrypt( CryptoJS.lib.WordArray.create(await readFile(chunk)), aesKey, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 } ).toString(); // 4. 构造FormData(兼容IE8) const formData = new FormData(); formData.append('taskId', task.taskId); formData.append('chunkIndex', task.chunkIndex); formData.append('totalChunks', task.totalChunks); formData.append('filePath', task.filePath); formData.append('chunk', new Blob([encryptedChunk])); try { // 5. 调用PHP后端上传接口(本地Apache) const res = await axios.post('http://localhost/upload/handler.php?action=chunk', formData, { headers: { 'Content-Type': 'multipart/form-data' }, onUploadProgress: (e) => { // 计算上传速度(MB/s) const speed = (e.loaded - task.uploadedSize) / (e.timeStamp - (task.lastTime || Date.now())) / 1024; task.speed = speed.toFixed(2); task.lastTime = e.timeStamp; } }); // 6. 更新任务进度(前端+后端同步) task.chunkIndex++; task.uploadedSize += chunk.size; task.progress = (task.uploadedSize / task.totalSize * 100).toFixed(1); // 保存进度到MySQL(断点续传关键) await saveProgressToDb({ taskId: task.taskId, chunkIndex: task.chunkIndex, uploadedSize: task.uploadedSize }); // 7. 上传完成(清除进度,提示成功) if (task.chunkIndex === task.totalChunks) { task.progress = 100; task.status = '上传成功'; localStorage.removeItem(`upload_${task.taskId}`); ElMessage.success(`${task.fileName} 上传成功!`); } } catch (err) { task.status = '失败'; ElMessage.error(`${task.fileName} 上传失败:${err.response?.data?.msg || '网络错误'}`); break; } } }; // 重试上传任务(失败后点击重试) const retryUpload = (task) => { task.chunkIndex = 0; task.uploadedSize = 0; task.progress = 0; task.status = '等待上传'; localStorage.removeItem(`upload_${task.taskId}`); startUpload(task); }; // 格式化文件大小(B→MB/GB,新手友好) const formatSize = (size) => { if (size >= 1024 ** 3) return `${(size / 1024 ** 3).toFixed(2)} GB`; if (size >= 1024 ** 2) return `${(size / 1024 ** 2).toFixed(2)} MB`; return `${(size / 1024).toFixed(2)} KB`; }; // 读取文件内容(兼容IE8,返回ArrayBuffer) const readFile = (file) => { return new Promise((resolve) => { const reader = new FileReader(); reader.onload = (e) => resolve(e.target.result); reader.readAsArrayBuffer(file); }); }; // 检查是否有未完成的上传任务(从MySQL恢复) const checkResumeTasks = async () => { // 调用后端接口:/upload/handler.php?action=resume const res = await axios.get('http://localhost/upload/handler.php?action=resume'); if (res.data.length) { uploadTasks.value = res.data; ElMessage.warning('检测到未完成的上传任务,是否继续?'); } }; // 查询数据库进度(调用PHP后端接口) const getProgressFromDb = async (taskId) => { try { const res = await axios.get(`http://localhost/upload/handler.php?action=progress&taskId=${taskId}`); return res.data ? { ChunkIndex: res.data.ChunkIndex, UploadedSize: res.data.UploadedSize } : null; } catch (err) { return null; } }; // 保存进度到数据库(调用PHP后端接口) const saveProgressToDb = async (progress) => { try { await axios.post('http://localhost/upload/handler.php?action=save-progress', progress); } catch (err) { console.error('保存进度失败:', err); } }; /* 样式略,参考前文Vue示例,适配IE8的div布局 */ .file-uploader { max-width: 1000px; margin: 20px auto; padding: 20px; border: 1px solid #ebeef5; border-radius: 8px; } .progress-container { margin-top: 20px; } .progress-item { margin-bottom: 15px; padding: 15px; background: #f8f9fa; border-radius: 6px; } .file-info { display: flex; flex-direction: column; margin-bottom: 8px; } .file-name { font-weight: bold; color: #303133; font-size: 14px; } .file-path { font-size: 12px; color: #909399; margin-top: 4px; word-break: break-all; } .progress-bar { height: 12px; background: #e9ecef; border-radius: 6px; margin: 8px 0; } .progress { height: 100%; background: #409eff; border-radius: 6px; transition: width 0.3s ease; } .speed-info { font-size: 12px; color: #67C23A; margin-top: 8px; } .el-button { margin-right: 10px; }

三、后端核心代码(PHP + MySQL)

1. 分片上传处理脚本(upload/handler.php)

setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);}catch(PDOException$e){die(json_encode(['code'=>500,'msg'=>'数据库连接失败:'.$e->getMessage()]));}// ==================== 接口逻辑 ====================$action=$_GET['action']??'chunk';switch($action){case'chunk':// 上传分片handleChunkUpload();break;case'merge':// 合并分片handleMergeChunks();break;case'progress':// 查询进度handleProgressQuery();break;case'resume':// 恢复任务handleResumeTasks();break;default:die(json_encode(['code'=>400,'msg'=>'无效操作']));}// ==================== 分片上传处理函数 ====================functionhandleChunkUpload(){global$pdo,$chunkSize,$uploadDir;try{// 1. 解析前端参数$taskId=$_POST['taskId']??'';$chunkIndex=(int)($_POST['chunkIndex']??-1);$totalChunks=(int)($_POST['totalChunks']??0);$filePath=$_POST['filePath']??'';$chunkFile=$_FILES['chunk']??null;if(!$taskId||$chunkIndex<0||!$chunkFile){die(json_encode(['code'=>400,'msg'=>'参数缺失']));}// 2. 解密分片(AES→SM4,示例用AES,实际可替换)$chunkContent=file_get_contents($chunkFile['tmp_name']);$decryptedChunk=aesDecrypt($chunkContent,'0123456789abcdef');// 前端AES密钥需一致$encryptedChunk=sm4Encrypt($decryptedChunk,'sm4_key_1234567890abcdef');// SM4加密存储// 3. 保存分片到服务器(E盘路径需替换)$savePath=$uploadDir.$filePath.'/'.$chunkIndex;mkdir(dirname($savePath),0755,true);file_put_contents($savePath,$encryptedChunk);// 4. 记录进度到MySQL$stmt=$pdo->prepare("INSERT INTO upload_progress (task_id, chunk_index, total_chunks, file_path, uploaded_size) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE chunk_index=?, uploaded_size=?");$stmt->execute([$taskId,$chunkIndex,$totalChunks,$filePath,$chunkFile['size'],$chunkIndex,$chunkFile['size']]);echojson_encode(['code'=>200,'msg'=>'分片上传成功']);}catch(Exception$e){echojson_encode(['code'=>500,'msg'=>'分片上传失败:'.$e->getMessage()]);}}// ==================== 合并分片处理函数 ====================functionhandleMergeChunks(){global$pdo,$uploadDir;try{$data=json_decode(file_get_contents('php://input'),true);$taskId=$data['taskId']??'';$filePath=$data['filePath']??'';if(!$taskId||!$filePath){die(json_encode(['code'=>400,'msg'=>'参数缺失']));}// 1. 查询所有分片$stmt=$pdo->prepare("SELECT chunk_index FROM upload_progress WHERE task_id=? ORDER BY chunk_index ASC");$stmt->execute([$taskId]);$chunks=$stmt->fetchAll(PDO::FETCH_COLUMN,0);// 2. 合并分片$mergedPath=$uploadDir.$filePath.'/merged_'.$taskId;$fp=fopen($mergedPath,'wb');foreach($chunksas$chunkIndex){$chunkPath=$uploadDir.$filePath.'/'.$chunkIndex;fwrite($fp,file_get_contents($chunkPath));unlink($chunkPath);// 删除临时分片}fclose($fp);// 3. 清理进度记录$pdo->prepare("DELETE FROM upload_progress WHERE task_id=?")->execute([$taskId]);echojson_encode(['code'=>200,'msg'=>'合并成功','path'=>$mergedPath]);}catch(Exception$e){echojson_encode(['code'=>500,'msg'=>'合并失败:'.$e->getMessage()]);}}// ==================== 加密函数 ====================functionaesEncrypt($data,$key){$iv=substr(md5($key),0,16);returnopenssl_encrypt($data,'AES-128-CBC',$key,OPENSSL_RAW_DATA,$iv);}functionaesDecrypt($data,$key){$iv=substr(md5($key),0,16);returnopenssl_decrypt($data,'AES-128-CBC',$key,OPENSSL_RAW_DATA,$iv);}functionsm4Encrypt($data,$key){// 实际需用SM4库(如https://github.com/xxtime/sm4-php)return$data;// 演示占位}functionsm4Decrypt($data,$key){// 实际需用SM4库return$data;// 演示占位}?>

四、数据库脚本(MySQL)

-- 创建数据库CREATEDATABASEIFNOTEXISTSfile_transferDEFAULTCHARSETutf8mb4COLLATEutf8mb4_unicode_ci;-- 使用数据库USEfile_transfer;-- 上传进度表(记录分片上传状态)CREATETABLEIFNOTEXISTSupload_progress(idINTAUTO_INCREMENTPRIMARYKEYCOMMENT'主键',task_idVARCHAR(255)NOTNULLCOMMENT'任务ID(如upload_1620000000_abc123)',chunk_indexINTNOTNULLCOMMENT'已上传分片索引(从0开始)',total_chunksINTNOTNULLCOMMENT'总分片数',file_pathVARCHAR(1000)NOTNULLCOMMENT'文件存储路径(如/folder_123/file.txt)',uploaded_sizeBIGINTNOTNULLCOMMENT'已上传大小(字节)',UNIQUEKEY(task_id,chunk_index)-- 防止重复记录)ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;

五、部署指南(客户服务器Apache)

1. 前端部署

  • Vue项目打包:npm run build,生成dist文件夹。
  • dist文件夹复制到Apache网站根目录(如/var/www/html/file-uploader)。

2. 后端部署

  • 将PHP代码上传到Apache的upload目录(如/var/www/html/upload)。
  • 安装Composer依赖:composer require mysql/pdo-mysql(用于数据库连接)。
  • 修改handler.php中的数据库配置($dbHost,$dbUser,$dbPass,$uploadDir)。

3. 服务器配置

  • 确保Apache启用mod_php模块(支持PHP脚本)。
  • /var/www/html/uploads/文件夹授予Apache用户(如www-data)读写权限:
    chown-R www-data:www-data /var/www/html/uploads/
  • 安装PHP扩展:pdo_mysql(用于数据库连接)、openssl(用于加密)。

六、找工作&接单群(学长真心话)

兄弟,这套系统你拿去给客户演示,甲方绝对挑不出刺——兼容IE8、支持20G文件、加密传输、断点续传全搞定。毕设答辩时老师看了直呼“专业”,找工作时面试官看了直接给offer!

现在加群(QQ:374992201),私聊我“外包”,直接发你客户案例和合同模板!群里还有一堆PHP大佬,遇到问题直接甩日志截图,老司机带你改代码。

:完整源码包链接(百度网盘):https://pan.baidu.com/s/1abc123defg(提取码:xyz123),输入密码即可下载!

安装环境

PHP:7.2.14

调整块大小

NOSQL

NOSQL不需要任何配置,可以直接访问测试

SQL

创建数据库

您可以直接复制脚本进行创建

配置数据库连接

安装依赖

访问页面进行测试

数据表中的数据

效果预览

文件上传

文件刷新续传

支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传

文件夹上传

支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。

免费下载示例

点击下载完整示例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1173237.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2026年1月美容仪推荐排行榜单深度评测与选购指南:五款产品客观对比分析 - 十大品牌推荐

一、引言 在追求高效、便捷与个性化护肤的今天,家用美容仪已成为众多消费者,特别是关注抗衰、提升肤质与追求高质价比护肤体验人群的重要选择工具。目标用户涵盖从护肤爱好者到寻求轻医美替代方案的消费者,其核心需…

2026年1月智能客服机器人服务商推荐排行榜单:五大服务商深度对比与评测分析 - 十大品牌推荐

一、引言 在数字化转型浪潮中,智能客服机器人已成为企业优化客户服务流程、降低运营成本、提升服务效率的关键工具。对于广大企业管理者、IT采购负责人及客户服务部门决策者而言,核心需求在于找到技术成熟、性能稳定…

2026年,银川本地做地图推广选哪家靠谱?门店地图推广,商家地图推广,企业地图推广,真实案例见证实力! - 宁夏壹山网络

现在银川本地商户和企业越来越重视地图推广,毕竟很多用户找本地服务、门店位置,第一反应就是打开地图搜索。但地图推广可不是简单标个地址就行,信息不准、排名靠后、内容单调,都会错失大量精准客源。找外地公司不懂…

PHP网页中如何编写支持文件夹上传的大文件示例?

2023年10月25日 星期三 多云转晴 毕业设计攻坚日记 - 大文件管理系统Day1 需求分析与技术选型 今天正式启动文件管理系统的毕业设计。核心需求很明确&#xff1a; 大文件传输&#xff1a;10G文件需分片上传&#xff0c;需兼容IE8&#xff08;地狱级难度&#xff09;加密&…

2026年行业内比较好的脚手架厂家推荐排行榜,顶托/穿墙螺丝/u型丝预埋件/脚手架/丝杠,脚手架实力厂家推荐 - 品牌推荐师

献县路杰建筑器材有限公司发布行业白皮书,解析脚手架领域发展趋势 近日,献县路杰建筑器材有限公司正式发布《2026年脚手架行业白皮书》,从行业现状、技术挑战、未来趋势及解决方案等多维度展开分析,为建筑工程领域…

2026年1月智能学习机品牌推荐排行榜:十款产品深度对比与选购评测 - 十大品牌推荐

一、引言 在数字化教育浪潮与人工智能技术加速普及的背景下,智能学习机已成为众多家庭辅助孩子进行课后学习、实现个性化提升的重要工具。对于广大家长及教育产品采购者而言,其核心需求在于通过这一工具有效保障学习…

军工仿真软件如何实现三维模型截图通过CKEDITOR上传?

山西网络公司程序员&#xff1a;Word粘贴与多格式文档导入功能开发实录 一、需求分析与技术选型 作为项目核心开发人员&#xff0c;我首先对客户需求进行了详细拆解&#xff1a; 富文本粘贴&#xff1a;需支持Word/微信公众号内容粘贴&#xff0c;自动上传图片&#xff08;二…

长春市英语雅思培训辅导机构推荐,2026权威出国雅思课程排行榜 - 苏木2025

全球化留学热潮下,雅思成绩是海外院校申请的核心敲门砖,但培训市场乱象丛生,给考生选课带来诸多阻碍。对长春市及全国雅思考生而言,筛选权威靠谱、性价比突出的优质机构,匹配个性化提分方案、掌握考试技巧实现高分…

石家庄市英语雅思培训辅导机构推荐,2026权威出国雅思课程排行榜 - 苏木2025

留学热潮下,雅思考试已成石家庄学子海外求学必经之路,但备考难题让众多考生受阻。雅思培训市场鱼龙混杂,精准选课、筛选靠谱优质教育机构,获取实用全面备考方案,掌握高效提分技巧实现高分突破,是考生及家长核心诉…

长春市英语雅思培训辅导机构推荐;2026权威出国雅思课程排行榜 - 苏木2025

在雅思培训领域,选课难、考试提分慢、优质教育机构甄别不易等问题一直困扰着广大考生及家长。据权威调研数据显示,超7成雅思考生在备考过程中因缺乏实用的提分技巧、未匹配个性化学习方案,导致备考周期延长、学习效…

2026年1月智能学习机品牌推荐排行榜:十款产品深度对比与选购指南 - 十大品牌推荐

一、引言 在当今教育环境持续变革的背景下,智能学习机已成为连接学校教育与家庭辅导的关键桥梁,尤其对于广大学生家长及关注子女学业成长的消费者而言,其重要性日益凸显。目标用户的核心需求聚焦于通过科技手段提升…

沈阳市英语雅思培训辅导机构推荐,2026权威出国雅思课程排行榜 - 苏木2025

随着留学热潮的持续升温,雅思考试已成为众多学子通往海外院校的必经之路,但雅思培训市场鱼龙混杂,选课难题让无数考生和家长陷入焦虑。如何在海量教育机构中筛选出优质、靠谱的选择,获取实用且全面的提分技巧,实现…

太原市英语雅思培训辅导机构推荐;2026权威出国雅思课程排行榜 - 苏木2025

在全球化留学热潮下,雅思考试已成为学子开启海外求学之路的关键门槛,而优质雅思培训的选择却成为众多考生及家长的核心困扰。当前雅思培训市场鱼龙混杂,选课过程中充斥着信息不对称、师资资质难甄别、提分效果无保障…

2026租车体验分享:哪些公司服务更胜一筹?婚车租赁/婚礼租车/大巴租车/会展包车/中巴租车/班车租赁,租车企业哪家好 - 品牌推荐师

随着出行需求多元化与消费升级,租车行业已成为连接个人出行、商务活动与大型场景服务的关键纽带。为帮助消费者及企业用户精准筛选优质服务商,本次评测聚焦车辆品质、服务响应、定制能力、性价比及售后保障五大维度,…

基于VUE的动漫后台管理系统[VUE]-计算机毕业设计源码+LW文档

摘要&#xff1a;随着动漫产业的蓬勃发展&#xff0c;高效管理动漫相关信息变得至关重要。本文旨在设计并实现基于VUE的动漫后台管理系统&#xff0c;以提升管理效率与信息处理能力。通过需求分析明确系统应具备的功能&#xff0c;如用户管理、商品&#xff08;动漫相关商品&am…

ssm609的班主任辅导员班级管理系统vue

目录SSM609班主任辅导员班级管理系统Vue摘要开发技术源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;SSM609班主任辅导员班级管理系统Vue摘要 该系统基于SSM&#xff08;SpringSpringMVCMyBatis&#xff09;框架与Vue.js前端技术开发&a…

2026年1月智能学习机品牌推荐排行榜:十款产品深度对比选购评测 - 十大品牌推荐

一、引言 在数字化教育浪潮与人工智能技术快速迭代的背景下,智能学习机已成为现代家庭辅助孩子学业成长的重要工具。对于广大家长及教育产品采购者而言,其核心需求在于通过这一工具,有效提升孩子的学习效率与效果,…

2026年1月智能学习机品牌推荐排行榜:十大品牌深度对比与选购评测 - 十大品牌推荐

一、引言 在数字化教育浪潮与人工智能技术深度结合的当下,智能学习机已成为众多家庭辅助孩子进行系统性学习、实现个性化提升的重要工具。对于广大家长及教育产品的采购者而言,面对市场上琳琅满目的品牌与型号,其核…

ssm610的班级同学通讯录网站系统

目录班级同学通讯录网站系统摘要开发技术源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;班级同学通讯录网站系统摘要 SSM610班级同学通讯录网站系统基于SSM框架&#xff08;SpringSpring MVCMyBatis&#xff09;开发&#xff0c;旨在为…

代码源挑战赛 Round 46

A 简单题 B 简单题 C 暴力模拟即可。 D 记 \(c _ {k, s}\) 为 \(1 \le i < j < i\) 且 \(a _ i + a _ j = s\) 的 \((i, j)\) 个数,那么枚举 \(k\) 和 \(l\),合法的 \((i, j)\) 个数即为 \(c _ {k, a _ k + a …