feat(duty): sync public H5 with time, work plans, and remark

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-08-20 21:19:06 +08:00
1 parent 8df0583ad1
commit 8d9f0b259e
1 file changed
+52 -12
+52 -12
View File
@@ -6,12 +6,17 @@
<h2>链接无效或已失效</h2>
<p>请确认是否复制完整,或向管理员重新索取当日值班链接。</p>
</div>
<div v-else-if="errorType === 'closed' || page?.linkStatus === 'closed' || page?.closed" class="state">
<div
v-else-if="errorType === 'closed' || page?.linkStatus === 'closed' || page?.closed"
class="state"
>
<div class="icon off">⊘</div>
<h2>报名已关闭</h2>
<p>管理员已关闭本链接,暂时无法继续抢班。</p>
<div v-if="page?.dutyDate" class="card">
<div class="kv"><span>日期</span><span>{{ page.dutyDate }}</span></div>
<div class="kv"
><span>日期</span><span>{{ page.dutyDate }}</span></div
>
</div>
</div>
<div v-else-if="success" class="page">
@@ -25,9 +30,15 @@
<h2>已抢到{{ success.shiftLabel }}</h2>
<p>{{ success.dutyDate }}</p>
<div class="card">
<div class="kv"><span>日期</span><span>{{ success.dutyDate }}</span></div>
<div class="kv"><span>班次</span><span>{{ success.shiftLabel }}</span></div>
<div class="kv"><span>姓名</span><span>{{ success.personName }}</span></div>
<div class="kv"
><span>日期</span><span>{{ success.dutyDate }}</span></div
>
<div class="kv"
><span>班次</span><span>{{ success.shiftLabel }}</span></div
>
<div class="kv"
><span>姓名</span><span>{{ success.personName }}</span></div
>
</div>
<button type="button" class="btn secondary" @click="backToList">返回查看当日班次</button>
</div>
@@ -48,7 +59,7 @@
<section v-for="slot in page.slots" :key="slot.shiftType" class="slot">
<div class="slot-hd">
<div class="title">
<i class="dot" :class="slot.shiftType"></i>
<i class="dot" :class="dotClass(slot.shiftType)"></i>
{{ slot.shiftLabel || slot.shiftType }}
</div>
<span class="badge" :class="isFull(slot) ? 'full' : 'open'">
@@ -59,12 +70,20 @@
<span>名额</span>
<strong>{{ slot.taken }} / {{ slot.capacity }}</strong>
</div>
<p v-if="slot.remark" class="slot-remark">
工作安排:<strong>{{ slot.remark }}</strong>
<p v-if="slot.timeLabel" class="slot-time">
值班时间:<strong>{{ slot.timeLabel }}</strong>
</p>
<div class="bar"><i :style="{ width: barWidth(slot) }" :class="slot.shiftType"></i></div>
<p v-if="slot.workPlanLabels?.length" class="slot-remark">
工作安排:<strong>{{ slot.workPlanLabels.join('、') }}</strong>
</p>
<p v-if="slot.remark" class="slot-note">备注:{{ slot.remark }}</p>
<div class="bar">
<i :style="{ width: barWidth(slot) }" :class="dotClass(slot.shiftType)"></i>
</div>
<div class="people">
<span v-for="(a, i) in slot.assignments" :key="i" class="person">{{ a.personName }}</span>
<span v-for="(a, i) in slot.assignments" :key="i" class="person">{{
a.personName
}}</span>
<span v-if="!slot.assignments?.length" class="person empty">暂无人报名</span>
<span v-else-if="slot.capacity - slot.taken > 0" class="person empty">
空缺 {{ slot.capacity - slot.taken }}
@@ -102,7 +121,9 @@
<button v-else type="button" class="btn" disabled>名额已满</button>
</section>
</div>
<footer class="note">提交即表示确认当日可到岗值班<br />链接由管理员分享 · 请勿转发无关人员</footer>
<footer class="note"
>提交即表示确认当日可到岗值班<br />链接由管理员分享 · 请勿转发无关人员</footer
>
</div>
</div>
</template>
@@ -142,6 +163,13 @@
return (slot.taken || 0) >= (slot.capacity || 0)
}
function dotClass(shiftType: string) {
if (shiftType === 'morning' || shiftType === 'evening' || shiftType === 'duty') {
return shiftType
}
return 'other'
}
function barWidth(slot: PublicDutySlot) {
if (!slot.capacity) return '0%'
return `${Math.min(100, Math.round((slot.taken / slot.capacity) * 100))}%`
@@ -353,6 +381,9 @@
.dot.duty {
background: #d14343;
}
.dot.other {
background: #6b7b74;
}
.badge {
padding: 3px 8px;
font-size: 11px;
@@ -379,7 +410,9 @@
font-size: 15px;
color: #1f2a26;
}
.slot-remark {
.slot-time,
.slot-remark,
.slot-note {
margin: 8px 0 0;
font-size: 13px;
line-height: 1.45;
@@ -387,10 +420,14 @@
white-space: pre-wrap;
word-break: break-word;
}
.slot-time strong,
.slot-remark strong {
font-weight: 600;
color: #1f2a26;
}
.slot-note {
color: #8a9a93;
}
.bar {
height: 7px;
margin-top: 8px;
@@ -413,6 +450,9 @@
.bar > i.duty {
background: #d14343;
}
.bar > i.other {
background: #6b7b74;
}
.people {
display: flex;
flex-wrap: wrap;