commit
|
After Width: | Height: | Size: 985 KiB |
|
After Width: | Height: | Size: 628 KiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 708 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 695 KiB |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128" fill="none">
|
||||
<circle cx="64" cy="64" r="58" stroke="#F5222D" stroke-width="3"/>
|
||||
<path d="M21 54A44 44 0 0 1 107 54" stroke="#F5222D" stroke-width="9" stroke-linecap="round"/>
|
||||
<path d="M21 74A44 44 0 0 0 107 74" stroke="#F5222D" stroke-width="9" stroke-linecap="round"/>
|
||||
<circle cx="64" cy="64" r="27" stroke="#F5222D" stroke-width="9"/>
|
||||
<path d="M64 20V108" stroke="#F5222D" stroke-width="8" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 531 B |
|
After Width: | Height: | Size: 930 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 462 KiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 469 B |
|
After Width: | Height: | Size: 414 B |
|
After Width: | Height: | Size: 448 B |
|
After Width: | Height: | Size: 447 B |
|
After Width: | Height: | Size: 722 B |
|
After Width: | Height: | Size: 1021 KiB |
@@ -0,0 +1,8 @@
|
||||
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="24" cy="24" r="22" fill="#EAF3FF"/>
|
||||
<rect x="15" y="11" width="18" height="17" rx="4" fill="#2F7CF6"/>
|
||||
<path d="M12 24C10.8954 24 10 24.8954 10 26V32C10 33.1046 10.8954 34 12 34H36C37.1046 34 38 33.1046 38 32V26C38 24.8954 37.1046 24 36 24C34.8954 24 34 24.8954 34 26V29H14V26C14 24.8954 13.1046 24 12 24Z" fill="#1769E8"/>
|
||||
<rect x="14" y="28" width="20" height="7" rx="2.5" fill="#2F7CF6"/>
|
||||
<path d="M16 34H20L19 38H15L16 34Z" fill="#1769E8"/>
|
||||
<path d="M28 34H32L33 38H29L28 34Z" fill="#1769E8"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 637 B |
|
After Width: | Height: | Size: 986 KiB |
|
After Width: | Height: | Size: 528 KiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 257 KiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
@@ -0,0 +1,634 @@
|
||||
<template>
|
||||
<div>
|
||||
<van-action-sheet
|
||||
v-model="visible"
|
||||
class="activity-schedule-calendar"
|
||||
:style="{ height: '78%' }"
|
||||
:close-on-click-overlay="true"
|
||||
title="活动日历"
|
||||
closeable>
|
||||
<div class="activity-schedule-calendar__body">
|
||||
<div class="activity-schedule-calendar__month-bar">
|
||||
<button type="button" class="activity-schedule-calendar__month-btn" @click="changeMonth(-1)">
|
||||
<van-icon name="arrow-left"></van-icon>
|
||||
</button>
|
||||
<div class="activity-schedule-calendar__month-title">{{ currentYear }}年{{ currentMonth }}月</div>
|
||||
<button type="button" class="activity-schedule-calendar__month-btn" @click="changeMonth(1)">
|
||||
<van-icon name="arrow"></van-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="activity-schedule-calendar__weekdays">
|
||||
<span v-for="item in weekdays" :key="item">{{ item }}</span>
|
||||
</div>
|
||||
<div class="activity-schedule-calendar__days">
|
||||
<button
|
||||
v-for="day in calendarDays"
|
||||
:key="day.key"
|
||||
type="button"
|
||||
class="activity-schedule-calendar__day"
|
||||
:class="{
|
||||
'is-other-month': !day.currentMonth,
|
||||
'is-selected': day.key === selectedDate,
|
||||
'is-today': day.isToday
|
||||
}"
|
||||
@click="selectDay(day)">
|
||||
<span>
|
||||
<span class="activity-schedule-calendar__day-number">{{ day.day }}</span>
|
||||
<small v-if="day.isToday" class="activity-schedule-calendar__today-label">今</small>
|
||||
</span>
|
||||
<i v-if="day.status" class="activity-schedule-calendar__day-status" :class="'is-' + day.status"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="activity-schedule-calendar__legend">
|
||||
<span><i class="is-solid"></i>已签到</span>
|
||||
<span><i class="is-outline"></i>可签到</span>
|
||||
<span><i class="is-muted"></i>未开始</span>
|
||||
</div>
|
||||
|
||||
<div v-if="showMap" :id="mapContainerId" class="activity-schedule-calendar__map"></div>
|
||||
|
||||
<section class="activity-schedule-calendar__schedule-card">
|
||||
<div class="activity-schedule-calendar__schedule-title">
|
||||
{{ selectedDate ? selectedDate + ' 的活动时段' : '活动时段' }}
|
||||
</div>
|
||||
<div v-if="selectedTimes.length" class="activity-schedule-calendar__schedule-list">
|
||||
<div v-for="item in selectedTimes" :key="item.id" class="activity-schedule-calendar__schedule-item">
|
||||
<div class="activity-schedule-calendar__schedule-main">
|
||||
<van-icon :name="item.isAttend === true ? 'checked' : 'clock-o'"></van-icon>
|
||||
<div class="activity-schedule-calendar__schedule-copy">
|
||||
<div class="activity-schedule-calendar__schedule-time">
|
||||
{{ formatTime(item.courseStartTime) }} - {{ formatTime(item.courseEndTime) }}
|
||||
</div>
|
||||
<div v-if="row && row.courseLocation" class="activity-schedule-calendar__schedule-location">
|
||||
<van-icon name="location-o"></van-icon>
|
||||
<span>{{ row.courseLocation }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span v-if="item.isAttend === true" class="activity-schedule-calendar__status is-success">已签到</span>
|
||||
<button
|
||||
v-else-if="canSignItem(item)"
|
||||
type="button"
|
||||
class="activity-schedule-calendar__sign-btn"
|
||||
@click.stop="onSign(item)">签到</button>
|
||||
<span v-else class="activity-schedule-calendar__status" :class="{
|
||||
'is-ended': getScheduleStatus(item) === '已结束',
|
||||
'is-progressing': getScheduleStatus(item) === '进行中'
|
||||
}">
|
||||
{{ getScheduleStatus(item) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="activity-schedule-calendar__empty">
|
||||
<img src="/assets/mobile/img/activity/schedule-empty.png?v=20260821-transparent" alt="">
|
||||
<div class="activity-schedule-calendar__empty-title">当天暂无签到时段</div>
|
||||
<div class="activity-schedule-calendar__empty-desc">当前日期没有需要签到的活动安排</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
|
||||
<van-popup
|
||||
v-model="signVisible"
|
||||
round
|
||||
closeable
|
||||
:safe-area-inset-bottom="true"
|
||||
:close-on-click-overlay="false"
|
||||
:style="{ width: '80%', height: '66%' }"
|
||||
get-container="#app"
|
||||
@close="onSignClose">
|
||||
<scan-code ref="scanCodeRef"></scan-code>
|
||||
</van-popup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
name: "ActivityScheduleCalendar",
|
||||
props: {
|
||||
moduleType: {
|
||||
type: String,
|
||||
default: "brand"
|
||||
}
|
||||
},
|
||||
components: {
|
||||
"scan-code": httpVueLoader("/components/plugins/sysScanCode/index.vue?v=" + new Date().getTime())
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
row: null,
|
||||
currentYear: new Date().getFullYear(),
|
||||
currentMonth: new Date().getMonth() + 1,
|
||||
selectedDate: "",
|
||||
weekdays: ["日", "一", "二", "三", "四", "五", "六"],
|
||||
selectCourseTime: null,
|
||||
signVisible: false,
|
||||
markerLayer: null,
|
||||
map: null,
|
||||
circle: null,
|
||||
mapContainerId: "activityScheduleMap_" + Math.random().toString(36).slice(2)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
courseTimes() {
|
||||
return this.row && Array.isArray(this.row.courseTimes) ? this.row.courseTimes : []
|
||||
},
|
||||
scheduleDateMap() {
|
||||
const map = {}
|
||||
this.courseTimes.forEach(item => {
|
||||
const key = this.dateKey(item)
|
||||
if (!key) return
|
||||
if (!map[key]) map[key] = []
|
||||
map[key].push(item)
|
||||
})
|
||||
return map
|
||||
},
|
||||
selectedTimes() {
|
||||
return this.scheduleDateMap[this.selectedDate] || []
|
||||
},
|
||||
canSign() {
|
||||
return !!(this.row && this.row.isSign === true && this.row.isMobileSign === true)
|
||||
},
|
||||
showMap() {
|
||||
return !!(this.moduleType === "brand" && this.row && this.row.isMobileSign === true && this.row.signType === 3)
|
||||
},
|
||||
calendarDays() {
|
||||
const firstDay = new Date(this.currentYear, this.currentMonth - 1, 1)
|
||||
const startDate = new Date(this.currentYear, this.currentMonth - 1, 1 - firstDay.getDay())
|
||||
const todayKey = this.formatDateKey(new Date())
|
||||
return Array.from({ length: 42 }, (_, index) => {
|
||||
const date = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate() + index)
|
||||
const key = this.formatDateKey(date)
|
||||
return {
|
||||
key,
|
||||
day: date.getDate(),
|
||||
currentMonth: date.getFullYear() === this.currentYear && date.getMonth() + 1 === this.currentMonth,
|
||||
isToday: key === todayKey,
|
||||
status: this.getDayStatus(this.scheduleDateMap[key] || [])
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onOpen(row) {
|
||||
this.row = row
|
||||
const initialDate = this.formatDateKey(new Date())
|
||||
const date = this.$moment(initialDate)
|
||||
this.currentYear = date.year()
|
||||
this.currentMonth = date.month() + 1
|
||||
this.selectedDate = initialDate
|
||||
this.visible = true
|
||||
this.$nextTick(() => {
|
||||
if (this.showMap) this.initMap()
|
||||
})
|
||||
},
|
||||
dateKey(item) {
|
||||
const value = item && (item.courseDate || item.courseStartTime)
|
||||
return value ? this.$moment(value).format("YYYY-MM-DD") : ""
|
||||
},
|
||||
formatDateKey(date) {
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0")
|
||||
const day = String(date.getDate()).padStart(2, "0")
|
||||
return year + "-" + month + "-" + day
|
||||
},
|
||||
formatTime(value) {
|
||||
return value ? this.$moment(value).format("HH:mm") : "--"
|
||||
},
|
||||
canSignItem(item) {
|
||||
if (!this.canSign || !item || !item.courseStartTime || !item.courseEndTime) return false
|
||||
const now = this.$moment()
|
||||
return !now.isBefore(this.$moment(item.courseStartTime)) && !now.isAfter(this.$moment(item.courseEndTime))
|
||||
},
|
||||
getScheduleStatus(item) {
|
||||
if (!item || !item.courseStartTime || !item.courseEndTime) return "待开始"
|
||||
const now = this.$moment()
|
||||
if (now.isBefore(this.$moment(item.courseStartTime))) return "待开始"
|
||||
if (now.isAfter(this.$moment(item.courseEndTime))) return "已结束"
|
||||
return "进行中"
|
||||
},
|
||||
getDayStatus(items) {
|
||||
if (items.some(item => item.isAttend === true)) return "signed"
|
||||
if (items.some(item => this.canSignItem(item))) return "available"
|
||||
if (items.some(item => item.courseStartTime && this.$moment().isBefore(this.$moment(item.courseStartTime)))) return "pending"
|
||||
return ""
|
||||
},
|
||||
changeMonth(offset) {
|
||||
const date = new Date(this.currentYear, this.currentMonth - 1 + offset, 1)
|
||||
this.currentYear = date.getFullYear()
|
||||
this.currentMonth = date.getMonth() + 1
|
||||
},
|
||||
selectDay(day) {
|
||||
this.selectedDate = day.key
|
||||
if (!day.currentMonth) {
|
||||
const date = this.$moment(day.key)
|
||||
this.currentYear = date.year()
|
||||
this.currentMonth = date.month() + 1
|
||||
}
|
||||
},
|
||||
onSign(courseTime) {
|
||||
this.selectCourseTime = courseTime
|
||||
if (this.row.signType === 1) {
|
||||
this.signVisible = true
|
||||
this.$nextTick(() => this.$refs.scanCodeRef.init())
|
||||
} else if (this.row.signType === 2) {
|
||||
this.makeCode()
|
||||
} else if (this.row.signType === 3 && this.moduleType === "brand") {
|
||||
this.positionSign()
|
||||
} else {
|
||||
this.$toast("此签到模式正在升级中")
|
||||
}
|
||||
},
|
||||
onSignClose() {
|
||||
if (this.$refs.scanCodeRef) this.$refs.scanCodeRef.closeScan()
|
||||
},
|
||||
makeCode() {
|
||||
const baseUrl = this.moduleType === "family"
|
||||
? "/platform/family/mine/passiveScan"
|
||||
: "/platform/trainSignUp/mine/passiveScan"
|
||||
const content = jrQrcode.getQrBase64(baseUrl + "?id=" + this.selectCourseTime.id)
|
||||
vant.ImagePreview([content])
|
||||
},
|
||||
positionSign() {
|
||||
this.getLocation(coords => {
|
||||
if (!coords) return
|
||||
this.$axios.post("/platform/trainSignUp/mine/positionSign", {
|
||||
timeId: this.selectCourseTime.id,
|
||||
courseId: this.row.id,
|
||||
lat: coords.lat,
|
||||
lng: coords.lng
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.selectCourseTime.isAttend = true
|
||||
this.$toast("签到成功")
|
||||
} else {
|
||||
this.$toast(res.msg)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
getLocation(callback) {
|
||||
if (!navigator.geolocation) {
|
||||
this.$toast("当前浏览器不支持定位功能")
|
||||
callback(null)
|
||||
return
|
||||
}
|
||||
const loading = vant.Toast.loading({ message: "获取定位中...", forbidClick: false, duration: 0 })
|
||||
navigator.geolocation.getCurrentPosition(position => {
|
||||
loading.close()
|
||||
callback({ lat: position.coords.latitude, lng: position.coords.longitude })
|
||||
}, error => {
|
||||
loading.close()
|
||||
const messageMap = {
|
||||
1: "请允许浏览器获取位置信息",
|
||||
2: "无法获取当前位置",
|
||||
3: "定位超时,请重试"
|
||||
}
|
||||
this.$toast(messageMap[error.code] || "定位失败,请稍后重试")
|
||||
callback(null)
|
||||
}, { enableHighAccuracy: true, timeout: 10000, maximumAge: 60000 })
|
||||
},
|
||||
initMap() {
|
||||
if (!this.row.courseLocationCoordinates || typeof TMap === "undefined") return
|
||||
const position = JSON.parse(this.row.courseLocationCoordinates)
|
||||
const center = new TMap.LatLng(position[0], position[1])
|
||||
if (this.map) this.map.destroy()
|
||||
this.map = new TMap.Map(this.mapContainerId, { zoom: 16, center })
|
||||
this.markerLayer = new TMap.MultiMarker({
|
||||
map: this.map,
|
||||
geometries: [{ id: "activity", position: center }]
|
||||
})
|
||||
this.circle = new TMap.MultiCircle({
|
||||
map: this.map,
|
||||
geometries: [{ center, radius: this.row.radius || 100 }]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.activity-schedule-calendar {
|
||||
overflow: hidden;
|
||||
border-radius: 18px 18px 0 0;
|
||||
background: #f4f7fc;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar /deep/ .van-action-sheet__header {
|
||||
height: 50px;
|
||||
color: #1f2f43;
|
||||
background: #fff;
|
||||
font-size: 16px;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar /deep/ .van-action-sheet__close {
|
||||
top: 14px;
|
||||
color: #7e899a;
|
||||
font-size: 21px;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__body {
|
||||
height: 100%;
|
||||
padding: 14px 14px 24px;
|
||||
overflow-y: auto;
|
||||
overflow-anchor: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__month-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__month-btn {
|
||||
display: flex;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid #edf1f6;
|
||||
border-radius: 50%;
|
||||
color: #263548;
|
||||
background: #fff;
|
||||
box-shadow: 0 5px 14px rgba(55, 85, 126, .08);
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__month-title {
|
||||
color: #1f2f43;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__weekdays,
|
||||
.activity-schedule-calendar__days {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, minmax(0, 1fr));
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__weekdays {
|
||||
margin-bottom: 5px;
|
||||
color: #58677b;
|
||||
font-size: 12px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__day {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 38px;
|
||||
height: 48px;
|
||||
margin: 1px auto;
|
||||
padding: 0;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
border: 0;
|
||||
color: #263548;
|
||||
background: transparent;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__day > span {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__day-number {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
line-height: 14px;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__today-label {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 0;
|
||||
left: 0;
|
||||
color: #1989fa;
|
||||
font-size: 10px;
|
||||
line-height: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__day.is-other-month > span {
|
||||
color: #bdc5d0;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__day.is-selected > span {
|
||||
flex: 0 0 40px;
|
||||
width: 40px;
|
||||
min-width: 40px;
|
||||
height: 40px;
|
||||
min-height: 40px;
|
||||
color: #fff;
|
||||
background: #1989fa;
|
||||
box-shadow: 0 5px 12px rgba(25, 137, 250, .22);
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__day.is-selected .activity-schedule-calendar__today-label {
|
||||
top: 2px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__day-status {
|
||||
position: absolute;
|
||||
bottom: -3px;
|
||||
left: 50%;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
transform: translateX(-50%);
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__day-status.is-signed {
|
||||
background: #1989fa;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__day-status.is-available {
|
||||
border: 1px solid #1989fa;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__day-status.is-pending {
|
||||
background: #d8dde5;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__legend {
|
||||
display: flex;
|
||||
margin: 12px 4px 16px;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
color: #78869a;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__legend span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__legend i {
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__legend .is-solid { background: #1989fa; }
|
||||
.activity-schedule-calendar__legend .is-outline { border: 1px solid #1989fa; }
|
||||
.activity-schedule-calendar__legend .is-muted { background: #d8dde5; }
|
||||
|
||||
.activity-schedule-calendar__map {
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
margin-bottom: 12px;
|
||||
overflow: hidden;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__schedule-card {
|
||||
overflow: hidden;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
box-shadow: 0 7px 20px rgba(55, 85, 126, .07);
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__schedule-title {
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid #edf1f6;
|
||||
color: #263548;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__schedule-item {
|
||||
display: flex;
|
||||
min-height: 70px;
|
||||
padding: 12px 14px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #edf1f6;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__schedule-item:last-child { border-bottom: 0; }
|
||||
|
||||
.activity-schedule-calendar__schedule-main {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: flex-start;
|
||||
gap: 9px;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__schedule-main > .van-icon {
|
||||
margin-top: 2px;
|
||||
color: #1989fa;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__schedule-time {
|
||||
color: #263548;
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__schedule-location {
|
||||
display: flex;
|
||||
margin-top: 5px;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
color: #7d899a;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__status {
|
||||
flex: 0 0 auto;
|
||||
padding: 4px 8px;
|
||||
border-radius: 5px;
|
||||
color: #8b96a7;
|
||||
background: #f1f4f8;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__status.is-success {
|
||||
color: #19a965;
|
||||
background: #eaf8f1;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__status.is-progressing {
|
||||
color: #ff8a00;
|
||||
background: #fff4e6;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__status.is-ended {
|
||||
color: #98a2b2;
|
||||
background: #eef1f5;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__sign-btn {
|
||||
display: inline-flex;
|
||||
min-width: 42px !important;
|
||||
height: 24px !important;
|
||||
padding: 0 8px !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid #1989fa !important;
|
||||
border-radius: 5px !important;
|
||||
color: #fff !important;
|
||||
background-color: #1989fa !important;
|
||||
box-shadow: none !important;
|
||||
font-size: 11px !important;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__empty {
|
||||
padding: 18px 14px 22px;
|
||||
color: #9aa5b5;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__empty img {
|
||||
display: block;
|
||||
width: 142px;
|
||||
height: 94px;
|
||||
margin: 0 auto 4px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__empty-title {
|
||||
color: #58677b;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.activity-schedule-calendar__empty-desc {
|
||||
margin-top: 2px;
|
||||
color: #a2adbc;
|
||||
font-size: 11px;
|
||||
line-height: 18px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,221 @@
|
||||
.club-user-join-popup {
|
||||
overflow: hidden;
|
||||
background: #f3f7fc;
|
||||
}
|
||||
|
||||
.club-user-join-detail {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding-top: 46px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
background: #f3f7fc;
|
||||
color: #1f2d3d;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.club-user-join-detail > .van-nav-bar {
|
||||
z-index: 20;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.club-user-join-detail > .van-nav-bar .van-icon,
|
||||
.club-user-join-detail > .van-nav-bar .van-nav-bar__text {
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
.club-user-join-detail__scroll {
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.club-user-join-detail__content {
|
||||
padding: 12px 15px calc(18px + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.club-user-join-card {
|
||||
margin-bottom: 11px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 11px rgba(51, 87, 126, .08);
|
||||
}
|
||||
|
||||
.club-user-join-card__title {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 12px 14px 8px 21px;
|
||||
color: #354255;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.club-user-join-card__title::before {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
bottom: 11px;
|
||||
left: 12px;
|
||||
width: 2px;
|
||||
border-radius: 2px;
|
||||
background: #1989fa;
|
||||
content: '';
|
||||
}
|
||||
|
||||
.club-user-join-card__grid {
|
||||
display: grid;
|
||||
padding: 0 14px;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.club-user-join-card__item {
|
||||
min-width: 0;
|
||||
padding: 0 10px 13px 0;
|
||||
}
|
||||
|
||||
.club-user-join-card__item--full {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.club-user-join-card__item span,
|
||||
.club-user-join-material > span {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
color: #8b9bb0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.club-user-join-card__item strong {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
color: #40526a;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
line-height: 19px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.club-user-join-card__item--full strong {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.club-user-join-material {
|
||||
display: flex;
|
||||
padding: 0 14px;
|
||||
align-items: center;
|
||||
min-height: 40px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.club-user-join-material > span {
|
||||
flex: 0 0 82px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.club-user-join-material strong {
|
||||
color: #40526a;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.club-user-join-material .van-image {
|
||||
width: 56px;
|
||||
height: 40px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #edf2f8;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.club-user-join-info-card .van-cell-group {
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.club-user-join-info-card .van-cell {
|
||||
min-height: 44px;
|
||||
padding: 10px 14px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.club-user-join-info-card .van-cell:not(:last-child)::after {
|
||||
right: 14px;
|
||||
left: 14px;
|
||||
border-color: #eef2f7;
|
||||
}
|
||||
|
||||
.club-user-join-info-card .van-cell__title {
|
||||
width: 102px;
|
||||
color: #596779;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
flex: 0 0 102px;
|
||||
}
|
||||
|
||||
.club-user-join-info-card .van-cell__value {
|
||||
min-width: 0;
|
||||
color: #4f5d70;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
text-align: left;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.club-user-join-info-card .club-user-join-info-long-cell {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.club-user-join-info-card .club-user-join-info-long-cell .van-cell__title {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.club-user-join-info-card .club-user-join-info-long-cell .van-cell__value {
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.club-user-join-info-image {
|
||||
display: block;
|
||||
width: 56px;
|
||||
height: 40px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #edf2f8;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.club-user-join-task-card .van-cell-group {
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.club-user-join-task-card .van-cell {
|
||||
min-height: 44px;
|
||||
padding: 10px 14px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.club-user-join-task-card .van-cell:not(:last-child)::after {
|
||||
right: 14px;
|
||||
left: 14px;
|
||||
border-color: #eef2f7;
|
||||
}
|
||||
|
||||
.club-user-join-task-card .van-cell__title {
|
||||
width: 102px;
|
||||
color: #596779;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
flex: 0 0 102px;
|
||||
}
|
||||
|
||||
.club-user-join-task-card .van-cell__value {
|
||||
min-width: 0;
|
||||
color: #4f5d70;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
text-align: left;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
/* 疗休养移动端统一视觉主题:仅使用 tour-h5-theme 下的业务类,避免影响其他 H5 模块。 */
|
||||
body {
|
||||
background-color: #f3f7fd;
|
||||
}
|
||||
|
||||
[v-cloak] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tour-h5-theme {
|
||||
min-height: 100vh;
|
||||
color: #263548;
|
||||
background-color: #f3f7fd;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 页面接口首次加载时使用结构化骨架,避免先显示空字段或旧列表。 */
|
||||
.tour-content-skeleton {
|
||||
padding: 12px;
|
||||
background: #f3f7fd;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.tour-content-skeleton__cover,
|
||||
.tour-content-skeleton__title,
|
||||
.tour-content-skeleton__row,
|
||||
.tour-content-skeleton__card {
|
||||
background: linear-gradient(90deg, #edf2f8 25%, #f8fbff 37%, #edf2f8 63%);
|
||||
background-size: 400% 100%;
|
||||
animation: tour-content-skeleton-loading 1.35s ease infinite;
|
||||
}
|
||||
|
||||
.tour-content-skeleton__cover { height: 168px; border-radius: 14px; }
|
||||
.tour-content-skeleton__title { width: 46%; height: 18px; margin: 16px 2px 10px; border-radius: 9px; }
|
||||
.tour-content-skeleton__row { width: 76%; height: 13px; margin: 10px 2px; border-radius: 7px; }
|
||||
.tour-content-skeleton__card { height: 126px; margin-top: 12px; border-radius: 14px; }
|
||||
|
||||
@keyframes tour-content-skeleton-loading {
|
||||
0% { background-position: 100% 50%; }
|
||||
100% { background-position: 0 50%; }
|
||||
}
|
||||
|
||||
.tour-h5-theme .van-nav-bar {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.tour-h5-theme .van-nav-bar__title {
|
||||
color: #172033;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.tour-h5-theme .van-nav-bar .van-icon,
|
||||
.tour-h5-theme .van-nav-bar__text {
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
.tour-h5-theme .van-nav-bar::after,
|
||||
.tour-h5-theme .van-hairline--bottom::after {
|
||||
border-bottom-color: #edf2f8;
|
||||
}
|
||||
|
||||
.tour-h5-card {
|
||||
overflow: hidden;
|
||||
border-radius: 12px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 7px 20px rgba(55, 85, 126, .08);
|
||||
}
|
||||
|
||||
.tour-h5-section-title {
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-height: 46px;
|
||||
padding: 0 14px 0 20px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: #202938;
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
font-weight: 600;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.tour-h5-section-title::before {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
bottom: 15px;
|
||||
left: 10px;
|
||||
width: 3px;
|
||||
border-radius: 2px;
|
||||
background-color: #1989fa;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.tour-h5-tag {
|
||||
display: inline-flex;
|
||||
min-height: 22px;
|
||||
padding: 2px 8px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 11px;
|
||||
color: #1989fa;
|
||||
background-color: #eaf4ff;
|
||||
font-size: 11px;
|
||||
line-height: 18px;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tour-h5-tag.is-success {
|
||||
color: #20a765;
|
||||
background-color: #e9f8f0;
|
||||
}
|
||||
|
||||
.tour-h5-tag.is-warning {
|
||||
color: #e98018;
|
||||
background-color: #fff3e4;
|
||||
}
|
||||
|
||||
.tour-h5-tag.is-muted {
|
||||
color: #7c899b;
|
||||
background-color: #f0f2f5;
|
||||
}
|
||||
|
||||
.tour-h5-search {
|
||||
margin: 0 0 8px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 12px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 5px 16px rgba(43, 73, 112, .1);
|
||||
}
|
||||
|
||||
.tour-h5-search .van-search__content {
|
||||
height: 42px;
|
||||
padding-left: 12px;
|
||||
align-items: center;
|
||||
border-radius: 12px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.tour-h5-search .van-field__control {
|
||||
color: #263548;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.tour-h5-search .van-field__control::placeholder {
|
||||
color: #a7b0bf;
|
||||
}
|
||||
|
||||
.tour-h5-filter {
|
||||
overflow: hidden;
|
||||
border-radius: 10px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 5px 16px rgba(43, 73, 112, .08);
|
||||
}
|
||||
|
||||
.tour-h5-filter .van-dropdown-menu__bar,
|
||||
.tour-h5-filter .van-dropdown-menu__item,
|
||||
.tour-h5-filter .van-dropdown-menu__title {
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.tour-h5-filter .van-dropdown-menu__bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.tour-h5-filter .van-dropdown-menu__title {
|
||||
color: #66758a;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.tour-h5-filter .van-dropdown-menu__title--active,
|
||||
.tour-h5-filter .van-dropdown-item__option--active,
|
||||
.tour-h5-filter .van-dropdown-item__option--active .van-dropdown-item__icon {
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
.tour-h5-filter .van-dropdown-item__content {
|
||||
width: calc(100% - 24px);
|
||||
margin: 0 12px;
|
||||
overflow: hidden;
|
||||
border-radius: 0 0 12px 12px;
|
||||
box-shadow: 0 10px 24px rgba(31, 65, 108, .14);
|
||||
}
|
||||
|
||||
.tour-h5-empty {
|
||||
display: flex;
|
||||
min-height: 290px;
|
||||
padding: 40px 18px 32px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tour-h5-empty img {
|
||||
display: block;
|
||||
width: 60%;
|
||||
max-width: 190px;
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.tour-h5-empty__title {
|
||||
margin-top: 8px;
|
||||
color: #50627a;
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.tour-h5-empty__hint {
|
||||
margin-top: 5px;
|
||||
color: #9aa7b8;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.tour-h5-fixed-bar {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 30;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
|
||||
border-top: 1px solid #edf1f6;
|
||||
background-color: rgba(255, 255, 255, .98);
|
||||
box-shadow: 0 -6px 18px rgba(38, 66, 103, .08);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.tour-h5-fixed-bar .van-button {
|
||||
height: 42px;
|
||||
border-radius: 8px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.tour-h5-theme .van-cell {
|
||||
min-height: 48px;
|
||||
padding: 13px 14px;
|
||||
color: #35445a;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.tour-h5-theme .van-cell__title {
|
||||
color: #65748a;
|
||||
}
|
||||
|
||||
.tour-h5-theme .van-cell__value {
|
||||
color: #263548;
|
||||
}
|
||||
|
||||
.tour-h5-theme .van-field__label {
|
||||
color: #65748a;
|
||||
}
|
||||
|
||||
.tour-h5-theme .van-field__control {
|
||||
color: #263548;
|
||||
}
|
||||
|
||||
.tour-h5-theme .van-button--info,
|
||||
.tour-h5-theme .van-button--primary {
|
||||
border-color: #0f7bf3;
|
||||
background-color: #0f7bf3;
|
||||
}
|
||||
|
||||
.tour-h5-theme .van-button--plain.van-button--info {
|
||||
color: #0f7bf3;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
@media (max-width: 350px) {
|
||||
.tour-h5-fixed-bar {
|
||||
gap: 7px;
|
||||
padding-right: 10px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,490 @@
|
||||
.union-reimburse-page {
|
||||
min-height: 100vh;
|
||||
padding-bottom: calc(24px + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
background: #f3f7fd;
|
||||
color: #40526a;
|
||||
}
|
||||
|
||||
.union-reimburse-page .van-nav-bar,
|
||||
.union-reimburse-page .van-sticky--fixed { background: #fff; }
|
||||
|
||||
.union-reimburse-page .van-nav-bar__title {
|
||||
color: #172033;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.union-reimburse-page .van-nav-bar .van-icon,
|
||||
.union-reimburse-page .van-nav-bar .van-nav-bar__text { color: #1989fa; }
|
||||
|
||||
.union-reimburse-sticky {
|
||||
padding: 22px 12px 1px;
|
||||
box-sizing: border-box;
|
||||
background: #f3f7fd;
|
||||
}
|
||||
|
||||
.union-reimburse-search {
|
||||
margin: 0 0 8px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
box-shadow: 0 5px 16px rgba(43, 73, 112, .1);
|
||||
}
|
||||
|
||||
.union-reimburse-search .van-search__content {
|
||||
height: 42px;
|
||||
padding-left: 12px;
|
||||
align-items: center;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.union-reimburse-search .van-field__control { color: #263548; font-size: 14px; }
|
||||
.union-reimburse-search .van-field__control::placeholder { color: #a7b0bf; }
|
||||
|
||||
.union-reimburse-filter {
|
||||
margin-bottom: 8px;
|
||||
overflow: hidden;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
box-shadow: 0 5px 16px rgba(43, 73, 112, .08);
|
||||
}
|
||||
|
||||
.union-reimburse-filter .van-dropdown-menu__bar { height: 44px; box-shadow: none; }
|
||||
.union-reimburse-filter .van-dropdown-menu__item,
|
||||
.union-reimburse-filter .van-dropdown-menu__title { height: 44px; }
|
||||
.union-reimburse-filter .van-dropdown-menu__item { align-items: center; justify-content: center; }
|
||||
.union-reimburse-filter .van-dropdown-menu__title {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
color: #66758a;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.union-reimburse-filter .van-dropdown-menu__title--active,
|
||||
.union-reimburse-filter .van-dropdown-item__option--active,
|
||||
.union-reimburse-filter .van-dropdown-item__option--active .van-dropdown-item__icon { color: #1989fa; }
|
||||
|
||||
.union-reimburse-filter .van-dropdown-item__content {
|
||||
width: calc(100% - 24px);
|
||||
margin: 0 12px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
border-radius: 0 0 12px 12px;
|
||||
box-shadow: 0 10px 24px rgba(31, 65, 108, .14);
|
||||
}
|
||||
|
||||
.union-reimburse-filter .van-dropdown-item__option {
|
||||
display: flex;
|
||||
min-height: 48px;
|
||||
padding: 0 16px;
|
||||
align-items: center;
|
||||
color: #46566c;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.union-reimburse-list-content { padding: 0 12px; }
|
||||
.union-reimburse-page .table-list-container { margin-top: 0; padding-bottom: 2px; }
|
||||
.union-reimburse-page .table-list-container .table-list-item {
|
||||
margin-bottom: 12px;
|
||||
padding: 14px;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 5px 16px rgba(43, 73, 112, .08);
|
||||
}
|
||||
|
||||
.union-reimburse-card-header { display: flex; margin-bottom: 8px; align-items: flex-start; justify-content: space-between; }
|
||||
.union-reimburse-card-header__heading { min-width: 0; padding-right: 10px; flex: 1; }
|
||||
.union-reimburse-card-header__title {
|
||||
overflow: hidden;
|
||||
color: #253247;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.union-reimburse-card-header__sub { margin-top: 1px; color: #9ba6b6; font-size: 12px; line-height: 18px; }
|
||||
.union-reimburse-card-header__status { display: inline-flex; flex: none; }
|
||||
.union-reimburse-card-header__status.van-tag,
|
||||
.union-reimburse-card-header__status .van-tag {
|
||||
min-height: 24px;
|
||||
padding: 3px 9px;
|
||||
border: 0;
|
||||
border-radius: 12px;
|
||||
box-sizing: border-box;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
.union-reimburse-card-header__status--pending { color: #1989fa; background: #eaf4ff; }
|
||||
/* 报销成功与社团审核页 ProcessInstanceStateEnum 的“已完成”保持一致。 */
|
||||
.union-reimburse-card-header__status--success { color: #67c23a; background: #f0f9eb; }
|
||||
.union-reimburse-card-header__status--danger { color: #e35d5d; background: #fff0f0; }
|
||||
|
||||
.union-reimburse-page .table-list-container .table-list-item .item-actions {
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
border-top-color: #edf1f6;
|
||||
}
|
||||
.union-reimburse-page .table-list-container .table-list-item .action-btn {
|
||||
min-height: 28px;
|
||||
padding: 4px 11px;
|
||||
border-radius: 14px;
|
||||
color: #1989fa;
|
||||
background: #eaf4ff;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
.union-reimburse-page .table-list-container .table-list-item .action-btn.delete { color: #f04444; background: #fff0f0; }
|
||||
.union-reimburse-page .table-list-container .table-list-item .action-btn.review { color: #1989fa; background: #eaf4ff; }
|
||||
.union-reimburse-page .table-list-container .table-list-item .action-btn .van-icon { margin-right: 5px; font-size: 13px; }
|
||||
.union-reimburse-page .empty-state { padding: 0; }
|
||||
|
||||
.union-reimburse-list-skeleton { padding: 0; }
|
||||
.union-reimburse-skeleton-card {
|
||||
margin-bottom: 12px;
|
||||
padding: 14px;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
}
|
||||
.union-reimburse-skeleton-line {
|
||||
height: 13px;
|
||||
margin-bottom: 12px;
|
||||
border-radius: 7px;
|
||||
background: linear-gradient(90deg, #f2f3f5 25%, #e6e8eb 37%, #f2f3f5 63%);
|
||||
background-size: 400% 100%;
|
||||
animation: union-reimburse-skeleton-loading 1.4s ease infinite;
|
||||
}
|
||||
.union-reimburse-skeleton-line--title { width: 46%; height: 16px; }
|
||||
.union-reimburse-skeleton-line--short { width: 60%; }
|
||||
|
||||
.union-reimburse-empty {
|
||||
display: flex;
|
||||
min-height: 280px;
|
||||
padding: 46px 18px 36px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
.union-reimburse-empty img { display: block; width: 86%; max-width: 290px; height: auto; object-fit: contain; }
|
||||
.union-reimburse-empty__title { margin-top: 14px; color: #50627a; font-size: 15px; font-weight: 600; line-height: 22px; }
|
||||
.union-reimburse-empty__hint { margin-top: 5px; color: #9aa7b8; font-size: 12px; line-height: 18px; }
|
||||
|
||||
/* 申请页沿用社团申请的卡片层级,保留报销业务原有字段与交互。 */
|
||||
.union-reimburse-form { padding-bottom: 0; }
|
||||
.union-reimburse-form .custom-nav { box-shadow: none; }
|
||||
.union-reimburse-form .form-container { padding: 12px 15px calc(86px + env(safe-area-inset-bottom)); }
|
||||
.union-reimburse-form .form-section {
|
||||
margin: 0 0 11px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 11px rgba(51, 87, 126, .08);
|
||||
}
|
||||
|
||||
.union-reimburse-form .form-section .van-cell-group__title,
|
||||
.union-reimburse-form .payment-toolbar,
|
||||
.union-reimburse-form .invoice-toolbar {
|
||||
position: relative;
|
||||
min-height: 42px;
|
||||
margin: 0;
|
||||
padding: 12px 14px 8px 21px;
|
||||
box-sizing: border-box;
|
||||
color: #354255;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.union-reimburse-form .form-section__title {
|
||||
position: relative;
|
||||
min-height: 41px;
|
||||
margin: 0;
|
||||
padding: 13px 15px 8px 24px;
|
||||
box-sizing: border-box;
|
||||
color: #1f2d3d;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.union-reimburse-form .form-section__title::before {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 15px;
|
||||
width: 3px;
|
||||
height: 14px;
|
||||
border-radius: 2px;
|
||||
background: #1989fa;
|
||||
content: '';
|
||||
}
|
||||
|
||||
.union-reimburse-form .form-section .van-cell-group__title::before,
|
||||
.union-reimburse-form .payment-toolbar::before,
|
||||
.union-reimburse-form .invoice-toolbar::before {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
bottom: 11px;
|
||||
left: 12px;
|
||||
width: 2px;
|
||||
border-radius: 2px;
|
||||
background: #1989fa;
|
||||
content: '';
|
||||
}
|
||||
|
||||
.union-reimburse-form .form-section .van-cell { min-height: 46px; padding: 11px 15px; background: transparent; }
|
||||
.union-reimburse-form .form-section .van-cell::after { right: 15px; left: 15px; border-color: #eef2f7; }
|
||||
.union-reimburse-form .form-section .van-field__label { width: 105px; color: #596779; font-size: 13px; line-height: 24px; }
|
||||
.union-reimburse-form .payment-detail-item .van-cell--required::before { left: 6px; color: #f06464; }
|
||||
.union-reimburse-form .form-section .van-field__control { color: #40526a; font-size: 14px; line-height: 24px; }
|
||||
.union-reimburse-form .form-section .van-field__control::placeholder { color: #a7b0bf; }
|
||||
.union-reimburse-form .more-text { display: block; }
|
||||
.union-reimburse-form .more-text .van-field__label { width: auto; margin-bottom: 7px; }
|
||||
.union-reimburse-form .more-text .van-field__control {
|
||||
min-height: 88px;
|
||||
padding: 10px 12px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #c9d5e5;
|
||||
border-radius: 10px;
|
||||
background: #f7f9fd;
|
||||
}
|
||||
|
||||
/* 附件上传区域与困难帮扶申请页保持一致,避免上传控件被文本域样式包裹。 */
|
||||
.union-reimburse-form .form-section .reimburse-upload-field .van-field__control {
|
||||
min-height: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.union-reimburse-form .payment-section,
|
||||
.union-reimburse-form .invoice-section { padding: 0 0 14px; }
|
||||
.union-reimburse-form .payment-toolbar,
|
||||
.union-reimburse-form .invoice-toolbar { display: flex; align-items: center; justify-content: space-between; }
|
||||
.union-reimburse-form .payment-toolbar .van-button,
|
||||
.union-reimburse-form .invoice-toolbar .van-button {
|
||||
height: 28px;
|
||||
padding: 0 12px;
|
||||
border: 0;
|
||||
border-radius: 14px;
|
||||
color: #1989fa;
|
||||
background: #eaf4ff;
|
||||
}
|
||||
.union-reimburse-form .payment-detail-item,
|
||||
.union-reimburse-form .invoice-detail-item {
|
||||
margin: 8px 14px 0;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e6ebf2;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
box-shadow: none;
|
||||
}
|
||||
.union-reimburse-form .invoice-detail-item { padding: 0; }
|
||||
.union-reimburse-form .invoice-detail-title {
|
||||
min-height: 38px;
|
||||
padding: 0 12px;
|
||||
box-sizing: border-box;
|
||||
color: #40526a;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
background: #f7f9fd;
|
||||
border-bottom: 1px solid #eef2f7;
|
||||
}
|
||||
.union-reimburse-form .invoice-detail-line {
|
||||
margin: 0;
|
||||
padding: 8px 12px 0;
|
||||
color: #718096;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
word-break: break-all;
|
||||
}
|
||||
.union-reimburse-form .invoice-detail-line:last-of-type { padding-bottom: 8px; }
|
||||
.union-reimburse-form .invoice-detail-actions,
|
||||
.union-reimburse-form .payment-detail-actions {
|
||||
min-height: 28px;
|
||||
margin-top: 8px;
|
||||
padding: 9px 12px;
|
||||
box-sizing: border-box;
|
||||
border-top: 1px solid #eef2f7;
|
||||
background: #fff;
|
||||
}
|
||||
.union-reimburse-form .invoice-detail-actions { justify-content: flex-end; gap: 6px; }
|
||||
.union-reimburse-form .invoice-detail-actions .van-button,
|
||||
.union-reimburse-form .payment-detail-actions .payment-delete-btn {
|
||||
height: 28px;
|
||||
min-width: 52px;
|
||||
padding: 0 10px;
|
||||
border: 0;
|
||||
border-radius: 14px;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
.union-reimburse-form .invoice-detail-actions .van-button--info,
|
||||
.union-reimburse-form .invoice-detail-actions .van-button--primary {
|
||||
color: #1989fa;
|
||||
background: #eaf4ff;
|
||||
}
|
||||
.union-reimburse-form .invoice-detail-actions .van-button--danger,
|
||||
.union-reimburse-form .payment-detail-actions .payment-delete-btn {
|
||||
color: #f04444;
|
||||
background: #fff0f0;
|
||||
}
|
||||
.union-reimburse-form .invoice-detail-actions .van-icon,
|
||||
.union-reimburse-form .payment-detail-actions .payment-delete-btn .van-icon {
|
||||
margin-right: 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.union-reimburse-form .payment-detail-item .van-cell { padding-right: 12px; padding-left: 12px; }
|
||||
.union-reimburse-form .payment-detail-title {
|
||||
min-height: 38px;
|
||||
padding: 0 12px;
|
||||
color: #40526a;
|
||||
background: #f7f9fd;
|
||||
border-bottom-color: #eef2f7;
|
||||
}
|
||||
.union-reimburse-form .invoice-tip { margin: 8px 14px 10px; border-color: #dce9f8; color: #718096; background: #f5f9ff; }
|
||||
.union-reimburse-form .form-actions {
|
||||
gap: 10px;
|
||||
padding: 10px 15px calc(10px + env(safe-area-inset-bottom));
|
||||
box-shadow: 0 -2px 12px rgba(43, 73, 112, .09);
|
||||
}
|
||||
.union-reimburse-form .form-actions .van-button { height: 40px; border-radius: 8px; font-size: 14px; font-weight: 500; }
|
||||
.union-reimburse-form .form-actions .van-button--primary { border-color: #1989fa; background: #1989fa; box-shadow: none; }
|
||||
.union-reimburse-form .form-actions .van-button--info.van-button--plain { color: #1989fa; border-color: #1989fa; }
|
||||
|
||||
/* 新增、编辑发票弹框与申请页共用卡片、字段和操作按钮视觉规范。 */
|
||||
.union-reimburse-form .invoice-popup {
|
||||
overflow: hidden;
|
||||
background: #f3f7fd;
|
||||
}
|
||||
.union-reimburse-form .invoice-popup .van-nav-bar { flex: none; box-shadow: 0 1px 6px rgba(43, 73, 112, .08); }
|
||||
.union-reimburse-form .invoice-popup .van-nav-bar__title { color: #1f2d3d; font-size: 16px; font-weight: 600; }
|
||||
.union-reimburse-form .invoice-popup-body {
|
||||
padding: 12px 15px;
|
||||
box-sizing: border-box;
|
||||
background: #f3f7fd;
|
||||
}
|
||||
.union-reimburse-form .invoice-popup-card {
|
||||
overflow: hidden;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 11px rgba(51, 87, 126, .08);
|
||||
}
|
||||
.union-reimburse-form .invoice-popup-card .van-cell { min-height: 46px; padding: 11px 15px; background: transparent; }
|
||||
.union-reimburse-form .invoice-popup-card .van-cell::after { right: 15px; left: 15px; border-color: #eef2f7; }
|
||||
.union-reimburse-form .invoice-popup-card .van-field__label { width: 105px; color: #596779; font-size: 13px; line-height: 24px; }
|
||||
.union-reimburse-form .invoice-popup-card .van-field__control { color: #40526a; font-size: 14px; line-height: 24px; }
|
||||
.union-reimburse-form .invoice-popup-card .van-field__control::placeholder { color: #a7b0bf; }
|
||||
.union-reimburse-form .invoice-popup-card .more-text { display: block; }
|
||||
.union-reimburse-form .invoice-popup-card .more-text .van-field__label { width: auto; margin-bottom: 7px; }
|
||||
.union-reimburse-form .invoice-popup-card .more-text .van-field__control {
|
||||
min-height: 88px;
|
||||
padding: 10px 12px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #c9d5e5;
|
||||
border-radius: 10px;
|
||||
background: #f7f9fd;
|
||||
}
|
||||
|
||||
/* 发票文件只保留上传控件本身,移除报销文本域的边框、背景和内边距。 */
|
||||
.union-reimburse-form .invoice-popup-card .more-text.invoice-popup-file-field .van-field__control {
|
||||
min-height: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.union-reimburse-form .invoice-popup-tip {
|
||||
margin: 10px 0 0;
|
||||
padding: 9px 11px;
|
||||
border-color: #dce9f8;
|
||||
color: #718096;
|
||||
background: #f5f9ff;
|
||||
}
|
||||
.union-reimburse-form .invoice-popup-actions {
|
||||
flex: none;
|
||||
gap: 10px;
|
||||
padding: 10px 15px calc(10px + env(safe-area-inset-bottom));
|
||||
box-shadow: 0 -2px 12px rgba(43, 73, 112, .09);
|
||||
}
|
||||
.union-reimburse-form .invoice-popup-actions .van-button { height: 40px; border-radius: 8px; font-size: 14px; font-weight: 500; }
|
||||
.union-reimburse-form .invoice-popup-actions .van-button--primary { border-color: #1989fa; background: #1989fa; box-shadow: none; }
|
||||
.union-reimburse-form .invoice-popup-actions .van-button--info.van-button--plain { color: #1989fa; border-color: #1989fa; background: #fff; }
|
||||
|
||||
/* 审核卡片与社团审核保持相同的标题、必填标记和按钮规格。 */
|
||||
.union-reimburse-approval { padding: 0; background: #f3f7fd; }
|
||||
.union-reimburse-approval-card {
|
||||
margin: 0 0 11px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 11px rgba(51, 87, 126, .08);
|
||||
}
|
||||
.union-reimburse-approval-card__title {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 12px 14px 8px 21px;
|
||||
color: #354255;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
}
|
||||
.union-reimburse-approval-card__title::before {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
bottom: 11px;
|
||||
left: 12px;
|
||||
width: 2px;
|
||||
border-radius: 2px;
|
||||
background: #1989fa;
|
||||
content: '';
|
||||
}
|
||||
.union-reimburse-approval-field-label {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 10px 14px 6px;
|
||||
color: #596779;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
}
|
||||
.union-reimburse-approval-required { position: absolute; left: 6px; color: #ee0a24; font-size: 12px; }
|
||||
.union-reimburse-approval-card .van-field.union-reimburse-approval-field {
|
||||
width: calc(100% - 28px);
|
||||
margin: 0 14px 14px;
|
||||
padding: 12px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #c9d5e5;
|
||||
border-radius: 10px;
|
||||
background: #f7f9fd;
|
||||
}
|
||||
.union-reimburse-approval-card .van-field.union-reimburse-approval-field .van-field__control {
|
||||
min-height: 150px;
|
||||
color: #253247;
|
||||
font-size: 12px;
|
||||
line-height: 22px;
|
||||
}
|
||||
.union-reimburse-approval-card .van-field.union-reimburse-approval-field::after { display: none; }
|
||||
.union-reimburse-approval-actions {
|
||||
display: flex;
|
||||
column-gap: 10px;
|
||||
padding: 10px 12px calc(12px + env(safe-area-inset-bottom));
|
||||
}
|
||||
.union-reimburse-approval-actions .van-button { height: 40px; border-radius: 14px; font-size: 14px; }
|
||||
|
||||
@keyframes union-reimburse-skeleton-loading {
|
||||
0% { background-position: 100% 50%; }
|
||||
100% { background-position: 0 50%; }
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
.proposal-view-page {
|
||||
--proposal-view-primary: #1677ee;
|
||||
--proposal-view-text: #354255;
|
||||
--proposal-view-muted: #8a97a8;
|
||||
min-height: 100%;
|
||||
padding-bottom: calc(20px + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
color: var(--proposal-view-text);
|
||||
background: #f3f7fc;
|
||||
}
|
||||
|
||||
/* 提案 H5 列表统一使用全屏 Popup 承载详情和办理表单。 */
|
||||
.proposal-full-popup {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: #f3f7fc;
|
||||
}
|
||||
|
||||
.proposal-full-popup__page {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding-top: 46px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.proposal-full-popup__page > .van-nav-bar {
|
||||
z-index: 20;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.proposal-full-popup__scroll {
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.proposal-full-popup__scroll .proposal-view-main {
|
||||
padding-top: 18px;
|
||||
}
|
||||
|
||||
.proposal-popup-form-actions {
|
||||
display: flex;
|
||||
padding: 10px 12px calc(12px + env(safe-area-inset-bottom));
|
||||
justify-content: space-between;
|
||||
column-gap: 10px;
|
||||
}
|
||||
|
||||
/* 提案页面按需启用的圆角按钮与分页样式,不影响未声明对应 class 的组件。 */
|
||||
.proposal-soft-button,
|
||||
.proposal-soft-pagination {
|
||||
--proposal-soft-primary: #1989fa;
|
||||
}
|
||||
|
||||
/* 提案审核弹框的次要操作按钮统一使用柔和圆角,不包含阴影或漫反射效果。 */
|
||||
.proposal-rounded-button {
|
||||
border-radius: 14px;
|
||||
}
|
||||
|
||||
.proposal-soft-pagination {
|
||||
column-gap: 2px;
|
||||
}
|
||||
|
||||
.proposal-soft-button {
|
||||
border-color: var(--proposal-soft-primary);
|
||||
border-radius: 14px;
|
||||
background-color: var(--proposal-soft-primary);
|
||||
}
|
||||
|
||||
/* 保持危险操作原有红色语义。 */
|
||||
.proposal-soft-button--danger {
|
||||
border-color: #ff4d4f;
|
||||
background-color: #ff4d4f;
|
||||
}
|
||||
|
||||
/* 保持退回类操作原有橙色语义。 */
|
||||
.proposal-soft-button--warning {
|
||||
border-color: #ff976a;
|
||||
background-color: #ff976a;
|
||||
}
|
||||
|
||||
/* 校工会预审核四个操作按钮与 PC 端 Element UI 的 primary、danger、info 配色保持一致。 */
|
||||
.proposal-pre-audit-actions .proposal-pre-audit-button--primary {
|
||||
border-color: var(--color-primary);
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.proposal-pre-audit-actions .proposal-pre-audit-button--danger {
|
||||
border-color: #f56c6c;
|
||||
background-color: #f56c6c;
|
||||
}
|
||||
|
||||
.proposal-pre-audit-actions .proposal-pre-audit-button--info {
|
||||
border-color: #909399;
|
||||
background-color: #909399;
|
||||
}
|
||||
|
||||
.proposal-soft-pagination .van-pagination__item {
|
||||
color: var(--proposal-soft-primary);
|
||||
background-color: #f8fbff;
|
||||
border-radius: 12px;
|
||||
transition: color 0.2s ease, background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.proposal-soft-pagination .van-pagination__item::after {
|
||||
border-color: rgba(25, 137, 250, 0.16);
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
.proposal-soft-pagination .van-pagination__item--active,
|
||||
.proposal-soft-pagination .van-pagination__item:not(.van-pagination__item--disabled):active {
|
||||
color: #fff;
|
||||
background-color: var(--proposal-soft-primary);
|
||||
}
|
||||
|
||||
.proposal-soft-pagination .van-pagination__item--disabled,
|
||||
.proposal-soft-pagination .van-pagination__item--disabled:active {
|
||||
color: #646566;
|
||||
background-color: #f7f8fa;
|
||||
}
|
||||
|
||||
.proposal-action-icon {
|
||||
margin-right: 6px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.reply-unit-popup {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.reply-unit-toolbar {
|
||||
display: grid;
|
||||
min-height: 48px;
|
||||
border-bottom: 1px solid #eee;
|
||||
grid-template-columns: 64px 1fr 64px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.reply-unit-toolbar button {
|
||||
height: 48px;
|
||||
padding: 0;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.reply-unit-toolbar button:last-child {
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
.reply-unit-toolbar-title {
|
||||
color: #222;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.reply-unit-list {
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.reply-unit-empty {
|
||||
padding: 48px 16px;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.transfer-dialog {
|
||||
padding: 18px 16px 76px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.proposal-info-card {
|
||||
margin-bottom: 16px;
|
||||
padding: 16px;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.proposal-info-card .info-item {
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
flex-direction: column;
|
||||
row-gap: 4px;
|
||||
}
|
||||
|
||||
.proposal-info-card .info-item label {
|
||||
color: #969799;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.proposal-full-popup__page > .button-group {
|
||||
display: flex;
|
||||
padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
|
||||
background: #fff;
|
||||
column-gap: 10px;
|
||||
}
|
||||
|
||||
.proposal-view-main {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding: 12px 15px 0;
|
||||
}
|
||||
|
||||
.proposal-view-card {
|
||||
margin-bottom: 11px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 10px;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 3px 11px rgba(51, 87, 126, 0.08);
|
||||
}
|
||||
|
||||
.proposal-view-card__title {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 12px 14px 8px 21px;
|
||||
color: #354255;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.proposal-view-card__title::before {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
bottom: 11px;
|
||||
left: 12px;
|
||||
width: 2px;
|
||||
border-radius: 2px;
|
||||
background: var(--proposal-view-primary);
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* 审核、附议、反馈及答复输入框统一复用提案查询 Card 的视觉规范。 */
|
||||
.proposal-audit-card__required {
|
||||
margin-left: 4px;
|
||||
color: #ee0a24;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.proposal-view-card .van-field.proposal-audit-field {
|
||||
width: calc(100% - 28px);
|
||||
margin: 0 14px 14px;
|
||||
padding: 12px;
|
||||
border: 1px solid #c9d5e5;
|
||||
border-radius: 10px;
|
||||
background-color: #f7f9fd;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.proposal-view-card .van-field.proposal-audit-field .van-field__control {
|
||||
min-height: 150px;
|
||||
color: #253247;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.proposal-view-card .van-field.proposal-audit-field .van-field__control::placeholder {
|
||||
color: #9aa7b8;
|
||||
}
|
||||
|
||||
.proposal-view-card .van-field.proposal-audit-field .van-field__word-limit {
|
||||
color: #718096;
|
||||
}
|
||||
|
||||
.proposal-view-card .van-field.proposal-audit-field::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.proposal-view-card .van-cell-group {
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.proposal-view-card .van-cell {
|
||||
min-height: 44px;
|
||||
padding: 10px 14px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.proposal-view-card .van-cell:not(:last-child)::after {
|
||||
right: 14px;
|
||||
left: 14px;
|
||||
border-color: #eef2f7;
|
||||
}
|
||||
|
||||
.proposal-view-card .van-cell__title {
|
||||
flex: 0 0 92px;
|
||||
width: 92px;
|
||||
color: #354255;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
/* 纵向字段中 flex-basis 会转为标题高度,需要取消横向字段使用的 92px 固定占位。 */
|
||||
.proposal-view-card .direction-column-field .van-cell__title {
|
||||
flex: none;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.proposal-view-card .van-cell__value {
|
||||
min-width: 0;
|
||||
color: #4f5d70;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
text-align: left;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.proposal-view-card .proposal-view-long-cell {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.proposal-view-card .proposal-view-long-cell .van-cell__title {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.proposal-view-card .proposal-view-long-cell .van-cell__value {
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.proposal-view-rich-value,
|
||||
.proposal-view-rich-value * {
|
||||
max-width: 100%;
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.proposal-view-rich-value img,
|
||||
.proposal-view-rich-value image {
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.proposal-view-card .van-tag {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.proposal-view-merge-cell .van-cell__title {
|
||||
flex: 1;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.proposal-view-merge-cell .van-cell__label {
|
||||
margin-top: 4px;
|
||||
color: var(--proposal-view-muted);
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.proposal-flow-card__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.proposal-flow-card__hint {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding-right: 14px;
|
||||
color: var(--proposal-view-muted);
|
||||
font-size: 13px;
|
||||
line-height: 22px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.proposal-flow-card__hint .van-icon {
|
||||
margin-left: 4px;
|
||||
color: #7f8da0;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.proposal-flow-scroll {
|
||||
width: 100%;
|
||||
padding: 4px 14px 15px;
|
||||
overflow-x: auto;
|
||||
box-sizing: border-box;
|
||||
scroll-behavior: smooth;
|
||||
scroll-snap-type: x proximity;
|
||||
scrollbar-width: none;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.proposal-flow-scroll::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.proposal-flow-track {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: max-content;
|
||||
min-width: 100%;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.proposal-flow-track::before {
|
||||
position: absolute;
|
||||
top: 24px;
|
||||
right: 52px;
|
||||
left: 52px;
|
||||
height: 2px;
|
||||
background: #d8e9ff;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.proposal-flow-node {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex: 0 0 108px;
|
||||
width: 108px;
|
||||
padding: 0 6px;
|
||||
border: 0;
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
color: var(--proposal-view-text);
|
||||
background: transparent;
|
||||
font-family: inherit;
|
||||
scroll-snap-align: center;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
.proposal-flow-node__icon {
|
||||
display: flex;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border: 3px solid #ffffff;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #ffffff;
|
||||
background: var(--proposal-view-primary);
|
||||
box-shadow: 0 2px 7px rgba(22, 119, 238, 0.22);
|
||||
transition: box-shadow 0.2s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
.proposal-flow-node__icon .van-icon {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.proposal-flow-node__title {
|
||||
display: -webkit-box;
|
||||
min-height: 40px;
|
||||
margin-top: 8px;
|
||||
overflow: hidden;
|
||||
color: #354255;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
word-break: break-word;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
|
||||
.proposal-flow-node__handler {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-top: 1px;
|
||||
overflow: hidden;
|
||||
color: var(--proposal-view-muted);
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.proposal-flow-node.is-active .proposal-flow-node__icon {
|
||||
box-shadow: 0 0 0 5px #e7f2ff, 0 3px 9px rgba(22, 119, 238, 0.28);
|
||||
transform: scale(1.06);
|
||||
}
|
||||
|
||||
.proposal-flow-node.is-active .proposal-flow-node__title {
|
||||
color: var(--proposal-view-primary);
|
||||
}
|
||||
|
||||
.proposal-flow-detail__name {
|
||||
margin: 0;
|
||||
padding: 4px 14px 10px;
|
||||
border-bottom: 1px solid #eef2f7;
|
||||
color: #26364a;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.proposal-flow-detail__tip {
|
||||
padding: 9px 14px 12px;
|
||||
border-top: 1px solid #eef2f7;
|
||||
color: var(--proposal-view-muted);
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.proposal-view-table-wrap {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.proposal-view-table-wrap .el-table {
|
||||
min-width: 560px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.proposal-view-slot:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 600px) {
|
||||
.proposal-view-main {
|
||||
max-width: 520px;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,457 @@
|
||||
const PROPOSAL_TASK_POPUP = {
|
||||
template: /*language=HTML*/ `
|
||||
<van-popup v-model="visible" position="right" class="proposal-full-popup" :close-on-click-overlay="false"
|
||||
get-container="#app">
|
||||
<div class="proposal-full-popup__page">
|
||||
<van-nav-bar @click-left="close" left-arrow left-text="返回" :title="title" placeholder
|
||||
fixed></van-nav-bar>
|
||||
<div class="proposal-full-popup__scroll">
|
||||
<proposal-info v-if="bizId" :biz-id="bizId" :visible="visible">
|
||||
<div v-if="isApproval">
|
||||
<van-form ref="formRef">
|
||||
<template
|
||||
v-if="kind === 'delegation' || kind === 'preAudit' || kind === 'schoolLeaderApproval'">
|
||||
<section class="proposal-view-card">
|
||||
<h2 class="proposal-view-card__title">审批意见<span
|
||||
class="proposal-audit-card__required">*</span></h2>
|
||||
<van-field v-model="formData.tf_opinion" class="proposal-audit-field"
|
||||
name="tf_opinion" type="textarea" rows="6" label=""
|
||||
placeholder="请输入审批意见"
|
||||
:rules="[{required:true,message:'请填写审批意见'}]" required
|
||||
maxlength="100" show-word-limit></van-field>
|
||||
</section>
|
||||
</template>
|
||||
<template v-if="kind === 'feedbackEvaluation'">
|
||||
<section class="proposal-view-card">
|
||||
|
||||
<h2 class="proposal-view-card__title">反馈评价<span
|
||||
class="proposal-audit-card__required">*</span></h2>
|
||||
<van-field v-model="formData.tf_feedback_name" label="满意度"
|
||||
placeholder="请选择满意度"
|
||||
:rules="[{required:true,message:'请选择满意度'}]" required readonly
|
||||
is-link @click="openLayer('feedback-picker')"></van-field>
|
||||
<van-field v-model="formData.tf_opinion" class="proposal-audit-field"
|
||||
name="tf_opinion" type="textarea" rows="6" label=""
|
||||
placeholder="请输入反馈意见"
|
||||
:rules="[{required:true,message:'请填写反馈意见'}]"
|
||||
maxlength="100" show-word-limit></van-field>
|
||||
</section>
|
||||
</template>
|
||||
<template v-if="kind === 'suggestion'">
|
||||
<section class="proposal-view-card">
|
||||
<van-field v-model="formData.result" label="承办意向"
|
||||
placeholder="请选择承办意向"
|
||||
:rules="[{required:true,message:'请选择承办意向'}]" required readonly
|
||||
is-link @click="openLayer('result-picker')"></van-field>
|
||||
<h2 class="proposal-view-card__title">反馈意见<span
|
||||
class="proposal-audit-card__required">*</span></h2>
|
||||
<van-field v-model="formData.opinion" class="proposal-audit-field"
|
||||
name="opinion" type="textarea" rows="6" label=""
|
||||
placeholder="请输入反馈意见"
|
||||
:rules="[{required:true,message:'请输入反馈意见'}]" required
|
||||
show-word-limit></van-field>
|
||||
</section>
|
||||
</template>
|
||||
<template v-if="kind === 'unitReply'">
|
||||
<section class="proposal-view-card">
|
||||
<h2 class="proposal-view-card__title">承办单位答复<span
|
||||
class="proposal-audit-card__required">*</span></h2>
|
||||
<van-field :value="formData.underTakeName" label="承办单位"
|
||||
readonly></van-field>
|
||||
<van-field v-model="formData.tf_implementStateName" label="落实情况"
|
||||
placeholder="请选择落实情况"
|
||||
:rules="[{required:true,message:'请选择落实情况'}]" required readonly
|
||||
is-link @click="openLayer('implement-picker')"></van-field>
|
||||
<!-- 承办单位答复附件上传入口暂时停用,保留公用上传组件配置便于后续恢复。 -->
|
||||
<!-- <van-field label="附件" name="tf_attachment" class="direction-column-field">-->
|
||||
<!-- <template #input>-->
|
||||
<!-- <h5-file-upload-->
|
||||
<!-- :value.sync="formData.tf_attachment"-->
|
||||
<!-- :upload_number="5"-->
|
||||
<!-- upload_mode="file"-->
|
||||
<!-- upload_result_category="array"-->
|
||||
<!-- upload_result_type="url"-->
|
||||
<!-- complete_result>-->
|
||||
<!-- </h5-file-upload>-->
|
||||
<!-- </template>-->
|
||||
<!-- </van-field>-->
|
||||
<van-field v-model="formData.tf_opinion" class="proposal-audit-field"
|
||||
name="tf_opinion" type="textarea" rows="6" label=""
|
||||
placeholder="请输入答复内容"
|
||||
:rules="[{required:true,message:'请填写答复内容'}]"
|
||||
maxlength="100" show-word-limit></van-field>
|
||||
</section>
|
||||
<van-field v-if="supportCandidate && formData.underTakeIsMaster"
|
||||
v-model="formData.tf_nextNodeOperatorName" label="校领导"
|
||||
placeholder="请选择校领导"
|
||||
:rules="[{required:true,message:'请选择校领导'}]" required readonly
|
||||
is-link @click="openLayer('candidate-picker')"></van-field>
|
||||
</template>
|
||||
<template v-if="kind === 'caseCheck'">
|
||||
<van-field :value="formData.tf_username" label="审核人" readonly></van-field>
|
||||
<van-field :value="formData.tf_auditTime" label="审核时间" readonly></van-field>
|
||||
<van-field :value="formData.tf_caseCheckNeedSecondReply" label="二次答复" required
|
||||
:rules="[{validator:validateSecondReply,message:'请选择是否需要二次答复'}]">
|
||||
<template #input>
|
||||
<van-radio-group v-model="formData.tf_caseCheckNeedSecondReply"
|
||||
direction="horizontal" @change="onSecondReplyChange">
|
||||
<van-radio :name="0">无需二次答复</van-radio>
|
||||
<van-radio :name="1">需要二次答复</van-radio>
|
||||
</van-radio-group>
|
||||
</template>
|
||||
</van-field>
|
||||
<van-field v-if="formData.tf_caseCheckNeedSecondReply === 1"
|
||||
:value="selectedReplyUnitNames" label="答复单位"
|
||||
placeholder="请选择办理单位" readonly required is-link
|
||||
:rules="[{validator:validateSecondReplyUnits,message:'请选择需要二次答复的办理单位'}]"
|
||||
@click="openReplyUnitPicker"></van-field>
|
||||
<section class="proposal-view-card">
|
||||
<h2 class="proposal-view-card__title">审批意见<span
|
||||
class="proposal-audit-card__required">*</span></h2>
|
||||
<van-field v-model="formData.tf_opinion" class="proposal-audit-field"
|
||||
name="tf_opinion" type="textarea" rows="6" label=""
|
||||
placeholder="请输入审批意见" required maxlength="100" show-word-limit
|
||||
:rules="[{required:true,message:'请填写审批意见'}]"></van-field>
|
||||
</section>
|
||||
</template>
|
||||
</van-form>
|
||||
<div class="proposal-popup-form-actions" v-if="kind === 'delegation'">
|
||||
<van-button type="primary" block :loading="formLoading" class="proposal-soft-button"
|
||||
@click="prepareSubmit(1)">同意
|
||||
</van-button>
|
||||
<van-button type="danger" block :loading="formLoading"
|
||||
class="proposal-soft-button proposal-soft-button--danger"
|
||||
@click="prepareSubmit(2)">不同意
|
||||
</van-button>
|
||||
<van-button type="danger" block :loading="formLoading"
|
||||
class="proposal-soft-button proposal-soft-button--danger"
|
||||
@click="prepareSubmit(6)">退回
|
||||
</van-button>
|
||||
</div>
|
||||
<div class="proposal-popup-form-actions proposal-pre-audit-actions" v-else-if="kind === 'preAudit'"
|
||||
style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr))">
|
||||
<van-button type="primary" :loading="formLoading"
|
||||
class="proposal-soft-button proposal-pre-audit-button--primary"
|
||||
@click="prepareSubmit(1)">同意
|
||||
</van-button>
|
||||
<van-button type="danger" :loading="formLoading"
|
||||
class="proposal-soft-button proposal-pre-audit-button--danger"
|
||||
@click="prepareSubmit(2)">不同意
|
||||
</van-button>
|
||||
<van-button type="info" :loading="formLoading"
|
||||
class="proposal-soft-button proposal-pre-audit-button--info"
|
||||
@click="prepareSubmit(4)">退回(不审核)
|
||||
</van-button>
|
||||
<van-button type="info" :loading="formLoading"
|
||||
class="proposal-soft-button proposal-pre-audit-button--info"
|
||||
@click="prepareSubmit(6)">退回(审核)
|
||||
</van-button>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="proposal-popup-form-actions" v-else-if="kind === 'schoolLeaderApproval'">
|
||||
<van-button type="primary" block :loading="formLoading" class="proposal-soft-button"
|
||||
@click="prepareSubmit('agree')">同意答复
|
||||
</van-button>
|
||||
<van-button type="danger" block :loading="formLoading"
|
||||
class="proposal-soft-button proposal-soft-button--danger"
|
||||
@click="prepareSubmit('back')">退回答复
|
||||
</van-button>
|
||||
</div>
|
||||
<div class="proposal-popup-form-actions" v-else>
|
||||
<van-button type="primary" block :loading="formLoading" class="proposal-soft-button"
|
||||
@click="prepareSubmit(1)">提交
|
||||
</van-button>
|
||||
<van-button block :disabled="formLoading" class="proposal-rounded-button"
|
||||
@click="close">返回
|
||||
</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</proposal-info>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 字典通过异步请求加载,初始化阶段可能为 null;使用空数组保证弹层首次渲染不执行 null.map。 -->
|
||||
<van-popup v-model="feedbackPickerVisible" position="bottom" :close-on-click-overlay="false">
|
||||
<van-picker show-toolbar
|
||||
:columns="(dict.type.PROPOSAL_FEEDBACK || []).map((item) => ({text:item.label,value:item.code}))"
|
||||
@confirm="confirmFeedback" @cancel="closeLayer('feedback-picker')"></van-picker>
|
||||
</van-popup>
|
||||
<van-popup v-model="resultPickerVisible" position="bottom" :close-on-click-overlay="false">
|
||||
<van-picker show-toolbar :columns="(dict.type.UNDERTAKE_SUGGESTION || []).map((item) => item.code)"
|
||||
@confirm="confirmResult" @cancel="closeLayer('result-picker')"></van-picker>
|
||||
</van-popup>
|
||||
<van-popup v-model="implementPickerVisible" position="bottom" :close-on-click-overlay="false">
|
||||
<van-picker show-toolbar
|
||||
:columns="(dict.type.PROPOSAL_REPLY_IMPLEMENT || []).map((item) => ({text:item.label,value:item.code}))"
|
||||
@confirm="confirmImplement" @cancel="closeLayer('implement-picker')"></van-picker>
|
||||
</van-popup>
|
||||
<van-popup v-model="candidatePickerVisible" position="bottom" :close-on-click-overlay="false">
|
||||
<van-picker show-toolbar :columns="candidates.map((item) => ({text:item.userName,value:item.userId}))"
|
||||
@confirm="confirmCandidate" @cancel="closeLayer('candidate-picker')"></van-picker>
|
||||
</van-popup>
|
||||
<van-popup v-model="replyUnitPickerVisible" position="bottom" round :close-on-click-overlay="false"
|
||||
:style="{height:'70%'}">
|
||||
<div class="reply-unit-popup">
|
||||
<div class="reply-unit-toolbar">
|
||||
<button type="button" @click="closeLayer('reply-unit-picker')">取消</button>
|
||||
<div class="reply-unit-toolbar-title">选择答复单位</div>
|
||||
<button type="button" @click="confirmReplyUnits">确定</button>
|
||||
</div>
|
||||
<div class="reply-unit-list" v-if="replyUnitOptions.length">
|
||||
<van-checkbox-group v-model="pendingReplyUnitIds">
|
||||
<van-cell v-for="item in replyUnitOptions" :key="item.unitId" clickable
|
||||
:title="item.unitName" :label="item.isMaster ? '主办单位' : '协办单位'"
|
||||
@click="toggleReplyUnit(item)">
|
||||
<template #right-icon>
|
||||
<van-checkbox :name="item.unitId" @click.stop></van-checkbox>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-checkbox-group>
|
||||
</div>
|
||||
<div class="reply-unit-empty" v-else>暂无可选办理单位</div>
|
||||
</div>
|
||||
</van-popup>
|
||||
<van-dialog :value="confirmVisible" title="提示" message="您确定要提交吗?" show-cancel-button
|
||||
@confirm="submit" @cancel="closeLayer('submit-confirm')"></van-dialog>
|
||||
</van-popup>
|
||||
`,
|
||||
dicts: ["PROPOSAL_FEEDBACK", "UNDERTAKE_SUGGESTION", "PROPOSAL_REPLY_IMPLEMENT"],
|
||||
components: {"proposal-info": PROPOSAL_INFO},
|
||||
props: {kind: {type: String, required: true}, pageKey: {type: String, required: true}},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
bizId: "",
|
||||
action: "view",
|
||||
formData: {},
|
||||
formLoading: false,
|
||||
pendingSubmitType: 1,
|
||||
feedbackPickerVisible: false,
|
||||
resultPickerVisible: false,
|
||||
implementPickerVisible: false,
|
||||
candidatePickerVisible: false,
|
||||
replyUnitPickerVisible: false,
|
||||
confirmVisible: false,
|
||||
supportCandidate: false,
|
||||
candidates: [],
|
||||
replyUnitOptions: [],
|
||||
pendingReplyUnitIds: [],
|
||||
unsubscribeHistoryLayer: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isApproval() {
|
||||
return this.action === "approval"
|
||||
},
|
||||
title() {
|
||||
const titles = {
|
||||
delegation: "团长审核",
|
||||
preAudit: "校工会预审核",
|
||||
schoolLeaderApproval: "分管校领导审批",
|
||||
feedbackEvaluation: "反馈评价",
|
||||
suggestion: "承办单位意见",
|
||||
unitReply: "承办单位答复",
|
||||
caseCheck: "提案委员会审查"
|
||||
};
|
||||
return this.isApproval ? titles[this.kind] : "提案详情"
|
||||
},
|
||||
selectedReplyUnitNames() {
|
||||
const ids = this.formData.tf_secondReplyUnitIds || [];
|
||||
return this.replyUnitOptions.filter((item) => ids.indexOf(item.unitId) > -1).map((item) => item.unitName + "(" + (item.isMaster ? "主办" : "协办") + ")").join("、")
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
syncLayers(stack) {
|
||||
this.$set(this, "visible", stack.includes("detail"));
|
||||
this.$set(this, "feedbackPickerVisible", stack.includes("feedback-picker"));
|
||||
this.$set(this, "resultPickerVisible", stack.includes("result-picker"));
|
||||
this.$set(this, "implementPickerVisible", stack.includes("implement-picker"));
|
||||
this.$set(this, "candidatePickerVisible", stack.includes("candidate-picker"));
|
||||
this.$set(this, "replyUnitPickerVisible", stack.includes("reply-unit-picker"));
|
||||
this.$set(this, "confirmVisible", stack.includes("submit-confirm"))
|
||||
},
|
||||
openLayer(name) {
|
||||
window.h5HistoryLayerManager.open(name)
|
||||
}, closeLayer(name, callback) {
|
||||
window.h5HistoryLayerManager.close(name, callback)
|
||||
}, close() {
|
||||
this.closeLayer("detail")
|
||||
},
|
||||
/** row 提供详情主键和当前 WF 任务参数,action 为 view 或 approval。 */
|
||||
open(row, action) {
|
||||
const defaultTaskNames = {
|
||||
delegation: "团长审核",
|
||||
preAudit: "校工会预审核",
|
||||
feedbackEvaluation: "反馈评价",
|
||||
unitReply: "承办单位答复",
|
||||
caseCheck: "提案委员会审查"
|
||||
}
|
||||
const taskName = this.kind === "unitReply" ? (row.taskName || defaultTaskNames[this.kind]) : (row.curTaskName || row.taskName || defaultTaskNames[this.kind] || "")
|
||||
this.$set(this, "bizId", row.id);
|
||||
this.$set(this, "action", action);
|
||||
this.$set(this, "formData", {
|
||||
proposalId: row.id,
|
||||
processTaskId: row.taskId || "",
|
||||
taskKey: row.taskKey || "",
|
||||
taskName: taskName,
|
||||
instanceId: row.instanceId || "",
|
||||
underTakeName: row.underTakeName || "",
|
||||
underTakeIsMaster: !!row.underTakeIsMaster,
|
||||
tf_opinion: "",
|
||||
opinion: ""
|
||||
})
|
||||
if (action === "approval" && this.kind === "unitReply") {
|
||||
// 承办单位答复附件上传入口暂时停用,保留初始化代码便于后续恢复。
|
||||
// this.$set(this.formData, "tf_attachment", [])
|
||||
this.loadCandidates(row.taskId || "")
|
||||
}
|
||||
if (action === "approval" && this.kind === "caseCheck") {
|
||||
this.$set(this.formData, "tf_auditTime", moment().format("YYYY-MM-DD"));
|
||||
this.$set(this.formData, "tf_username", (this.$store.state.user && this.$store.state.user.username) || "");
|
||||
this.$set(this.formData, "tf_caseCheckNeedSecondReply", 0);
|
||||
this.$set(this.formData, "tf_secondReplyUnitIds", []);
|
||||
this.loadReplyUnits(row.id)
|
||||
}
|
||||
this.openLayer("detail")
|
||||
},
|
||||
loadCandidates(taskId) {
|
||||
this.$axios.post("/flow/common/candidate", {taskId: taskId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$set(this, "candidates", res.data.candidates || []);
|
||||
this.$set(this, "supportCandidate", res.data.support)
|
||||
}
|
||||
})
|
||||
},
|
||||
confirmFeedback(value) {
|
||||
this.$set(this.formData, "tf_feedback_name", value.text);
|
||||
this.$set(this.formData, "tf_feedback", value.value);
|
||||
this.closeLayer("feedback-picker")
|
||||
},
|
||||
confirmResult(value) {
|
||||
this.$set(this.formData, "result", value);
|
||||
this.closeLayer("result-picker")
|
||||
},
|
||||
confirmImplement(value) {
|
||||
this.$set(this.formData, "tf_implementStateName", value.text);
|
||||
this.$set(this.formData, "tf_implementState", value.value);
|
||||
this.closeLayer("implement-picker")
|
||||
},
|
||||
confirmCandidate(value) {
|
||||
this.$set(this.formData, "tf_nextNodeOperatorName", value.text);
|
||||
this.$set(this.formData, "tf_nextNodeOperator", value.value);
|
||||
this.closeLayer("candidate-picker")
|
||||
},
|
||||
validateSecondReply(value) {
|
||||
return value === 0 || value === 1
|
||||
},
|
||||
validateSecondReplyUnits() {
|
||||
return this.formData.tf_caseCheckNeedSecondReply !== 1 || (this.formData.tf_secondReplyUnitIds || []).length > 0
|
||||
},
|
||||
onSecondReplyChange(value) {
|
||||
if (value !== 1) this.$set(this.formData, "tf_secondReplyUnitIds", [])
|
||||
},
|
||||
loadReplyUnits(proposalId) {
|
||||
this.$axios.post("/platform/proposal/case/check/listReplyUnits", {proposalId: proposalId}).then((res) => {
|
||||
if (res && res.code === 0) this.$set(this, "replyUnitOptions", res.data || [])
|
||||
})
|
||||
},
|
||||
openReplyUnitPicker() {
|
||||
this.$set(this, "pendingReplyUnitIds", [...(this.formData.tf_secondReplyUnitIds || [])]);
|
||||
this.openLayer("reply-unit-picker")
|
||||
},
|
||||
toggleReplyUnit(item) {
|
||||
const ids = [...this.pendingReplyUnitIds];
|
||||
const index = ids.indexOf(item.unitId);
|
||||
if (index > -1) ids.splice(index, 1); else ids.push(item.unitId);
|
||||
this.$set(this, "pendingReplyUnitIds", ids)
|
||||
},
|
||||
confirmReplyUnits() {
|
||||
this.$set(this.formData, "tf_secondReplyUnitIds", [...this.pendingReplyUnitIds]);
|
||||
this.closeLayer("reply-unit-picker")
|
||||
},
|
||||
buildCaseCheckData() {
|
||||
const data = {...this.formData};
|
||||
const units = data.tf_caseCheckNeedSecondReply === 1 ? this.replyUnitOptions.filter((item) => data.tf_secondReplyUnitIds.indexOf(item.unitId) > -1) : [];
|
||||
const masters = units.filter((item) => item.isMaster);
|
||||
const slaves = units.filter((item) => !item.isMaster);
|
||||
data.tf_masterUnitIds = masters.map((item) => item.unitId);
|
||||
data.tf_masterUnitId = data.tf_masterUnitIds[0] || "";
|
||||
data.tf_masterUnitNames = masters.map((item) => item.unitName);
|
||||
data.tf_masterUnitName = data.tf_masterUnitNames[0] || "";
|
||||
data.tf_masterUnitNameStr = data.tf_masterUnitNames.join(",");
|
||||
data.tf_slaveUnitIds = slaves.map((item) => item.unitId);
|
||||
data.tf_slaveUnitNames = slaves.map((item) => item.unitName);
|
||||
data.tf_slaveUnitNameStr = data.tf_slaveUnitNames.join(",");
|
||||
return data
|
||||
},
|
||||
prepareSubmit(value) {
|
||||
// 各办理页面提交前统一校验意见字段;空白字符按未填写处理,提示后不再打开确认弹框。
|
||||
const opinionConfig = this.kind === "suggestion"
|
||||
? {field: "opinion", message: "请输入反馈意见"}
|
||||
: this.kind === "unitReply"
|
||||
? {field: "tf_opinion", message: "请填写答复内容"}
|
||||
: {field: "tf_opinion", message: "请填写审批意见"}
|
||||
if (!(this.formData[opinionConfig.field] || "").trim()) {
|
||||
this.$toast(opinionConfig.message)
|
||||
return
|
||||
}
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$set(this, "pendingSubmitType", value);
|
||||
this.openLayer("submit-confirm")
|
||||
}).catch(() => {
|
||||
})
|
||||
},
|
||||
/** 根据页面类型保留原接口和参数分支,成功后清理全部弹层历史并通知列表刷新。 */
|
||||
submit() {
|
||||
this.$set(this, "formLoading", true)
|
||||
let request
|
||||
if (this.kind === "suggestion") request = this.$axios.post("/platform/proposal/suggestion/suggest", this.formData)
|
||||
else if (this.kind === "schoolLeaderApproval") {
|
||||
const data = {...this.formData, tf_approval: this.pendingSubmitType};
|
||||
delete data.taskKey;
|
||||
delete data.taskName;
|
||||
request = this.$axios.post("/platform/proposal/schoolLeaderApproval/executeTask", {data: JSON.stringify(data)})
|
||||
} else {
|
||||
const data = this.kind === "caseCheck" ? {
|
||||
...this.buildCaseCheckData(),
|
||||
submitType: this.pendingSubmitType
|
||||
} : {...this.formData, submitType: this.pendingSubmitType}
|
||||
if (this.kind === "preAudit") {
|
||||
data.taskName = "startTask";
|
||||
if (this.pendingSubmitType === 4) {
|
||||
data.tf_sourceTaskKey = this.formData.taskKey;
|
||||
data.tf_audit = false
|
||||
}
|
||||
}
|
||||
if (this.kind === "unitReply") {
|
||||
delete data.underTakeIsMaster;
|
||||
delete data.underTakeName
|
||||
}
|
||||
if (this.kind === "feedbackEvaluation" && data.tf_feedback === "DISSATISFIED") request = this.$axios.post("/platform/proposal/feedbackEvaluation/caseInfo", {instId: data.instanceId}).then((res) => {
|
||||
if (res.code !== 0) return Promise.reject(new Error(res.msg || "查询立案信息失败"));
|
||||
data.tf_masterUnitId = res.data.tf_masterUnitId;
|
||||
return this.$axios.post("/flow/common/executeTask", {data: JSON.stringify(data)})
|
||||
})
|
||||
else request = this.$axios.post("/flow/common/executeTask", {data: JSON.stringify(data)})
|
||||
}
|
||||
request.then((res) => {
|
||||
if (res && res.code === 0) {
|
||||
this.$toast.success(res.msg);
|
||||
window.h5HistoryLayerManager.closeAll(() => this.$emit("success"))
|
||||
}
|
||||
}).catch((error) => {
|
||||
if (error && error.message && error.message !== "cancel") this.$toast.fail(error.message)
|
||||
}).finally(() => {
|
||||
this.$set(this, "formLoading", false)
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
window.h5HistoryLayerManager.ensureRegistered(this.pageKey);
|
||||
this.$set(this, "unsubscribeHistoryLayer", window.h5HistoryLayerManager.subscribe((stack) => this.syncLayers(stack)))
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.unsubscribeHistoryLayer) this.unsubscribeHistoryLayer();
|
||||
if (window.h5HistoryLayerManager.pageKey === this.pageKey) window.h5HistoryLayerManager.unregister(this.pageKey)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/* 提案办理页统一使用 #1989fa 品牌蓝,并覆盖动态弹框及 Vant 组件继承的全局主题色。 */
|
||||
:root {
|
||||
--color-primary: #1989fa;
|
||||
}
|
||||
|
||||
/* 公共提案详情组件拥有独立主题变量,需要在办理页内同步覆盖。 */
|
||||
.proposal-view {
|
||||
--proposal-view-primary: #1989fa;
|
||||
}
|
||||
|
||||
.proposal-flow-node__icon {
|
||||
box-shadow: 0 2px 7px rgba(25, 137, 250, 0.22);
|
||||
}
|
||||
|
||||
.proposal-flow-node.is-active .proposal-flow-node__icon {
|
||||
box-shadow: 0 0 0 5px #e7f2ff, 0 3px 9px rgba(25, 137, 250, 0.28);
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
.condolence-full-popup {
|
||||
--color-primary: #1989fa;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: #f3f7fc;
|
||||
}
|
||||
|
||||
.condolence-full-popup__page {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding-top: 46px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.condolence-full-popup__page > .van-nav-bar {
|
||||
z-index: 20;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.condolence-full-popup__page > .van-nav-bar .van-icon,
|
||||
.condolence-full-popup__page > .van-nav-bar .van-nav-bar__text {
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
.condolence-full-popup__scroll {
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.condolence-info-main {
|
||||
padding: 12px 15px calc(18px + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.condolence-info-card {
|
||||
margin-bottom: 11px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 11px rgba(51, 87, 126, .08);
|
||||
}
|
||||
|
||||
.condolence-info-card__title {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 12px 14px 8px 21px;
|
||||
color: #354255;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.condolence-info-card__title::before {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
bottom: 11px;
|
||||
left: 12px;
|
||||
width: 2px;
|
||||
border-radius: 2px;
|
||||
background: #1989fa;
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* 审核意见复用详情 Card 标题,并与提案 delegation 审核输入区保持一致。 */
|
||||
.condolence-audit-card__required {
|
||||
margin-left: 4px;
|
||||
color: #ee0a24;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.condolence-info-card .van-field.condolence-audit-field {
|
||||
width: calc(100% - 28px);
|
||||
margin: 0 14px 14px;
|
||||
padding: 12px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #c9d5e5;
|
||||
border-radius: 10px;
|
||||
background: #f7f9fd;
|
||||
}
|
||||
|
||||
.condolence-info-card .van-field.condolence-audit-field .van-field__control {
|
||||
min-height: 150px;
|
||||
color: #253247;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.condolence-info-card .van-field.condolence-audit-field .van-field__control::placeholder {
|
||||
color: #9aa7b8;
|
||||
}
|
||||
|
||||
.condolence-info-card .van-field.condolence-audit-field .van-field__word-limit {
|
||||
color: #718096;
|
||||
}
|
||||
|
||||
.condolence-info-card .van-field.condolence-audit-field::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.condolence-popup-actions {
|
||||
display: flex;
|
||||
padding: 10px 12px calc(12px + env(safe-area-inset-bottom));
|
||||
justify-content: space-between;
|
||||
column-gap: 10px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.condolence-popup-actions .van-button {
|
||||
border-radius: 14px;
|
||||
}
|
||||
|
||||
.condolence-popup-actions .condolence-action-primary {
|
||||
border-color: #1989fa;
|
||||
background: #1989fa;
|
||||
}
|
||||
|
||||
.condolence-popup-actions .condolence-action-danger {
|
||||
border-color: #ff4d4f;
|
||||
background: #ff4d4f;
|
||||
}
|
||||
|
||||
.condolence-info-card .van-cell-group {
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.condolence-info-card .van-cell {
|
||||
min-height: 44px;
|
||||
padding: 10px 14px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.condolence-info-card .van-cell:not(:last-child)::after {
|
||||
right: 14px;
|
||||
left: 14px;
|
||||
border-color: #eef2f7;
|
||||
}
|
||||
|
||||
.condolence-info-card .van-cell__title {
|
||||
width: 102px;
|
||||
color: #596779;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
flex: 0 0 102px;
|
||||
}
|
||||
|
||||
.condolence-info-card .van-cell__value {
|
||||
min-width: 0;
|
||||
color: #4f5d70;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
text-align: left;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.condolence-info-long-cell {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.condolence-info-long-cell .van-cell__title {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.condolence-info-long-cell .van-cell__value {
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.condolence-signature-image {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
#app {
|
||||
--color-primary: #1989fa;
|
||||
}
|
||||
|
||||
.difficult-help-approval-page {
|
||||
min-height: 100vh;
|
||||
padding-bottom: calc(24px + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
background: #f3f7fd;
|
||||
}
|
||||
|
||||
.difficult-help-approval-page .van-nav-bar,
|
||||
.difficult-help-approval-page .van-sticky--fixed {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.difficult-help-approval-page .van-nav-bar__title {
|
||||
color: #172033;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.difficult-help-approval-page .van-nav-bar .van-icon,
|
||||
.difficult-help-approval-page .van-nav-bar__text {
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
.difficult-help-approval-sticky {
|
||||
padding: 22px 12px 1px;
|
||||
box-sizing: border-box;
|
||||
background: #f3f7fd;
|
||||
}
|
||||
|
||||
.difficult-help-approval-search {
|
||||
margin: 0 0 8px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
box-shadow: 0 5px 16px rgba(43, 73, 112, .1);
|
||||
}
|
||||
|
||||
.difficult-help-approval-search .van-search__content {
|
||||
height: 42px;
|
||||
padding-left: 12px;
|
||||
align-items: center;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.difficult-help-approval-search .van-field__control {
|
||||
color: #263548;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.difficult-help-approval-search .van-field__control::placeholder {
|
||||
color: #a7b0bf;
|
||||
}
|
||||
|
||||
.difficult-help-approval-filter {
|
||||
margin-bottom: 10px;
|
||||
overflow: hidden;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 5px 16px rgba(43, 73, 112, .08);
|
||||
transition: border-radius .18s ease;
|
||||
}
|
||||
|
||||
.difficult-help-approval-filter.is-open {
|
||||
border-radius: 10px 10px 0 0;
|
||||
}
|
||||
|
||||
.difficult-help-approval-filter .van-dropdown-menu__bar,
|
||||
.difficult-help-approval-filter .van-dropdown-menu__item,
|
||||
.difficult-help-approval-filter .van-dropdown-menu__title {
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.difficult-help-approval-filter .van-dropdown-menu__bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.difficult-help-approval-filter .van-dropdown-menu__item {
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.difficult-help-approval-filter .van-dropdown-menu__title {
|
||||
display: inline-flex;
|
||||
max-width: calc(100% - 12px);
|
||||
align-items: center;
|
||||
color: #66758a;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.difficult-help-approval-filter .van-dropdown-menu__title--active,
|
||||
.difficult-help-approval-filter .van-dropdown-item__option--active,
|
||||
.difficult-help-approval-filter .van-dropdown-item__option--active .van-cell__title,
|
||||
.difficult-help-approval-filter .van-dropdown-item__option--active .van-dropdown-item__icon {
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
.difficult-help-approval-filter .van-dropdown-item__content {
|
||||
width: calc(100% - 24px);
|
||||
max-height: 50%;
|
||||
margin: 0 12px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
box-sizing: border-box;
|
||||
border-radius: 0 0 12px 12px;
|
||||
box-shadow: 0 10px 24px rgba(31, 65, 108, .14);
|
||||
}
|
||||
|
||||
.difficult-help-approval-filter .van-dropdown-item__option {
|
||||
display: flex;
|
||||
min-height: 48px;
|
||||
padding: 0 16px;
|
||||
align-items: center;
|
||||
color: #46566c;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.difficult-help-approval-filter .van-dropdown-item__option .van-cell__title {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
min-height: 20px;
|
||||
align-items: center;
|
||||
flex: 1 1 auto;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.difficult-help-approval-filter .van-dropdown-item__option .van-cell__value {
|
||||
display: flex;
|
||||
width: 20px;
|
||||
min-width: 0;
|
||||
overflow: visible;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
flex: 0 0 20px;
|
||||
}
|
||||
|
||||
.difficult-help-approval-content {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.difficult-help-list-skeleton {
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.difficult-help-list-skeleton__card {
|
||||
margin-bottom: 12px;
|
||||
padding: 14px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
box-shadow: 0 5px 16px rgba(43, 73, 112, .08);
|
||||
}
|
||||
|
||||
.difficult-help-list-skeleton__card .van-skeleton {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.difficult-help-list-skeleton__card .van-skeleton__title {
|
||||
width: 34%;
|
||||
height: 17px;
|
||||
margin-bottom: 13px;
|
||||
}
|
||||
|
||||
.difficult-help-list-skeleton__card .van-skeleton__row {
|
||||
height: 12px;
|
||||
margin-top: 11px;
|
||||
}
|
||||
|
||||
.difficult-help-list-skeleton__card .van-skeleton__row:nth-child(2n) {
|
||||
width: 88%;
|
||||
}
|
||||
|
||||
.difficult-help-list-skeleton__card .van-skeleton__row:last-child {
|
||||
width: 48%;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.difficult-help-approval-page .table-list-container {
|
||||
margin-top: 0;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.difficult-help-approval-page .table-list-container .table-list-item {
|
||||
margin-bottom: 12px;
|
||||
padding: 14px;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 5px 16px rgba(43, 73, 112, .08);
|
||||
}
|
||||
|
||||
.difficult-help-approval-card-header {
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.difficult-help-approval-card-heading {
|
||||
min-width: 0;
|
||||
padding-right: 10px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.difficult-help-approval-card-title {
|
||||
overflow: hidden;
|
||||
color: #253247;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.difficult-help-approval-card-code {
|
||||
margin-top: 1px;
|
||||
color: #9ba6b6;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.difficult-help-approval-card-status {
|
||||
display: inline-flex;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.difficult-help-approval-card-status .van-tag {
|
||||
min-height: 24px;
|
||||
padding: 3px 9px;
|
||||
border: 0;
|
||||
border-radius: 12px;
|
||||
box-sizing: border-box;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.difficult-help-approval-page .table-list-container .table-list-item .item-actions {
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
border-top-color: #edf1f6;
|
||||
}
|
||||
|
||||
.difficult-help-approval-page .table-list-container .table-list-item .action-btn {
|
||||
min-height: 28px;
|
||||
padding: 4px 11px;
|
||||
border-radius: 14px;
|
||||
color: #1989fa;
|
||||
background: #eaf4ff;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.difficult-help-approval-page .table-list-container .table-list-item .action-btn.delete {
|
||||
color: #f04444;
|
||||
background: #fff0f0;
|
||||
}
|
||||
|
||||
.difficult-help-approval-page .table-list-container .table-list-item .action-btn .van-icon {
|
||||
margin-right: 5px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.difficult-help-approval-page .empty-state {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.difficult-help-approval-empty {
|
||||
display: flex;
|
||||
min-height: 280px;
|
||||
padding: 46px 18px 36px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.difficult-help-approval-empty img {
|
||||
display: block;
|
||||
width: 86%;
|
||||
max-width: 290px;
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.difficult-help-approval-empty__title {
|
||||
margin-top: 14px;
|
||||
color: #50627a;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.difficult-help-approval-empty__hint {
|
||||
margin-top: 5px;
|
||||
color: #9aa7b8;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
@@ -0,0 +1,353 @@
|
||||
.difficult-help-full-popup {
|
||||
--color-primary: #1989fa;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: #f3f7fc;
|
||||
}
|
||||
|
||||
.difficult-help-full-popup__page {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding-top: 46px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.difficult-help-full-popup__page > .van-nav-bar {
|
||||
z-index: 20;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.difficult-help-full-popup__page > .van-nav-bar .van-icon,
|
||||
.difficult-help-full-popup__page > .van-nav-bar .van-nav-bar__text {
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
.difficult-help-full-popup__scroll {
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.difficult-help-info-main {
|
||||
padding: 12px 15px calc(18px + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.difficult-help-info-card {
|
||||
margin-bottom: 11px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 11px rgba(51, 87, 126, .08);
|
||||
}
|
||||
|
||||
.difficult-help-info-card__title {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 12px 14px 8px 21px;
|
||||
color: #354255;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.difficult-help-info-card__title::before {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
bottom: 11px;
|
||||
left: 12px;
|
||||
width: 2px;
|
||||
border-radius: 2px;
|
||||
background: #1989fa;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.difficult-help-audit-card__required {
|
||||
margin-left: 4px;
|
||||
color: #ee0a24;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.difficult-help-audit-form {
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.difficult-help-info-card .van-field.difficult-help-audit-select,
|
||||
.difficult-help-info-card .van-field.difficult-help-audit-money {
|
||||
min-height: 48px;
|
||||
padding: 11px 14px;
|
||||
}
|
||||
|
||||
.difficult-help-info-card .van-field.difficult-help-audit-select .van-field__label,
|
||||
.difficult-help-info-card .van-field.difficult-help-audit-money .van-field__label {
|
||||
width: 88px;
|
||||
color: #596779;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.difficult-help-info-card .van-field.difficult-help-audit-select .van-field__control,
|
||||
.difficult-help-info-card .van-field.difficult-help-audit-money .van-field__control {
|
||||
color: #253247;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.difficult-help-info-card .van-field.difficult-help-audit-textarea {
|
||||
width: calc(100% - 28px);
|
||||
margin: 0 14px 14px;
|
||||
padding: 12px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #c9d5e5;
|
||||
border-radius: 10px;
|
||||
background: #f7f9fd;
|
||||
}
|
||||
|
||||
.difficult-help-info-card .van-field.difficult-help-audit-textarea .van-field__control {
|
||||
min-height: 132px;
|
||||
color: #253247;
|
||||
font-size: 13px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.difficult-help-info-card .van-field.difficult-help-audit-textarea .van-field__control::placeholder,
|
||||
.difficult-help-info-card .van-field.difficult-help-audit-select .van-field__control::placeholder,
|
||||
.difficult-help-info-card .van-field.difficult-help-audit-money .van-field__control::placeholder {
|
||||
color: #9aa7b8;
|
||||
}
|
||||
|
||||
.difficult-help-info-card .van-field.difficult-help-audit-textarea .van-field__word-limit {
|
||||
color: #718096;
|
||||
}
|
||||
|
||||
.difficult-help-info-card .van-field.difficult-help-audit-textarea::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.difficult-help-popup-actions {
|
||||
display: flex;
|
||||
padding: 10px 0 calc(12px + env(safe-area-inset-bottom));
|
||||
justify-content: space-between;
|
||||
column-gap: 10px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.difficult-help-popup-actions .van-button {
|
||||
min-width: 0;
|
||||
border-radius: 14px;
|
||||
}
|
||||
|
||||
.difficult-help-popup-actions .difficult-help-action-primary {
|
||||
border-color: #1989fa;
|
||||
background: #1989fa;
|
||||
}
|
||||
|
||||
.difficult-help-popup-actions .difficult-help-action-danger {
|
||||
border-color: #ff4d4f;
|
||||
background: #ff4d4f;
|
||||
}
|
||||
|
||||
.difficult-help-info-card .van-cell-group {
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.difficult-help-info-card .van-cell {
|
||||
min-height: 44px;
|
||||
padding: 10px 14px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.difficult-help-info-card .van-cell:not(:last-child)::after {
|
||||
right: 14px;
|
||||
left: 14px;
|
||||
border-color: #eef2f7;
|
||||
}
|
||||
|
||||
.difficult-help-info-card .van-cell__title {
|
||||
width: 112px;
|
||||
color: #596779;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
flex: 0 0 112px;
|
||||
}
|
||||
|
||||
.difficult-help-info-card .van-cell__value {
|
||||
min-width: 0;
|
||||
color: #4f5d70;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
text-align: left;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.difficult-help-info-long-cell {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.difficult-help-info-long-cell .van-cell__title {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.difficult-help-info-long-cell .van-cell__value {
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.difficult-help-info-pre-line {
|
||||
white-space: pre-line;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.difficult-help-family-list {
|
||||
padding: 0 14px 14px;
|
||||
}
|
||||
|
||||
.difficult-help-family-item {
|
||||
overflow: hidden;
|
||||
border: 1px solid #e5edf7;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 8px rgba(51, 87, 126, .06);
|
||||
}
|
||||
|
||||
.difficult-help-family-item + .difficult-help-family-item {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.difficult-help-family-header {
|
||||
display: flex;
|
||||
min-height: 44px;
|
||||
padding: 9px 11px;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
background: linear-gradient(90deg, #f0f6ff 0%, #f8fbff 100%);
|
||||
}
|
||||
|
||||
.difficult-help-family-index {
|
||||
display: inline-flex;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 8px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 0 0 24px;
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
background: #1989fa;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.difficult-help-family-name {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
color: #2f3d51;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.difficult-help-family-relation {
|
||||
max-width: 92px;
|
||||
margin-left: 8px;
|
||||
padding: 2px 8px;
|
||||
overflow: hidden;
|
||||
border-radius: 10px;
|
||||
color: #1989fa;
|
||||
background: #e7f2ff;
|
||||
font-size: 11px;
|
||||
line-height: 18px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.difficult-help-family-summary {
|
||||
display: grid;
|
||||
margin: 0 11px;
|
||||
padding: 11px 0;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
border-bottom: 1px solid #eef2f7;
|
||||
}
|
||||
|
||||
.difficult-help-family-summary__item {
|
||||
min-width: 0;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.difficult-help-family-summary__item:first-child {
|
||||
padding-left: 0;
|
||||
border-right: 1px solid #eef2f7;
|
||||
}
|
||||
|
||||
.difficult-help-family-summary__item span,
|
||||
.difficult-help-family-summary__item strong,
|
||||
.difficult-help-family-detail__row span,
|
||||
.difficult-help-family-detail__row strong {
|
||||
display: block;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.difficult-help-family-summary__item span,
|
||||
.difficult-help-family-detail__row span {
|
||||
color: #909bac;
|
||||
font-size: 11px;
|
||||
line-height: 17px;
|
||||
}
|
||||
|
||||
.difficult-help-family-summary__item strong {
|
||||
margin-top: 3px;
|
||||
color: #435167;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.difficult-help-family-detail {
|
||||
padding: 4px 11px 7px;
|
||||
}
|
||||
|
||||
.difficult-help-family-detail__row {
|
||||
display: grid;
|
||||
padding: 7px 0;
|
||||
grid-template-columns: 68px minmax(0, 1fr);
|
||||
column-gap: 8px;
|
||||
}
|
||||
|
||||
.difficult-help-family-detail__row strong {
|
||||
color: #536176;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.difficult-help-info-card .van-empty {
|
||||
padding: 12px 0 20px;
|
||||
}
|
||||
|
||||
.difficult-help-info-promise {
|
||||
color: #4f5d70;
|
||||
font-size: 12px;
|
||||
line-height: 21px;
|
||||
}
|
||||
|
||||
.difficult-help-info-commitment {
|
||||
display: flex;
|
||||
margin-top: 8px;
|
||||
align-items: flex-end;
|
||||
color: #8995a6;
|
||||
font-size: 11px;
|
||||
line-height: 18px;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.difficult-help-signature-image {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,524 @@
|
||||
:root {
|
||||
--member-primary: #1989fa;
|
||||
--member-page-bg: #f3f7fd;
|
||||
--member-text: #263548;
|
||||
--member-muted: #8c98aa;
|
||||
--member-border: #e8eef6;
|
||||
--color-primary: #1989fa;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--member-page-bg);
|
||||
}
|
||||
|
||||
.member-h5-page {
|
||||
min-height: 100vh;
|
||||
padding-bottom: calc(24px + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
color: var(--member-text);
|
||||
background: var(--member-page-bg);
|
||||
}
|
||||
|
||||
.member-h5-page.has-fixed-actions {
|
||||
padding-bottom: calc(78px + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.member-h5-page .van-nav-bar {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.member-h5-page .van-nav-bar__title {
|
||||
color: #1f2937;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.member-h5-page .van-nav-bar .van-icon,
|
||||
.member-h5-page .van-nav-bar__text {
|
||||
color: var(--member-primary);
|
||||
}
|
||||
|
||||
.member-hero {
|
||||
position: relative;
|
||||
height: 116px;
|
||||
padding: 18px 18px 0;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
background-color: #edf5ff;
|
||||
background-image: url("/assets/mobile/img/home/v4/hero-campus.png");
|
||||
background-position: 66% 46%;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.member-hero::after {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(242, 247, 255, .76);
|
||||
content: "";
|
||||
}
|
||||
|
||||
.member-hero__content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.member-hero__title {
|
||||
color: var(--member-primary);
|
||||
font-size: 23px;
|
||||
font-weight: 700;
|
||||
line-height: 30px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.member-hero__subtitle {
|
||||
margin-top: 2px;
|
||||
color: #718096;
|
||||
font-size: 11px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.member-page-main {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
margin-top: -34px;
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.member-toolbar {
|
||||
padding: 10px;
|
||||
border: 1px solid var(--member-border);
|
||||
border-radius: 12px;
|
||||
background: rgba(255, 255, 255, .98);
|
||||
box-shadow: 0 5px 16px rgba(43, 73, 112, .09);
|
||||
}
|
||||
|
||||
.member-toolbar .van-search {
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.member-toolbar .van-search__content {
|
||||
height: 42px;
|
||||
align-items: center;
|
||||
border-radius: 10px;
|
||||
background: #f5f8fc;
|
||||
}
|
||||
|
||||
.member-toolbar .van-field__control {
|
||||
color: var(--member-text);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.member-toolbar .van-search__action {
|
||||
padding: 0 4px 0 12px;
|
||||
color: var(--member-primary);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.member-toolbar .van-dropdown-menu {
|
||||
margin-top: 8px;
|
||||
/* Vant 下拉选项弹层位于菜单内部,吸顶状态下必须允许弹层超出筛选卡片显示。 */
|
||||
overflow: visible;
|
||||
border-top: 1px solid #edf1f6;
|
||||
}
|
||||
|
||||
.member-toolbar .van-dropdown-menu__bar {
|
||||
height: 42px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.member-toolbar .van-dropdown-menu__title {
|
||||
color: #66758a;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.member-list-section {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.member-list-section .table-list-container {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.member-list-section .table-list-item {
|
||||
border-color: var(--member-border) !important;
|
||||
border-radius: 12px !important;
|
||||
box-shadow: 0 7px 20px rgba(55, 85, 126, .08) !important;
|
||||
}
|
||||
|
||||
.member-list-section .item-title {
|
||||
color: #263548 !important;
|
||||
font-size: 15px !important;
|
||||
}
|
||||
|
||||
.member-list-section .action-btn {
|
||||
color: var(--member-primary) !important;
|
||||
background: #eaf4ff !important;
|
||||
}
|
||||
|
||||
.member-list-section .action-btn.delete {
|
||||
color: #e95757 !important;
|
||||
background: #fff0f0 !important;
|
||||
}
|
||||
|
||||
.member-empty {
|
||||
display: flex;
|
||||
min-height: 280px;
|
||||
padding: 20px 18px 30px;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.member-empty img {
|
||||
display: block;
|
||||
width: 84%;
|
||||
max-width: 290px;
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.member-empty__title {
|
||||
margin-top: -8px;
|
||||
color: #50627a;
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.member-empty__hint {
|
||||
margin-top: 6px;
|
||||
color: #9aa7b8;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.member-list-skeleton {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.member-list-skeleton__card {
|
||||
min-height: 154px;
|
||||
margin-bottom: 10px;
|
||||
padding: 14px;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 7px 20px rgba(55, 85, 126, .08);
|
||||
}
|
||||
|
||||
.member-list-skeleton__card .van-skeleton {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.member-list-skeleton__card .van-skeleton__title {
|
||||
height: 17px;
|
||||
}
|
||||
|
||||
.member-list-skeleton__card .van-skeleton__row {
|
||||
height: 12px;
|
||||
margin-top: 13px;
|
||||
}
|
||||
|
||||
/* 页面首次进入时统一遮住尚未完成初始化的横幅、筛选栏和列表,避免返回页面时出现空筛选项。 */
|
||||
.member-page-skeleton {
|
||||
min-height: calc(100vh - 46px);
|
||||
padding: 12px;
|
||||
box-sizing: border-box;
|
||||
background: var(--member-page-bg);
|
||||
}
|
||||
|
||||
.member-page-skeleton__hero {
|
||||
height: 82px;
|
||||
margin-bottom: 10px;
|
||||
padding: 18px;
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(135deg, #e4f1ff 0%, #f2f7ff 100%);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.member-page-skeleton__toolbar {
|
||||
min-height: 96px;
|
||||
margin-bottom: 10px;
|
||||
padding: 14px;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 5px 16px rgba(43, 73, 112, .07);
|
||||
}
|
||||
|
||||
.member-page-skeleton__toolbar .van-skeleton,
|
||||
.member-page-skeleton__hero .van-skeleton {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.member-page-skeleton__cards .member-list-skeleton {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.member-count-chip {
|
||||
display: inline-flex;
|
||||
height: 28px;
|
||||
margin: 10px 0 0;
|
||||
padding: 0 11px;
|
||||
align-items: center;
|
||||
border-radius: 14px;
|
||||
color: #397de0;
|
||||
background: #edf5ff;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.member-form-intro {
|
||||
display: flex;
|
||||
min-height: 58px;
|
||||
margin-bottom: 10px;
|
||||
padding: 11px 12px;
|
||||
align-items: flex-start;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #dfeafb;
|
||||
border-radius: 10px;
|
||||
background: rgba(246, 250, 255, .98);
|
||||
box-shadow: 0 3px 10px rgba(53, 98, 154, .08);
|
||||
}
|
||||
|
||||
.member-form-intro .van-icon {
|
||||
margin: 1px 9px 0 0;
|
||||
color: var(--member-primary);
|
||||
font-size: 19px;
|
||||
}
|
||||
|
||||
.member-form-intro__title {
|
||||
color: var(--member-primary);
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.member-form-intro__text {
|
||||
margin-top: 2px;
|
||||
color: #8a97a8;
|
||||
font-size: 10px;
|
||||
line-height: 17px;
|
||||
}
|
||||
|
||||
.member-application-form.form-container {
|
||||
padding-bottom: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.member-application-form .form-section {
|
||||
margin-bottom: 11px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 11px rgba(51, 87, 126, .08);
|
||||
}
|
||||
|
||||
.member-form-section__title {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 12px 14px 8px 21px;
|
||||
color: #354255;
|
||||
background: #fff;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.member-form-section__title::before {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
bottom: 11px;
|
||||
left: 12px;
|
||||
width: 2px;
|
||||
border-radius: 2px;
|
||||
background: var(--member-primary);
|
||||
content: "";
|
||||
}
|
||||
|
||||
.member-application-form .form-section > .van-cell-group {
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.member-application-form .van-cell {
|
||||
min-height: 44px;
|
||||
padding: 10px 14px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.member-application-form .van-field__label {
|
||||
width: 84px;
|
||||
color: #596779;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.member-application-form .van-field__control,
|
||||
.member-application-form .van-field__value {
|
||||
color: #4f5d70;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.member-form-actions,
|
||||
.member-approval-actions {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
gap: 9px;
|
||||
padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
|
||||
border-top: 1px solid #edf1f6;
|
||||
background: rgba(255, 255, 255, .98);
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 -4px 14px rgba(50, 78, 112, .06);
|
||||
}
|
||||
|
||||
.member-form-actions .van-button,
|
||||
.member-approval-actions .van-button {
|
||||
height: 42px;
|
||||
margin: 0;
|
||||
border-radius: 14px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.member-form-actions .member-save-button {
|
||||
color: var(--member-primary);
|
||||
border-color: var(--member-primary);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.member-form-actions .member-submit-button,
|
||||
.member-approval-actions .member-agree-button {
|
||||
color: #fff;
|
||||
border-color: var(--member-primary);
|
||||
background: var(--member-primary);
|
||||
}
|
||||
|
||||
.member-approval-actions .member-return-button {
|
||||
color: #fff;
|
||||
border-color: #e6a23c;
|
||||
background: #e6a23c;
|
||||
}
|
||||
|
||||
.member-form-skeleton {
|
||||
padding: 0 12px 24px;
|
||||
}
|
||||
|
||||
.member-form-skeleton__card {
|
||||
min-height: 200px;
|
||||
margin-bottom: 10px;
|
||||
padding: 16px 14px;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.member-form-skeleton__card .van-skeleton {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.member-full-popup {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: var(--member-page-bg);
|
||||
}
|
||||
|
||||
.member-full-popup__page {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding-top: 46px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.member-full-popup__page > .van-nav-bar {
|
||||
z-index: 20;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.member-full-popup__page > .van-nav-bar .van-nav-bar__title {
|
||||
color: #172033;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.member-full-popup__page > .van-nav-bar .van-icon,
|
||||
.member-full-popup__page > .van-nav-bar .van-nav-bar__text {
|
||||
color: var(--member-primary);
|
||||
}
|
||||
|
||||
.member-info-scroll {
|
||||
min-height: 0;
|
||||
padding: 12px 12px calc(82px + env(safe-area-inset-bottom));
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.member-detail-card {
|
||||
margin-bottom: 11px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 11px rgba(51, 87, 126, .08);
|
||||
}
|
||||
|
||||
.member-detail-card__title {
|
||||
position: relative;
|
||||
padding: 12px 14px 8px 21px;
|
||||
color: #354255;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.member-detail-card__title::before {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
bottom: 11px;
|
||||
left: 12px;
|
||||
width: 2px;
|
||||
border-radius: 2px;
|
||||
background: var(--member-primary);
|
||||
content: "";
|
||||
}
|
||||
|
||||
.member-detail-card .van-cell {
|
||||
padding: 10px 14px;
|
||||
color: #4f5d70;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.member-detail-card .van-cell__title {
|
||||
color: #7b899b;
|
||||
}
|
||||
|
||||
@media (min-width: 600px) {
|
||||
.member-hero__content,
|
||||
.member-page-main,
|
||||
.member-form-skeleton {
|
||||
max-width: 520px;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.member-form-actions,
|
||||
.member-approval-actions {
|
||||
right: 50%;
|
||||
left: auto;
|
||||
width: 520px;
|
||||
transform: translateX(50%);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const root = path.resolve(__dirname, '../../..');
|
||||
const Vue = require(path.join(root, 'src/main/resources/static/assets/platform/plugins/vue/vue.js'));
|
||||
const roots = ['src/main/resources/views/platform/zhghh5', 'src/main/resources/views/layouts', 'src/main/resources/static/components'];
|
||||
|
||||
// 只检查模板事件,排除注释;methods 中绑定了实例的 this 不属于此回归。
|
||||
const collectEvents = () => {
|
||||
const records = [];
|
||||
const walk = directory => {
|
||||
for (const entry of fs.readdirSync(directory, {withFileTypes: true})) {
|
||||
const file = path.join(directory, entry.name);
|
||||
if (entry.isDirectory()) { walk(file); continue; }
|
||||
if (!/\.(html|js|vue)$/.test(file)) continue;
|
||||
const source = new TextDecoder('utf-8', {fatal: true}).decode(fs.readFileSync(file));
|
||||
const active = source.replace(/<!--[\s\S]*?-->/g, text => text.replace(/[^\n\r]/g, ' '));
|
||||
for (const match of active.matchAll(/(?:@|v-on:)([\w.:-]+)\s*=\s*(["'])([\s\S]*?)\2/g)) {
|
||||
records.push({file: path.relative(root, file).replaceAll('\\', '/'), line: source.slice(0, match.index).split('\n').length, attribute: match[0], event: match[1], expression: match[3], start: match.index});
|
||||
}
|
||||
}
|
||||
};
|
||||
roots.forEach(directory => walk(path.join(root, directory)));
|
||||
return records;
|
||||
};
|
||||
|
||||
const run = () => {
|
||||
const records = collectEvents();
|
||||
const unsafe = records.filter(record => /\$set\(this\s*,/.test(record.expression) && !/=>/.test(record.expression));
|
||||
assert.deepEqual(unsafe.map(record => record.file + ':' + record.line), [], '内联事件不能把调用时的 this 当作页面实例');
|
||||
let checked = 0;
|
||||
for (const record of records.filter(record => /\$set\(\$data\s*,/.test(record.expression))) {
|
||||
const setters = [...record.expression.matchAll(/\$set\(\$data\s*,\s*['"]([^'"]+)['"]\s*,\s*(true|false|0|row)\s*\)/g)];
|
||||
assert(setters.length > 0, record.attribute);
|
||||
const row = {id: 'test-row'};
|
||||
const data = {row, item: {id: 'test-address'}};
|
||||
for (const setter of setters) data[setter[1]] = setter[2] === 'true' ? false : setter[2] === 'false' ? true : null;
|
||||
const instance = new Vue({data: () => data, methods: {addressClick: () => {}}});
|
||||
const compiled = Vue.compile('<test-event ' + record.attribute + '></test-event>');
|
||||
instance.$options.render = compiled.render;
|
||||
instance.$options.staticRenderFns = compiled.staticRenderFns;
|
||||
const listener = instance._render().data.on[record.event];
|
||||
// 模拟 Vue 组件事件的无实例调用,防止测试人为绑定 this 掩盖原缺陷。
|
||||
listener.apply(null, []);
|
||||
for (const setter of setters) {
|
||||
const expected = setter[2] === 'row' ? row : JSON.parse(setter[2]);
|
||||
assert.equal(instance[setter[1]], expected, record.file + ':' + record.line);
|
||||
}
|
||||
instance.$destroy();
|
||||
checked++;
|
||||
}
|
||||
const activity = fs.readFileSync(path.join(root, 'src/main/resources/views/platform/zhghh5/activity/trainSignUp/apply/index.html'), 'utf8');
|
||||
assert.match(activity, /title="活动介绍"[^>]*@click-left="historyBack"/, '活动介绍返回必须使用统一历史栈');
|
||||
console.log(JSON.stringify({scannedEvents: records.length, checkedDataEvents: checked, unsafeInlineSetters: unsafe.length, activityBack: 'passed'}));
|
||||
};
|
||||
|
||||
module.exports = {collectEvents};
|
||||
if (require.main === module) run();
|
||||