/* ========================================================================== * JCSS 小程序 · UI 统一规范层 * -------------------------------------------------------------------------- * 依据:jcss-mp-design/index.html(42 页设计稿,1px = 2rpx) * 引入:App.vue 全局 style(非 scoped),一处改动全站生效 * 约束:只定义样式;不涉及任何 JS / 接口 / 状态判断 / 点击事件 / 数据渲染 * ========================================================================== */ /* ========================================================================== * 1. 设计令牌(与设计稿 :root 变量一一对应,px × 2 = rpx) * ========================================================================== */ /* --- 1.1 品牌色 --- */ $j-brand: #2563EB; $j-brand-a: #1D4ED8; $j-brand-light: #EBF3FF; /* --- 1.2 操作语义色:严格绑定按钮类型 --- */ $j-approve: #16A34A; // 审批通过 · 绿 $j-assign: #2563EB; // 分配 / 转派 / 详情 · 蓝 $j-return: #D97706; // 退回 · 橙 $j-reject: #DC2626; // 驳回 / 危险操作 · 红 $j-neutral: #6B7280; // 撤回 / 次要 · 灰 $j-doing: #0891B2; // 进行中 · 青 /* --- 1.2.1 操作按钮色板(列表 / 详情卡片按钮,按设计稿 94 取色) --- */ $j-btn-primary: #3B9DFF; // 分配 / 详情 · 亮蓝 $j-btn-primary-a: #2E8AE6; $j-btn-success: #078D0A; // 审批通过 / 实施 / 结束 · 深绿 $j-btn-success-a: #066B08; $j-btn-warning: #F9AE3D; // 退回 · 琥珀 $j-btn-warning-a: #E39A2C; $j-btn-danger: #F56C6C; // 驳回 / 危险操作 · 柔红 $j-btn-danger-a: #E05959; $j-btn-info: #909399; // 撤回 / 次要 · 灰 $j-btn-info-a: #7D8085; $j-btn-transfer: #0891B2; // 转办 / 转派 · 青 $j-btn-transfer-a: #077A96; /* --- 1.3 语义底色(标签 / 提示条) --- */ $j-approve-bg: #EAF7EF; $j-assign-bg: #EBF3FF; $j-return-bg: #FDF4E7; $j-reject-bg: #FDECEC; $j-neutral-bg: #F4F5F7; $j-doing-bg: #E6F6FA; /* --- 1.4 点击态:同色系明暗微调,不换主色 --- */ $j-approve-a: #12833C; $j-assign-a: #1D4ED8; $j-return-a: #B96504; $j-reject-a: #B91C1C; $j-neutral-a: #565E6B; /* --- 1.5 文本色 --- */ $j-text-title: #111827; // 卡片主标题 $j-text-label: #6B7280; // 标签(次级灰) $j-text-value: #1F2937; // 内容值(正文黑) $j-text-weak: #6B7280; // 辅助说明 $j-text-strong: #111827; // 强调值 /* --- 1.6 字号层级(全站 6 档) --- */ $j-fs-title: 32rpx; // 16px 卡片主标题 $j-fs-lg: 30rpx; // 15px 次级标题 $j-fs-label: 26rpx; // 13px 标签 / 内容值 $j-fs-value: 26rpx; // 13px 内容值 $j-fs-btn: 24rpx; // 12px 按钮文字 $j-fs-tip: 22rpx; // 11px 标签 / 辅助说明 /* --- 1.7 间距 --- */ $j-sp-xs: 8rpx; // 4px $j-sp-sm: 16rpx; // 8px $j-sp-md: 24rpx; // 12px $j-sp-lg: 32rpx; // 16px $j-gap-item: 6rpx; // 3px 信息行之间 $j-gap-btn: 16rpx; // 8px 按钮之间 $j-page-pad: 24rpx; // 12px 页面内边距 $j-card-pad: 24rpx; // 12px 卡片内边距 /* --- 1.8 容器色 --- */ $j-bg: #F4F6FA; // 页面底 $j-card: #ffffff; // 卡片 $j-line: #E8EBF0; // 分隔线 $j-block: #F4F6FA; // 弱区块 / 次级标签底 /* --- 1.9 圆角(4px / 8px / 12px / 胶囊) --- */ $j-r-btn: 8rpx; $j-r-card: 16rpx; $j-r-lg: 24rpx; $j-r-pill: 999rpx; /* --- 1.10 阴影 --- */ $j-shadow-card: 0 4rpx 16rpx rgba(17, 24, 39, 0.06); $j-shadow-float: 0 -8rpx 28rpx rgba(17, 24, 39, 0.08); /* ========================================================================== * 2. 信息项:标签自然宽 + 值左对齐(设计稿 .kv) * -------------------------------------------------------------------------- * 标签浅灰靠左,值紧跟标签之后并左对齐,读起来是「标签:值」一句话, * 长文本换行也从固定位置起始,不会出现值忽左忽右的观感。 * ========================================================================== */ .u-body-item { display: flex !important; align-items: flex-start !important; gap: $j-sp-sm !important; margin-bottom: $j-gap-item !important; &:last-child { margin-bottom: 0 !important; } } /* 单行信息项(带 common-item-center)仍按垂直居中排版 */ .u-body-item.common-item-center { align-items: center !important; } .u-body-item-title { flex: 0 0 auto !important; width: auto !important; min-width: 0 !important; font-size: $j-fs-label !important; font-weight: 400 !important; color: $j-text-label !important; line-height: 1.5 !important; white-space: nowrap; } .u-body-value { flex: 1 1 auto; min-width: 0; font-size: $j-fs-value !important; font-weight: 400 !important; color: $j-text-value !important; line-height: 1.5 !important; text-align: left; word-break: break-all; } /* 卡片主标题:比信息项高一级 */ .common-card-list .common-name, .card-header .common-name, .common-card-title { font-size: $j-fs-title !important; font-weight: 500 !important; color: $j-text-title !important; line-height: 1.4 !important; } /* ========================================================================== * 3. 操作按钮:五类语义色 + 统一尺寸(含三套现有实现) * -------------------------------------------------------------------------- * task-btn:列表卡按钮 order-action-btn:详情底部按钮 * 均为 56rpx 高(28px)/ 24rpx 白字 / 8rpx 圆角,文字过长省略不换行 * ========================================================================== */ .task-btn, .order-action-btn { box-sizing: border-box; height: 56rpx; line-height: 56rpx; padding: 0 24rpx; border-radius: $j-r-btn; font-size: $j-fs-btn !important; font-weight: 400; color: #ffffff !important; // 按钮内文字统一白色 text-align: center !important; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: background-color 0.15s ease; } // 亮蓝:详情等次要主操作 .task-btn--primary, .order-action-btn--primary { background-color: $j-btn-primary !important; &:active { background-color: $j-btn-primary-a !important; } } // 深蓝:分配(卡片主操作,比「详情」深一级) .task-btn--assign, .order-action-btn--assign { background-color: $j-assign !important; &:active { background-color: $j-assign-a !important; } } // 深绿:审批通过 / 实施 / 结束 .task-btn--success, .order-action-btn--success { background-color: $j-btn-success !important; &:active { background-color: $j-btn-success-a !important; } } // 琥珀:退回 .task-btn--warning, .order-action-btn--warning { background-color: $j-btn-warning !important; &:active { background-color: $j-btn-warning-a !important; } } // 青:转办 / 转派 .task-btn--transfer, .order-action-btn--transfer { background-color: $j-btn-transfer !important; &:active { background-color: $j-btn-transfer-a !important; } } // 红:驳回 / 危险操作 .task-btn--error, .order-action-btn--error { background-color: $j-btn-danger !important; &:active { background-color: $j-btn-danger-a !important; } } // 灰:撤回 / 次要 .task-btn--info, .order-action-btn--info { background-color: $j-btn-info !important; &:active { background-color: $j-btn-info-a !important; } } /* ========================================================================== * 4. 按钮行:auto-fit 自适应换行 * -------------------------------------------------------------------------- * 原实现为 grid repeat(var(--cols)),列数由 JS 算出(最多 5 列), * 按钮多时被压窄溢出。改为 auto-fit 后由容器宽度决定每行个数: * 5 个 → 3+2 两行;3 个 → 一行等分;2 个 → 各占一半;1 个 → 独占一行 * JS 传入的 --cols 自动失效(仅样式层变化,不改 JS)。 * ========================================================================== */ .task-btn-row, .order-action-row { display: grid !important; grid-template-columns: repeat(auto-fit, minmax(144rpx, 1fr)) !important; gap: $j-gap-btn !important; margin-bottom: 0 !important; } .task-btn-row > view, .order-action-row > view { min-width: 0; // 防止长文案撑破栅格 } /* ========================================================================== * 5. 通用绝对定位按钮(历史实现,仅保留配色,新页面改用 .card-action-row) * ========================================================================== */ .common-custom-btn { background-color: $j-assign !important; color: #ffffff !important; border-radius: $j-r-btn !important; padding: 8rpx 24rpx !important; font-size: $j-fs-btn !important; line-height: 1.4; text-align: center; white-space: nowrap; transition: background-color 0.15s ease; &:active { background-color: $j-assign-a !important; } &.disabled { background-color: #93B4F5 !important; opacity: 0.7; } } /* ========================================================================== * 5.1 卡片内按钮语义化(设计稿 .btn.sm / .btn-link) * -------------------------------------------------------------------------- * 主操作 = 蓝底白字 / 次要操作 = 白底描边 / 危险操作 = 红色文字 * 尺寸:高 56rpx(28px) · 字号 24rpx(12px) · 圆角 8rpx(4px) · 左右 24rpx * ========================================================================== */ .mini-btn { box-sizing: border-box; display: flex; align-items: center; justify-content: center; min-width: 120rpx; height: 56rpx; padding: 0 $j-sp-md; font-size: $j-fs-btn !important; font-weight: 400; color: #ffffff !important; text-align: center !important; border-radius: $j-r-btn; flex-shrink: 0; white-space: nowrap; transition: background-color 0.15s ease; } .mini-btn--primary { background-color: $j-assign !important; &:active { background-color: $j-assign-a !important; } } .mini-btn--info { background-color: $j-neutral !important; &:active { background-color: $j-neutral-a !important; } } /* 次要操作:白底描边,与主操作同一行时形成主次对比 */ .mini-btn--plain { color: $j-text-value !important; background-color: #ffffff !important; border: 1rpx solid $j-line; &:active { background-color: $j-block !important; } } /* 置为失效 / 删除类危险操作:红色文字按钮,占位与普通按钮一致 */ .btn-text-danger, .btn-set-invalid { flex-shrink: 0; padding: 8rpx 0; font-size: $j-fs-label !important; font-weight: 400; color: $j-reject !important; line-height: 1.4; white-space: nowrap; transition: color 0.15s ease; &:active { color: $j-reject-a !important; opacity: 0.8; } } /* ========================================================================== * 6. 详情页统一:u-cell 排版收口(设计稿 .card.pad + .kv) * -------------------------------------------------------------------------- * 三类工单(养护 / 区域 / AI)详情都用 up-cell 渲染字段,此处统一层级: * 标签 26rpx #6B7280 左 / 内容值 26rpx #1F2937 紧跟标签后,左对齐 / 行内 16rpx 上下 * 注意:uview-plus 单元格内部类名为 u-cell__xxx(组件内为 scoped 样式), * 全局层必须带 !important 才生效。 * 组件默认给 title 加 flex:1、给 value 加 margin-left:auto,值会被推到最右, * 只改 text-align 不生效,必须同时收回 title 的 flex 并让 value 占满剩余宽度。 * ========================================================================== */ .u-cell__body { display: flex !important; justify-content: space-between !important; column-gap: $j-sp-sm !important; padding: 16rpx $j-card-pad !important; } /* 单元格之间的分隔线沿用 uview 的 u-line,仅去掉卡片最后一行的尾线 */ .u-cell-group__wrapper > .u-cell:last-child .u-line { display: none !important; } .u-cell__title-text, .u-cell__label { font-size: $j-fs-label !important; font-weight: 400 !important; color: $j-text-label !important; line-height: 1.5 !important; } /* 标签只占自身宽度,值紧随其后: * 标签与内容之间的距离固定 16rpx(与列表卡片 .u-body-item 的 gap 保持一致) */ .u-cell__title { flex: 0 1 auto !important; min-width: 0; } /* 标题区外层容器:组件默认 flex:1,会把整行剩余宽度都吃掉, * 导致 value 只能从半行之后开始,看起来像居中/右对齐,这里收回成「按内容宽度」 */ .u-cell__body__content { flex: 0 1 auto !important; min-width: 0; } /* #value 插槽:内容会被直接渲染成 .u-cell__body 的 flex 子元素(不是 u-cell__value), * 上面那套规则管不到,必须单独补一份,否则插槽渲染的字段仍然贴在最右边 */ .u-cell__body > view:not(.u-cell__body__content):not(.u-cell__left-icon-wrap):not(.u-cell__right-icon-wrap) { flex: 1 1 auto !important; min-width: 0; text-align: left !important; } /* 标题插槽(#title 自定义 view)同样收到「标签」层级; * 模板里常给这个 view 写 inline 的 min-width: 200rpx,会把间距撑成一大段, * 这里用 !important 统一收回,保证所有页面的「标签—内容」距离都是 16rpx */ .u-cell__title > view { min-width: 0 !important; font-size: $j-fs-label !important; font-weight: 400 !important; color: $j-text-label !important; line-height: 1.5 !important; } .u-cell__value { flex: 1 1 auto !important; min-width: 0; margin-left: 0 !important; font-size: $j-fs-value !important; font-weight: 400 !important; color: $j-text-value !important; line-height: 1.5 !important; text-align: left !important; word-break: break-all; } /* 插槽内的内容值统一走 .common-text-color(App.vue 中定义为 #1F2937) */ /* 信息区块统一成卡片:四周留白一致,标题/内容与边框保持固定间距 */ .u-cell-group { box-sizing: border-box; margin: 0 $j-page-pad $j-sp-md !important; border-radius: $j-r-card; overflow: hidden; background-color: $j-card; } /* 级联选择器弹层内的单元格保持原样(多列并排,不能加外边距) */ .area-item .u-cell-group { margin: 0 !important; border-radius: 0; background-color: transparent; } /* 「我的」页单元格本来就在白色圆角面板内,不再叠加卡片外框 */ .mine-content .u-cell-group { margin-left: 0 !important; margin-right: 0 !important; border-radius: 0; } /* 详情页附图区块:与上方信息卡同宽同圆角,避免出现整宽的白色通栏 */ .img-tabs-block { margin: 0 $j-page-pad $j-sp-md; border-radius: $j-r-card; overflow: hidden; } /* ========================================================================== * 6.1 卡片内的操作区(设计稿 .tcard-foot) * -------------------------------------------------------------------------- * 操作按钮不再用绝对定位悬浮在卡片上,统一收进底部操作区: * 上方 16rpx 留白 + 1rpx 分隔线,按钮右对齐,间距 16rpx * ========================================================================== */ .card-action-row { display: flex; align-items: center; justify-content: flex-end; gap: $j-gap-btn; margin-top: $j-sp-sm; padding-top: $j-sp-sm; border-top: 1rpx solid $j-line; } /* ========================================================================== * 7. 状态标签(设计稿 .tag:高 40rpx / 字号 22rpx / 圆角 8rpx / 左右 16rpx) * ========================================================================== */ .urgency-tag, .common-invalid-tag, .common-finish-tag, .common-pending-tag, .common-timeout-tag, .status-tag { display: inline-flex !important; align-items: center !important; flex-shrink: 0; height: 40rpx; padding: 0 $j-sp-sm; font-size: $j-fs-tip !important; font-weight: 500; border-radius: $j-r-btn; line-height: 1; white-space: nowrap; } /* 待完成:浅蓝底蓝字 */ .common-pending-tag { background-color: $j-assign-bg !important; color: $j-assign !important; } /* 已完成:浅绿底绿字 */ .common-finish-tag { background-color: $j-approve-bg !important; color: $j-approve !important; } /* 已失效:灰底灰字(设计稿 invalid 为中性灰,不是红色) */ .common-invalid-tag { background-color: $j-neutral-bg !important; color: $j-neutral !important; } /* 超时:浅红底红字 */ .common-timeout-tag { background-color: $j-reject-bg !important; color: $j-reject !important; } /* ========================================================================== * 8. 全局文本基线 * ========================================================================== */ page { font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: $j-fs-value; color: $j-text-title; line-height: 1.5; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: 100%; background-color: $j-bg; } /* ========================================================================== * 9. Tab 组件统一 * ========================================================================== */ .u-tabs__wrapper__nav__line { background-color: $j-brand !important; } .u-tabs__wrapper__nav__item__text { font-size: 28rpx !important; // 设计稿 tab 字号 14px } /* --- 9.1 首页下划线式一级 Tab --- */ .main-tab-item { font-size: $j-fs-lg; color: $j-text-value; font-weight: 400; &.active { color: $j-brand; font-weight: 500; &::after { background-color: $j-brand; } } } /* --- 9.2 胶囊 Tab --- */ .tab-capsule { font-size: $j-fs-label; color: $j-text-weak; background-color: $j-block; border-radius: $j-r-btn; &.active { color: $j-brand; background-color: $j-brand-light; } } /* ========================================================================== * 9.3 搜索条(设计稿 .search-bar / .sbox) * -------------------------------------------------------------------------- * u-search 在 animation=true 时右侧「搜索」宽度为 0,只在输入框聚焦后才展开; * 设计稿要求常显,这里用样式补回宽度与间距,不修改组件 props。 * 圆角按设计稿做成圆角矩形(8px),不是左右全圆的胶囊。 * ========================================================================== */ .u-search__content { border-radius: $j-r-card !important; } .u-search__action { width: 40px !important; margin-left: $j-sp-sm !important; font-size: $j-fs-label !important; color: $j-brand !important; } /* ========================================================================== * 10. 弹层收起兜底:过渡层不拦截点击 * -------------------------------------------------------------------------- * uview-plus 的 u-transition 把 mergeStyle 里的 display:none 注释掉了, * 收起动画结束后要等 setTimeout(onTransitionEnd) 才真正移除节点。 * u-popup 的遮罩是 position:fixed + z-index 10075 的全屏层,收起时透明度 * 已降为 0,一旦该定时器被页面重渲染打断,就会残留一个「看不见但吃点击」 * 的透明层,表现为页面正常显示、所有按钮却都点不动。 * 这里让处于收起动画的过渡层不接收点击:无功能变化(300ms 收起期间本来 * 也不该再点下层),但可以彻底消除上述残留遮挡。 * ========================================================================== */ .u-transition.u-fade-leave-active, .u-transition.u-fade-up-leave-active, .u-transition.u-fade-down-leave-active, .u-transition.u-fade-left-leave-active, .u-transition.u-fade-right-leave-active, .u-transition.u-fade-zoom-leave-active, .u-transition.u-slide-up-leave-active, .u-transition.u-slide-down-leave-active, .u-transition.u-slide-left-leave-active, .u-transition.u-slide-right-leave-active, .u-transition.u-zoom-leave-active { pointer-events: none !important; }