Regression / regression (push) Canceled after 0s
## 品牌标识(本次会话) 起因:品牌此前没有任何图形标识 —— 唯一 favicon 是内联 data-URI 里的字母「A」, 那是 v2.0.0「Aurora Admin → Kole UI」改名漏掉的一处(PC 顶栏也是「A」, 移动端站已是「K」;移动端文档站则完全没有 favicon)。 - 几何:24 网格三个互不接触的笔画(竖 + 两斜),圆头描边; 描边 2.25 → 16px 标签页尺寸下正好 1.5px = 规范原文「描边1.5px」 - 取色分两套(刻意):favicon 硬编码品牌蓝/白(渲染在浏览器标签栏,不继承 kole-dark); 顶栏标记走 currentColor(实测暗色下自动转 rgb(20,22,28)) - 新增 theme-color 双条(light #FFFFFF / dark #1C1F26,取 --kole-color-card-bg) - 修 site/app.js hero 标语 KOLE ADMIN → KOLE UI(改名变形残留) - 移动端 7 个模板补 favicon(此前计数 0) 验收:门禁 9 条全 OK(site-routing/site-routes/mobile-docs/mobile-site/isolation/ theme/nav/i18n/icons);PC 回归 1464/1464 · 移动端 807/807,各连跑 8 次一致; 两端 favicon 405 字节逐字节一致;PC 站控制台错误 1→0。 ## 并行会话成果(本次一并入库) - 图标系统:2576 图标(TDesign/Element Plus,MIT)+ 11 端注入 + 5 个构建门禁工具 + IconPreview 预览页 + ICON-SPEC.md 冻结规格 - 移动端平台:47 组件 × 6 端 + 文档站 53 页 + 隔离门禁 - PC 组件:103 个大后台组件 / 组件11 批次 - uni-app:PC 端试点 + 移动端端实现 + 真实编译验证 ## 工程 - .gitignore 补 .scratch/ 与 .zcode-preexisting-*.txt(会话中间产物,实测 9.1MB,不入库) - CHANGELOG 补品牌标识条目 - ROADMAP 登 S8-P4(品牌标识任务包 + og:image/apple-touch-icon 未做部分)
250 lines
9.3 KiB
JSON
250 lines
9.3 KiB
JSON
{
|
||
"schemaVersion": 1,
|
||
"sourceKind": "authored-spec",
|
||
"provenance": "authored-in-repo",
|
||
"specFile": "spec/移动端规格.md",
|
||
"specSection": "46 · 上传 Upload",
|
||
"confidence": "high",
|
||
"slug": "mobile-upload",
|
||
"name": "上传 Upload",
|
||
"semanticTypeCandidates": [
|
||
"upload",
|
||
"file-input",
|
||
"attachment"
|
||
],
|
||
"variantDimensions": [
|
||
{
|
||
"name": "variant",
|
||
"values": [
|
||
"dashed",
|
||
"button"
|
||
]
|
||
},
|
||
{
|
||
"name": "maxCount",
|
||
"values": [
|
||
"reached",
|
||
"not-reached"
|
||
]
|
||
}
|
||
],
|
||
"representativeVariants": [
|
||
{
|
||
"variant": "dashed",
|
||
"maxCount": "not-reached",
|
||
"label": "虚线框(页面级上传区)"
|
||
},
|
||
{
|
||
"variant": "button",
|
||
"maxCount": "not-reached",
|
||
"label": "实心按钮(列表内嵌的「+ 添加」)"
|
||
},
|
||
{
|
||
"variant": "dashed",
|
||
"maxCount": "reached",
|
||
"label": "到上限(触发器变成不可点的提示行)"
|
||
},
|
||
{
|
||
"variant": "dashed",
|
||
"maxCount": "not-reached",
|
||
"label": "禁用(触发器与删除按钮都不可用)"
|
||
}
|
||
],
|
||
"anatomy": {
|
||
"upload": "根元素,纵向排列「标题行 + 触发器 + 文件列表」",
|
||
"upload__header": "标题与计数(已选 N / 上限 M)",
|
||
"upload__trigger": "选择触发器,点击调起系统文件选择器;dashed 是虚线框,button 是实心按钮",
|
||
"upload__list": "文件列表容器",
|
||
"upload__item": "单个文件行,行高不小于 44px",
|
||
"upload__thumb": "缩略图位(图片用背景图,其他类型放扩展名文字块)",
|
||
"upload__body": "文件名与「进度条 + 状态文案」的容器",
|
||
"upload__track": "进度条轨道,role=progressbar",
|
||
"upload__bar": "进度段,宽度取 --kole-m-upload-percent",
|
||
"upload__actions": "行内动作(重试 / 删除),各自 44px 热区"
|
||
},
|
||
"structurePatterns": {
|
||
"variant": "dashed(虚线框,页面级上传区)/ button(实心按钮,列表内嵌的「+ 添加」)",
|
||
"maxCount": "文件数上限(到达上限后触发器变成提示行,不再可点)",
|
||
"disabled": "false(可交互)/ true(触发器与删除按钮都不可用)"
|
||
},
|
||
"usageHints": [
|
||
"把手机里的文件交给服务端(实名认证的身份证照、报销的发票、工单的附件)",
|
||
"移动端没有拖拽也没有 hover,触发按钮是唯一入口,虚线框只表达「这里可以放东西」",
|
||
"点触发器调起系统文件选择器(本组件不发请求,选完由宿主拿文件并自行上传)",
|
||
"进度不自己走:没有内置定时器或假进度,百分比全部由宿主回传",
|
||
"删除按钮自己 44px 热区,点一次移除该项;删除进行中(uploading)时文案是「取消」",
|
||
"失败行提供「重试」,重试由宿主重新发起,组件只回传下标"
|
||
],
|
||
"doNotInvent": [
|
||
"真实的传输:请求、分片、断点续传、并发数(本组件只回传事件,不发任何请求)",
|
||
"图片压缩、裁剪、水印与方向纠正",
|
||
"服务端的校验规则(大小上限、类型白名单以文案与 accept 表达,不代为判断)",
|
||
"拍照与相册的原生调起(由宿主在 select 事件里自行调用平台 API)"
|
||
],
|
||
"unknowns": [
|
||
"上传中能否同时继续添加文件(当前允许,列表各自独立)",
|
||
"失败自动重试的次数与退避策略",
|
||
"是否需要在成功行上展示服务端返回的文件 id / URL"
|
||
],
|
||
"interaction": [
|
||
"点触发器调起系统文件选择器(本组件不发请求,选完由宿主拿文件并自行上传)",
|
||
"删除按钮自己 44px 热区,点一次移除该项;删除进行中(uploading)时文案是「取消」",
|
||
"失败行提供「重试」,重试由宿主重新发起,组件只回传下标",
|
||
"进度不自己走:没有内置定时器或假进度,百分比全部由宿主回传,避免出现「看起来在上传其实没动」",
|
||
"列表为空时显示空态文案;到 maxCount 后触发器改成不可点的提示行"
|
||
],
|
||
"accessibility": [
|
||
"触发器是原生 button,带 aria-disabled;到上限时用 disabled 让键盘跳过",
|
||
"进度条写 role=\"progressbar\" + aria-valuemin / aria-valuemax / aria-valuenow,aria-label 说明是哪个文件的进度",
|
||
"删除 / 重试按钮各自带 aria-label(含文件名),读屏播报「删除 合同扫描件.pdf」而不是孤零零的「删除」",
|
||
"状态文案是文字而不只是颜色(「已上传」「上传失败」),颜色不作为唯一信息通道"
|
||
],
|
||
"api": {
|
||
"source": "implementation",
|
||
"note": "props / events / slots 为 6 端实现的公共接口(说明文字取自规格对应小节)。字段名与各端源码逐名核对:node tools/verify-mobile-docs.mjs",
|
||
"requiredNote": "「必传」按严格定义:实现里**没有默认值**时才为 Y(本门禁逐条核对 props 与各端源码的默认值,防止契约与实现脱节)。",
|
||
"props": [
|
||
{
|
||
"name": "files",
|
||
"type": "Array<{ name: string, uid?: string, status?: 'pending'|'uploading'|'success'|'error', percent?: number }>",
|
||
"default": "[]",
|
||
"desc": "文件列表(宿主提供,状态与进度都由宿主回传)(规格 §46.4)",
|
||
"required": false
|
||
},
|
||
{
|
||
"name": "maxCount",
|
||
"type": "number",
|
||
"default": "9",
|
||
"desc": "文件数上限,到达后触发器变成提示行(规格 §46.3)",
|
||
"required": false
|
||
},
|
||
{
|
||
"name": "disabled",
|
||
"type": "boolean",
|
||
"default": "false",
|
||
"desc": "变体 disabled:触发器与删除按钮都不可用(规格 §46.3)",
|
||
"required": false
|
||
},
|
||
{
|
||
"name": "variant",
|
||
"type": "'dashed' | 'button'",
|
||
"default": "'dashed'",
|
||
"desc": "变体 variant:dashed 虚线框(页面级),button 实心按钮(列表内嵌)(规格 §46.3)",
|
||
"required": false
|
||
},
|
||
{
|
||
"name": "title",
|
||
"type": "string",
|
||
"default": "'附件'",
|
||
"desc": "标题行文案(规格 §46.2 upload__header)",
|
||
"required": false
|
||
},
|
||
{
|
||
"name": "emptyText",
|
||
"type": "string",
|
||
"default": "'还没有上传文件'",
|
||
"desc": "状态 empty 的占位文案(规格 §46.4)",
|
||
"required": false
|
||
},
|
||
{
|
||
"name": "accept",
|
||
"type": "string",
|
||
"default": "''",
|
||
"desc": "可接受的文件类型(透传给文件选择器;服务端校验规则不由本组件代为判断)(规格 §46.7)",
|
||
"required": false
|
||
}
|
||
],
|
||
"events": [
|
||
{
|
||
"name": "select",
|
||
"params": "—",
|
||
"desc": "点触发器时触发,宿主在此调起系统文件选择器(规格 §46.5)"
|
||
},
|
||
{
|
||
"name": "remove",
|
||
"params": "index: number",
|
||
"desc": "点删除(uploading 时是取消)时触发,回传条目下标(规格 §46.5)"
|
||
},
|
||
{
|
||
"name": "retry",
|
||
"params": "index: number",
|
||
"desc": "失败行点重试时触发,回传条目下标(规格 §46.5)"
|
||
}
|
||
],
|
||
"slots": [
|
||
{
|
||
"name": "default",
|
||
"desc": "自定义内容(追加在文件列表之后)"
|
||
}
|
||
]
|
||
},
|
||
"variantClasses": {
|
||
"variant": {
|
||
"dashed": [
|
||
".kole-m-upload--dashed"
|
||
],
|
||
"button": [
|
||
".kole-m-upload--button"
|
||
]
|
||
},
|
||
"maxCount": {
|
||
"reached": [
|
||
".kole-m-upload--full"
|
||
],
|
||
"not-reached": []
|
||
}
|
||
},
|
||
"demos": [
|
||
{
|
||
"id": "trigger",
|
||
"group": "01 组件类型",
|
||
"title": "选择触发",
|
||
"desc": "点一下调起系统文件选择器:移动端没有拖拽,这是唯一入口。",
|
||
"variant": "variant=dashed"
|
||
},
|
||
{
|
||
"id": "states",
|
||
"group": "01 组件类型",
|
||
"title": "四种状态",
|
||
"desc": "待上传 / 上传中(60%)/ 成功 / 失败;进度由宿主回传,组件不发请求。",
|
||
"variant": "variant=button"
|
||
},
|
||
{
|
||
"id": "removable",
|
||
"group": "02 组件状态",
|
||
"title": "可删除",
|
||
"desc": "删除按钮自己 44px 热区;删完后回到空态。",
|
||
"variant": "状态 removable"
|
||
},
|
||
{
|
||
"id": "disabled",
|
||
"group": "02 组件状态",
|
||
"title": "禁用与到顶",
|
||
"desc": "disabled 时触发器与删除都不可用;到 maxCount 后触发器改成提示行。",
|
||
"variant": "状态 disabled | 变体 maxCount=reached"
|
||
}
|
||
],
|
||
"related": [
|
||
{
|
||
"slug": "mobile-avatar",
|
||
"why": "单张头像的更换是更窄的场景,用头像组件自带的编辑态,不需要整个上传列表"
|
||
},
|
||
{
|
||
"slug": "mobile-dialog",
|
||
"why": "上传前要用户确认条款或选择来源时用它承载一步确认"
|
||
},
|
||
{
|
||
"slug": "mobile-list",
|
||
"why": "只读的附件陈列(不可增删)用列表更轻,上传的列表带状态与动作"
|
||
},
|
||
{
|
||
"slug": "mobile-toast",
|
||
"why": "上传成功 / 失败的单次反馈用它,不必在列表里堆第二条状态文案"
|
||
},
|
||
{
|
||
"slug": "mobile-loading",
|
||
"why": "等待服务端返回文件地址这类短暂阻塞用它,进度有多少用上传自己的进度条"
|
||
}
|
||
]
|
||
}
|