fix(feedback): stabilize error banner layout

This commit is contained in:
zhangheng
2026-07-22 20:25:06 +08:00
parent fb4adbac76
commit 9f1d68cdd3
2 changed files with 73 additions and 51 deletions

View File

@@ -6,14 +6,16 @@
<text class="page-subtitle">填写课堂表现并保存到教学反馈记录。</text>
<view wx:if="{{errorMessage}}" class="status-banner feedback-error-banner">
<text class="feedback-error-message">{{errorMessage}}</text>
<view class="feedback-error-actions">
<button wx:if="{{errorRequestId}}" class="feedback-error-copy" aria-label="复制问题编号" bindtap="copyRequestId">复制</button>
<button class="feedback-error-retry" loading="{{errorRetrying}}" disabled="{{errorRetrying}}" bindtap="retryError">重试</button>
<view class="feedback-error-content">
<text class="feedback-error-message">{{errorMessage}}</text>
<button class="feedback-error-close" aria-label="关闭提示" bindtap="dismissError">
<view class="feedback-error-close-icon"></view>
<icon type="clear" size="16" color="#8E5B5B" />
</button>
</view>
<view class="feedback-error-actions">
<button wx:if="{{errorRequestId}}" class="feedback-error-copy" aria-label="复制问题编号" bindtap="copyRequestId">复制编号</button>
<button class="feedback-error-retry" loading="{{errorRetrying}}" disabled="{{errorRetrying}}" bindtap="retryError">重试</button>
</view>
</view>
<view class="feedback-form surface">

View File

@@ -8,98 +8,99 @@
}
.feedback-error-banner {
display: block;
width: 100%;
align-items: center;
gap: 16rpx;
padding: 18rpx 20rpx;
padding: 20rpx;
border-color: rgba(209, 63, 58, 0.24);
background: #fff6f5;
}
.feedback-error-content {
display: grid;
grid-template-columns: minmax(0, 1fr) 64rpx;
align-items: start;
width: 100%;
gap: 12rpx;
}
.feedback-error-actions {
display: flex;
flex: none;
align-items: center;
gap: 8rpx;
justify-content: flex-end;
width: 100%;
gap: 10rpx;
margin-top: 14rpx;
}
.feedback-error-message {
display: block;
flex: 1;
min-width: 0;
padding: 5rpx 0;
color: #9b2c27;
font-size: 24rpx;
line-height: 1.4;
font-weight: 500;
line-height: 1.5;
word-break: normal;
overflow-wrap: break-word;
}
.feedback-error-close {
display: flex;
flex: none;
align-items: center;
justify-content: center;
width: 44rpx;
height: 44rpx;
width: 64rpx;
min-width: 64rpx;
max-width: 64rpx;
height: 64rpx;
margin: 0;
padding: 0;
border: 0;
border-radius: 12rpx;
background: transparent;
line-height: 1;
transition: transform 100ms ease-out, background-color 100ms ease-out;
}
.feedback-error-close::after {
border: 0;
}
.feedback-error-close-icon {
position: relative;
width: 22rpx;
height: 22rpx;
}
.feedback-error-close-icon::before,
.feedback-error-close-icon::after {
position: absolute;
top: 10rpx;
left: 1rpx;
width: 20rpx;
height: 2rpx;
border-radius: 1rpx;
background: #8e5b5b;
content: '';
}
.feedback-error-close-icon::before {
transform: rotate(45deg);
}
.feedback-error-close-icon::after {
transform: rotate(-45deg);
.feedback-error-close:active {
transform: scale(0.94);
background: rgba(209, 63, 58, 0.08);
}
.feedback-error-copy,
.feedback-error-retry {
display: flex;
flex: none;
align-items: center;
justify-content: center;
height: 52rpx;
height: 62rpx;
margin: 0;
border: 0;
border-radius: 8rpx;
border-radius: 10rpx;
font-size: 22rpx;
font-weight: 600;
line-height: 1;
transition: transform 100ms ease-out, background-color 100ms ease-out;
}
.feedback-error-copy {
min-width: 68rpx;
padding: 0 10rpx;
background: transparent;
width: 128rpx;
min-width: 128rpx;
max-width: 128rpx;
padding: 0;
background: #f1f3f6;
color: #6e6e73;
font-weight: 500;
}
.feedback-error-retry {
min-width: 92rpx;
padding: 0 16rpx;
width: 112rpx;
min-width: 112rpx;
max-width: 112rpx;
padding: 0;
background: #007aff;
color: #ffffff;
font-weight: 600;
}
.feedback-error-copy::after,
@@ -113,6 +114,19 @@
opacity: 1;
}
.feedback-error-copy:active,
.feedback-error-retry:active {
transform: scale(0.96);
}
.feedback-error-copy:active {
background: #e5e5ea;
}
.feedback-error-retry:active {
background: #006ee6;
}
.feedback-field,
.content-field {
padding: 24rpx;
@@ -576,12 +590,18 @@
@media (prefers-reduced-motion: reduce) {
.voice-button,
.voice-state-actionable,
.voice-state-arrow {
.voice-state-arrow,
.feedback-error-copy,
.feedback-error-retry,
.feedback-error-close {
transition: none;
}
.voice-button:active,
.voice-state-actionable:active {
.voice-state-actionable:active,
.feedback-error-copy:active,
.feedback-error-retry:active,
.feedback-error-close:active {
transform: none;
}
}