|
@@ -9,7 +9,14 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="filter-row">
|
|
<view class="filter-row">
|
|
|
- <text class="filter-label">时间区间</text>
|
|
|
|
|
|
|
+ <view class="date-filter-trigger" @click="openDateRangeModal">
|
|
|
|
|
+ <view class="date-filter-icon">
|
|
|
|
|
+ <view class="date-filter-icon-line"></view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <text class="date-filter-text">{{ period === 'custom' ? startDate + ' 至 ' + endDate : '时间区间' }}</text>
|
|
|
|
|
+ <!-- <text class="date-filter-hint">{{ period === 'custom' ? '重选' : '选择日期' }}</text> -->
|
|
|
|
|
+ <view class="date-filter-arrow"></view>
|
|
|
|
|
+ </view>
|
|
|
<view
|
|
<view
|
|
|
v-for="p in periodTabs"
|
|
v-for="p in periodTabs"
|
|
|
:key="p.value"
|
|
:key="p.value"
|
|
@@ -37,7 +44,6 @@
|
|
|
v-for="(item, index) in list.data"
|
|
v-for="(item, index) in list.data"
|
|
|
:key="item.id || index"
|
|
:key="item.id || index"
|
|
|
class="gift-card"
|
|
class="gift-card"
|
|
|
- @click="onCardClick(item)"
|
|
|
|
|
>
|
|
>
|
|
|
<image v-if="item.avatar" class="avatar" :src="item.avatar" mode="aspectFill" />
|
|
<image v-if="item.avatar" class="avatar" :src="item.avatar" mode="aspectFill" />
|
|
|
<view v-else class="avatar placeholder" />
|
|
<view v-else class="avatar placeholder" />
|
|
@@ -53,49 +59,152 @@
|
|
|
/>
|
|
/>
|
|
|
<text v-if="item.memberName" class="level-name">{{ item.memberName }}</text>
|
|
<text v-if="item.memberName" class="level-name">{{ item.memberName }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view v-if="item.status === 0" class="line link" @click.stop="fillBirthday(item)">点击填写生日</view>
|
|
|
|
|
- <view v-else class="line">生日:{{ item.birthdayDisplay }}</view>
|
|
|
|
|
- <view class="line gift-line">生日赠礼:{{ item.giftName || '—' }}</view>
|
|
|
|
|
- <view v-if="item.status === 2 && item.pickupTime" class="line sub">预约领取时间:{{ formatTime(item.pickupTime) }}</view>
|
|
|
|
|
- <view v-if="item.status === 3 && item.collectTime" class="line sub">领取时间:{{ formatTime(item.collectTime) }}</view>
|
|
|
|
|
- <view v-if="item.status === 4" class="line sub">预约领取时间:超时自动放弃</view>
|
|
|
|
|
|
|
+ <view class="info-row">
|
|
|
|
|
+ <view class="info-lines">
|
|
|
|
|
+ <view v-if="item.status === 0" class="line link" @click="fillBirthday(index, list.data)">点击填写生日</view>
|
|
|
|
|
+ <view v-else class="line">生日:{{ item.birthdayDisplay }}</view>
|
|
|
|
|
+ <view class="line gift-line">生日赠礼:{{ item.giftName || '—' }}</view>
|
|
|
|
|
+ <view v-if="item.status === 3 && item.pickupTime" class="line sub">预约领取时间:{{ formatTime(item.pickupTime) }}</view>
|
|
|
|
|
+ <view v-if="item.status === 4 && item.collectTime" class="line sub">领取时间:{{ formatTime(item.collectTime) }}</view>
|
|
|
|
|
+ <view v-if="item.status === 5" class="line sub">预约领取时间:超时自动放弃</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view
|
|
|
|
|
+ class="status-badge"
|
|
|
|
|
+ :class="['st-' + item.status, { clickable: canOperateStatus(item), disabled: isNotifyDisabled(item) }]"
|
|
|
|
|
+ @click.stop="confirmStatusAction(index, list.data)"
|
|
|
|
|
+ >{{ item.statusName }}</view>
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="status-badge" :class="'st-' + item.status">{{ item.statusName }}</view>
|
|
|
|
|
</view>
|
|
</view>
|
|
|
<app-wrapper-empty v-if="list.finished && $util.isEmpty(list.data)" title="暂无数据" :is-empty="true" />
|
|
<app-wrapper-empty v-if="list.finished && $util.isEmpty(list.data)" title="暂无数据" :is-empty="true" />
|
|
|
</view>
|
|
</view>
|
|
|
|
|
+
|
|
|
|
|
+ <modal-module :show="birthdayModal" @click="birthdayModalClick" :maskClosable="false" title="生日" padding="30rpx 30rpx" width="90%">
|
|
|
|
|
+ <template v-slot:content>
|
|
|
|
|
+ <view class="app-modal-input-wrap">
|
|
|
|
|
+ <view class="birthday-container">
|
|
|
|
|
+ <view class="birthday-section">
|
|
|
|
|
+ <view class="section-title">类型</view>
|
|
|
|
|
+ <view class="type-buttons">
|
|
|
|
|
+ <button
|
|
|
|
|
+ class="admin-button-com middle"
|
|
|
|
|
+ :class="[lunar == 0 ? 'blue' : 'default']"
|
|
|
|
|
+ @click="lunar = 0"
|
|
|
|
|
+ >公历</button>
|
|
|
|
|
+ <button
|
|
|
|
|
+ class="admin-button-com middle"
|
|
|
|
|
+ :class="[lunar == 1 ? 'blue' : 'default']"
|
|
|
|
|
+ @click="lunar = 1"
|
|
|
|
|
+ >农历</button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="birthday-section">
|
|
|
|
|
+ <view class="section-title">月份</view>
|
|
|
|
|
+ <view class="month-buttons">
|
|
|
|
|
+ <button
|
|
|
|
|
+ v-for="month in monthArray"
|
|
|
|
|
+ :key="month"
|
|
|
|
|
+ class="month-button"
|
|
|
|
|
+ :class="{ active: birthdayMonth == month }"
|
|
|
|
|
+ @click="birthdayMonth = month"
|
|
|
|
|
+ >{{ month }}</button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="birthday-section">
|
|
|
|
|
+ <view class="section-title">日期</view>
|
|
|
|
|
+ <view class="date-buttons-wrapper">
|
|
|
|
|
+ <scroll-view
|
|
|
|
|
+ scroll-y="true"
|
|
|
|
|
+ class="date-buttons-scroll"
|
|
|
|
|
+ enhanced="true"
|
|
|
|
|
+ show-scrollbar="true"
|
|
|
|
|
+ always-bounce-vertical="true"
|
|
|
|
|
+ >
|
|
|
|
|
+ <view class="date-buttons">
|
|
|
|
|
+ <button
|
|
|
|
|
+ v-for="date in dateArray"
|
|
|
|
|
+ :key="date"
|
|
|
|
|
+ class="date-button"
|
|
|
|
|
+ :class="{ active: birthdayDate == date }"
|
|
|
|
|
+ @click="birthdayDate = date"
|
|
|
|
|
+ >{{ date }}</button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </scroll-view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </modal-module>
|
|
|
|
|
+
|
|
|
|
|
+ <modal-module :show="dateRangeModal" @click="dateRangeModalClick" :maskClosable="true" title="时间区间" padding="30rpx" width="86%">
|
|
|
|
|
+ <template v-slot:content>
|
|
|
|
|
+ <view class="date-range-form">
|
|
|
|
|
+ <view class="date-range-row">
|
|
|
|
|
+ <text class="date-range-label">开始日期</text>
|
|
|
|
|
+ <picker mode="date" :value="draftStartDate" @change="startDateChange" class="date-range-picker">
|
|
|
|
|
+ <view :class="['date-range-value', draftStartDate ? '' : 'placeholder']">{{ draftStartDate || '请选择' }}</view>
|
|
|
|
|
+ </picker>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="date-range-row">
|
|
|
|
|
+ <text class="date-range-label">结束日期</text>
|
|
|
|
|
+ <picker mode="date" :value="draftEndDate" @change="endDateChange" class="date-range-picker">
|
|
|
|
|
+ <view :class="['date-range-value', draftEndDate ? '' : 'placeholder']">{{ draftEndDate || '请选择' }}</view>
|
|
|
|
|
+ </picker>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </modal-module>
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
import list from '@/mixins/list'
|
|
import list from '@/mixins/list'
|
|
|
import AppWrapperEmpty from '@/components/app-wrapper-empty'
|
|
import AppWrapperEmpty from '@/components/app-wrapper-empty'
|
|
|
-import { getBoardList, getBoardCounts, notifyTomorrow } from '@/api/birthday'
|
|
|
|
|
|
|
+import ModalModule from '@/components/plugin/modal'
|
|
|
|
|
+import { getBoardList, getBoardCounts, notifyTomorrow, notifyBirthdayGift, modifyBirthday, collectBirthdayGift } from '@/api/birthday'
|
|
|
import { iconSrc } from '@/utils/iconSrc'
|
|
import { iconSrc } from '@/utils/iconSrc'
|
|
|
|
|
|
|
|
export default {
|
|
export default {
|
|
|
name: 'BirthdayBoard',
|
|
name: 'BirthdayBoard',
|
|
|
- components: { AppWrapperEmpty },
|
|
|
|
|
|
|
+ components: { AppWrapperEmpty, ModalModule },
|
|
|
mixins: [list],
|
|
mixins: [list],
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
|
searchText: '',
|
|
searchText: '',
|
|
|
period: 'week',
|
|
period: 'week',
|
|
|
|
|
+ startDate: '',
|
|
|
|
|
+ endDate: '',
|
|
|
|
|
+ draftStartDate: '',
|
|
|
|
|
+ draftEndDate: '',
|
|
|
statusFilter: -1,
|
|
statusFilter: -1,
|
|
|
|
|
+ dateRangeModal: false,
|
|
|
|
|
+ birthdayModal: false,
|
|
|
|
|
+ customId: null,
|
|
|
|
|
+ lunar: 0,
|
|
|
|
|
+ birthdayMonth: '',
|
|
|
|
|
+ birthdayDate: '',
|
|
|
|
|
+ monthArray: Array.from({ length: 12 }, (_, i) => i + 1),
|
|
|
|
|
+ dateArray: Array.from({ length: 31 }, (_, i) => i + 1),
|
|
|
periodTabs: [
|
|
periodTabs: [
|
|
|
{ name: '今日', value: 'today' },
|
|
{ name: '今日', value: 'today' },
|
|
|
{ name: '明日', value: 'tomorrow' },
|
|
{ name: '明日', value: 'tomorrow' },
|
|
|
- { name: '近一周', value: 'week' }
|
|
|
|
|
|
|
+ { name: '近一周', value: 'week' },
|
|
|
|
|
+ { name: '全部', value: 'all' }
|
|
|
],
|
|
],
|
|
|
statusTabs: [
|
|
statusTabs: [
|
|
|
{ name: '全部', key: 'all', value: -1 },
|
|
{ name: '全部', key: 'all', value: -1 },
|
|
|
{ name: '待通知', key: 'pendingNotify', value: 1 },
|
|
{ name: '待通知', key: 'pendingNotify', value: 1 },
|
|
|
{ name: '待领取', key: 'pendingClaim', value: 2 },
|
|
{ name: '待领取', key: 'pendingClaim', value: 2 },
|
|
|
- { name: '已领取', key: 'collected', value: 3 },
|
|
|
|
|
|
|
+ { name: '已领取', key: 'collected', value: 4 },
|
|
|
{ name: '未填写', key: 'noBirthday', value: 0 },
|
|
{ name: '未填写', key: 'noBirthday', value: 0 },
|
|
|
- { name: '超时放弃', key: 'expired', value: 4 }
|
|
|
|
|
|
|
+ { name: '超时放弃', key: 'expired', value: 5 }
|
|
|
],
|
|
],
|
|
|
- counts: {}
|
|
|
|
|
|
|
+ counts: {},
|
|
|
|
|
+ collectSubmitting: false,
|
|
|
|
|
+ notifySubmitting: false
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
@@ -115,8 +224,16 @@ export default {
|
|
|
this.loadCounts()
|
|
this.loadCounts()
|
|
|
this.resetList()
|
|
this.resetList()
|
|
|
},
|
|
},
|
|
|
|
|
+ getListParams() {
|
|
|
|
|
+ const params = { period: this.period }
|
|
|
|
|
+ if (this.period === 'custom') {
|
|
|
|
|
+ params.startDate = this.startDate
|
|
|
|
|
+ params.endDate = this.endDate
|
|
|
|
|
+ }
|
|
|
|
|
+ return params
|
|
|
|
|
+ },
|
|
|
loadCounts() {
|
|
loadCounts() {
|
|
|
- getBoardCounts({ period: this.period }).then(res => {
|
|
|
|
|
|
|
+ getBoardCounts(this.getListParams()).then(res => {
|
|
|
if (res.code === 1) {
|
|
if (res.code === 1) {
|
|
|
this.counts = res.data || {}
|
|
this.counts = res.data || {}
|
|
|
}
|
|
}
|
|
@@ -124,6 +241,39 @@ export default {
|
|
|
},
|
|
},
|
|
|
changePeriod(v) {
|
|
changePeriod(v) {
|
|
|
this.period = v
|
|
this.period = v
|
|
|
|
|
+ this.startDate = ''
|
|
|
|
|
+ this.endDate = ''
|
|
|
|
|
+ this.loadCounts()
|
|
|
|
|
+ this.resetList()
|
|
|
|
|
+ },
|
|
|
|
|
+ openDateRangeModal() {
|
|
|
|
|
+ this.draftStartDate = this.startDate
|
|
|
|
|
+ this.draftEndDate = this.endDate
|
|
|
|
|
+ this.dateRangeModal = true
|
|
|
|
|
+ },
|
|
|
|
|
+ startDateChange(e) {
|
|
|
|
|
+ this.draftStartDate = e.detail.value
|
|
|
|
|
+ },
|
|
|
|
|
+ endDateChange(e) {
|
|
|
|
|
+ this.draftEndDate = e.detail.value
|
|
|
|
|
+ },
|
|
|
|
|
+ dateRangeModalClick(e) {
|
|
|
|
|
+ if (e.index === 0) {
|
|
|
|
|
+ this.dateRangeModal = false
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!this.draftStartDate || !this.draftEndDate) {
|
|
|
|
|
+ this.$msg('请选择开始日期和结束日期')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (this.draftStartDate > this.draftEndDate) {
|
|
|
|
|
+ this.$msg('开始日期不能晚于结束日期')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ this.startDate = this.draftStartDate
|
|
|
|
|
+ this.endDate = this.draftEndDate
|
|
|
|
|
+ this.period = 'custom'
|
|
|
|
|
+ this.dateRangeModal = false
|
|
|
this.loadCounts()
|
|
this.loadCounts()
|
|
|
this.resetList()
|
|
this.resetList()
|
|
|
},
|
|
},
|
|
@@ -143,13 +293,12 @@ export default {
|
|
|
},
|
|
},
|
|
|
loadMore() {
|
|
loadMore() {
|
|
|
if (this.list.finished) return
|
|
if (this.list.finished) return
|
|
|
- getBoardList({
|
|
|
|
|
|
|
+ getBoardList(Object.assign(this.getListParams(), {
|
|
|
page: this.list.page,
|
|
page: this.list.page,
|
|
|
pageSize: 20,
|
|
pageSize: 20,
|
|
|
- period: this.period,
|
|
|
|
|
status: this.statusFilter,
|
|
status: this.statusFilter,
|
|
|
searchText: this.searchText
|
|
searchText: this.searchText
|
|
|
- }).then(res => {
|
|
|
|
|
|
|
+ })).then(res => {
|
|
|
if (res.code === 1) {
|
|
if (res.code === 1) {
|
|
|
const d = res.data || {}
|
|
const d = res.data || {}
|
|
|
const listArr = d.list || []
|
|
const listArr = d.list || []
|
|
@@ -175,15 +324,107 @@ export default {
|
|
|
goGiftStats() {
|
|
goGiftStats() {
|
|
|
this.$util.pageTo({ url: '/admin/birthday/giftStats', query: { period: this.period } })
|
|
this.$util.pageTo({ url: '/admin/birthday/giftStats', query: { period: this.period } })
|
|
|
},
|
|
},
|
|
|
- fillBirthday(item) {
|
|
|
|
|
- this.$util.pageTo({ url: '/admin/member/detail', query: { id: item.customId } })
|
|
|
|
|
|
|
+ canCollect(item = {}) {
|
|
|
|
|
+ return Number(item.status) === 3
|
|
|
|
|
+ },
|
|
|
|
|
+ canNotify(item = {}) {
|
|
|
|
|
+ return Number(item.status) === 1 && !!item.canNotify
|
|
|
|
|
+ },
|
|
|
|
|
+ canOperateStatus(item = {}) {
|
|
|
|
|
+ return this.canCollect(item) || this.canNotify(item)
|
|
|
|
|
+ },
|
|
|
|
|
+ isNotifyDisabled(item = {}) {
|
|
|
|
|
+ return Number(item.status) === 1 && !this.canNotify(item)
|
|
|
|
|
+ },
|
|
|
|
|
+ confirmStatusAction(index, list) {
|
|
|
|
|
+ const item = list[index]
|
|
|
|
|
+ if (this.canNotify(item)) {
|
|
|
|
|
+ this.confirmNotify(item)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ this.confirmCollect(index, list)
|
|
|
|
|
+ },
|
|
|
|
|
+ confirmNotify(item = {}) {
|
|
|
|
|
+ this.$util.confirmModal({ content: '确认发送通知', okText: '确认', cancelText: '取消' }, () => {
|
|
|
|
|
+ this.notifyGift(item)
|
|
|
|
|
+ })
|
|
|
},
|
|
},
|
|
|
- onCardClick(item) {
|
|
|
|
|
- if (item.status === 0) {
|
|
|
|
|
- this.fillBirthday(item)
|
|
|
|
|
|
|
+ notifyGift(item = {}) {
|
|
|
|
|
+ if (this.notifySubmitting) return
|
|
|
|
|
+ const id = item.id || ''
|
|
|
|
|
+ if (!id) {
|
|
|
|
|
+ this.$msg('记录信息异常')
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
- this.$util.pageTo({ url: '/admin/member/detail', query: { id: item.customId } })
|
|
|
|
|
|
|
+ this.notifySubmitting = true
|
|
|
|
|
+ notifyBirthdayGift({ id }).then(res => {
|
|
|
|
|
+ if (res.code === 1) {
|
|
|
|
|
+ this.$msg(res.msg || '通知成功')
|
|
|
|
|
+ this.reload()
|
|
|
|
|
+ }
|
|
|
|
|
+ }).finally(() => {
|
|
|
|
|
+ this.notifySubmitting = false
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ confirmCollect(index, list) {
|
|
|
|
|
+ const item = list[index]
|
|
|
|
|
+ if (!this.canCollect(item)) return
|
|
|
|
|
+ this.$util.confirmModal({ content: '是否更新为已领取?', okText: '确认', cancelText: '取消' }, () => {
|
|
|
|
|
+ this.collectGift(item)
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ collectGift(item = {}) {
|
|
|
|
|
+ if (this.collectSubmitting) return
|
|
|
|
|
+ const id = item.id || ''
|
|
|
|
|
+ if (!id) {
|
|
|
|
|
+ this.$msg('记录信息异常')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ this.collectSubmitting = true
|
|
|
|
|
+ collectBirthdayGift({ id }).then(res => {
|
|
|
|
|
+ if (res.code === 1) {
|
|
|
|
|
+ this.$msg(res.msg || '更新成功')
|
|
|
|
|
+ this.reload()
|
|
|
|
|
+ }
|
|
|
|
|
+ }).finally(() => {
|
|
|
|
|
+ this.collectSubmitting = false
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ getCustomId(item = {}) {
|
|
|
|
|
+ return item.customId || item.custom_id || item.custom?.id || ''
|
|
|
|
|
+ },
|
|
|
|
|
+ fillBirthday(index, list) {
|
|
|
|
|
+ const item = list[index]
|
|
|
|
|
+ this.birthdayModal = true
|
|
|
|
|
+ this.customId = this.getCustomId(item)
|
|
|
|
|
+ },
|
|
|
|
|
+ birthdayModalClick(e) {
|
|
|
|
|
+ if (e.index === 0) {
|
|
|
|
|
+ this.birthdayModal = false
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!this.birthdayMonth || !this.birthdayDate) {
|
|
|
|
|
+ this.$msg('请选择月份和日期')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ const customId = this.customId
|
|
|
|
|
+ if (!customId) {
|
|
|
|
|
+ this.$msg('客户信息异常123')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ modifyBirthday({
|
|
|
|
|
+ customId,
|
|
|
|
|
+ lunar: this.lunar,
|
|
|
|
|
+ birthdayMonth: this.birthdayMonth,
|
|
|
|
|
+ birthdayDate: this.birthdayDate
|
|
|
|
|
+ }).then(res => {
|
|
|
|
|
+ if (res.code === 1) {
|
|
|
|
|
+ this.$msg('修改成功')
|
|
|
|
|
+ this.birthdayModal = false
|
|
|
|
|
+ this.birthdayOperateItem = null
|
|
|
|
|
+ this.reload()
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
onPullDownRefresh() {
|
|
onPullDownRefresh() {
|
|
@@ -244,10 +485,65 @@ export default {
|
|
|
margin-top: 20upx;
|
|
margin-top: 20upx;
|
|
|
flex-wrap: wrap;
|
|
flex-wrap: wrap;
|
|
|
}
|
|
}
|
|
|
-.filter-label {
|
|
|
|
|
- font-size: 26upx;
|
|
|
|
|
- color: #666;
|
|
|
|
|
|
|
+.date-filter-trigger {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ height: 52upx;
|
|
|
|
|
+ padding: 0 18upx;
|
|
|
margin-right: 12upx;
|
|
margin-right: 12upx;
|
|
|
|
|
+ margin-bottom: 10upx;
|
|
|
|
|
+ background: #f0fbf5;
|
|
|
|
|
+ border: 1upx solid #08b955;
|
|
|
|
|
+ border-radius: 28upx;
|
|
|
|
|
+ box-shadow: 0 4upx 12upx rgba(8, 185, 85, 0.12);
|
|
|
|
|
+}
|
|
|
|
|
+.date-filter-icon {
|
|
|
|
|
+ width: 24upx;
|
|
|
|
|
+ height: 24upx;
|
|
|
|
|
+ margin-right: 8upx;
|
|
|
|
|
+ border: 2upx solid #08b955;
|
|
|
|
|
+ border-radius: 5upx;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+}
|
|
|
|
|
+.date-filter-icon::before,
|
|
|
|
|
+.date-filter-icon::after {
|
|
|
|
|
+ content: '';
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: -6upx;
|
|
|
|
|
+ width: 4upx;
|
|
|
|
|
+ height: 8upx;
|
|
|
|
|
+ background: #08b955;
|
|
|
|
|
+ border-radius: 2upx;
|
|
|
|
|
+}
|
|
|
|
|
+.date-filter-icon::before {
|
|
|
|
|
+ left: 4upx;
|
|
|
|
|
+}
|
|
|
|
|
+.date-filter-icon::after {
|
|
|
|
|
+ right: 4upx;
|
|
|
|
|
+}
|
|
|
|
|
+.date-filter-icon-line {
|
|
|
|
|
+ height: 2upx;
|
|
|
|
|
+ margin-top: 7upx;
|
|
|
|
|
+ background: #08b955;
|
|
|
|
|
+}
|
|
|
|
|
+.date-filter-text {
|
|
|
|
|
+ font-size: 24upx;
|
|
|
|
|
+ color: #08b955;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+}
|
|
|
|
|
+.date-filter-hint {
|
|
|
|
|
+ margin-left: 8upx;
|
|
|
|
|
+ font-size: 22upx;
|
|
|
|
|
+ color: #6abf8e;
|
|
|
|
|
+}
|
|
|
|
|
+.date-filter-arrow {
|
|
|
|
|
+ width: 12upx;
|
|
|
|
|
+ height: 12upx;
|
|
|
|
|
+ margin-left: 8upx;
|
|
|
|
|
+ border-top: 2upx solid #08b955;
|
|
|
|
|
+ border-right: 2upx solid #08b955;
|
|
|
|
|
+ transform: rotate(45deg);
|
|
|
}
|
|
}
|
|
|
.pill {
|
|
.pill {
|
|
|
padding: 8upx 20upx;
|
|
padding: 8upx 20upx;
|
|
@@ -261,6 +557,36 @@ export default {
|
|
|
background: #08b955;
|
|
background: #08b955;
|
|
|
color: #fff;
|
|
color: #fff;
|
|
|
}
|
|
}
|
|
|
|
|
+.date-range-form {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+}
|
|
|
|
|
+.date-range-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ height: 84upx;
|
|
|
|
|
+ border-bottom: 1upx solid #eee;
|
|
|
|
|
+}
|
|
|
|
|
+.date-range-row:last-child {
|
|
|
|
|
+ border-bottom: 0;
|
|
|
|
|
+}
|
|
|
|
|
+.date-range-label {
|
|
|
|
|
+ flex: 0 0 150upx;
|
|
|
|
|
+ font-size: 28upx;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+}
|
|
|
|
|
+.date-range-picker {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+}
|
|
|
|
|
+.date-range-value {
|
|
|
|
|
+ height: 84upx;
|
|
|
|
|
+ line-height: 84upx;
|
|
|
|
|
+ text-align: right;
|
|
|
|
|
+ font-size: 28upx;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+}
|
|
|
|
|
+.date-range-value.placeholder {
|
|
|
|
|
+ color: #999;
|
|
|
|
|
+}
|
|
|
.status-tabs {
|
|
.status-tabs {
|
|
|
white-space: nowrap;
|
|
white-space: nowrap;
|
|
|
margin-top: 16upx;
|
|
margin-top: 16upx;
|
|
@@ -333,6 +659,14 @@ export default {
|
|
|
padding: 2upx 10upx;
|
|
padding: 2upx 10upx;
|
|
|
border-radius: 8upx;
|
|
border-radius: 8upx;
|
|
|
}
|
|
}
|
|
|
|
|
+.info-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+}
|
|
|
|
|
+.info-lines {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+}
|
|
|
.line {
|
|
.line {
|
|
|
font-size: 24upx;
|
|
font-size: 24upx;
|
|
|
color: #666;
|
|
color: #666;
|
|
@@ -349,16 +683,97 @@ export default {
|
|
|
color: #333;
|
|
color: #333;
|
|
|
}
|
|
}
|
|
|
.status-badge {
|
|
.status-badge {
|
|
|
- position: absolute;
|
|
|
|
|
- right: 250upx;
|
|
|
|
|
- top: 110upx;
|
|
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ margin-top: 8upx;
|
|
|
|
|
+ margin-left: 16upx;
|
|
|
font-size: 22upx;
|
|
font-size: 22upx;
|
|
|
padding: 4upx 12upx;
|
|
padding: 4upx 12upx;
|
|
|
border-radius: 8upx;
|
|
border-radius: 8upx;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
}
|
|
}
|
|
|
.st-1 { background: #ffe8e8; color: #e54; }
|
|
.st-1 { background: #ffe8e8; color: #e54; }
|
|
|
.st-2 { background: #e8f0ff; color: #36c; }
|
|
.st-2 { background: #e8f0ff; color: #36c; }
|
|
|
-.st-3 { background: #eee; color: #888; }
|
|
|
|
|
|
|
+.st-3 { background: #e8f8ef; color: #08b955; }
|
|
|
.st-0 { background: #fff3e0; color: #f90; }
|
|
.st-0 { background: #fff3e0; color: #f90; }
|
|
|
-.st-4 { background: #ddd; color: #555; }
|
|
|
|
|
|
|
+.st-4 { background: #eee; color: #888; }
|
|
|
|
|
+.st-5 { background: #ddd; color: #555; }
|
|
|
|
|
+.status-badge.clickable {
|
|
|
|
|
+ border: 1upx solid #08b955;
|
|
|
|
|
+}
|
|
|
|
|
+.status-badge.disabled {
|
|
|
|
|
+ background: #eee;
|
|
|
|
|
+ color: #999;
|
|
|
|
|
+ border: 1upx solid #ddd;
|
|
|
|
|
+}
|
|
|
|
|
+.birthday-container {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+}
|
|
|
|
|
+.birthday-section {
|
|
|
|
|
+ margin-bottom: 30upx;
|
|
|
|
|
+}
|
|
|
|
|
+.birthday-section:last-child {
|
|
|
|
|
+ margin-bottom: 0;
|
|
|
|
|
+}
|
|
|
|
|
+.section-title {
|
|
|
|
|
+ font-size: 32upx;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ margin-bottom: 20upx;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+}
|
|
|
|
|
+.type-buttons {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+}
|
|
|
|
|
+.type-buttons button {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ margin-right: 20upx;
|
|
|
|
|
+}
|
|
|
|
|
+.type-buttons button:last-child {
|
|
|
|
|
+ margin-right: 0;
|
|
|
|
|
+}
|
|
|
|
|
+.month-buttons,
|
|
|
|
|
+.date-buttons {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+}
|
|
|
|
|
+.month-button,
|
|
|
|
|
+.date-button {
|
|
|
|
|
+ width: calc(25% - 10upx);
|
|
|
|
|
+ height: 80upx;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border: 2upx solid #e9ecef;
|
|
|
|
|
+ border-radius: 8upx;
|
|
|
|
|
+ font-size: 30upx;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ margin-right: 10upx;
|
|
|
|
|
+ margin-bottom: 10upx;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+}
|
|
|
|
|
+.month-button:nth-child(4n),
|
|
|
|
|
+.date-button:nth-child(4n) {
|
|
|
|
|
+ margin-right: 0;
|
|
|
|
|
+}
|
|
|
|
|
+.month-button.active,
|
|
|
|
|
+.date-button.active {
|
|
|
|
|
+ background: #e8f5ff;
|
|
|
|
|
+ border-color: #3385ff;
|
|
|
|
|
+ color: #3385ff;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+}
|
|
|
|
|
+.date-buttons-wrapper {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 340upx;
|
|
|
|
|
+ background: #f8f9fa;
|
|
|
|
|
+ border: 2upx solid #e9ecef;
|
|
|
|
|
+ border-radius: 8upx;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+}
|
|
|
|
|
+.date-buttons-scroll {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ padding: 10upx;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|