style(mini): 全面修复活动相关页面样式+全局按钮统一

1. 我的活动页:
   - 副标题从'已报名的活动'改为'发布的活动与审核状态'
   - 空状态卡片样式优化,文字颜色加深可见
   - 发布新活动按钮改为蓝紫渐变主按钮
   - 编辑按钮改为统一选项按钮样式

2. 活动发布页(完整重写表单样式):
   - 统一输入框 evt-input(圆角14rpx,白色半透明背景)
   - 统一文本域 evt-textarea
   - 选项按钮选中态从'加粗+●前缀'改为蓝紫渐变背景+白字(evt-opt.active)
   - 提交审核按钮从无样式的btn-primary改为蓝紫渐变主按钮(evt-btn-submit)
   - 存草稿按钮改为统一次按钮(evt-btn-draft)
   - 封面上传按钮优化为虚线边框占位
   - 必填字段标签加红色星号

3. 全局按钮统一:
   - btn-primary 和 btn-cta 全局未定义,现在统一为和 btn-main 一样的蓝紫渐变样式
   - 修复 event-detail/pay-qr/ent-company/ent-members 等页面使用 btn-primary 但无样式的问题
   - disabled 状态选择器同步更新

4. 逐页检查:
   - 任务/服务/岗位/人才/发帖发布页:已确认使用 hl-btn/hl-input 统一样式,正常
   - 所有卡片使用全局 .card 毛玻璃样式,统一
   - 所有页面边距在 24rpx-32rpx 范围内,合理
This commit is contained in:
Pine
2026-09-02 00:10:53 +08:00
parent f42b47b1a0
commit ff9b7eab08
5 changed files with 191 additions and 83 deletions
+4 -2
View File
@@ -100,7 +100,7 @@ page { -ms-overflow-style: none; scrollbar-width: none; }
margin-top: 8px;
}
.btn-main {
.btn-main, .btn-primary, .btn-cta {
background: linear-gradient(135deg, #6b8bff, #8f7bff);
color: #ffffff;
border-radius: 999px;
@@ -111,7 +111,7 @@ page { -ms-overflow-style: none; scrollbar-width: none; }
box-shadow: 0 8rpx 24rpx rgba(98, 132, 255, 0.28);
}
.btn-main::after {
.btn-main::after, .btn-primary::after, .btn-cta::after {
border: none;
}
@@ -134,6 +134,8 @@ page { -ms-overflow-style: none; scrollbar-width: none; }
/* 禁用态:微信原生 button[disabled] 浅底浅字会盖掉单类样式(特异度更高),这里显式压回可读配色 */
.btn-main[disabled], .btn-main.button-disabled,
.btn-primary[disabled], .btn-primary.button-disabled,
.btn-cta[disabled], .btn-cta.button-disabled,
.btn-ghost[disabled], .btn-ghost.button-disabled {
background: rgba(120, 140, 220, 0.14);
color: #8b97c4;
@@ -116,114 +116,106 @@ export default function EventEdit() {
return (
<View className="page-in">
<PageHeader back no="EV" title={editId ? '编辑活动' : '发布活动'} sub="编辑活动信息"/>
<View className="adm-wrap">
<View className="card adm-form">
<View className="adm-field">
<Text className="adm-label">活动封面3.35:1</Text>
{cover ? <Image className="adm-cover" src={cover} mode="aspectFill" onClick={pickCover} /> : (
<Button className="btn-ghost adm-actbtn" onClick={pickCover}>+ 上传封面</Button>
<View className="evt-edit">
<View className="evt-form">
<View className="evt-field">
<Text className="evt-label">活动封面3.35:1</Text>
{cover ? <Image className="evt-cover" src={cover} mode="aspectFill" onClick={pickCover} /> : (
<Button className="evt-cover-btn" onClick={pickCover}>+ 上传封面</Button>
)}
</View>
<View className="adm-field">
<Text className="adm-label">活动名称 *</Text>
<Input className="input" placeholder="活动主题" value={title} onInput={(e) => setTitle(e.detail.value)} />
<View className="evt-field">
<Text className="evt-label">活动名称<span className="req">*</span></Text>
<Input className="evt-input" placeholder="活动主题" value={title} onInput={(e) => setTitle(e.detail.value)} />
</View>
<View className="adm-field">
<Text className="adm-label">副标题</Text>
<Input className="input" placeholder="一句话亮点(选填)" value={subtitle} onInput={(e) => setSubtitle(e.detail.value)} />
<View className="evt-field">
<Text className="evt-label">副标题</Text>
<Input className="evt-input" placeholder="一句话亮点(选填)" value={subtitle} onInput={(e) => setSubtitle(e.detail.value)} />
</View>
<View className="adm-field">
<Text className="adm-label">类型 *</Text>
<View className="adm-search" style="flex-wrap:wrap">
<View className="evt-field">
<Text className="evt-label">类型<span className="req">*</span></Text>
<View className="evt-opts">
{EVENT_CATEGORIES.map((c) => (
<Button key={c} className="btn-ghost adm-actbtn" style={category === c ? 'font-weight:700' : ''} onClick={() => setCategory(c)}>
{category === c ? `${c}` : c}
</Button>
<Button key={c} className={`evt-opt${category === c ? ' active' : ''}`} onClick={() => setCategory(c)}>{c}</Button>
))}
</View>
</View>
<View className="adm-field">
<Text className="adm-label">区域</Text>
<View className="adm-search" style="flex-wrap:wrap">
<View className="evt-field">
<Text className="evt-label">区域</Text>
<View className="evt-opts">
{EVENT_REGIONS.map((r) => (
<Button key={r} className="btn-ghost adm-actbtn" style={region === r ? 'font-weight:700' : ''} onClick={() => setRegion(r)}>
{region === r ? `${r}` : r}
</Button>
<Button key={r} className={`evt-opt${region === r ? ' active' : ''}`} onClick={() => setRegion(r)}>{r}</Button>
))}
</View>
</View>
<View className="adm-field">
<Text className="adm-label">模式</Text>
<View className="adm-search">
<View className="evt-field">
<Text className="evt-label">模式</Text>
<View className="evt-opts">
{MODES.map((m) => (
<Button key={m.key} className="btn-ghost adm-actbtn" style={mode === m.key ? 'font-weight:700' : ''} onClick={() => setMode(m.key)}>
{mode === m.key ? `${m.label}` : m.label}
</Button>
<Button key={m.key} className={`evt-opt${mode === m.key ? ' active' : ''}`} onClick={() => setMode(m.key)}>{m.label}</Button>
))}
</View>
</View>
<View className="adm-field">
<Text className="adm-label">名额留空 = 不限</Text>
<Input className="input" type="number" placeholder="不限" value={capacity} onInput={(e) => setCapacity(e.detail.value)} />
<View className="evt-field">
<Text className="evt-label">名额留空 = 不限</Text>
<Input className="evt-input" type="number" placeholder="不限" value={capacity} onInput={(e) => setCapacity(e.detail.value)} />
</View>
<View className="adm-field">
<Text className="adm-label">地点</Text>
<Input className="input" placeholder={mode === 'online' ? '线上活动可留空' : '活动地点'} value={location} onInput={(e) => setLocation(e.detail.value)} />
<View className="evt-field">
<Text className="evt-label">地点</Text>
<Input className="evt-input" placeholder={mode === 'online' ? '线上活动可留空' : '活动地点'} value={location} onInput={(e) => setLocation(e.detail.value)} />
</View>
<View className="adm-field">
<Text className="adm-label">签到时间</Text>
<Input className="input" placeholder="如 2026-09-01T13:30" value={checkinAt} onInput={(e) => setCheckinAt(e.detail.value)} />
<View className="evt-field">
<Text className="evt-label">签到时间</Text>
<Input className="evt-input" placeholder="如 2026-09-01T13:30" value={checkinAt} onInput={(e) => setCheckinAt(e.detail.value)} />
</View>
<View className="adm-field">
<Text className="adm-label">开始时间 *</Text>
<Input className="input" placeholder="如 2026-09-01T14:00" value={startAt} onInput={(e) => setStartAt(e.detail.value)} />
<View className="evt-field">
<Text className="evt-label">开始时间<span className="req">*</span></Text>
<Input className="evt-input" placeholder="如 2026-09-01T14:00" value={startAt} onInput={(e) => setStartAt(e.detail.value)} />
</View>
<View className="adm-field">
<Text className="adm-label">结束时间 *</Text>
<Input className="input" placeholder="如 2026-09-01T16:00" value={endAt} onInput={(e) => setEndAt(e.detail.value)} />
<View className="evt-field">
<Text className="evt-label">结束时间<span className="req">*</span></Text>
<Input className="evt-input" placeholder="如 2026-09-01T16:00" value={endAt} onInput={(e) => setEndAt(e.detail.value)} />
</View>
<View className="adm-field">
<Text className="adm-label">活动价格0 为免费</Text>
<Input className="input" type="digit" value={priceYuan} onInput={(e) => setPriceYuan(e.detail.value)} />
<View className="evt-field">
<Text className="evt-label">活动价格0 为免费</Text>
<Input className="evt-input" type="digit" value={priceYuan} onInput={(e) => setPriceYuan(e.detail.value)} />
</View>
<View className="adm-field">
<Text className="adm-label">主办方</Text>
<Input className="input" placeholder="主办方名称" value={host} onInput={(e) => setHost(e.detail.value)} />
<View className="evt-field">
<Text className="evt-label">主办方</Text>
<Input className="evt-input" placeholder="主办方名称" value={host} onInput={(e) => setHost(e.detail.value)} />
</View>
<View className="adm-field">
<Text className="adm-label">报名方式</Text>
<View className="adm-search">
<Button className="btn-ghost adm-actbtn" style={signupMode === 'mini' ? 'font-weight:700' : ''} onClick={() => setSignupMode('mini')}> 小程序报名</Button>
<Button className="btn-ghost adm-actbtn" style={signupMode === 'external' ? 'font-weight:700' : ''} onClick={() => setSignupMode('external')}>外链报名</Button>
<View className="evt-field">
<Text className="evt-label">报名方式</Text>
<View className="evt-opts">
<Button className={`evt-opt${signupMode === 'mini' ? ' active' : ''}`} onClick={() => setSignupMode('mini')}>小程序报名</Button>
<Button className={`evt-opt${signupMode === 'external' ? ' active' : ''}`} onClick={() => setSignupMode('external')}>外链报名</Button>
</View>
{signupMode === 'external' && (
<Input className="input" placeholder="报名链接 URL *" value={externalUrl} onInput={(e) => setExternalUrl(e.detail.value)} />
<Input className="evt-input" placeholder="报名链接 URL *" value={externalUrl} onInput={(e) => setExternalUrl(e.detail.value)} />
)}
</View>
<View className="adm-field">
<Text className="adm-label">活动范围</Text>
<View className="adm-search">
<Button className="btn-ghost adm-actbtn" style={scope === 'public' ? 'font-weight:700' : ''} onClick={() => setScope('public')}> 公开运营端审核</Button>
<Button className="btn-ghost adm-actbtn" style={scope === 'park' ? 'font-weight:700' : ''} onClick={() => setScope('park')}>本园区园区审核</Button>
<View className="evt-field">
<Text className="evt-label">活动范围</Text>
<View className="evt-opts">
<Button className={`evt-opt${scope === 'public' ? ' active' : ''}`} onClick={() => setScope('public')}>公开运营端审核</Button>
<Button className={`evt-opt${scope === 'park' ? ' active' : ''}`} onClick={() => setScope('park')}>本园区园区审核</Button>
</View>
{scope === 'park' && tenants.map((t) => (
<Button key={t.id} className="btn-ghost adm-actbtn" onClick={() => setTargetTenantId(t.id)}>
{targetTenantId === t.id ? '● ' : ''}{t.name}
</Button>
<Button key={t.id} className={`evt-opt${targetTenantId === t.id ? ' active' : ''}`} onClick={() => setTargetTenantId(t.id)}>{t.name}</Button>
))}
</View>
<View className="adm-field">
<Text className="adm-label">活动注意事项</Text>
<Textarea className="input op-textarea" placeholder="如:请提前 15 分钟签到;线下参加请携带身份证…" value={notice} onInput={(e) => setNotice(e.detail.value)} />
<View className="evt-field">
<Text className="evt-label">活动注意事项</Text>
<Textarea className="evt-textarea" placeholder="如:请提前 15 分钟签到;线下参加请携带身份证…" value={notice} onInput={(e) => setNotice(e.detail.value)} />
</View>
<View className="adm-field">
<Text className="adm-label">活动介绍</Text>
<Textarea className="input op-textarea" placeholder="活动介绍(支持多行文字)" value={desc} onInput={(e) => setDesc(e.detail.value)} />
<View className="evt-field">
<Text className="evt-label">活动介绍</Text>
<Textarea className="evt-textarea" placeholder="活动介绍(支持多行文字)" value={desc} onInput={(e) => setDesc(e.detail.value)} />
</View>
{err ? <Text className="adm-note" style="color:#e05252">{err}</Text> : null}
<View className="adm-search">
<Button className="btn-ghost adm-actbtn" disabled={saving} onClick={() => submit('draft')}>存草稿</Button>
<Button className="btn-primary adm-actbtn" disabled={saving} onClick={() => submit('pending')}>提交审核</Button>
{err ? <Text className="evt-err">{err}</Text> : null}
<View className="evt-actions">
<Button className="evt-btn evt-btn-draft" disabled={saving} onClick={() => submit('draft')}>存草稿</Button>
<Button className="evt-btn evt-btn-submit" disabled={saving} onClick={() => submit('pending')}>提交审核</Button>
</View>
</View>
</View>
@@ -1,2 +1,115 @@
@import "../../app.scss";
@import "../../styles/admin-pages.scss";
/* 活动发布/编辑页 · 表单样式 */
.evt-edit { padding: 0 24rpx 40rpx; }
.evt-form {
display: flex; flex-direction: column; gap: 24rpx;
background: rgba(255,255,255,0.55);
backdrop-filter: blur(20px) saturate(160%);
-webkit-backdrop-filter: blur(20px) saturate(160%);
border: 1rpx solid rgba(99,132,255,0.12);
border-radius: 20rpx;
padding: 28rpx 24rpx 32rpx;
box-shadow: 0 10rpx 28rpx rgba(59,79,125,0.09);
}
.evt-field { display: flex; flex-direction: column; gap: 12rpx; }
.evt-label { font-size: 26rpx; color: #5a6aa3; font-weight: 600; }
.evt-label .req { color: #e05252; margin-left: 4rpx; }
/* 输入框统一 */
.evt-input {
width: 100%; box-sizing: border-box;
height: 80rpx; line-height: 80rpx;
padding: 0 24rpx;
font-size: 28rpx; color: #23315c;
background: rgba(255,255,255,0.7);
border: 1rpx solid rgba(99,132,255,0.16);
border-radius: 14rpx;
}
.evt-textarea {
width: 100%; box-sizing: border-box;
min-height: 180rpx;
padding: 20rpx 24rpx;
font-size: 28rpx; color: #23315c;
background: rgba(255,255,255,0.7);
border: 1rpx solid rgba(99,132,255,0.16);
border-radius: 14rpx;
line-height: 1.6;
}
/* 选项按钮组(类型/区域/模式/报名方式/活动范围) */
.evt-opts { display: flex; flex-wrap: wrap; gap: 12rpx; }
.evt-opt {
font-size: 26rpx; color: #5a6aa3;
padding: 14rpx 28rpx;
background: rgba(255,255,255,0.55);
border: 1rpx solid rgba(99,132,255,0.22);
border-radius: 999rpx;
line-height: 1.4;
font-weight: 500;
}
.evt-opt::after { border: none; }
.evt-opt.active {
color: #fff;
background: linear-gradient(135deg, #6b8bff, #8f7bff);
border-color: transparent;
font-weight: 600;
box-shadow: 0 6rpx 18rpx rgba(98,132,255,0.3);
}
/* 封面 */
.evt-cover { width: 100%; height: 200rpx; border-radius: 14rpx; }
.evt-cover-btn {
width: 100%; height: 200rpx;
display: flex; align-items: center; justify-content: center;
background: rgba(255,255,255,0.4);
border: 2rpx dashed rgba(99,132,255,0.3);
border-radius: 14rpx;
color: #8a94c0; font-size: 26rpx;
}
.evt-cover-btn::after { border: none; }
/* 底部按钮 */
.evt-actions { display: flex; gap: 16rpx; margin-top: 8rpx; }
.evt-btn {
flex: 1; height: 88rpx; line-height: 88rpx;
font-size: 30rpx; font-weight: 600;
border-radius: 999rpx;
text-align: center;
}
.evt-btn::after { border: none; }
.evt-btn-draft {
color: #5a6aa3;
background: rgba(255,255,255,0.55);
border: 1rpx solid rgba(99,132,255,0.22);
}
.evt-btn-submit {
color: #fff;
background: linear-gradient(135deg, #6b8bff, #8f7bff);
border: none;
box-shadow: 0 8rpx 24rpx rgba(98,132,255,0.35);
}
.evt-btn[disabled] { opacity: 0.5; }
/* 错误提示 */
.evt-err { font-size: 24rpx; color: #e05252; line-height: 1.5; }
/* 我的活动页 · 空状态 */
.myevt-empty {
padding: 80rpx 0; text-align: center;
background: rgba(255,255,255,0.55);
border: 1rpx solid rgba(99,132,255,0.12);
border-radius: 20rpx;
}
.myevt-empty-text { font-size: 28rpx; color: #7a85ad; }
.myevt-new {
width: 100%; height: 88rpx; line-height: 88rpx;
font-size: 30rpx; font-weight: 600;
color: #fff;
background: linear-gradient(135deg, #6b8bff, #8f7bff);
border: none; border-radius: 999rpx;
margin-bottom: 20rpx;
box-shadow: 0 8rpx 24rpx rgba(98,132,255,0.35);
}
.myevt-new::after { border: none; }
@@ -32,14 +32,14 @@ export default function MyEvents() {
return (
<View className="page-in">
<PageHeader back no="MY" title="我的活动" sub="已报名的活动"/>
<View className="adm-wrap">
<Button className="btn-ghost adm-new" onClick={() => Taro.navigateTo({ url: '/pages-extra/event-edit/index' })}>+ 发布新活动</Button>
<PageHeader back no="MY" title="我的活动" sub="发布的活动与审核状态"/>
<View className="evt-edit">
<Button className="myevt-new" onClick={() => Taro.navigateTo({ url: '/pages-extra/event-edit/index' })}>+ 发布新活动</Button>
{err ? <View className="card"><Text className="adm-note">{err}</Text></View> : null}
{!loaded ? (
<View className="card adm-empty"><Text className="adm-note">加载中</Text></View>
<View className="myevt-empty"><Text className="myevt-empty-text">加载中</Text></View>
) : items.length === 0 ? (
<View className="card adm-empty"><Text className="adm-note">还没有发布过活动</Text></View>
<View className="myevt-empty"><Text className="myevt-empty-text">还没有发布过活动点击上方按钮发布</Text></View>
) : (
<View className="adm-list">
{items.map((e) => {
@@ -59,7 +59,7 @@ export default function MyEvents() {
</View>
{e.reviewStatus === 'rejected' && e.reviewComment ? <Text className="adm-note">驳回原因{e.reviewComment}</Text> : null}
<View className="adm-acts">
<Button className="btn-ghost adm-actbtn" onClick={() => openEdit(e)}>编辑</Button>
<Button className="evt-opt" onClick={() => openEdit(e)}>编辑</Button>
</View>
</View>
);
@@ -1,2 +1,3 @@
@import "../../app.scss";
@import "../../styles/admin-pages.scss";
@import "../event-edit/index.scss";