The old 售后 flow was an order-refund appendage: tickets were hard-bound to an order number, users could only file them from 「我的订单」against a paid order, and the admin action bottomed out at 「标记订单已退款」. It could not carry account questions or feature requests that have nothing to do with an order. Replace it with a general ticket system modelled on 魔方财务云's idcsmart_ticket: title + department + description are required, linking an order is optional (user's own paid orders only). Add departments, custom statuses, preset replies and internal admin notes as four configuration surfaces. Conversation history moves off the ticket row's JSON log into dedicated ticket_reply rows, which unlocks quoted replies. Front end gets a 工单中心 panel under 我的服务; back end moves from 支付中心 → 售后服务 to users.php → 工单管理. Per CLAUDE.md's rewrite-over-compatibility rule: drop the old table, build new ones, delete the old code. No dual paths, no data migration. The upstream plugin's upstream/downstream delivery and internal-ticket conversion are deliberately left out — both are multi-provider platform concerns with no meaning on a single WordPress site. Data: order_aftersale becomes six aksrt_ticket* tables (ticket, ticket_reply, ticket_status, ticket_type, ticket_prereply, ticket_note). SCHEMA_VERSION 2.6.0 -> 3.0.0. Status and department seeds are idempotent; the default status 「待接单」is flagged as non-editable. Domain: new src/Ticket/ (13 files, all under 460 lines). Attachments reuse UserController::rest_upload_comment_image with a ticket-specific permission callback, mirroring the existing /report/upload-image route rather than growing a second upload path. Notifications go through AKSRT\Messages\Message::send() and deep-link to the right surface; email/SMS stay out of scope since the theme's mail and SMS stacks are separate implementations. Refund gate opens up: marking an order refunded no longer requires an in-flight ticket, only that the order is paid. Also generalise a hardcoded special case in tools/audit-admin-contracts.php — schema domain inference now reads the parent directory instead of matching "PostList" by name, so new leaf schema files need no per-name exception. Verification: php tools/audit-admin-contracts.php exit 0, errors=0 node --test (widget-system + admin) 664 pass / 0 fail php -l over all new/changed files clean node --check over all JS clean npm run build + build:public clean Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
615 lines
17 KiB
CSS
615 lines
17 KiB
CSS
/**
|
||
* Modal runtime + ajax list primitives (shared).
|
||
*
|
||
* @package AKSRT
|
||
*/
|
||
|
||
/* ---- portal token bridge ----
|
||
*
|
||
* 弹窗由 runtime portal 到 <body>,因此它位于任何「页面级 token 作用域」之外。
|
||
* 典型陷阱:路由样式把语义别名挂在页面上,例如
|
||
*
|
||
* .aksrt-orders-page { --orders-ink: var(--color-ink, #333); }
|
||
*
|
||
* 弹窗内部再去 `var(--orders-ink)` 时该变量不存在,整条声明会被静默丢弃——
|
||
* 表现为边框消失、次级文字变透明,而不是抛错,排查成本很高。
|
||
*
|
||
* 因此共享调色板在这里声明:本壳层永远在 portal 内,任何弹窗都能直接消费
|
||
* `--modal-*`。路由样式应把自己的局部别名映射到这里,而不是映射到页面级变量。
|
||
*/
|
||
.aksrt-modal-runtime {
|
||
--modal-ink: var(--color-ink, #333333);
|
||
--modal-ink-2: var(--color-ink-2, #4e5358);
|
||
--modal-muted: var(--color-ink-3, #777777);
|
||
--modal-line: var(--color-line-stronger, rgba(50, 50, 50, 0.12));
|
||
--modal-line-soft: var(--color-line, rgba(50, 50, 50, 0.06));
|
||
--modal-surface: var(--surface-1, #ffffff);
|
||
--modal-surface-2: var(--surface-2, #eeeeee);
|
||
--modal-surface-3: var(--surface-4, #f8f8f8);
|
||
--modal-primary: var(--color-primary, #f04494);
|
||
--modal-on-primary: var(--color-on-primary, #ffffff);
|
||
--modal-warning: var(--color-warning, #f59e0b);
|
||
--modal-success: var(--color-success, #10b981);
|
||
--modal-danger: var(--color-danger, #ef4444);
|
||
}
|
||
|
||
/* ---- scroll lock ---- */
|
||
html.aksrt-modal-runtime-open,
|
||
body.aksrt-modal-runtime-open {
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* ---- 对话框宽度类不得作用于壳 ----
|
||
触发器沿用参考主题的 data-class 语义(modal-mini/full-sm 等),
|
||
但这些类落在 fixed 全屏壳上时,.modal-mini 的 width:400px +
|
||
auto 边距会把壳压成居中单列,蒙版随之只覆盖一列。 */
|
||
.aksrt-modal-runtime.modal-mini,
|
||
.aksrt-modal-runtime.full-sm {
|
||
width: auto;
|
||
max-width: none;
|
||
margin: 0;
|
||
}
|
||
|
||
/* ---- modal runtime shell ---- */
|
||
.aksrt-modal-runtime {
|
||
position: fixed;
|
||
inset: 0;
|
||
z-index: 100050;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
opacity: 0;
|
||
visibility: hidden;
|
||
transition: opacity 0.2s ease, visibility 0.2s ease;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.aksrt-modal-runtime.is-open {
|
||
opacity: 1;
|
||
visibility: visible;
|
||
pointer-events: auto;
|
||
}
|
||
|
||
.aksrt-modal-runtime__overlay {
|
||
position: absolute;
|
||
inset: 0;
|
||
/* 参考主题 .modal-backdrop 同款:纯黑 50%,无模糊、无色调偏移 */
|
||
background: rgba(0, 0, 0, 0.5);
|
||
}
|
||
|
||
.aksrt-modal-runtime__dialog {
|
||
position: relative;
|
||
z-index: 1;
|
||
width: min(440px, calc(100vw - 32px));
|
||
max-height: min(88vh, 720px);
|
||
overflow: auto;
|
||
background: var(--surface-1, #fff);
|
||
border-radius: 16px;
|
||
box-shadow: 0 18px 48px rgba(15, 18, 28, 0.22);
|
||
transform: translateY(12px) scale(0.98);
|
||
transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1);
|
||
color: var(--color-ink, #1f2937);
|
||
}
|
||
|
||
.aksrt-modal-runtime.is-open .aksrt-modal-runtime__dialog {
|
||
transform: translateY(0) scale(1);
|
||
}
|
||
|
||
.aksrt-modal-runtime--bottom {
|
||
align-items: flex-end;
|
||
}
|
||
|
||
.aksrt-modal-runtime--bottom .aksrt-modal-runtime__dialog {
|
||
width: 100%;
|
||
max-width: 100%;
|
||
border-radius: 16px 16px 0 0;
|
||
max-height: 90vh;
|
||
transform: translateY(24px);
|
||
}
|
||
|
||
.aksrt-modal-runtime--bottom.is-open .aksrt-modal-runtime__dialog {
|
||
transform: translateY(0);
|
||
}
|
||
|
||
.aksrt-modal-runtime__header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 12px;
|
||
padding: 16px 18px 0;
|
||
}
|
||
|
||
.aksrt-modal-runtime__title {
|
||
margin: 0;
|
||
font-size: 17px;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.aksrt-modal-runtime__content {
|
||
padding: 18px 18px 16px;
|
||
}
|
||
|
||
.aksrt-modal-runtime__loading,
|
||
.aksrt-modal-runtime__error-body {
|
||
padding: 28px 8px;
|
||
text-align: center;
|
||
color: var(--color-ink-2, #6b7280);
|
||
font-size: 14px;
|
||
}
|
||
|
||
.aksrt-modal-runtime__skeleton {
|
||
display: grid;
|
||
gap: 12px;
|
||
padding: 8px 2px;
|
||
}
|
||
|
||
.aksrt-modal-runtime__skeleton-line,
|
||
.aksrt-modal-runtime__skeleton-block {
|
||
display: block;
|
||
border-radius: 8px;
|
||
background: linear-gradient(90deg, rgba(148, 163, 184, 0.16), rgba(148, 163, 184, 0.3), rgba(148, 163, 184, 0.16));
|
||
background-size: 200% 100%;
|
||
animation: aksrt-modal-skeleton 1.2s ease-in-out infinite;
|
||
}
|
||
|
||
.aksrt-modal-runtime__skeleton-line {
|
||
width: 72%;
|
||
height: 12px;
|
||
}
|
||
|
||
.aksrt-modal-runtime__skeleton-line.is-wide {
|
||
width: 92%;
|
||
height: 18px;
|
||
}
|
||
|
||
.aksrt-modal-runtime__skeleton-line.is-short {
|
||
width: 44%;
|
||
}
|
||
|
||
.aksrt-modal-runtime__skeleton-block {
|
||
width: 100%;
|
||
min-height: 84px;
|
||
}
|
||
|
||
.aksrt-modal-runtime__retry {
|
||
cursor: pointer;
|
||
}
|
||
|
||
@keyframes aksrt-modal-skeleton {
|
||
0% { background-position: 100% 0; }
|
||
100% { background-position: -100% 0; }
|
||
}
|
||
|
||
.aksrt-modal-runtime .touch.border-title,
|
||
.aksrt-modal-runtime .border-title {
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
margin: 0 0 14px;
|
||
display: flex;
|
||
align-items: baseline;
|
||
flex-wrap: wrap;
|
||
gap: 6px;
|
||
}
|
||
|
||
.aksrt-modal-runtime .aksrt-modal-runtime__close {
|
||
position: absolute;
|
||
top: 10px;
|
||
right: 10px;
|
||
width: 32px;
|
||
height: 32px;
|
||
border: 0;
|
||
border-radius: 999px;
|
||
background: transparent;
|
||
color: var(--color-ink-3, #9ca3af);
|
||
cursor: pointer;
|
||
font-size: 18px;
|
||
line-height: 1;
|
||
}
|
||
|
||
.aksrt-modal-runtime .but-average.modal-buts,
|
||
.aksrt-modal-runtime .modal-buts {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 10px;
|
||
margin-top: 16px;
|
||
}
|
||
|
||
.aksrt-modal-runtime .but-average.modal-buts .but,
|
||
.aksrt-modal-runtime .modal-buts .but,
|
||
.aksrt-modal-runtime .modal-buts button {
|
||
min-height: 40px;
|
||
border-radius: 10px;
|
||
border: 1px solid var(--color-line, #e5e7eb);
|
||
background: var(--surface-4, #f3f4f6);
|
||
color: var(--color-ink, #111);
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.aksrt-modal-runtime .modal-buts .but.c-blue,
|
||
.aksrt-modal-runtime .modal-buts button.c-blue,
|
||
.aksrt-modal-runtime .modal-buts .btn-primary {
|
||
background: var(--color-primary, #f04494);
|
||
border-color: color-mix(in srgb, var(--color-primary, #f04494) 70%, #000 0%);
|
||
color: var(--color-on-primary, #fff);
|
||
}
|
||
|
||
/* ---- 签到详情弹窗(参考主题 refresh_modal modal-mini 同构壳) ----
|
||
内容为服务端 HTML(modal-colorful-header + modal-body),与参考主题
|
||
.modal-dialog.modal-mini 几何 1:1:宽 400px、圆角 var(--main-radius)。 */
|
||
.aksrt-modal-runtime.aksrt-checkin-details-modal:not(.aksrt-modal-runtime--bottom) .aksrt-modal-runtime__dialog {
|
||
width: min(400px, calc(100vw - 32px));
|
||
border-radius: var(--main-radius, 8px);
|
||
background: var(--main-bg-color, #fff);
|
||
}
|
||
|
||
.aksrt-modal-runtime.aksrt-checkin-details-modal .aksrt-modal-runtime__content {
|
||
padding: 0;
|
||
}
|
||
|
||
.aksrt-modal-runtime.aksrt-checkin-details-modal .aksrt-modal-runtime__skeleton {
|
||
padding: 24px 18px;
|
||
}
|
||
|
||
/* ---- ajax list ---- */
|
||
.ajaxpager.is-ajax-loading {
|
||
position: relative;
|
||
min-height: 80px;
|
||
}
|
||
|
||
/* 骨架默认收起,由 JS 加 .is-loading 展开(参考主题 post_ajax 的 beforeSend
|
||
remove + fadeIn / success .hide() 语义等价物)。
|
||
这里不依赖 .ajaxpager 祖先:首页 tab pane、归档流、评论列表的 loader 层级各不
|
||
相同,而且并非每个 loader 都在 bootstrap 的 .tab-pane 里(bootstrap 只负责
|
||
隐藏 tab-pane 内的骨架),统一按类名自身控制。 */
|
||
.post_ajax_loader {
|
||
display: none;
|
||
}
|
||
|
||
.post_ajax_loader.is-loading {
|
||
display: block;
|
||
animation: aksrtFadeIn 0.2s ease both;
|
||
}
|
||
|
||
.ajax-item.is-fading {
|
||
opacity: 0.35;
|
||
transition: opacity 0.15s ease;
|
||
}
|
||
|
||
/* ---- 举报弹窗(参考主题报告弹窗几何 1:1)----
|
||
宽度对齐参考主题 Bootstrap 默认模态(>=768px 600px),圆角/底色走
|
||
--main-radius / --main-bg-color;移动端仍由 --bottom 底部抽屉接管。 */
|
||
.aksrt-report-modal:not(.aksrt-modal-runtime--bottom) .aksrt-modal-runtime__dialog {
|
||
width: min(600px, calc(100vw - 32px));
|
||
border-radius: var(--main-radius, 8px);
|
||
background: var(--main-bg-color, #fff);
|
||
}
|
||
|
||
/* edit-header:参考主题弹窗头(关闭钮靠右,红色警示徽标 + 标题居左)。 */
|
||
.aksrt-report-modal .edit-header {
|
||
position: relative;
|
||
padding-right: 32px;
|
||
}
|
||
|
||
.aksrt-report-modal .edit-header .close {
|
||
position: absolute;
|
||
right: 0;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
float: none;
|
||
font-size: 20px;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
background: none;
|
||
border: 0;
|
||
padding: 2px 6px;
|
||
}
|
||
|
||
/* 原因徽章行:与参考主题一致,徽章可换行且间距走 mr6/mb6 工具类。 */
|
||
.aksrt-report-modal .form-but-radio .badg {
|
||
cursor: pointer;
|
||
user-select: none;
|
||
}
|
||
|
||
/* ---- 禁封用户弹窗(参考主题 set_user_ban 模态框几何 1:1)----
|
||
参考主题 zib_get_edit_user_ban_link 未传 data-class → 走 Bootstrap 默认
|
||
.modal-dialog(>=768px 宽 600px);data-height=360 → .modal-content 初始
|
||
高度 360 后动画至内容高度;mobile-bottom → <769px 底部抽屉。
|
||
此处以 min-height:360px 复刻初始高度契约,桌面宽取 600px。 */
|
||
.aksrt-user-ban-modal:not(.aksrt-modal-runtime--bottom) .aksrt-modal-runtime__dialog {
|
||
width: min(600px, calc(100vw - 32px));
|
||
border-radius: var(--main-radius, 8px);
|
||
background: var(--main-bg-color, #fff);
|
||
}
|
||
|
||
/* ---- 查看禁封状态 / 禁封申诉 / 禁封记录弹窗(参考主题 modal-mini 几何 1:1)----
|
||
参考主题三个链接均传 data_class='modal-mini'(宽 400px)、data-height=240。 */
|
||
.aksrt-user-ban-info-modal:not(.aksrt-modal-runtime--bottom) .aksrt-modal-runtime__dialog,
|
||
.aksrt-user-ban-appeal-modal:not(.aksrt-modal-runtime--bottom) .aksrt-modal-runtime__dialog,
|
||
.aksrt-user-ban-log-modal:not(.aksrt-modal-runtime--bottom) .aksrt-modal-runtime__dialog {
|
||
width: min(400px, calc(100vw - 32px));
|
||
border-radius: var(--main-radius, 8px);
|
||
background: var(--main-bg-color, #fff);
|
||
}
|
||
|
||
.aksrt-user-ban-info-modal .aksrt-modal-runtime__skeleton,
|
||
.aksrt-user-ban-appeal-modal .aksrt-modal-runtime__skeleton,
|
||
.aksrt-user-ban-log-modal .aksrt-modal-runtime__skeleton {
|
||
padding: 24px 18px;
|
||
}
|
||
|
||
.aksrt-user-ban-modal .aksrt-modal-runtime__skeleton {
|
||
padding: 24px 18px;
|
||
}
|
||
|
||
/* edit-header:与禁封表单头部同构(关闭钮靠右,红色警示徽标 + 标题居左)。 */
|
||
.aksrt-user-ban-modal .edit-header,
|
||
.aksrt-user-ban-appeal-modal .edit-header {
|
||
position: relative;
|
||
padding-right: 32px;
|
||
}
|
||
|
||
.aksrt-user-ban-modal .edit-header .close,
|
||
.aksrt-user-ban-appeal-modal .edit-header .close {
|
||
position: absolute;
|
||
right: 0;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
float: none;
|
||
font-size: 20px;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
background: none;
|
||
border: 0;
|
||
padding: 2px 6px;
|
||
}
|
||
|
||
/* 解封视图多彩横幅(参考主题 zib_get_modal_colorful_header('c-yellow', ...)):
|
||
120px 高绝对定位横幅 + 旋转彩斑,后续表单整体下移 120px。 */
|
||
.aksrt-user-ban-modal .modal-colorful-header,
|
||
.aksrt-user-ban-modal .colorful-bg,
|
||
.aksrt-user-ban-info-modal .modal-colorful-header,
|
||
.aksrt-user-ban-info-modal .colorful-bg,
|
||
.aksrt-user-ban-log-modal .modal-colorful-header,
|
||
.aksrt-user-ban-log-modal .colorful-bg {
|
||
position: relative;
|
||
overflow: hidden;
|
||
color: var(--this-color);
|
||
background: var(--this-bg);
|
||
background-size: 120%;
|
||
}
|
||
|
||
.aksrt-user-ban-modal .modal-colorful-header,
|
||
.aksrt-user-ban-info-modal .modal-colorful-header,
|
||
.aksrt-user-ban-log-modal .modal-colorful-header {
|
||
position: absolute;
|
||
top: 0;
|
||
right: 0;
|
||
left: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 120px;
|
||
border-radius: var(--main-radius, 8px) var(--main-radius, 8px) 0 0;
|
||
}
|
||
|
||
.aksrt-user-ban-modal .modal-colorful-header + *,
|
||
.aksrt-user-ban-info-modal .modal-colorful-header + *,
|
||
.aksrt-user-ban-log-modal .modal-colorful-header + * {
|
||
margin-top: 120px;
|
||
}
|
||
|
||
.aksrt-user-ban-modal .modal-colorful-header > .close,
|
||
.aksrt-user-ban-info-modal .modal-colorful-header > .close,
|
||
.aksrt-user-ban-log-modal .modal-colorful-header > .close {
|
||
position: absolute;
|
||
top: 10px;
|
||
right: 10px;
|
||
z-index: 9;
|
||
color: var(--this-color);
|
||
font-size: 18px;
|
||
opacity: 0.6;
|
||
}
|
||
|
||
.aksrt-user-ban-modal .colorful-bg > .colorful-make,
|
||
.aksrt-user-ban-modal .colorful-bg > .colorful-make::before,
|
||
.aksrt-user-ban-modal .colorful-bg > .colorful-make::after,
|
||
.aksrt-user-ban-info-modal .colorful-bg > .colorful-make,
|
||
.aksrt-user-ban-info-modal .colorful-bg > .colorful-make::before,
|
||
.aksrt-user-ban-info-modal .colorful-bg > .colorful-make::after,
|
||
.aksrt-user-ban-log-modal .colorful-bg > .colorful-make,
|
||
.aksrt-user-ban-log-modal .colorful-bg > .colorful-make::before,
|
||
.aksrt-user-ban-log-modal .colorful-bg > .colorful-make::after {
|
||
position: absolute;
|
||
color: var(--this-color);
|
||
background: var(--this-bg);
|
||
border-radius: 100%;
|
||
content: '';
|
||
}
|
||
|
||
.aksrt-user-ban-modal .colorful-bg > .colorful-make,
|
||
.aksrt-user-ban-info-modal .colorful-bg > .colorful-make,
|
||
.aksrt-user-ban-log-modal .colorful-bg > .colorful-make {
|
||
top: 60%;
|
||
bottom: 0;
|
||
width: 323px;
|
||
height: 290px;
|
||
animation: aksrt-ban-colorful 120s linear infinite;
|
||
}
|
||
|
||
.aksrt-user-ban-modal .colorful-bg > .colorful-make::before,
|
||
.aksrt-user-ban-info-modal .colorful-bg > .colorful-make::before,
|
||
.aksrt-user-ban-log-modal .colorful-bg > .colorful-make::before {
|
||
top: -325px;
|
||
right: -558px;
|
||
bottom: 0;
|
||
width: 677px;
|
||
height: 300px;
|
||
opacity: 0.6;
|
||
transform: rotate(341deg);
|
||
}
|
||
|
||
.aksrt-user-ban-modal .colorful-bg > .colorful-make::after,
|
||
.aksrt-user-ban-info-modal .colorful-bg > .colorful-make::after,
|
||
.aksrt-user-ban-log-modal .colorful-bg > .colorful-make::after {
|
||
top: -170px;
|
||
bottom: 0;
|
||
left: -262px;
|
||
width: 402px;
|
||
height: 214px;
|
||
opacity: 0.4;
|
||
transform: rotate(326deg);
|
||
}
|
||
|
||
.aksrt-user-ban-modal .colorful-bg > .colorful-make + *,
|
||
.aksrt-user-ban-info-modal .colorful-bg > .colorful-make + *,
|
||
.aksrt-user-ban-log-modal .colorful-bg > .colorful-make + * {
|
||
position: relative;
|
||
}
|
||
|
||
/* 单选徽章行(参考主题 .form-but-radio 契约):input 由 main.css 隐藏,
|
||
label 可点;选中态由 main.css 的 input:checked + .but-radio 驱动。 */
|
||
.aksrt-user-ban-modal .form-but-radio label {
|
||
cursor: pointer;
|
||
}
|
||
|
||
.aksrt-user-ban-modal .form-but-radio .but-radio {
|
||
user-select: none;
|
||
}
|
||
|
||
/* 开关行(删除全部内容 / 禁止用户申诉):原生 checkbox 隐藏,
|
||
视觉态由 main.css 的 input:checked ~ .form-switch 驱动。 */
|
||
.aksrt-user-ban-modal .aksrt-user-ban-form label {
|
||
user-select: none;
|
||
}
|
||
|
||
@keyframes aksrt-ban-colorful {
|
||
0% { transform: rotate(0deg); }
|
||
100% { transform: rotate(360deg); }
|
||
}
|
||
|
||
/* ---- order review modal content ---- */
|
||
.order-comment-from .shop-score-box {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
min-height: 36px;
|
||
}
|
||
|
||
.order-comment-from .score-title {
|
||
width: 4.5em;
|
||
flex: 0 0 auto;
|
||
font-size: 13px;
|
||
color: var(--color-ink-2, #6b7280);
|
||
}
|
||
|
||
.order-comment-from .score-icon {
|
||
display: inline-flex;
|
||
gap: 4px;
|
||
align-items: center;
|
||
height: 30px;
|
||
}
|
||
|
||
.order-comment-from .icon-star {
|
||
display: inline-flex;
|
||
width: 22px;
|
||
height: 22px;
|
||
color: #d1d5db;
|
||
cursor: pointer;
|
||
transition: color 0.12s ease, transform 0.12s ease;
|
||
}
|
||
|
||
.order-comment-from .icon-star svg {
|
||
width: 22px;
|
||
height: 22px;
|
||
fill: currentColor;
|
||
}
|
||
|
||
.order-comment-from .icon-star.active,
|
||
.order-comment-from .icon-star.hover {
|
||
color: #fc7049;
|
||
}
|
||
|
||
.order-comment-from .icon-star.hover {
|
||
transform: scale(1.08);
|
||
}
|
||
|
||
.order-comment-from .score-text {
|
||
min-width: 3em;
|
||
font-size: 13px;
|
||
color: var(--color-ink-2, #6b7280);
|
||
}
|
||
|
||
.order-comment-from textarea.form-control {
|
||
width: 100%;
|
||
border: 1px solid var(--color-line, #e5e7eb);
|
||
border-radius: 10px;
|
||
padding: 10px 12px;
|
||
font-size: 14px;
|
||
resize: vertical;
|
||
min-height: 96px;
|
||
background: var(--surface-1, #fff);
|
||
color: var(--color-ink, #111);
|
||
}
|
||
|
||
:is(.order-comment-from, .aksrt-report-modal) .form-upload .preview {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
}
|
||
|
||
:is(.order-comment-from, .aksrt-report-modal) .form-upload .preview .add,
|
||
:is(.order-comment-from, .aksrt-report-modal) .form-upload .preview .preview-item {
|
||
width: 80px;
|
||
height: 80px;
|
||
border-radius: 10px;
|
||
border: 1px dashed var(--color-line, #d1d5db);
|
||
background: var(--surface-4, #f9fafb);
|
||
position: relative;
|
||
overflow: hidden;
|
||
cursor: pointer;
|
||
}
|
||
|
||
/* 加号图标不在此重复定义:main.css 已有参考主题原生实现
|
||
(.preview .add:before/:after —— 25px 圆角杠,inset:0 + margin:auto 居中)。
|
||
此前这里的 left/top:50% + translate 版本与该规则叠加导致过约束,
|
||
加号被推到 75%/75% 只剩“L”形,故整体删除、统一走主样式包。 */
|
||
|
||
:is(.order-comment-from, .aksrt-report-modal) .form-upload .preview .preview-item img {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
display: block;
|
||
}
|
||
|
||
:is(.order-comment-from, .aksrt-report-modal) .form-upload .preview .preview-item .remove {
|
||
position: absolute;
|
||
top: 2px;
|
||
right: 2px;
|
||
width: 20px;
|
||
height: 20px;
|
||
border: 0;
|
||
border-radius: 999px;
|
||
background: rgba(0, 0, 0, 0.55);
|
||
color: #fff;
|
||
font-size: 12px;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
}
|
||
|
||
:is(.order-comment-from, .aksrt-report-modal) .form-upload .hide {
|
||
display: none !important;
|
||
}
|
||
|
||
.order-comment-from .review-error {
|
||
color: #ef4444;
|
||
font-size: 13px;
|
||
margin-top: 8px;
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.aksrt-modal-runtime:not(.aksrt-modal-runtime--bottom) .aksrt-modal-runtime__dialog {
|
||
width: calc(100vw - 20px);
|
||
}
|
||
}
|