| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- <template>
- <!-- #ifdef APP -->
- <scroll-view class="page-scroll">
- <!-- #endif -->
- <view class="page">
- <view class="hero-card">
- <text class="hero-title">接单时间设置</text>
- <text class="hero-desc">按半小时粒度安排可接单时间,黄色卡片表示当前已开启。</text>
- </view>
- <view class="toolbar">
- <view class="toolbar-button" @click="toggleAllTime">
- <text class="toolbar-button-text">{{ allSelected ? '取消全选' : '全部可接单' }}</text>
- </view>
- <view class="toolbar-meta">
- <text class="toolbar-meta-text">已选 {{ timeItems.filter((item : TimeItem) : boolean => item.selected).length }} 段</text>
- </view>
- </view>
- <view class="grid">
- <view v-for="item in timeItems" :key="item.startTime" class="time-card" :class="item.selected ? 'time-card-active' : 'time-card-idle'" @click="toggleTimeItem(item.startTime)">
- <text class="time-card-time" :class="item.selected ? 'time-card-time-active' : 'time-card-time-idle'">{{ item.startTime }}</text>
- <text class="time-card-state" :class="item.selected ? 'time-card-time-active' : 'time-card-time-idle'">{{ item.selected ? '可接单' : '休息' }}</text>
- </view>
- </view>
- <view class="footer-button" @click="saveTimeSetting">
- <text class="footer-button-text">保存设置</text>
- </view>
- </view>
- <!-- #ifdef APP -->
- </scroll-view>
- <!-- #endif -->
- </template>
- <script setup lang="uts">
- import { computed, ref } from 'vue'
- import { getWorkTimeSetting, editWorkTimeSetting } from '@/utils/api/workbenches.uts'
- type TimeItem = {
- startTime: string
- endTime: string
- selected: boolean
- }
- const timeItems = ref<TimeItem[]>([])
- const buildTimeItems = () : TimeItem[] => {
- const result : TimeItem[] = []
- for (let i = 0; i < 48; i++) {
- const startHour = Math.floor(i / 2)
- const startMinute = i % 2 == 0 ? '00' : '30'
- let endHour = Math.floor((i + 1) / 2)
- let endMinute = (i + 1) % 2 == 0 ? '00' : '30'
- if (endHour >= 24) {
- endHour = 24
- endMinute = '00'
- }
- const startTime = `${startHour < 10 ? '0' : ''}${startHour}:${startMinute}`
- const endTime = `${endHour < 10 ? '0' : ''}${endHour}:${endMinute}`
- result.push({
- startTime: startTime,
- endTime: endTime,
- selected: false,
- })
- }
- return result
- }
- timeItems.value = buildTimeItems()
- const allSelected = computed(() : boolean => {
- return timeItems.value.length > 0 && timeItems.value.every((item : TimeItem) : boolean => item.selected)
- })
- const toggleTimeItem = (startTime : string) : void => {
- for (let i = 0; i < timeItems.value.length; i++) {
- const item = timeItems.value[i]
- if (item.startTime == startTime) {
- item.selected = !item.selected
- return
- }
- }
- }
- const toggleAllTime = () : void => {
- const nextSelected = !allSelected.value
- for (let i = 0; i < timeItems.value.length; i++) {
- timeItems.value[i].selected = nextSelected
- }
- }
- const applyServerRanges = (ranges : UTSArray<UTSJSONObject> | null) : void => {
- const freshItems = buildTimeItems()
- if (ranges != null) {
- for (let i = 0; i < freshItems.length; i++) {
- const item = freshItems[i]
- for (let j = 0; j < ranges.length; j++) {
- const range = ranges[j]
- const startTime = (range['start_time'] as string | null) ?? ''
- const endTime = (range['end_time'] as string | null) ?? ''
- if (item.startTime == startTime && item.endTime == endTime) {
- item.selected = true
- break
- }
- }
- }
- }
- timeItems.value = freshItems
- }
- const loadTimeSetting = async () : Promise<void> => {
- try {
- const response = await getWorkTimeSetting() as UTSJSONObject
- const code = (response['code'] as number | null) ?? -1
- if (code != 0 && code != 200) {
- applyServerRanges(null)
- return
- }
- const data = (response['data'] as UTSJSONObject | null)
- const ranges = (data?.['time_ranges'] as UTSArray<UTSJSONObject> | null)
- applyServerRanges(ranges)
- } catch (error) {
- applyServerRanges(null)
- }
- }
- const saveTimeSetting = async () : Promise<void> => {
- const selectedRanges : UTSArray<UTSJSONObject> = []
- for (let i = 0; i < timeItems.value.length; i++) {
- const item = timeItems.value[i]
- if (item.selected) {
- selectedRanges.push({
- start_time: item.startTime,
- end_time: item.endTime,
- } as UTSJSONObject)
- }
- }
- if (selectedRanges.length == 0) {
- uni.showToast({ title: '请至少选择一个时间段', icon: 'none' })
- return
- }
- try {
- const response = await editWorkTimeSetting({
- time_ranges: selectedRanges,
- } as UTSJSONObject) as UTSJSONObject
- const code = (response['code'] as number | null) ?? -1
- uni.showToast({
- title: code == 0 || code == 200 ? '保存成功' : '保存失败',
- icon: 'none',
- })
- } catch (error) {
- uni.showToast({ title: '保存失败,请重试', icon: 'none' })
- }
- }
- onLoad(() => {
- loadTimeSetting()
- })
- </script>
- <style>
- .page-scroll {
- flex: 1;
- }
- .page {
- min-height: 1000rpx;
- padding: 24rpx;
- box-sizing: border-box;
- background-color: #fff8e8;
- flex-direction: column;
- }
- .hero-card {
- padding: 28rpx;
- border-radius: 28rpx;
- background-color: #ffe68a;
- flex-direction: column;
- }
- .hero-title {
- font-size: 38rpx;
- font-weight: 700;
- color: #3d3528;
- }
- .hero-desc {
- margin-top: 10rpx;
- font-size: 24rpx;
- line-height: 34rpx;
- color: #6f6047;
- }
- .toolbar {
- margin-top: 20rpx;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 24rpx;
- }
- .toolbar-button {
- padding: 18rpx 28rpx;
- border-radius: 18rpx;
- background-color: #ffdb5a;
- flex-direction: row;
- justify-content: center;
- align-items: center;
- }
- .toolbar-meta {
- padding-left: 20rpx;
- padding-right: 20rpx;
- height: 64rpx;
- border-radius: 18rpx;
- background-color: #ffffff;
- flex-direction: row;
- justify-content: center;
- align-items: center;
- }
- .toolbar-meta-text {
- font-size: 24rpx;
- color: #7d7261;
- }
- .toolbar-button-text {
- font-size: 28rpx;
- font-weight: 700;
- color: #3d3528;
- }
- .grid {
- flex-direction: row;
- flex-wrap: wrap;
- justify-content: space-between;
- }
- .time-card {
- width: 158rpx;
- height: 104rpx;
- margin-bottom: 18rpx;
- border-radius: 18rpx;
- box-sizing: border-box;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- }
- .time-card-active {
- background-color: #fff6d8;
- border-width: 2rpx;
- border-style: solid;
- border-color: #ffdb5a;
- }
- .time-card-idle {
- background-color: #f1f1f1;
- }
- .time-card-time {
- font-size: 28rpx;
- }
- .time-card-state {
- margin-top: 8rpx;
- font-size: 24rpx;
- }
- .time-card-time-active {
- color: #3d3528;
- }
- .time-card-time-idle {
- color: #9c988f;
- }
- .footer-button {
- margin-top: 20rpx;
- height: 96rpx;
- border-radius: 24rpx;
- background-color: #ffd84d;
- flex-direction: row;
- justify-content: center;
- align-items: center;
- }
- .footer-button-text {
- font-size: 32rpx;
- font-weight: 700;
- color: #3d3528;
- }
- </style>
|