master
lion 2 months ago
parent dd99201628
commit bc3c9cd304

@ -15,7 +15,9 @@ use Illuminate\Validation\ValidationException;
class ActivityBookingController extends Controller
{
private const BOOKING_MODE_INDIVIDUAL = 'individual';
private const BOOKING_MODE_GROUP = 'group';
private const BOOKING_MODE_BOTH = 'both';
public function show(Request $request, Activity $activity): JsonResponse
@ -34,17 +36,19 @@ class ActivityBookingController extends Controller
'min_people_per_order' => ['nullable', 'integer', 'min:1'],
'max_people_per_order' => ['nullable', 'integer', 'min:1'],
'days' => ['required', 'array', 'min:1'],
'days.*.activity_date' => ['required', 'date'],
'days.*.day_quota' => ['required', 'integer', 'min:0'],
'days.*.opens_at' => ['required', 'date'],
'days.*.closes_at' => ['required', 'date'],
'days.*.id' => ['nullable', 'integer', 'min:1'],
'days.*.session_name' => ['required', 'string', 'max:200'],
'days.*.session_start_at' => ['required', 'date'],
'days.*.session_end_at' => ['required', 'date'],
'days.*.booking_deadline_at' => ['required', 'date'],
'days.*.day_quota' => ['required', 'integer', 'min:1'],
]);
$mode = $data['booking_audience'];
$venue = Venue::query()->findOrFail($activity->venue_id);
if ($venue->appointment_type === 'team_only' && $mode !== self::BOOKING_MODE_GROUP) {
throw ValidationException::withMessages([
'booking_audience' => ['该场馆预约类型为「仅团队」,放票设置只能选择团体'],
'booking_audience' => ['该场馆预约类型为「仅团队」,场次设置只能选择团体'],
]);
}
@ -63,9 +67,7 @@ class ActivityBookingController extends Controller
}
}
$this->validateDaysWithinActivityRange($activity, $data['days']);
$this->validateUniqueDates($data['days']);
$this->validateBookingPeriodWithinActivityDay($data['days']);
$this->validateSessionRows($activity, $data['days']);
$sumDay = 0;
foreach ($data['days'] as $row) {
@ -79,51 +81,61 @@ class ActivityBookingController extends Controller
$activity->max_people_per_order = $maxPeople;
$activity->save();
$incomingDateKeys = collect($data['days'])->map(function (array $row) {
return Carbon::parse($row['activity_date'])->format('Y-m-d');
})->values();
$existing = ActivityDay::where('activity_id', $activity->id)->get()->keyBy(fn (ActivityDay $d) => $d->activity_date->format('Y-m-d'));
$incomingIds = [];
foreach ($data['days'] as $row) {
$dateKey = Carbon::parse($row['activity_date'])->format('Y-m-d');
$id = isset($row['id']) ? (int) $row['id'] : 0;
$sessionStart = Carbon::parse($row['session_start_at']);
$sessionEnd = Carbon::parse($row['session_end_at']);
$deadline = Carbon::parse($row['booking_deadline_at']);
$dayQuota = (int) $row['day_quota'];
$opensAt = Carbon::parse($row['opens_at']);
$closesAt = Carbon::parse($row['closes_at']);
$name = trim((string) $row['session_name']);
if ($existing->has($dateKey)) {
/** @var ActivityDay $day */
$day = $existing->get($dateKey);
if ($id > 0) {
$day = ActivityDay::query()
->where('activity_id', $activity->id)
->where('id', $id)
->first();
if (!$day) {
throw ValidationException::withMessages(['days' => ['存在无效的场次 id']]);
}
if ($day->booked_count > $dayQuota) {
throw ValidationException::withMessages([
'days' => ["{$dateKey} 当日已占用 {$day->booked_count} 张,放票数不能少于该值"],
'days' => ['「' . $name . '」已占用 ' . (int) $day->booked_count . ' 人,总名额不能小于该值'],
]);
}
$day->session_name = $name;
$day->session_start_at = $sessionStart;
$day->session_end_at = $sessionEnd;
$day->booking_deadline_at = $deadline;
$day->day_quota = $dayQuota;
$day->opens_at = $opensAt;
$day->closes_at = $closesAt;
$this->fillLegacyOpenClose($activity, $day, $sessionStart, $sessionEnd, $deadline);
$day->save();
$incomingIds[] = (int) $day->id;
} else {
ActivityDay::create([
$d = new ActivityDay([
'activity_id' => $activity->id,
'activity_date' => $dateKey,
'session_name' => $name,
'day_quota' => $dayQuota,
'booked_count' => 0,
'opens_at' => $opensAt,
'closes_at' => $closesAt,
'session_start_at' => $sessionStart,
'session_end_at' => $sessionEnd,
'booking_deadline_at' => $deadline,
]);
$this->fillLegacyOpenClose($activity, $d, $sessionStart, $sessionEnd, $deadline);
$d->save();
$incomingIds[] = (int) $d->id;
}
}
foreach ($existing as $dateKey => $day) {
if (!$incomingDateKeys->contains($dateKey)) {
if ($day->booked_count > 0) {
throw ValidationException::withMessages([
'days' => ["{$dateKey} 已有预约占用,不能移除该放票日"],
]);
}
$day->delete();
$toDelete = ActivityDay::query()
->where('activity_id', $activity->id)
->whereNotIn('id', $incomingIds)
->get();
foreach ($toDelete as $d) {
if ((int) $d->booked_count > 0) {
throw ValidationException::withMessages(['days' => ['已有预约占用,不能删除该场次']]);
}
$d->delete();
}
});
@ -134,66 +146,66 @@ class ActivityBookingController extends Controller
}
/**
* @param array<int, array{activity_date: mixed, day_quota: int, opens_at: mixed}> $days
* 部分旧逻辑仍读 opens_at/closes_at写入合理近似值以兼容H5/前台以场次、预约截止为准。
*/
private function validateDaysWithinActivityRange(Activity $activity, array $days): void
{
if (!$activity->start_at || !$activity->end_at) {
return;
}
// 按应用时区的「日历日」比较,避免 date-only / ISO 与库中 datetime 混用时出现跨日误判
$tz = config('app.timezone');
$startDate = $activity->start_at->copy()->timezone($tz)->format('Y-m-d');
$endDate = $activity->end_at->copy()->timezone($tz)->format('Y-m-d');
foreach ($days as $row) {
$dayStr = Carbon::parse($row['activity_date'])->timezone($tz)->format('Y-m-d');
if ($dayStr < $startDate || $dayStr > $endDate) {
throw ValidationException::withMessages([
'days' => ['活动日 '.$dayStr.' 须在活动开始、结束日期范围内'],
]);
}
private function fillLegacyOpenClose(
Activity $activity,
ActivityDay $day,
Carbon $sessionStart,
Carbon $sessionEnd,
Carbon $deadline,
): void {
$open = $activity->start_at?->copy()->startOfDay() ?? $sessionStart->copy()->subDays(30);
if ($open->gt($sessionStart)) {
$open = $sessionStart->copy()->subDays(1);
}
$day->opens_at = $open;
$day->closes_at = $deadline;
}
/**
* 开始/结束预约时刻的日期不能晚于活动日,且结束时刻需晚于开始时刻。
*
* @param array<int, array{activity_date: mixed, opens_at: mixed, closes_at: mixed}> $days
* @param array<int, array<string, mixed>> $days
*/
private function validateBookingPeriodWithinActivityDay(array $days): void
private function validateSessionRows(Activity $activity, array $days): void
{
$tz = config('app.timezone');
$tz = (string) config('app.timezone');
$actStartD = $activity->start_at?->copy()->timezone($tz)->format('Y-m-d');
$actEndD = $activity->end_at?->copy()->timezone($tz)->format('Y-m-d');
foreach ($days as $row) {
$actDayStr = Carbon::parse($row['activity_date'])->timezone($tz)->format('Y-m-d');
$opens = Carbon::parse($row['opens_at']);
$closes = Carbon::parse($row['closes_at']);
$opensDateStr = $opens->copy()->timezone($tz)->format('Y-m-d');
$closesDateStr = $closes->copy()->timezone($tz)->format('Y-m-d');
if ($opensDateStr > $actDayStr || $closesDateStr > $actDayStr) {
$name = (string) ($row['session_name'] ?? '');
$sessionStart = Carbon::parse($row['session_start_at'])->timezone($tz);
$sessionEnd = Carbon::parse($row['session_end_at'])->timezone($tz);
$deadline = Carbon::parse($row['booking_deadline_at'])->timezone($tz);
if (!$sessionStart->isSameDay($sessionEnd)) {
throw ValidationException::withMessages([
'days' => ['活动日 '.$actDayStr.':预约开始/结束时刻的日期不能晚于活动日当天'],
'days' => ['「' . $name . '」场次的开始与结束须为同一天内'],
]);
}
if ($closes->lte($opens)) {
if ($sessionEnd->lte($sessionStart)) {
throw ValidationException::withMessages([
'days' => ['活动日 '.$actDayStr.':预约结束时刻必须晚于开始时刻'],
'days' => ['「' . $name . '」场次结束时间须晚于开始时间'],
]);
}
}
}
/**
* @param array<int, array{activity_date: mixed}> $days
*/
private function validateUniqueDates(array $days): void
{
$seen = [];
foreach ($days as $row) {
$key = Carbon::parse($row['activity_date'])->format('Y-m-d');
if (isset($seen[$key])) {
throw ValidationException::withMessages(['days' => ['活动日不能重复']]);
if ($actStartD || $actEndD) {
$dStr = $sessionStart->format('Y-m-d');
if ($actStartD && $dStr < $actStartD) {
throw ValidationException::withMessages([
'days' => ['「' . $name . '」场次开始日期不能早于活动开始日期'],
]);
}
if ($actEndD && $dStr > $actEndD) {
throw ValidationException::withMessages([
'days' => ['「' . $name . '」场次开始日期不能晚于活动结束日期'],
]);
}
}
if ($deadline->gt($sessionStart)) {
throw ValidationException::withMessages([
'days' => ['「' . $name . '」预约截止时间不能晚于场次开始时间'],
]);
}
$seen[$key] = true;
}
}
@ -202,14 +214,20 @@ class ActivityBookingController extends Controller
*/
private function formatBookingPayload(Activity $activity): array
{
$days = $activity->activityDays()->orderBy('activity_date')->get()->map(function (ActivityDay $d) {
$days = $activity->activityDays()->get()->map(function (ActivityDay $d) {
$deadline = $d->booking_deadline_at ?? $d->closes_at;
return [
'id' => $d->id,
'activity_date' => $d->activity_date->format('Y-m-d'),
'session_name' => (string) ($d->session_name ?? ''),
'session_start_at' => $d->session_start_at?->format('Y-m-d H:i:s'),
'session_end_at' => $d->session_end_at?->format('Y-m-d H:i:s'),
'booking_deadline_at' => $d->booking_deadline_at?->format('Y-m-d H:i:s'),
'activity_date' => $d->activity_date?->format('Y-m-d'),
'day_quota' => $d->day_quota,
'booked_count' => $d->booked_count,
'opens_at' => $d->opens_at->format('Y-m-d H:i:s'),
'closes_at' => ($d->closes_at ?: $d->opens_at->copy()->endOfDay())->format('Y-m-d H:i:s'),
'opens_at' => $d->opens_at?->format('Y-m-d H:i:s'),
'closes_at' => $deadline?->format('Y-m-d H:i:s') ?? $d->opens_at?->format('Y-m-d H:i:s'),
];
})->values()->all();

@ -17,7 +17,7 @@ class ActivityRegistrationController extends Controller
$query = Reservation::with([
'venue:id,name',
'activity:id,title',
'activityDay:id,activity_id,activity_date',
'activityDay:id,activity_id,activity_date,session_name,session_start_at,session_end_at',
])
->orderByDesc('id');
@ -72,7 +72,7 @@ class ActivityRegistrationController extends Controller
$query = Reservation::with([
'venue:id,name',
'activity:id,title',
'activityDay:id,activity_id,activity_date',
'activityDay:id,activity_id,activity_date,session_name,session_start_at,session_end_at',
])->orderByDesc('id');
$user = $request->user();
if (!$user->isSuperAdmin()) {
@ -102,10 +102,11 @@ class ActivityRegistrationController extends Controller
return response()->streamDownload(function () use ($rows) {
$out = fopen('php://output', 'w');
fprintf($out, chr(0xEF) . chr(0xBB) . chr(0xBF));
fputcsv($out, ['ID', '活动', '场馆', '报名人', '手机号', '预约类型', '预约票数', '预约入馆日期', '状态', '预约时间', '核销时间', '二维码Token']);
fputcsv($out, ['ID', '活动', '场馆', '报名人', '手机号', '预约类型', '预约票数', '场次名称', '预约时间', '状态', '下单时间', '核销时间', '二维码Token']);
foreach ($rows as $row) {
$entryDate = $row->activityDay?->activity_date;
$entryDateStr = $entryDate ? Carbon::parse($entryDate)->timezone('Asia/Shanghai')->format('Y-m-d') : '';
$ad = $row->activityDay;
$sessionName = $ad ? (string) ($ad->session_name ?? '') : '';
$timeStr = $ad ? $ad->formatSessionTimeRangeZh() : '';
fputcsv($out, [
$row->id,
$row->activity?->title ?? '',
@ -114,7 +115,8 @@ class ActivityRegistrationController extends Controller
$row->visitor_phone ?? '',
self::bookingTypeLabel($row->booking_type, $row->ticket_count),
(string) ($row->ticket_count ?? 1),
$entryDateStr,
$sessionName,
$timeStr,
self::statusLabel($row->status),
self::formatShanghai($row->created_at),
self::formatShanghai($row->verified_at),

@ -6,10 +6,13 @@ use App\Http\Controllers\Controller;
use App\Models\Activity;
use App\Models\ActivityDay;
use App\Models\DictItem;
use App\Models\Reservation;
use App\Models\StudyTour;
use App\Models\Venue;
use App\Models\WechatUser;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Laravel\Sanctum\PersonalAccessToken;
class H5ContentController extends Controller
{
@ -60,7 +63,7 @@ class H5ContentController extends Controller
return response()->json($rows);
}
public function activityDetail(int $id): JsonResponse
public function activityDetail(Request $request, int $id): JsonResponse
{
$a = Activity::query()
->with([
@ -74,6 +77,33 @@ class H5ContentController extends Controller
fn (ActivityDay $d) => $d->isCurrentlyBookable()
);
$wechatUser = $this->authWechatUser($request);
$myReservedDayIds = [];
if ($wechatUser) {
$myReservedDayIds = Reservation::query()
->where('activity_id', $a->id)
->where('status', '!=', 'cancelled')
->where(function ($sub) use ($wechatUser) {
$sub->where('wechat_user_id', $wechatUser->id);
$p = trim((string) ($wechatUser->phone ?? ''));
if ($p !== '' && preg_match('/^1\d{10}$/', $p)) {
$sub->orWhere('visitor_phone', $p);
}
})
->pluck('activity_day_id')
->map(fn ($rowId) => (int) $rowId)
->all();
}
$mySet = array_fill_keys($myReservedDayIds, true);
$bookingDays = $a->activityDays
->values()
->map(function (ActivityDay $d) use ($mySet) {
$already = isset($mySet[$d->id]);
return $d->toH5BookingDayArray($already);
});
return response()->json([
'id' => $a->id,
'title' => $a->title,
@ -95,6 +125,7 @@ class H5ContentController extends Controller
'reservation_notice' => $a->reservation_notice,
'is_bookable' => $isBookable,
'venue_type_color' => $this->resolveVenueTypeColor($a->venue?->venue_type, $a->venue?->venue_types),
'booking_days' => $bookingDays,
]);
}
@ -339,4 +370,18 @@ class H5ContentController extends Controller
'ticket_type' => DictItem::activeOptions('ticket_type'),
]);
}
private function authWechatUser(Request $request): ?WechatUser
{
$token = $request->bearerToken();
if (!$token) {
return null;
}
$accessToken = PersonalAccessToken::findToken($token);
if (!$accessToken || ! ($accessToken->tokenable instanceof WechatUser)) {
return null;
}
return $accessToken->tokenable;
}
}

@ -65,40 +65,11 @@ class H5ReservationController extends Controller
$mySet = array_fill_keys($myReservedDayIds, true);
$days = $activity->activityDays
->sortBy('activity_date')
->values()
->map(function (ActivityDay $d) use ($mySet) {
$available = max(0, (int) $d->day_quota - (int) $d->booked_count);
$closesAt = $d->closes_at ?: $d->opens_at->copy()->endOfDay();
$now = now();
$isOpenWindow = $d->opens_at->lte($now) && $closesAt->gte($now);
$isBookable = $d->isCurrentlyBookable();
$unavailableReason = null;
if ($available <= 0) {
$unavailableReason = 'sold_out';
} elseif ($d->opens_at->gt($now)) {
$unavailableReason = 'not_started';
} elseif ($closesAt->lt($now)) {
$unavailableReason = 'closed';
}
$already = isset($mySet[$d->id]);
if ($already) {
$isBookable = false;
$unavailableReason = 'already_reserved';
}
return [
'id' => $d->id,
'activity_date' => $d->activity_date->format('Y-m-d'),
'opens_at' => $d->opens_at->format('Y-m-d H:i:s'),
'closes_at' => $closesAt->format('Y-m-d H:i:s'),
'day_quota' => (int) $d->day_quota,
'booked_count' => (int) $d->booked_count,
'available_count' => $available,
'is_open' => $isOpenWindow,
'is_bookable' => $isBookable,
'unavailable_reason' => $unavailableReason,
'already_reserved' => $already,
];
return $d->toH5BookingDayArray($already);
});
return response()->json([
@ -156,15 +127,21 @@ class H5ReservationController extends Controller
->where('activity_id', $activity->id)
->first();
if (!$day) {
throw ValidationException::withMessages(['activity_day_id' => ['预约日期不存在或不属于该活动']]);
}
if ($day->opens_at->gt(now())) {
$closeText = ($day->closes_at ?: $day->opens_at->copy()->endOfDay())->format('Y-m-d H:i');
throw ValidationException::withMessages(['activity_day_id' => ['该日期尚未开放预约,可预约时段:'.$day->opens_at->format('Y-m-d H:i').' ~ '.$closeText]]);
throw ValidationException::withMessages(['activity_day_id' => ['预约场次不存在或不属于该活动']]);
}
$closesAt = $day->closes_at ?: $day->opens_at->copy()->endOfDay();
if ($closesAt->lt(now())) {
throw ValidationException::withMessages(['activity_day_id' => ['该日期预约已截止,可预约时段:'.$day->opens_at->format('Y-m-d H:i').' ~ '.$closesAt->format('Y-m-d H:i')]]);
if ($day->isSessionMode()) {
if (now()->gt($day->booking_deadline_at)) {
throw ValidationException::withMessages(['activity_day_id' => ['该场次预约已截止']]);
}
} else {
if ($day->opens_at->gt(now())) {
$closeText = ($day->closes_at ?: $day->opens_at->copy()->endOfDay())->format('Y-m-d H:i');
throw ValidationException::withMessages(['activity_day_id' => ['该日期尚未开放预约,可预约时段:'.$day->opens_at->format('Y-m-d H:i').' ~ '.$closeText]]);
}
$closesAt = $day->closes_at ?: $day->opens_at->copy()->endOfDay();
if ($closesAt->lt(now())) {
throw ValidationException::withMessages(['activity_day_id' => ['该日期预约已截止,可预约时段:'.$day->opens_at->format('Y-m-d H:i').' ~ '.$closesAt->format('Y-m-d H:i')]]);
}
}
[$bookingType, $peopleCount] = $this->resolveBookingTypeAndPeopleCount($mode, $data, $minPeople, $maxPeople);
@ -192,7 +169,7 @@ class H5ReservationController extends Controller
$day->refresh();
$available = (int) $day->day_quota - (int) $day->booked_count;
if ($available < $peopleCount) {
throw ValidationException::withMessages(['activity_day_id' => ['该日期余票不足']]);
throw ValidationException::withMessages(['activity_day_id' => ['该场次余票不足']]);
}
// 去重:同一活动、同一活动日,同一用户只能有一单未取消预约(取消后可再约)
@ -210,7 +187,7 @@ class H5ReservationController extends Controller
->exists();
if ($dup) {
throw ValidationException::withMessages([
'activity_day_id' => ['您已预约过该日期,无需重复预约'],
'activity_day_id' => ['您已预约过该场次,无需重复预约'],
]);
}
@ -239,7 +216,7 @@ class H5ReservationController extends Controller
$reservation->load([
'activity:id,title,summary,cover_image,address,start_at,end_at,tags,lat,lng',
'venue:id,name,address',
'activityDay:id,activity_id,activity_date',
'activityDay:id,activity_id,activity_date,session_name,session_start_at,session_end_at,booking_deadline_at',
]);
return response()->json([
@ -258,7 +235,7 @@ class H5ReservationController extends Controller
->with([
'activity:id,title,summary,cover_image,address,start_at,end_at,tags,lat,lng',
'venue:id,name,address',
'activityDay:id,activity_id,activity_date',
'activityDay:id,activity_id,activity_date,session_name,session_start_at,session_end_at,booking_deadline_at',
])
->orderByDesc('id')
->limit(200);
@ -285,7 +262,7 @@ class H5ReservationController extends Controller
->with([
'activity:id,title,summary,cover_image,address,start_at,end_at,tags,lat,lng',
'venue:id,name,address',
'activityDay:id,activity_id,activity_date',
'activityDay:id,activity_id,activity_date,session_name,session_start_at,session_end_at,booking_deadline_at',
])
->where('id', $reservationId);
@ -456,6 +433,10 @@ class H5ReservationController extends Controller
'activity_day' => $day && $day->activity_date ? [
'id' => $day->id,
'activity_date' => $day->activity_date->format('Y-m-d'),
'session_name' => (string) ($day->session_name ?? ''),
'session_start_at' => $day->session_start_at?->format('Y-m-d H:i:s'),
'session_end_at' => $day->session_end_at?->format('Y-m-d H:i:s'),
'time_range_text' => $day->formatSessionTimeRangeZh(),
] : null,
'venue' => $venue ? [
'id' => $venue->id,

@ -47,7 +47,7 @@ class ReservationVerifyController extends Controller
$reservation = Reservation::with([
'venue:id,name,reservation_notice',
'activity:id,title',
'activityDay:id,activity_id,activity_date',
'activityDay:id,activity_id,activity_date,session_name,session_start_at,session_end_at',
])->where('qr_token', $data['qr_token'])->first();
if (!$reservation) {
@ -87,7 +87,7 @@ class ReservationVerifyController extends Controller
$query = Reservation::with([
'venue:id,name,reservation_notice',
'activity:id,title',
'activityDay:id,activity_id,activity_date',
'activityDay:id,activity_id,activity_date,session_name,session_start_at,session_end_at',
])
// 核销端列表:待核销在前,已过期/已取消置后,同状态内按 id 倒序
->orderByRaw("CASE status WHEN 'pending' THEN 0 WHEN 'verified' THEN 1 WHEN 'expired' THEN 2 WHEN 'cancelled' THEN 3 ELSE 4 END")
@ -200,7 +200,7 @@ class ReservationVerifyController extends Controller
'reservation' => $reservation->fresh()->load([
'venue:id,name,reservation_notice',
'activity:id,title',
'activityDay:id,activity_id,activity_date',
'activityDay:id,activity_id,activity_date,session_name,session_start_at,session_end_at',
'verifier:id,name,username',
]),
]);

@ -84,7 +84,9 @@ class Activity extends Model
public function activityDays(): HasMany
{
return $this->hasMany(ActivityDay::class)->orderBy('activity_date');
return $this->hasMany(ActivityDay::class)
->orderBy('session_start_at')
->orderBy('id');
}
/**

@ -2,6 +2,7 @@
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -9,36 +10,184 @@ class ActivityDay extends Model
{
protected $fillable = [
'activity_id',
'session_name',
'activity_date',
'day_quota',
'booked_count',
'opens_at',
'closes_at',
'session_start_at',
'session_end_at',
'booking_deadline_at',
];
protected $casts = [
'activity_date' => 'date',
'opens_at' => 'datetime',
'closes_at' => 'datetime',
'session_start_at' => 'datetime',
'session_end_at' => 'datetime',
'booking_deadline_at' => 'datetime',
'day_quota' => 'integer',
'booked_count' => 'integer',
];
protected static function booted(): void
{
static::saving(function (ActivityDay $day) {
if ($day->session_start_at) {
$tz = (string) config('app.timezone');
$day->activity_date = $day->session_start_at->copy()->timezone($tz)->format('Y-m-d');
}
});
}
public function activity(): BelongsTo
{
return $this->belongsTo(Activity::class);
}
/**
* 当前时刻是否处于预约开放窗口且仍有余量(与 H5 预约接口判定一致)。
* 场次时间段展示同日则「Y年m月d日 H:i-H:i」。
*/
public function formatSessionTimeRangeZh(): string
{
if (!$this->session_start_at || !$this->session_end_at) {
return $this->activity_date?->format('Y年m月d日') ?? '';
}
$tz = (string) config('app.timezone');
$s = $this->session_start_at->copy()->timezone($tz);
$e = $this->session_end_at->copy()->timezone($tz);
if ($s->toDateString() === $e->toDateString()) {
return $s->format('Y年m月d日 H:i') . '-' . $e->format('H:i');
}
return $s->format('Y年m月d日 H:i') . ' ~ ' . $e->format('Y年m月d日 H:i');
}
public function isSessionMode(): bool
{
return $this->session_start_at !== null
&& $this->session_end_at !== null
&& $this->booking_deadline_at !== null;
}
/**
* 当前时刻是否可预约:截止前、有余量、未重复预约等由业务层与 H5 数组字段共同约束。
* 这里仅表示「未过预约截止且有余量」legacy 为原 opens/closes 窗口逻辑)。
*/
public function isCurrentlyBookable(): bool
{
$available = max(0, (int) $this->day_quota - (int) $this->booked_count);
$closesAt = $this->closes_at ?: $this->opens_at->copy()->endOfDay();
if ($available <= 0) {
return false;
}
if ($this->isSessionMode()) {
return now()->lte($this->booking_deadline_at);
}
$closesAt = $this->closes_at ?: $this->opens_at?->copy()->endOfDay();
$now = now();
if (!$this->opens_at || !$closesAt) {
return false;
}
$isOpenWindow = $this->opens_at->lte($now) && $closesAt->gte($now);
return $isOpenWindow && $available > 0;
return $isOpenWindow;
}
/**
* H5 预约页/活动详情:单场次展示与可约态。
*
* @return array<string, mixed>
*/
public function toH5BookingDayArray(bool $alreadyReserved = false): array
{
$available = max(0, (int) $this->day_quota - (int) $this->booked_count);
$now = now();
if ($this->isSessionMode()) {
$deadline = $this->booking_deadline_at;
$unavailableReason = null;
$isBookable = false;
if ($alreadyReserved) {
$unavailableReason = 'already_reserved';
$statusText = '已约';
$statusKind = 'reserved';
} elseif ($now->gt($deadline)) {
$unavailableReason = 'deadline_passed';
$statusText = '已约' . (int) $this->booked_count . '人';
$statusKind = 'booked_info';
} elseif ($available <= 0) {
$unavailableReason = 'sold_out';
$statusText = '预约已满';
$statusKind = 'full';
} else {
$isBookable = true;
$unavailableReason = null;
$statusText = '已约' . (int) $this->booked_count . '人';
$statusKind = 'open';
}
$timeDisplay = $this->formatSessionTimeRangeZh();
} else {
// legacy无场次字段时沿用原预约窗口
$timeDisplay = $this->activity_date?->format('Y年m月d日') ?? '';
if ($alreadyReserved) {
$unavailableReason = 'already_reserved';
$statusText = '已约';
$statusKind = 'reserved';
} elseif ($available <= 0) {
$unavailableReason = 'sold_out';
$statusText = '预约已满';
$statusKind = 'full';
} else {
$closesAt = $this->closes_at ?: $this->opens_at?->copy()->endOfDay();
if ($this->opens_at && $this->opens_at->gt($now)) {
$unavailableReason = 'not_started';
$statusText = '未开放';
$statusKind = 'closed';
} elseif ($closesAt && $closesAt->lt($now)) {
$unavailableReason = 'closed';
$statusText = '不可预约';
$statusKind = 'closed';
} else {
$unavailableReason = null;
$statusText = '已约' . (int) $this->booked_count . '人';
$statusKind = 'open';
}
}
$isBookable = $this->isCurrentlyBookable() && !$alreadyReserved;
}
if ($alreadyReserved) {
$isBookable = false;
}
$closesAtLegacy = $this->closes_at ?: $this->opens_at?->copy()->endOfDay();
$isOpenWindow = $this->opens_at && $closesAtLegacy
? ($this->opens_at->lte($now) && $closesAtLegacy->gte($now))
: false;
return [
'id' => $this->id,
'session_name' => (string) ($this->session_name ?? ''),
'session_start_at' => $this->session_start_at?->format('Y-m-d H:i:s'),
'session_end_at' => $this->session_end_at?->format('Y-m-d H:i:s'),
'booking_deadline_at' => $this->booking_deadline_at?->format('Y-m-d H:i:s'),
'time_display' => $timeDisplay,
'activity_date' => $this->activity_date?->format('Y-m-d'),
'opens_at' => $this->opens_at?->format('Y-m-d H:i:s'),
'closes_at' => $closesAtLegacy?->format('Y-m-d H:i:s'),
'day_quota' => (int) $this->day_quota,
'booked_count' => (int) $this->booked_count,
'available_count' => $available,
'is_open' => $isOpenWindow,
'is_bookable' => $isBookable,
'unavailable_reason' => $unavailableReason,
'status_text' => $statusText,
'status_kind' => $statusKind,
'already_reserved' => $alreadyReserved,
];
}
}

@ -0,0 +1,56 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
/**
* 活动日扩展为「场次」:可同日多场;原 (activity_id, activity_date) 唯一约束与多场冲突,故删除。
*/
return new class extends Migration
{
public function up(): void
{
Schema::table('activity_days', function (Blueprint $table) {
$table->string('session_name', 200)->default('')->after('activity_id');
$table->dateTime('session_start_at')->nullable()->after('closes_at');
$table->dateTime('session_end_at')->nullable();
$table->dateTime('booking_deadline_at')->nullable();
});
$rows = DB::table('activity_days')->orderBy('id')->get();
foreach ($rows as $row) {
$actDate = (string) $row->activity_date;
$open = $row->opens_at ? Carbon::parse($row->opens_at) : Carbon::parse($actDate)->setTime(9, 0, 0);
$close = $row->closes_at ? Carbon::parse($row->closes_at) : $open->copy()->endOfDay();
$sessionStart = Carbon::parse($actDate . ' ' . $open->format('H:i:s'));
$sessionEnd = Carbon::parse($actDate)->setTime(17, 0, 0);
if ($sessionEnd->lte($sessionStart)) {
$sessionEnd = $sessionStart->copy()->addHours(8);
}
DB::table('activity_days')->where('id', $row->id)->update([
'session_name' => '场次 '.$actDate,
'session_start_at' => $sessionStart,
'session_end_at' => $sessionEnd,
'booking_deadline_at' => $close,
]);
}
Schema::table('activity_days', function (Blueprint $table) {
$table->dropUnique('activity_days_activity_id_activity_date_unique');
});
}
public function down(): void
{
Schema::table('activity_days', function (Blueprint $table) {
$table->unique(['activity_id', 'activity_date']);
});
Schema::table('activity_days', function (Blueprint $table) {
$table->dropColumn(['session_name', 'session_start_at', 'session_end_at', 'booking_deadline_at']);
});
}
};

@ -1 +0,0 @@
.activity-address-coord-row[data-v-6c037a0d]{flex-wrap:wrap;align-items:center;gap:12px;width:100%;display:flex}.activity-address-coord-row__address[data-v-6c037a0d]{flex:45%;min-width:320px;max-width:100%}.activity-address-coord-row__lng[data-v-6c037a0d],.activity-address-coord-row__lat[data-v-6c037a0d]{flex:180px;width:200px;min-width:180px}.activity-address-coord-row__map[data-v-6c037a0d]{flex-shrink:0}.activity-cover-carousel-wrap[data-v-6c037a0d]{flex-wrap:wrap;align-items:flex-start;gap:20px;width:100%;display:flex}.activity-cover-carousel-row__col[data-v-6c037a0d]{flex:320px;min-width:min(100%,320px)}.activity-cover-carousel-row__sub[data-v-6c037a0d]{color:var(--color-text-1);margin-bottom:8px;font-weight:500}.activity-cover-thumb[data-v-6c037a0d]{object-fit:cover;cursor:zoom-in;border:1px solid #e5e6eb;border-radius:4px;width:120px;height:70px}.activity-gallery-grid[data-v-6c037a0d]{flex-wrap:wrap;align-items:flex-start;gap:12px;width:100%;display:flex}.activity-gallery-item[data-v-6c037a0d]{flex-direction:column;align-items:flex-start;gap:8px;display:flex}.activity-gallery-thumb[data-v-6c037a0d]{object-fit:cover;cursor:zoom-in;border:1px solid #e5e6eb;border-radius:4px;width:120px;height:70px}.activity-gallery-thumb--video[data-v-6c037a0d]{display:block}

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
.activity-address-coord-row[data-v-e9e0d75c]{flex-wrap:wrap;align-items:center;gap:12px;width:100%;display:flex}.activity-address-coord-row__address[data-v-e9e0d75c]{flex:45%;min-width:320px;max-width:100%}.activity-address-coord-row__lng[data-v-e9e0d75c],.activity-address-coord-row__lat[data-v-e9e0d75c]{flex:180px;width:200px;min-width:180px}.activity-address-coord-row__map[data-v-e9e0d75c]{flex-shrink:0}.activity-cover-carousel-wrap[data-v-e9e0d75c]{flex-wrap:wrap;align-items:flex-start;gap:20px;width:100%;display:flex}.activity-cover-carousel-row__col[data-v-e9e0d75c]{flex:320px;min-width:min(100%,320px)}.activity-cover-carousel-row__sub[data-v-e9e0d75c]{color:var(--color-text-1);margin-bottom:8px;font-weight:500}.activity-cover-thumb[data-v-e9e0d75c]{object-fit:cover;cursor:zoom-in;border:1px solid #e5e6eb;border-radius:4px;width:120px;height:70px}.activity-gallery-grid[data-v-e9e0d75c]{flex-wrap:wrap;align-items:flex-start;gap:12px;width:100%;display:flex}.activity-gallery-item[data-v-e9e0d75c]{flex-direction:column;align-items:flex-start;gap:8px;display:flex}.activity-gallery-thumb[data-v-e9e0d75c]{object-fit:cover;cursor:zoom-in;border:1px solid #e5e6eb;border-radius:4px;width:120px;height:70px}.activity-gallery-thumb--video[data-v-e9e0d75c]{display:block}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
import{n as e}from"./axios-CiYFffbI.js";import{I as t,N as n,V as r,Y as i,_ as a,d as o,it as s,kt as c,nt as l,ut as u,v as d,y as f}from"./runtime-core.esm-bundler-CnFWH3R5.js";import{n as p}from"./index-CnpIIn-A.js";import{t as m}from"./datetime-3T8f3S0H.js";import{t as h}from"./listTable-DKAruyoN.js";var g=f({__name:`AuditLogs`,setup(f){let g=s(!1),_=s([]),v=l({current:1,pageSize:20,total:0}),y=l({keyword:``,method:`all`,status_code:void 0,dateRange:[]});async function b(){g.value=!0;try{let{data:e}=await p.get(`/audit-logs`,{params:{keyword:y.keyword||void 0,method:y.method,status_code:y.status_code||void 0,start_date:y.dateRange?.[0]||void 0,end_date:y.dateRange?.[1]||void 0,page:v.current,page_size:v.pageSize}});_.value=e.data,v.total=e.total}catch(t){e.error(t?.response?.data?.message??`加载操作日志失败`)}finally{g.value=!1}}function x(){v.current=1,b()}function S(e){v.current=e,b()}function C(e){return e===`super_admin`?`超级管理员`:e===`venue_admin`?`场馆管理员`:`-`}return n(b),(e,n)=>{let s=r(`a-input`),l=r(`a-option`),f=r(`a-select`),p=r(`a-input-number`),w=r(`a-range-picker`),T=r(`a-button`),E=r(`a-space`),D=r(`a-table-column`),O=r(`a-typography-paragraph`),k=r(`a-table`),A=r(`a-card`);return t(),o(A,{title:`用户与权限 / 操作日志`},{default:i(()=>[d(E,{wrap:``,size:12,style:{"margin-bottom":`12px`}},{default:i(()=>[d(s,{modelValue:y.keyword,"onUpdate:modelValue":n[0]||=e=>y.keyword=e,placeholder:`操作人/路径/动作`,"allow-clear":``,style:{width:`240px`}},null,8,[`modelValue`]),d(f,{modelValue:y.method,"onUpdate:modelValue":n[1]||=e=>y.method=e,style:{width:`120px`}},{default:i(()=>[d(l,{value:`all`},{default:i(()=>[...n[4]||=[a(`全部方法`,-1)]]),_:1}),d(l,{value:`POST`},{default:i(()=>[...n[5]||=[a(`POST`,-1)]]),_:1}),d(l,{value:`PUT`},{default:i(()=>[...n[6]||=[a(`PUT`,-1)]]),_:1}),d(l,{value:`PATCH`},{default:i(()=>[...n[7]||=[a(`PATCH`,-1)]]),_:1}),d(l,{value:`DELETE`},{default:i(()=>[...n[8]||=[a(`DELETE`,-1)]]),_:1})]),_:1},8,[`modelValue`]),d(p,{modelValue:y.status_code,"onUpdate:modelValue":n[2]||=e=>y.status_code=e,min:100,max:599,placeholder:`状态码`,style:{width:`120px`}},null,8,[`modelValue`]),d(w,{modelValue:y.dateRange,"onUpdate:modelValue":n[3]||=e=>y.dateRange=e,style:{width:`260px`}},null,8,[`modelValue`]),d(T,{type:`primary`,onClick:x},{default:i(()=>[...n[9]||=[a(`查询`,-1)]]),_:1}),d(T,{onClick:b},{default:i(()=>[...n[10]||=[a(`刷新`,-1)]]),_:1})]),_:1}),d(k,{class:`list-data-table`,scroll:{x:u(h)},data:_.value,loading:g.value,"row-key":`id`,pagination:{current:v.current,pageSize:v.pageSize,total:v.total,showTotal:!0},onPageChange:S},{columns:i(()=>[d(D,{title:`ID`,"data-index":`id`,width:88}),d(D,{title:`操作人`,"data-index":`username`,width:140,ellipsis:!0,tooltip:!0}),d(D,{title:`角色`,width:120},{cell:i(({record:e})=>[a(c(C(e.role)),1)]),_:1}),d(D,{title:`方法`,"data-index":`method`,width:90}),d(D,{title:`路径`,"data-index":`path`,width:260,ellipsis:!0,tooltip:!0}),d(D,{title:`动作`,"data-index":`action`,width:220,ellipsis:!0,tooltip:!0}),d(D,{title:`状态码`,"data-index":`status_code`,width:100}),d(D,{title:`IP`,"data-index":`ip`,width:140,ellipsis:!0,tooltip:!0}),d(D,{title:`时间`,width:190},{cell:i(({record:e})=>[a(c(u(m)(e.created_at)),1)]),_:1}),d(D,{title:`请求参数`,"min-width":260},{cell:i(({record:e})=>[d(O,{ellipsis:{rows:2}},{default:i(()=>[a(c(e.request_payload?JSON.stringify(e.request_payload):`-`),1)]),_:2},1024)]),_:1})]),_:1},8,[`scroll`,`data`,`loading`,`pagination`])]),_:1})}}});export{g as default};
import{n as e}from"./axios-CiYFffbI.js";import{I as t,N as n,V as r,Y as i,_ as a,d as o,it as s,kt as c,nt as l,ut as u,v as d,y as f}from"./runtime-core.esm-bundler-CnFWH3R5.js";import{n as p}from"./index-CxYyK2oU.js";import{t as m}from"./datetime-3T8f3S0H.js";import{t as h}from"./listTable-DKAruyoN.js";var g=f({__name:`AuditLogs`,setup(f){let g=s(!1),_=s([]),v=l({current:1,pageSize:20,total:0}),y=l({keyword:``,method:`all`,status_code:void 0,dateRange:[]});async function b(){g.value=!0;try{let{data:e}=await p.get(`/audit-logs`,{params:{keyword:y.keyword||void 0,method:y.method,status_code:y.status_code||void 0,start_date:y.dateRange?.[0]||void 0,end_date:y.dateRange?.[1]||void 0,page:v.current,page_size:v.pageSize}});_.value=e.data,v.total=e.total}catch(t){e.error(t?.response?.data?.message??`加载操作日志失败`)}finally{g.value=!1}}function x(){v.current=1,b()}function S(e){v.current=e,b()}function C(e){return e===`super_admin`?`超级管理员`:e===`venue_admin`?`场馆管理员`:`-`}return n(b),(e,n)=>{let s=r(`a-input`),l=r(`a-option`),f=r(`a-select`),p=r(`a-input-number`),w=r(`a-range-picker`),T=r(`a-button`),E=r(`a-space`),D=r(`a-table-column`),O=r(`a-typography-paragraph`),k=r(`a-table`),A=r(`a-card`);return t(),o(A,{title:`用户与权限 / 操作日志`},{default:i(()=>[d(E,{wrap:``,size:12,style:{"margin-bottom":`12px`}},{default:i(()=>[d(s,{modelValue:y.keyword,"onUpdate:modelValue":n[0]||=e=>y.keyword=e,placeholder:`操作人/路径/动作`,"allow-clear":``,style:{width:`240px`}},null,8,[`modelValue`]),d(f,{modelValue:y.method,"onUpdate:modelValue":n[1]||=e=>y.method=e,style:{width:`120px`}},{default:i(()=>[d(l,{value:`all`},{default:i(()=>[...n[4]||=[a(`全部方法`,-1)]]),_:1}),d(l,{value:`POST`},{default:i(()=>[...n[5]||=[a(`POST`,-1)]]),_:1}),d(l,{value:`PUT`},{default:i(()=>[...n[6]||=[a(`PUT`,-1)]]),_:1}),d(l,{value:`PATCH`},{default:i(()=>[...n[7]||=[a(`PATCH`,-1)]]),_:1}),d(l,{value:`DELETE`},{default:i(()=>[...n[8]||=[a(`DELETE`,-1)]]),_:1})]),_:1},8,[`modelValue`]),d(p,{modelValue:y.status_code,"onUpdate:modelValue":n[2]||=e=>y.status_code=e,min:100,max:599,placeholder:`状态码`,style:{width:`120px`}},null,8,[`modelValue`]),d(w,{modelValue:y.dateRange,"onUpdate:modelValue":n[3]||=e=>y.dateRange=e,style:{width:`260px`}},null,8,[`modelValue`]),d(T,{type:`primary`,onClick:x},{default:i(()=>[...n[9]||=[a(`查询`,-1)]]),_:1}),d(T,{onClick:b},{default:i(()=>[...n[10]||=[a(`刷新`,-1)]]),_:1})]),_:1}),d(k,{class:`list-data-table`,scroll:{x:u(h)},data:_.value,loading:g.value,"row-key":`id`,pagination:{current:v.current,pageSize:v.pageSize,total:v.total,showTotal:!0},onPageChange:S},{columns:i(()=>[d(D,{title:`ID`,"data-index":`id`,width:88}),d(D,{title:`操作人`,"data-index":`username`,width:140,ellipsis:!0,tooltip:!0}),d(D,{title:`角色`,width:120},{cell:i(({record:e})=>[a(c(C(e.role)),1)]),_:1}),d(D,{title:`方法`,"data-index":`method`,width:90}),d(D,{title:`路径`,"data-index":`path`,width:260,ellipsis:!0,tooltip:!0}),d(D,{title:`动作`,"data-index":`action`,width:220,ellipsis:!0,tooltip:!0}),d(D,{title:`状态码`,"data-index":`status_code`,width:100}),d(D,{title:`IP`,"data-index":`ip`,width:140,ellipsis:!0,tooltip:!0}),d(D,{title:`时间`,width:190},{cell:i(({record:e})=>[a(c(u(m)(e.created_at)),1)]),_:1}),d(D,{title:`请求参数`,"min-width":260},{cell:i(({record:e})=>[d(O,{ellipsis:{rows:2}},{default:i(()=>[a(c(e.request_payload?JSON.stringify(e.request_payload):`-`),1)]),_:2},1024)]),_:1})]),_:1},8,[`scroll`,`data`,`loading`,`pagination`])]),_:1})}}});export{g as default};

@ -1 +1 @@
import{n as e}from"./axios-CiYFffbI.js";import{I as t,V as n,Y as r,_ as i,it as a,nt as o,p as s,v as c,y as l}from"./runtime-core.esm-bundler-CnFWH3R5.js";import{i as u,n as d,t as f}from"./index-CnpIIn-A.js";var p={style:{height:`100vh`,display:`grid`,"place-items":`center`,background:`var(--color-fill-2)`}},m=l({__name:`Login`,setup(l){let m=u(),h=a(!1),g=o({username:`admin`,password:`admin123456`});async function _(){h.value=!0;try{let{data:t}=await d.post(`/auth/login`,g);localStorage.setItem(f,t.token),e.success(`登录成功`),m.replace(`/dashboard`)}catch(t){e.error(t?.response?.data?.message??`登录失败`)}finally{h.value=!1}}return(e,a)=>{let o=n(`a-input`),l=n(`a-form-item`),u=n(`a-input-password`),d=n(`a-button`),f=n(`a-form`),m=n(`a-card`);return t(),s(`div`,p,[c(m,{title:`苏州市科普场馆地图管理后台登录`,style:{width:`380px`}},{default:r(()=>[c(f,{model:g,layout:`vertical`,onSubmitSuccess:_},{default:r(()=>[c(l,{field:`username`,label:`用户名`},{default:r(()=>[c(o,{modelValue:g.username,"onUpdate:modelValue":a[0]||=e=>g.username=e,placeholder:`请输入用户名`},null,8,[`modelValue`])]),_:1}),c(l,{field:`password`,label:`密码`},{default:r(()=>[c(u,{modelValue:g.password,"onUpdate:modelValue":a[1]||=e=>g.password=e,placeholder:`请输入密码`},null,8,[`modelValue`])]),_:1}),c(d,{type:`primary`,long:``,loading:h.value,onClick:_},{default:r(()=>[...a[2]||=[i(`登录`,-1)]]),_:1},8,[`loading`])]),_:1},8,[`model`])]),_:1})])}}});export{m as default};
import{n as e}from"./axios-CiYFffbI.js";import{I as t,V as n,Y as r,_ as i,it as a,nt as o,p as s,v as c,y as l}from"./runtime-core.esm-bundler-CnFWH3R5.js";import{i as u,n as d,t as f}from"./index-CxYyK2oU.js";var p={style:{height:`100vh`,display:`grid`,"place-items":`center`,background:`var(--color-fill-2)`}},m=l({__name:`Login`,setup(l){let m=u(),h=a(!1),g=o({username:`admin`,password:`admin123456`});async function _(){h.value=!0;try{let{data:t}=await d.post(`/auth/login`,g);localStorage.setItem(f,t.token),e.success(`登录成功`),m.replace(`/dashboard`)}catch(t){e.error(t?.response?.data?.message??`登录失败`)}finally{h.value=!1}}return(e,a)=>{let o=n(`a-input`),l=n(`a-form-item`),u=n(`a-input-password`),d=n(`a-button`),f=n(`a-form`),m=n(`a-card`);return t(),s(`div`,p,[c(m,{title:`苏州市科普场馆地图管理后台登录`,style:{width:`380px`}},{default:r(()=>[c(f,{model:g,layout:`vertical`,onSubmitSuccess:_},{default:r(()=>[c(l,{field:`username`,label:`用户名`},{default:r(()=>[c(o,{modelValue:g.username,"onUpdate:modelValue":a[0]||=e=>g.username=e,placeholder:`请输入用户名`},null,8,[`modelValue`])]),_:1}),c(l,{field:`password`,label:`密码`},{default:r(()=>[c(u,{modelValue:g.password,"onUpdate:modelValue":a[1]||=e=>g.password=e,placeholder:`请输入密码`},null,8,[`modelValue`])]),_:1}),c(d,{type:`primary`,long:``,loading:h.value,onClick:_},{default:r(()=>[...a[2]||=[i(`登录`,-1)]]),_:1},8,[`loading`])]),_:1},8,[`model`])]),_:1})])}}});export{m as default};

@ -1 +1 @@
import{I as e,V as t,Y as n,_ as r,d as i,v as a}from"./runtime-core.esm-bundler-CnFWH3R5.js";import{o}from"./index-CnpIIn-A.js";var s={};function c(o,s){let c=t(`a-alert`),l=t(`a-descriptions-item`),u=t(`a-descriptions`),d=t(`a-card`);return e(),i(d,{title:`系统设置 / 地图与第三方配置`},{default:n(()=>[a(c,{type:`info`,style:{"margin-bottom":`12px`}},{default:n(()=>[...s[0]||=[r(` 当前后台场馆地图选点已使用腾讯地图,坐标统一为 GCJ-02火星坐标系`,-1)]]),_:1}),a(u,{column:1,bordered:``},{default:n(()=>[a(l,{label:`前端地图Key`},{default:n(()=>[...s[1]||=[r(" 在 `code/szkp-map-web/.env` 配置 `VITE_TENCENT_MAP_KEY=你的腾讯地图JS_KEY` ",-1)]]),_:1}),a(l,{label:`地图外链 referer`},{default:n(()=>[...s[2]||=[r(" 在 `code/szkp-map-web/.env` 配置 `VITE_TENCENT_MAP_REFERER=你的应用标识` ",-1)]]),_:1}),a(l,{label:`后端服务Key`},{default:n(()=>[...s[3]||=[r(" 在 `code/szkp-map-service/.env` 配置 `TENCENT_MAP_SERVER_KEY=你的腾讯地图WebService_KEY` ",-1)]]),_:1})]),_:1})]),_:1})}var l=o(s,[[`render`,c]]);export{l as default};
import{I as e,V as t,Y as n,_ as r,d as i,v as a}from"./runtime-core.esm-bundler-CnFWH3R5.js";import{o}from"./index-CxYyK2oU.js";var s={};function c(o,s){let c=t(`a-alert`),l=t(`a-descriptions-item`),u=t(`a-descriptions`),d=t(`a-card`);return e(),i(d,{title:`系统设置 / 地图与第三方配置`},{default:n(()=>[a(c,{type:`info`,style:{"margin-bottom":`12px`}},{default:n(()=>[...s[0]||=[r(` 当前后台场馆地图选点已使用腾讯地图,坐标统一为 GCJ-02火星坐标系`,-1)]]),_:1}),a(u,{column:1,bordered:``},{default:n(()=>[a(l,{label:`前端地图Key`},{default:n(()=>[...s[1]||=[r(" 在 `code/szkp-map-web/.env` 配置 `VITE_TENCENT_MAP_KEY=你的腾讯地图JS_KEY` ",-1)]]),_:1}),a(l,{label:`地图外链 referer`},{default:n(()=>[...s[2]||=[r(" 在 `code/szkp-map-web/.env` 配置 `VITE_TENCENT_MAP_REFERER=你的应用标识` ",-1)]]),_:1}),a(l,{label:`后端服务Key`},{default:n(()=>[...s[3]||=[r(" 在 `code/szkp-map-service/.env` 配置 `TENCENT_MAP_SERVER_KEY=你的腾讯地图WebService_KEY` ",-1)]]),_:1})]),_:1})]),_:1})}var l=o(s,[[`render`,c]]);export{l as default};

File diff suppressed because one or more lines are too long

@ -1 +0,0 @@
.reg-toolbar[data-v-ad6fce8a]{box-sizing:border-box;width:100%;max-width:100%;margin-bottom:12px}.reg-export-bar[data-v-ad6fce8a]{box-sizing:border-box;grid-template-columns:130px minmax(0,1fr) auto;align-items:start;gap:12px;width:100%;margin-top:12px;display:grid}.reg-export-scope[data-v-ad6fce8a]{width:130px}.reg-export-fields[data-v-ad6fce8a]{width:100%;min-width:0}.reg-export-fields[data-v-ad6fce8a] .arco-select-view{max-width:100%}.reg-export-btn[data-v-ad6fce8a]{justify-self:start}@media (width<=720px){.reg-export-bar[data-v-ad6fce8a]{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"scope btn""fields fields"}.reg-export-scope[data-v-ad6fce8a]{grid-area:scope}.reg-export-fields[data-v-ad6fce8a]{grid-area:fields}.reg-export-btn[data-v-ad6fce8a]{grid-area:btn;justify-self:end}}.registrations-table[data-v-ad6fce8a] .arco-table-td .arco-table-cell{white-space:normal;word-break:break-word}.registrations-table[data-v-ad6fce8a] .arco-table-text-ellipsis{white-space:nowrap}

@ -0,0 +1 @@
.reg-toolbar[data-v-232ff18b]{box-sizing:border-box;width:100%;max-width:100%;margin-bottom:12px}.reg-export-bar[data-v-232ff18b]{box-sizing:border-box;grid-template-columns:130px minmax(0,1fr) auto;align-items:start;gap:12px;width:100%;margin-top:12px;display:grid}.reg-export-scope[data-v-232ff18b]{width:130px}.reg-export-fields[data-v-232ff18b]{width:100%;min-width:0}.reg-export-fields[data-v-232ff18b] .arco-select-view{max-width:100%}.reg-export-btn[data-v-232ff18b]{justify-self:start}@media (width<=720px){.reg-export-bar[data-v-232ff18b]{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"scope btn""fields fields"}.reg-export-scope[data-v-232ff18b]{grid-area:scope}.reg-export-fields[data-v-232ff18b]{grid-area:fields}.reg-export-btn[data-v-232ff18b]{grid-area:btn;justify-self:end}}.registrations-table[data-v-232ff18b] .arco-table-td .arco-table-cell{white-space:normal;word-break:break-word}.registrations-table[data-v-232ff18b] .arco-table-text-ellipsis{white-space:nowrap}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
import{n as e}from"./axios-CiYFffbI.js";import{I as t,N as n,V as r,Y as i,_ as a,d as o,f as s,i as c,it as l,kt as u,l as d,p as f,v as p,y as m,z as h}from"./runtime-core.esm-bundler-CnFWH3R5.js";import{n as g}from"./index-CnpIIn-A.js";var _=m({__name:`Roles`,setup(m){let _=l(!1),v=l(!1),y=l(!1),b=l([]),x=l([]),S=l(`super_admin`),C=l([]),w=d(()=>{let e=new Map;b.value.forEach(t=>e.set(t.id,{key:t.id,title:t.name,children:[]}));let t=[];return b.value.forEach(n=>{let r=e.get(n.id);n.parent_id>0&&e.has(n.parent_id)?e.get(n.parent_id).children.push(r):t.push(r)}),t}),T=d(()=>x.value.find(e=>e.role===S.value));async function E(){let{data:e}=await g.get(`/me`);y.value=e?.role===`super_admin`}async function D(){_.value=!0;try{let{data:e}=await g.get(`/role-menu-permissions`);b.value=e.menus||[],x.value=e.roles||[];let t=x.value[0];t&&(S.value=t.role,C.value=[...t.menu_ids||[]])}catch(t){e.error(t?.response?.data?.message??`加载角色菜单权限失败`)}finally{_.value=!1}}function O(e){S.value=e,C.value=[...x.value.find(t=>t.role===e)?.menu_ids||[]]}function k(e){C.value=e.map(e=>Number(e))}async function A(){if(y.value){v.value=!0;try{await g.put(`/role-menu-permissions/${S.value}`,{menu_ids:C.value});let t=x.value.find(e=>e.role===S.value);t&&(t.menu_ids=[...C.value]),e.success(`角色菜单权限保存成功`)}catch(t){e.error(t?.response?.data?.message??`保存失败`)}finally{v.value=!1}}}return n(async()=>{await E(),await D()}),(e,n)=>{let l=r(`a-alert`),d=r(`a-button`),m=r(`a-space`),g=r(`a-card`),b=r(`a-tree`),E=r(`a-spin`);return t(),o(g,{title:`用户与权限 / 角色管理(菜单权限)`},{default:i(()=>[p(l,{style:{"margin-bottom":`12px`}},{default:i(()=>[...n[0]||=[a(` 当前仅控制“每个角色可查看哪些菜单”;接口级细粒度权限后续可继续扩展。 `,-1)]]),_:1}),y.value?s(``,!0):(t(),o(l,{key:0,type:`info`,style:{"margin-bottom":`12px`}},{default:i(()=>[...n[1]||=[a(` 当前为只读模式,仅超级管理员可以修改角色菜单权限。 `,-1)]]),_:1})),p(E,{loading:_.value},{default:i(()=>[p(m,{align:`start`,fill:``},{default:i(()=>[p(g,{title:`角色列表`,size:`small`,style:{width:`220px`}},{default:i(()=>[p(m,{direction:`vertical`,fill:``},{default:i(()=>[(t(!0),f(c,null,h(x.value,e=>(t(),o(d,{key:e.role,type:S.value===e.role?`primary`:`secondary`,long:``,onClick:t=>O(e.role)},{default:i(()=>[a(u(e.label),1)]),_:2},1032,[`type`,`onClick`]))),128))]),_:1})]),_:1}),p(g,{title:`${T.value?.label||``} - 菜单权限`,size:`small`,style:{flex:`1`}},{extra:i(()=>[p(d,{type:`primary`,disabled:!y.value,loading:v.value,onClick:A},{default:i(()=>[...n[2]||=[a(`保存当前角色`,-1)]]),_:1},8,[`disabled`,`loading`])]),default:i(()=>[p(b,{checkable:``,"block-node":``,data:w.value,"checked-keys":C.value,"default-expand-all":!0,onCheck:k},null,8,[`data`,`checked-keys`])]),_:1},8,[`title`])]),_:1})]),_:1},8,[`loading`])]),_:1})}}});export{_ as default};
import{n as e}from"./axios-CiYFffbI.js";import{I as t,N as n,V as r,Y as i,_ as a,d as o,f as s,i as c,it as l,kt as u,l as d,p as f,v as p,y as m,z as h}from"./runtime-core.esm-bundler-CnFWH3R5.js";import{n as g}from"./index-CxYyK2oU.js";var _=m({__name:`Roles`,setup(m){let _=l(!1),v=l(!1),y=l(!1),b=l([]),x=l([]),S=l(`super_admin`),C=l([]),w=d(()=>{let e=new Map;b.value.forEach(t=>e.set(t.id,{key:t.id,title:t.name,children:[]}));let t=[];return b.value.forEach(n=>{let r=e.get(n.id);n.parent_id>0&&e.has(n.parent_id)?e.get(n.parent_id).children.push(r):t.push(r)}),t}),T=d(()=>x.value.find(e=>e.role===S.value));async function E(){let{data:e}=await g.get(`/me`);y.value=e?.role===`super_admin`}async function D(){_.value=!0;try{let{data:e}=await g.get(`/role-menu-permissions`);b.value=e.menus||[],x.value=e.roles||[];let t=x.value[0];t&&(S.value=t.role,C.value=[...t.menu_ids||[]])}catch(t){e.error(t?.response?.data?.message??`加载角色菜单权限失败`)}finally{_.value=!1}}function O(e){S.value=e,C.value=[...x.value.find(t=>t.role===e)?.menu_ids||[]]}function k(e){C.value=e.map(e=>Number(e))}async function A(){if(y.value){v.value=!0;try{await g.put(`/role-menu-permissions/${S.value}`,{menu_ids:C.value});let t=x.value.find(e=>e.role===S.value);t&&(t.menu_ids=[...C.value]),e.success(`角色菜单权限保存成功`)}catch(t){e.error(t?.response?.data?.message??`保存失败`)}finally{v.value=!1}}}return n(async()=>{await E(),await D()}),(e,n)=>{let l=r(`a-alert`),d=r(`a-button`),m=r(`a-space`),g=r(`a-card`),b=r(`a-tree`),E=r(`a-spin`);return t(),o(g,{title:`用户与权限 / 角色管理(菜单权限)`},{default:i(()=>[p(l,{style:{"margin-bottom":`12px`}},{default:i(()=>[...n[0]||=[a(` 当前仅控制“每个角色可查看哪些菜单”;接口级细粒度权限后续可继续扩展。 `,-1)]]),_:1}),y.value?s(``,!0):(t(),o(l,{key:0,type:`info`,style:{"margin-bottom":`12px`}},{default:i(()=>[...n[1]||=[a(` 当前为只读模式,仅超级管理员可以修改角色菜单权限。 `,-1)]]),_:1})),p(E,{loading:_.value},{default:i(()=>[p(m,{align:`start`,fill:``},{default:i(()=>[p(g,{title:`角色列表`,size:`small`,style:{width:`220px`}},{default:i(()=>[p(m,{direction:`vertical`,fill:``},{default:i(()=>[(t(!0),f(c,null,h(x.value,e=>(t(),o(d,{key:e.role,type:S.value===e.role?`primary`:`secondary`,long:``,onClick:t=>O(e.role)},{default:i(()=>[a(u(e.label),1)]),_:2},1032,[`type`,`onClick`]))),128))]),_:1})]),_:1}),p(g,{title:`${T.value?.label||``} - 菜单权限`,size:`small`,style:{flex:`1`}},{extra:i(()=>[p(d,{type:`primary`,disabled:!y.value,loading:v.value,onClick:A},{default:i(()=>[...n[2]||=[a(`保存当前角色`,-1)]]),_:1},8,[`disabled`,`loading`])]),default:i(()=>[p(b,{checkable:``,"block-node":``,data:w.value,"checked-keys":C.value,"default-expand-all":!0,onCheck:k},null,8,[`data`,`checked-keys`])]),_:1},8,[`title`])]),_:1})]),_:1},8,[`loading`])]),_:1})}}});export{_ as default};

@ -0,0 +1 @@
.verify-list-toolbar[data-v-9f06923f]{box-sizing:border-box;width:100%;max-width:100%}

File diff suppressed because one or more lines are too long

@ -1 +0,0 @@
.verify-list-toolbar[data-v-3f89bb59]{box-sizing:border-box;width:100%;max-width:100%}

@ -1 +0,0 @@
import{n as e}from"./axios-CiYFffbI.js";import{I as t,N as n,V as r,Y as i,_ as a,d as o,it as s,kt as c,u as l,ut as u,v as d,y as f}from"./runtime-core.esm-bundler-CnFWH3R5.js";import{n as p,o as m}from"./index-CnpIIn-A.js";import{n as h,t as g}from"./datetime-3T8f3S0H.js";import{t as _}from"./listTable-DKAruyoN.js";import{n as v,t as y}from"./reservationStatus-B4mW5yim.js";var b={class:`verify-list-toolbar`},x=m(f({__name:`Verify`,setup(f){let m=s(!1),x=s([]),S=s(``),C=s(!1),w=s(`all`),T=s(``),E=s([]);async function D(){m.value=!0;try{let{data:e}=await p.get(`/reservations`,{params:{status:w.value,keyword:T.value||void 0,start_date:E.value?.[0]||void 0,end_date:E.value?.[1]||void 0}});x.value=e}catch(t){e.error(t?.response?.data?.message??`加载预约列表失败`)}finally{m.value=!1}}function O(){D()}function k(){w.value=`all`,T.value=``,E.value=[],D()}async function A(){if(!S.value){e.warning(`请输入二维码 token`);return}C.value=!0;try{await p.post(`/reservations/verify`,{qr_token:S.value}),e.success(`核销成功`),S.value=``,await D()}catch(t){e.error(t?.response?.data?.message??`核销失败`)}finally{C.value=!1}}return n(D),(e,n)=>{let s=r(`a-alert`),f=r(`a-input`),p=r(`a-button`),j=r(`a-space`),M=r(`a-radio`),N=r(`a-radio-group`),P=r(`a-range-picker`),F=r(`a-table-column`),I=r(`a-tag`),L=r(`a-table`),R=r(`a-card`);return t(),o(R,{title:`活动管理 / 现场核销`},{default:i(()=>[d(j,{direction:`vertical`,fill:``},{default:i(()=>[d(s,null,{default:i(()=>[...n[4]||=[a(` 输入预约二维码 token 进行核销。场馆管理员仅可核销自己绑定场馆的预约。 `,-1)]]),_:1}),d(j,{wrap:``,size:12},{default:i(()=>[d(f,{modelValue:S.value,"onUpdate:modelValue":n[0]||=e=>S.value=e,style:{width:`min(100%, 420px)`},placeholder:`请输入二维码 token`,"allow-clear":``},null,8,[`modelValue`]),d(p,{type:`primary`,loading:C.value,onClick:A},{default:i(()=>[...n[5]||=[a(`立即核销`,-1)]]),_:1},8,[`loading`])]),_:1}),l(`div`,b,[d(j,{wrap:``,size:12},{default:i(()=>[d(N,{modelValue:w.value,"onUpdate:modelValue":n[1]||=e=>w.value=e,type:`button`,size:`small`,onChange:D},{default:i(()=>[d(M,{value:`all`},{default:i(()=>[...n[6]||=[a(`全部`,-1)]]),_:1}),d(M,{value:`pending`},{default:i(()=>[...n[7]||=[a(`待核销`,-1)]]),_:1}),d(M,{value:`verified`},{default:i(()=>[...n[8]||=[a(`已核销`,-1)]]),_:1}),d(M,{value:`cancelled`},{default:i(()=>[...n[9]||=[a(`已取消`,-1)]]),_:1}),d(M,{value:`expired`},{default:i(()=>[...n[10]||=[a(`已过期`,-1)]]),_:1})]),_:1},8,[`modelValue`]),d(f,{modelValue:T.value,"onUpdate:modelValue":n[2]||=e=>T.value=e,placeholder:`报名人/手机/token`,"allow-clear":``,style:{width:`220px`}},null,8,[`modelValue`]),d(P,{modelValue:E.value,"onUpdate:modelValue":n[3]||=e=>E.value=e,style:{width:`260px`}},null,8,[`modelValue`]),d(p,{type:`primary`,onClick:O},{default:i(()=>[...n[11]||=[a(`查询`,-1)]]),_:1}),d(p,{onClick:k},{default:i(()=>[...n[12]||=[a(`重置`,-1)]]),_:1}),d(p,{onClick:D},{default:i(()=>[...n[13]||=[a(`刷新列表`,-1)]]),_:1})]),_:1})]),d(L,{class:`list-data-table verify-table`,scroll:{x:u(_)},data:x.value,loading:m.value,"row-key":`id`,pagination:{pageSize:10,showTotal:!0}},{columns:i(()=>[d(F,{title:`ID`,"data-index":`id`,width:88}),d(F,{title:`活动`,width:240,"min-width":180,ellipsis:!0,tooltip:!0},{cell:i(({record:e})=>[a(c(e.activity?.title??`-`),1)]),_:1}),d(F,{title:`场馆`,width:200,"min-width":160,ellipsis:!0,tooltip:!0},{cell:i(({record:e})=>[a(c(e.venue?.name??`-`),1)]),_:1}),d(F,{title:`报名人`,"data-index":`visitor_name`,width:120,ellipsis:!0,tooltip:!0}),d(F,{title:`手机号`,"data-index":`visitor_phone`,width:130,ellipsis:!0,tooltip:!0}),d(F,{title:`预约类型`,width:100},{cell:i(({record:e})=>[a(c(u(v)(e.booking_type,e.ticket_count)),1)]),_:1}),d(F,{title:`预约票数`,width:100},{cell:i(({record:e})=>[a(c(e.ticket_count??1),1)]),_:1}),d(F,{title:`预约入馆日期`,width:140,ellipsis:!0,tooltip:!0},{cell:i(({record:e})=>[a(c(e.activity_day?.activity_date?u(h)(e.activity_day.activity_date):`-`),1)]),_:1}),d(F,{title:`状态`,width:100},{cell:i(({record:e})=>[d(I,{color:e.status===`verified`?`green`:e.status===`pending`?`arcoblue`:e.status===`expired`?`orange`:`gray`},{default:i(()=>[a(c(u(y)(e.status)),1)]),_:2},1032,[`color`])]),_:1}),d(F,{title:`预约时间`,width:175,ellipsis:!0,tooltip:!0},{cell:i(({record:e})=>[a(c(u(g)(e.created_at)),1)]),_:1}),d(F,{title:`核销时间`,width:175,ellipsis:!0,tooltip:!0},{cell:i(({record:e})=>[a(c(u(g)(e.verified_at)),1)]),_:1}),d(F,{title:`二维码 token`,"data-index":`qr_token`,width:220,"min-width":180,ellipsis:!0,tooltip:!0,fixed:`right`,align:`left`})]),_:1},8,[`scroll`,`data`,`loading`])]),_:1})]),_:1})}}}),[[`__scopeId`,`data-v-3f89bb59`]]);export{x as default};

@ -1 +1 @@
import{n as e}from"./axios-CiYFffbI.js";import{I as t,V as n,Y as r,_ as i,it as a,nt as o,p as s,u as c,v as l,y as u}from"./runtime-core.esm-bundler-CnFWH3R5.js";import{i as d,o as f,r as p}from"./index-CnpIIn-A.js";import{n as m,t as h}from"./h5Http-nx8aETIZ.js";var g={class:`m-verify-page`},_={class:`m-verify-card`},v=f(u({__name:`VerifyLogin`,setup(u){let f=d(),v=p(),y=a(!1),b=o({username:``,password:``});function x(){return v.path.startsWith(`/m/`)?`/m/verify`:`/h5/verify/scan`}async function S(){y.value=!0;try{let{data:t}=await m.post(`/auth/login`,{...b,client:`h5_verify`});localStorage.setItem(h,t.token),localStorage.setItem(`${h}_saved_at`,String(Date.now())),e.success(`登录成功`),f.replace(x())}catch(t){e.error(t?.response?.data?.message??`登录失败`)}finally{y.value=!1}}return(e,a)=>{let o=n(`a-input`),u=n(`a-form-item`),d=n(`a-input-password`),f=n(`a-button`),p=n(`a-form`);return t(),s(`div`,g,[a[4]||=c(`div`,{class:`m-verify-hero`},[c(`div`,{class:`m-verify-title`},`苏州市科普场馆地图`),c(`div`,{class:`m-verify-sub`},`移动端核销登录`)],-1),c(`div`,_,[l(p,{model:b,layout:`vertical`,onSubmitSuccess:S},{default:r(()=>[l(u,{label:`用户名`},{default:r(()=>[l(o,{modelValue:b.username,"onUpdate:modelValue":a[0]||=e=>b.username=e,placeholder:`请输入账号`,size:`large`,"allow-clear":``},null,8,[`modelValue`])]),_:1}),l(u,{label:`密码`},{default:r(()=>[l(d,{modelValue:b.password,"onUpdate:modelValue":a[1]||=e=>b.password=e,placeholder:`请输入密码`,size:`large`,"allow-clear":``},null,8,[`modelValue`])]),_:1}),l(f,{type:`primary`,long:``,size:`large`,loading:y.value,onClick:S},{default:r(()=>[...a[2]||=[i(`登录`,-1)]]),_:1},8,[`loading`])]),_:1},8,[`model`]),a[3]||=c(`p`,{class:`m-verify-tip`},`登录状态将保持较长时间;若已失效会自动回到本页。`,-1)])])}}}),[[`__scopeId`,`data-v-b762ebdf`]]);export{v as default};
import{n as e}from"./axios-CiYFffbI.js";import{I as t,V as n,Y as r,_ as i,it as a,nt as o,p as s,u as c,v as l,y as u}from"./runtime-core.esm-bundler-CnFWH3R5.js";import{i as d,o as f,r as p}from"./index-CxYyK2oU.js";import{n as m,t as h}from"./h5Http-nx8aETIZ.js";var g={class:`m-verify-page`},_={class:`m-verify-card`},v=f(u({__name:`VerifyLogin`,setup(u){let f=d(),v=p(),y=a(!1),b=o({username:``,password:``});function x(){return v.path.startsWith(`/m/`)?`/m/verify`:`/h5/verify/scan`}async function S(){y.value=!0;try{let{data:t}=await m.post(`/auth/login`,{...b,client:`h5_verify`});localStorage.setItem(h,t.token),localStorage.setItem(`${h}_saved_at`,String(Date.now())),e.success(`登录成功`),f.replace(x())}catch(t){e.error(t?.response?.data?.message??`登录失败`)}finally{y.value=!1}}return(e,a)=>{let o=n(`a-input`),u=n(`a-form-item`),d=n(`a-input-password`),f=n(`a-button`),p=n(`a-form`);return t(),s(`div`,g,[a[4]||=c(`div`,{class:`m-verify-hero`},[c(`div`,{class:`m-verify-title`},`苏州市科普场馆地图`),c(`div`,{class:`m-verify-sub`},`移动端核销登录`)],-1),c(`div`,_,[l(p,{model:b,layout:`vertical`,onSubmitSuccess:S},{default:r(()=>[l(u,{label:`用户名`},{default:r(()=>[l(o,{modelValue:b.username,"onUpdate:modelValue":a[0]||=e=>b.username=e,placeholder:`请输入账号`,size:`large`,"allow-clear":``},null,8,[`modelValue`])]),_:1}),l(u,{label:`密码`},{default:r(()=>[l(d,{modelValue:b.password,"onUpdate:modelValue":a[1]||=e=>b.password=e,placeholder:`请输入密码`,size:`large`,"allow-clear":``},null,8,[`modelValue`])]),_:1}),l(f,{type:`primary`,long:``,size:`large`,loading:y.value,onClick:S},{default:r(()=>[...a[2]||=[i(`登录`,-1)]]),_:1},8,[`loading`])]),_:1},8,[`model`]),a[3]||=c(`p`,{class:`m-verify-tip`},`登录状态将保持较长时间;若已失效会自动回到本页。`,-1)])])}}}),[[`__scopeId`,`data-v-b762ebdf`]]);export{v as default};

File diff suppressed because one or more lines are too long

@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="/admin/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>苏州市科普场馆地图管理后台</title>
<script type="module" crossorigin src="/admin/assets/index-CnpIIn-A.js"></script>
<script type="module" crossorigin src="/admin/assets/index-CxYyK2oU.js"></script>
<link rel="modulepreload" crossorigin href="/admin/assets/runtime-core.esm-bundler-CnFWH3R5.js">
<link rel="modulepreload" crossorigin href="/admin/assets/axios-CiYFffbI.js">
<link rel="stylesheet" crossorigin href="/admin/assets/index-2DjvV_uU.css">

@ -0,0 +1 @@
import{h as t}from"./index-DRm95jLB.js";function n(n={}){return t.get("/h5/activities",n,{withAuth:!1})}function i(n){return t.get(`/h5/activities/${n}`,{})}function e(){return t.get("/h5/venues",{},{withAuth:!1})}function s(){return t.get("/h5/venue-dicts",{},{withAuth:!1})}function u(n){return t.get(`/h5/venues/${n}`,{},{withAuth:!1})}function r(n){return t.get(`/h5/study-tours/${n}`,{},{withAuth:!1})}function h(n={}){return t.get("/h5/study-tours",n,{withAuth:!1})}function o(n){return t.get(`/h5/activities/${n}/booking-info`,{},{withAuth:!0})}function a(n,i){return t.post(`/h5/activities/${n}/reservations`,i,{withAuth:!0})}function c(n){const i={};return n&&/^1\d{10}$/.test(n)&&(i.visitor_phone=n),t.get("/h5/my/reservations",i,{withAuth:!0})}function f(n,i){const e={};return i&&/^1\d{10}$/.test(i)&&(e.visitor_phone=i),t.get(`/h5/my/reservations/${n}`,e,{withAuth:!0})}function v(n,i){const e={};return i&&/^1\d{10}$/.test(i)&&(e.visitor_phone=i),t.post(`/h5/my/reservations/${n}/cancel`,e,{withAuth:!0})}export{e as a,n as b,h as c,c as d,v as e,i as f,s as g,o as h,a as i,f as j,r as k,u as l};

@ -1 +0,0 @@
import{h as t}from"./index-BQvUePVO.js";function n(n={}){return t.get("/h5/activities",n,{withAuth:!1})}function i(n){return t.get(`/h5/activities/${n}`,{},{withAuth:!1})}function e(){return t.get("/h5/venues",{},{withAuth:!1})}function s(){return t.get("/h5/venue-dicts",{},{withAuth:!1})}function u(n){return t.get(`/h5/venues/${n}`,{},{withAuth:!1})}function h(n){return t.get(`/h5/study-tours/${n}`,{},{withAuth:!1})}function r(n={}){return t.get("/h5/study-tours",n,{withAuth:!1})}function o(n){return t.get(`/h5/activities/${n}/booking-info`,{},{withAuth:!0})}function a(n,i){return t.post(`/h5/activities/${n}/reservations`,i,{withAuth:!0})}function c(n){const i={};return n&&/^1\d{10}$/.test(n)&&(i.visitor_phone=n),t.get("/h5/my/reservations",i,{withAuth:!0})}function f(n,i){const e={};return i&&/^1\d{10}$/.test(i)&&(e.visitor_phone=i),t.get(`/h5/my/reservations/${n}`,e,{withAuth:!0})}function v(n,i){const e={};return i&&/^1\d{10}$/.test(i)&&(e.visitor_phone=i),t.post(`/h5/my/reservations/${n}/cancel`,e,{withAuth:!0})}export{e as a,n as b,r as c,c as d,v as e,i as f,s as g,o as h,a as i,f as j,h as k,u as l};

@ -1 +1 @@
function t(t){if(null==t||""===t)return"-";const e=String(t).trim();if(/^\d{4}-\d{2}-\d{2}$/.test(e))return e;if(/^\d{4}-\d{2}-\d{2}[ T]/.test(e))return e.slice(0,10);const n=new Date(e);if(Number.isNaN(n.getTime()))return e;const r=t=>String(t).padStart(2,"0");return`${n.getFullYear()}-${r(n.getMonth()+1)}-${r(n.getDate())}`}function e(e){const n=t(e??"");if(!n||"-"===n)return!1;const r=new Date,i=t=>String(t).padStart(2,"0");return n<`${r.getFullYear()}-${i(r.getMonth()+1)}-${i(r.getDate())}`}function n(t){if(null==t||""===t)return"-";const e=String(t).trim();if(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(e))return e;if(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/.test(e))return`${e}:00`;const n=new Date(e);if(Number.isNaN(n.getTime()))return e;const r=t=>String(t).padStart(2,"0");return`${n.getFullYear()}-${r(n.getMonth()+1)}-${r(n.getDate())} ${r(n.getHours())}:${r(n.getMinutes())}:${r(n.getSeconds())}`}export{n as a,t as f,e as i};
function t(t){if(null==t||""===t)return"-";const e=String(t).trim();if(/^\d{4}-\d{2}-\d{2}$/.test(e))return e;if(/^\d{4}-\d{2}-\d{2}[ T]/.test(e))return e.slice(0,10);const n=new Date(e);if(Number.isNaN(n.getTime()))return e;const r=t=>String(t).padStart(2,"0");return`${n.getFullYear()}-${r(n.getMonth()+1)}-${r(n.getDate())}`}function e(e){const n=t(e??"");if(!n||"-"===n)return!1;const r=new Date,i=t=>String(t).padStart(2,"0");return n<`${r.getFullYear()}-${i(r.getMonth()+1)}-${i(r.getDate())}`}function n(t){if(null==t||""===t)return"-";const e=String(t).trim();if(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(e))return e;if(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/.test(e))return`${e}:00`;const n=new Date(e);if(Number.isNaN(n.getTime()))return e;const r=t=>String(t).padStart(2,"0");return`${n.getFullYear()}-${r(n.getMonth()+1)}-${r(n.getDate())} ${r(n.getHours())}:${r(n.getMinutes())}:${r(n.getSeconds())}`}export{t as a,n as f,e as i};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
import{h as t,g as n,S as r,b as e}from"./index-BQvUePVO.js";function o(){return t.get("/h5/me/profile",{},{withAuth:!0})}function i(n){return t.put("/h5/me/profile",n,{withAuth:!0})}function u(){try{const t=n(r.localProfile);if(!t)return null;const e="string"==typeof t?JSON.parse(t):t;return e&&"object"==typeof e?e:null}catch{return null}}function l(t){e(r.localProfile,JSON.stringify(t))}export{o as g,u as l,l as s,i as u};
import{h as t,g as n,S as r,b as e}from"./index-DRm95jLB.js";function o(){return t.get("/h5/me/profile",{},{withAuth:!0})}function i(n){return t.put("/h5/me/profile",n,{withAuth:!0})}function u(){try{const t=n(r.localProfile);if(!t)return null;const e="string"==typeof t?JSON.parse(t):t;return e&&"object"==typeof e?e:null}catch{return null}}function l(t){e(r.localProfile,JSON.stringify(t))}export{o as g,u as l,l as s,i as u};

@ -1 +0,0 @@
.page[data-v-ae6fbff3]{padding:.5rem;padding-top:calc(.5rem + env(safe-area-inset-top));background:#f3f3f3;min-height:100vh;box-sizing:border-box}.notice-top[data-v-ae6fbff3]{margin-bottom:.375rem;padding:.4375rem .5rem;background:#fff9e6;border-radius:.375rem;border:.03125rem solid rgba(255,193,7,.35);box-sizing:border-box}.notice-text[data-v-ae6fbff3]{font-size:.75rem;color:#8d6e1a;line-height:1.55}.card[data-v-ae6fbff3]{background:#fff;border-radius:.5rem;padding:.625rem}.title[data-v-ae6fbff3]{font-size:1rem;font-weight:400;color:#1d2129;line-height:1.35}.sub[data-v-ae6fbff3]{margin-top:.3125rem;font-size:.8125rem;color:#86909c;line-height:1.5}.row[data-v-ae6fbff3]{margin-top:.375rem;display:flex;gap:.3125rem}.ipt[data-v-ae6fbff3]{flex:1;height:1.875rem;border:.03125rem solid #e5e6eb;border-radius:.25rem;padding:0 .375rem;font-size:.75rem;color:#4e5969;background:#fff}.btn[data-v-ae6fbff3]{flex-shrink:0;width:3.75rem;height:1.875rem;line-height:1.875rem;border:none;background:#05c9ac;color:#fff;border-radius:.25rem;font-size:.75rem;padding:0}.filters[data-v-ae6fbff3]{margin-top:.375rem;display:flex;gap:.25rem;flex-wrap:wrap}.chip[data-v-ae6fbff3]{padding:.25rem .4375rem;border-radius:.75rem;background:#f2f3f5;color:#4e5969;font-size:.75rem;line-height:1.35}.chip.active[data-v-ae6fbff3]{background:#05c9ac;color:#fff}.order-card[data-v-ae6fbff3]{margin-top:.4375rem;background:#fff;border-radius:.4375rem;padding:.5625rem}.order-top[data-v-ae6fbff3]{display:flex;justify-content:space-between;align-items:flex-start;gap:.375rem;margin-bottom:.3125rem}.t[data-v-ae6fbff3]{flex:1;min-width:0;font-size:.9375rem;font-weight:400;color:#1d2129;line-height:1.35}.status[data-v-ae6fbff3]{flex-shrink:0;padding:.25rem .5rem;border-radius:.3125rem;font-size:.625rem;line-height:.875rem;color:#fff}.status.pending[data-v-ae6fbff3]{background:#05c9ac}.status.verified[data-v-ae6fbff3],.status.cancelled[data-v-ae6fbff3]{background:#c7c7c7}.status.expired[data-v-ae6fbff3]{background:#e67e22}.line[data-v-ae6fbff3]{margin-top:.25rem;font-size:.8125rem;color:#4e5969;line-height:1.5}.actions[data-v-ae6fbff3]{margin-top:.4375rem;width:100%;display:flex;flex-direction:row;justify-content:flex-end;align-items:center;gap:.375rem;flex-wrap:nowrap;box-sizing:border-box}.actions .mini[data-v-ae6fbff3]{flex-shrink:0;width:auto!important;min-width:3.5rem;height:1.5rem;line-height:1.5rem;border-radius:.25rem;font-size:.6875rem;padding:0 .5rem;margin:0;display:inline-flex;align-items:center;justify-content:center}.btn-main[data-v-ae6fbff3]{background:#05c9ac;color:#fff;border:none}.btn-light[data-v-ae6fbff3]{background:#f2f2f2;color:#666;border:none}

@ -0,0 +1 @@
.page[data-v-52e9c43e]{padding:.5rem;padding-top:calc(.5rem + env(safe-area-inset-top));background:#f3f3f3;min-height:100vh;box-sizing:border-box}.notice-top[data-v-52e9c43e]{margin-bottom:.375rem;padding:.4375rem .5rem;background:#fff9e6;border-radius:.375rem;border:.03125rem solid rgba(255,193,7,.35);box-sizing:border-box}.notice-text[data-v-52e9c43e]{font-size:.75rem;color:#8d6e1a;line-height:1.55}.card[data-v-52e9c43e]{background:#fff;border-radius:.5rem;padding:.625rem}.title[data-v-52e9c43e]{font-size:1rem;font-weight:400;color:#1d2129;line-height:1.35}.sub[data-v-52e9c43e]{margin-top:.3125rem;font-size:.8125rem;color:#86909c;line-height:1.5}.row[data-v-52e9c43e]{margin-top:.375rem;display:flex;gap:.3125rem}.ipt[data-v-52e9c43e]{flex:1;height:1.875rem;border:.03125rem solid #e5e6eb;border-radius:.25rem;padding:0 .375rem;font-size:.75rem;color:#4e5969;background:#fff}.btn[data-v-52e9c43e]{flex-shrink:0;width:3.75rem;height:1.875rem;line-height:1.875rem;border:none;background:#05c9ac;color:#fff;border-radius:.25rem;font-size:.75rem;padding:0}.filters[data-v-52e9c43e]{margin-top:.375rem;display:flex;gap:.25rem;flex-wrap:wrap}.chip[data-v-52e9c43e]{padding:.25rem .4375rem;border-radius:.75rem;background:#f2f3f5;color:#4e5969;font-size:.75rem;line-height:1.35}.chip.active[data-v-52e9c43e]{background:#05c9ac;color:#fff}.order-card[data-v-52e9c43e]{margin-top:.4375rem;background:#fff;border-radius:.4375rem;padding:.5625rem}.order-top[data-v-52e9c43e]{display:flex;justify-content:space-between;align-items:flex-start;gap:.375rem;margin-bottom:.3125rem}.t[data-v-52e9c43e]{flex:1;min-width:0;font-size:.9375rem;font-weight:400;color:#1d2129;line-height:1.35}.status[data-v-52e9c43e]{flex-shrink:0;padding:.25rem .5rem;border-radius:.3125rem;font-size:.625rem;line-height:.875rem;color:#fff}.status.pending[data-v-52e9c43e]{background:#05c9ac}.status.verified[data-v-52e9c43e],.status.cancelled[data-v-52e9c43e]{background:#c7c7c7}.status.expired[data-v-52e9c43e]{background:#e67e22}.line[data-v-52e9c43e]{margin-top:.25rem;font-size:.8125rem;color:#4e5969;line-height:1.5}.actions[data-v-52e9c43e]{margin-top:.4375rem;width:100%;display:flex;flex-direction:row;justify-content:flex-end;align-items:center;gap:.375rem;flex-wrap:nowrap;box-sizing:border-box}.actions .mini[data-v-52e9c43e]{flex-shrink:0;width:auto!important;min-width:3.5rem;height:1.5rem;line-height:1.5rem;border-radius:.25rem;font-size:.6875rem;padding:0 .5rem;margin:0;display:inline-flex;align-items:center;justify-content:center}.btn-main[data-v-52e9c43e]{background:#05c9ac;color:#fff;border:none}.btn-light[data-v-52e9c43e]{background:#f2f2f2;color:#666;border:none}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
import{d as a,e,f as l,o as s,N as t,O as u,P as n,j as r,k as i,m as o,n as c,p as d,D as v,E as f,I as p,G as _,t as m,v as y,x as g,y as h,F as b,z as k,C as j,H as w,J as C,B as P,K as x}from"./index-BQvUePVO.js";import{g as A,b as F}from"./content.R922wQQ4.js";import{a as N}from"./venueThemeColors.DRxjaxXI.js";import{f as V,a as z,i as I,c as $}from"./activity.4NBjJ4my.js";import{P as B}from"./poster.DLiVsUXX.js";import{s as D}from"./search.BJnl3YRK.js";import{d as E}from"./down.BCKq9i8s.js";import{_ as G}from"./_plugin-vue_export-helper.BCo6x5W8.js";const H=G(a({__name:"index",setup(a){const G=e([]),H=e(null),J=e(1),K=e(0),O=e(!1),T=e(!1),U=e(""),q=e(""),L=[{value:"",label:"全部状态"},{value:"ongoing",label:"进行中"},{value:"not_started",label:"未开始"},{value:"ended",label:"已结束"}],M=e(0),Q=l(()=>K.value>0&&J.value<K.value);async function R(a,e){if(!O.value||e){if(e){if(T.value||!Q.value)return;T.value=!0}else O.value=!0;try{const l=await F({page:a,page_size:10,keyword:U.value.trim()||void 0,schedule_status:q.value||void 0}),{list:s,lastPage:t}=function(a){if(!a||"object"!=typeof a)return{list:[],lastPage:1};const e=a;if(Array.isArray(e))return{list:e,lastPage:1};const l=e.data;if(Array.isArray(l))return{list:l,lastPage:Number(e.last_page??1)||1};if(l&&"object"==typeof l){const a=l;if(Array.isArray(a.data)){const l=Number(a.last_page??e.last_page??1)||1;return{list:a.data,lastPage:l}}}return{list:[],lastPage:1}}(l);K.value=t,G.value=e?[...G.value,...s]:s,J.value=a}catch{e||(G.value=[])}finally{O.value=!1,T.value=!1}}}async function S(){J.value=1,await R(1,!1)}function W(){S()}function X(a){var e;const l=Number((null==(e=null==a?void 0:a.detail)?void 0:e.value)??0);M.value=Number.isFinite(l)?l:0;const s=L[M.value];q.value=(null==s?void 0:s.value)??"",S()}function Y(a){x({url:`/pages/activity/detail?id=${a}`})}function Z(a){const e=null==a?void 0:a.schedule_status;return"not_started"===e||"ongoing"===e||"ended"===e?e:$(null==a?void 0:a.start_at,null==a?void 0:a.end_at)}function aa(a){return z(Z(a))}return s(()=>{!async function(){try{H.value=await A()}catch{H.value=null}J.value=1,await R(1,!1)}()}),t(()=>{O.value||T.value||!Q.value||R(J.value+1,!0)}),u(async()=>{try{await S()}finally{n()}}),(a,e)=>{const l=v,s=p,t=o,u=m,n=_;return c(),r(t,{class:"page"},{default:i(()=>[d(t,{class:"toolbar"},{default:i(()=>[d(t,{class:"toolbar-row"},{default:i(()=>[d(t,{class:"search-wrap"},{default:i(()=>[d(l,{class:"search-icon-img",src:f(D),mode:"aspectFit"},null,8,["src"]),d(s,{modelValue:U.value,"onUpdate:modelValue":e[0]||(e[0]=a=>U.value=a),class:"search-input",placeholder:"搜索活动标题","placeholder-class":"ph","confirm-type":"search",onConfirm:W},null,8,["modelValue"])]),_:1}),d(n,{mode:"selector",range:L,"range-key":"label",value:M.value,class:"status-picker",onChange:X},{default:i(()=>[d(t,{class:"status-pick"},{default:i(()=>[d(u,{class:"status-pick-text"},{default:i(()=>{var a;return[y(g((null==(a=L[M.value])?void 0:a.label)||"全部"),1)]}),_:1}),d(l,{class:"status-pick-arrow",src:f(E),mode:"aspectFit"},null,8,["src"])]),_:1})]),_:1},8,["value"])]),_:1})]),_:1}),d(t,{class:"list-inner"},{default:i(()=>[(c(!0),h(b,null,k(G.value,a=>(c(),r(t,{key:a.id,class:"item",onClick:e=>Y(a.id)},{default:i(()=>[d(t,{class:"poster-wrap"},{default:i(()=>{return[d(l,{class:"poster",src:a.image||f(B),mode:"aspectFill"},null,8,["src"]),d(t,{class:j(["status",(e=a,`st-${Z(e)}`)])},{default:i(()=>[y(g(aa(a)),1)]),_:2},1032,["class"])];var e}),_:2},1024),d(t,{class:"body"},{default:i(()=>{var e,l;return[d(t,{class:"title"},{default:i(()=>[y(g(a.title),1)]),_:2},1024),(null==(e=a.tags)?void 0:e.length)?(c(),r(t,{key:0,class:"act-tags"},{default:i(()=>[(c(!0),h(b,null,k((a.tags||[]).slice(0,4),(e,l)=>{var s;return c(),r(u,{key:"t-"+a.id+"-"+l,class:"act-tag-chip",style:w(f(N)(l,null==(s=H.value)?void 0:s.venue_type))},{default:i(()=>[y(g(e),1)]),_:2},1032,["style"])}),128))]),_:2},1024)):C("",!0),d(t,{class:"meta"},{default:i(()=>[y(g(f(V)(a.start_at,a.end_at)),1)]),_:2},1024),d(t,{class:"meta venue-line"},{default:i(()=>[y(g(a.venue_name||"场馆待定"),1)]),_:2},1024),(l=a,I(null==l?void 0:l.end_at)||!0!==(null==l?void 0:l.is_bookable)?C("",!0):(c(),r(t,{key:1,class:"action-row"},{default:i(()=>[d(t,{class:"btn",onClick:P(e=>Y(a.id),["stop"])},{default:i(()=>[y("立即预约")]),_:2},1032,["onClick"])]),_:2},1024)))]}),_:2},1024)]),_:2},1032,["onClick"]))),128)),O.value&&!G.value.length?(c(),r(t,{key:0,class:"hint"},{default:i(()=>[y("加载中…")]),_:1})):C("",!0),T.value?(c(),r(t,{key:1,class:"hint"},{default:i(()=>[y("加载更多…")]),_:1})):C("",!0),K.value>0&&!Q.value&&G.value.length&&!O.value?(c(),r(t,{key:2,class:"hint muted"},{default:i(()=>[y("没有更多了")]),_:1})):C("",!0),O.value||G.value.length?C("",!0):(c(),r(t,{key:3,class:"hint muted"},{default:i(()=>[y("暂无活动")]),_:1}))]),_:1})]),_:1})}}}),[["__scopeId","data-v-510c66b7"]]);export{H as default};
import{d as a,e,f as l,o as s,N as t,O as u,P as n,j as r,k as i,m as o,n as c,p as d,D as v,E as f,I as p,G as _,t as m,v as y,x as g,y as h,F as b,z as k,C as j,H as w,J as C,B as P,K as x}from"./index-DRm95jLB.js";import{g as A,b as F}from"./content.B6hfFJlR.js";import{a as N}from"./venueThemeColors.DRxjaxXI.js";import{f as V,a as z,i as I,c as $}from"./activity.4NBjJ4my.js";import{P as B}from"./poster.DLiVsUXX.js";import{s as D}from"./search.BJnl3YRK.js";import{d as E}from"./down.BCKq9i8s.js";import{_ as G}from"./_plugin-vue_export-helper.BCo6x5W8.js";const H=G(a({__name:"index",setup(a){const G=e([]),H=e(null),J=e(1),K=e(0),O=e(!1),T=e(!1),U=e(""),q=e(""),L=[{value:"",label:"全部状态"},{value:"ongoing",label:"进行中"},{value:"not_started",label:"未开始"},{value:"ended",label:"已结束"}],M=e(0),Q=l(()=>K.value>0&&J.value<K.value);async function R(a,e){if(!O.value||e){if(e){if(T.value||!Q.value)return;T.value=!0}else O.value=!0;try{const l=await F({page:a,page_size:10,keyword:U.value.trim()||void 0,schedule_status:q.value||void 0}),{list:s,lastPage:t}=function(a){if(!a||"object"!=typeof a)return{list:[],lastPage:1};const e=a;if(Array.isArray(e))return{list:e,lastPage:1};const l=e.data;if(Array.isArray(l))return{list:l,lastPage:Number(e.last_page??1)||1};if(l&&"object"==typeof l){const a=l;if(Array.isArray(a.data)){const l=Number(a.last_page??e.last_page??1)||1;return{list:a.data,lastPage:l}}}return{list:[],lastPage:1}}(l);K.value=t,G.value=e?[...G.value,...s]:s,J.value=a}catch{e||(G.value=[])}finally{O.value=!1,T.value=!1}}}async function S(){J.value=1,await R(1,!1)}function W(){S()}function X(a){var e;const l=Number((null==(e=null==a?void 0:a.detail)?void 0:e.value)??0);M.value=Number.isFinite(l)?l:0;const s=L[M.value];q.value=(null==s?void 0:s.value)??"",S()}function Y(a){x({url:`/pages/activity/detail?id=${a}`})}function Z(a){const e=null==a?void 0:a.schedule_status;return"not_started"===e||"ongoing"===e||"ended"===e?e:$(null==a?void 0:a.start_at,null==a?void 0:a.end_at)}function aa(a){return z(Z(a))}return s(()=>{!async function(){try{H.value=await A()}catch{H.value=null}J.value=1,await R(1,!1)}()}),t(()=>{O.value||T.value||!Q.value||R(J.value+1,!0)}),u(async()=>{try{await S()}finally{n()}}),(a,e)=>{const l=v,s=p,t=o,u=m,n=_;return c(),r(t,{class:"page"},{default:i(()=>[d(t,{class:"toolbar"},{default:i(()=>[d(t,{class:"toolbar-row"},{default:i(()=>[d(t,{class:"search-wrap"},{default:i(()=>[d(l,{class:"search-icon-img",src:f(D),mode:"aspectFit"},null,8,["src"]),d(s,{modelValue:U.value,"onUpdate:modelValue":e[0]||(e[0]=a=>U.value=a),class:"search-input",placeholder:"搜索活动标题","placeholder-class":"ph","confirm-type":"search",onConfirm:W},null,8,["modelValue"])]),_:1}),d(n,{mode:"selector",range:L,"range-key":"label",value:M.value,class:"status-picker",onChange:X},{default:i(()=>[d(t,{class:"status-pick"},{default:i(()=>[d(u,{class:"status-pick-text"},{default:i(()=>{var a;return[y(g((null==(a=L[M.value])?void 0:a.label)||"全部"),1)]}),_:1}),d(l,{class:"status-pick-arrow",src:f(E),mode:"aspectFit"},null,8,["src"])]),_:1})]),_:1},8,["value"])]),_:1})]),_:1}),d(t,{class:"list-inner"},{default:i(()=>[(c(!0),h(b,null,k(G.value,a=>(c(),r(t,{key:a.id,class:"item",onClick:e=>Y(a.id)},{default:i(()=>[d(t,{class:"poster-wrap"},{default:i(()=>{return[d(l,{class:"poster",src:a.image||f(B),mode:"aspectFill"},null,8,["src"]),d(t,{class:j(["status",(e=a,`st-${Z(e)}`)])},{default:i(()=>[y(g(aa(a)),1)]),_:2},1032,["class"])];var e}),_:2},1024),d(t,{class:"body"},{default:i(()=>{var e,l;return[d(t,{class:"title"},{default:i(()=>[y(g(a.title),1)]),_:2},1024),(null==(e=a.tags)?void 0:e.length)?(c(),r(t,{key:0,class:"act-tags"},{default:i(()=>[(c(!0),h(b,null,k((a.tags||[]).slice(0,4),(e,l)=>{var s;return c(),r(u,{key:"t-"+a.id+"-"+l,class:"act-tag-chip",style:w(f(N)(l,null==(s=H.value)?void 0:s.venue_type))},{default:i(()=>[y(g(e),1)]),_:2},1032,["style"])}),128))]),_:2},1024)):C("",!0),d(t,{class:"meta"},{default:i(()=>[y(g(f(V)(a.start_at,a.end_at)),1)]),_:2},1024),d(t,{class:"meta venue-line"},{default:i(()=>[y(g(a.venue_name||"场馆待定"),1)]),_:2},1024),(l=a,I(null==l?void 0:l.end_at)||!0!==(null==l?void 0:l.is_bookable)?C("",!0):(c(),r(t,{key:1,class:"action-row"},{default:i(()=>[d(t,{class:"btn",onClick:P(e=>Y(a.id),["stop"])},{default:i(()=>[y("立即预约")]),_:2},1032,["onClick"])]),_:2},1024)))]}),_:2},1024)]),_:2},1032,["onClick"]))),128)),O.value&&!G.value.length?(c(),r(t,{key:0,class:"hint"},{default:i(()=>[y("加载中…")]),_:1})):C("",!0),T.value?(c(),r(t,{key:1,class:"hint"},{default:i(()=>[y("加载更多…")]),_:1})):C("",!0),K.value>0&&!Q.value&&G.value.length&&!O.value?(c(),r(t,{key:2,class:"hint muted"},{default:i(()=>[y("没有更多了")]),_:1})):C("",!0),O.value||G.value.length?C("",!0):(c(),r(t,{key:3,class:"hint muted"},{default:i(()=>[y("暂无活动")]),_:1}))]),_:1})]),_:1})}}}),[["__scopeId","data-v-510c66b7"]]);export{H as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
import{d as a,e as s,o as e,O as l,P as t,j as u,k as o,m as r,n as c,p as n,D as d,E as i,I as m,y as f,F as p,z as _,t as v,v as y,x as h,J as g,K as k}from"./index-BQvUePVO.js";import{c as w}from"./content.R922wQQ4.js";import{P as j}from"./poster.DLiVsUXX.js";import{s as x}from"./search.BJnl3YRK.js";import{_ as b}from"./_plugin-vue_export-helper.BCo6x5W8.js";const C=b(a({__name:"index",setup(a){const b=s([]),C=s(!1),F=s("");async function V(){C.value=!0;try{b.value=await w({keyword:F.value.trim()||void 0})||[]}catch{b.value=[]}finally{C.value=!1}}function I(){V()}return e(()=>{V()}),l(async()=>{try{await V()}finally{t()}}),(a,s)=>{const e=d,l=m,t=r,w=v;return c(),u(t,{class:"page"},{default:o(()=>[n(t,{class:"toolbar"},{default:o(()=>[n(t,{class:"search-wrap"},{default:o(()=>[n(e,{class:"search-icon-img",src:i(x),mode:"aspectFit"},null,8,["src"]),n(l,{modelValue:F.value,"onUpdate:modelValue":s[0]||(s[0]=a=>F.value=a),class:"search-input",placeholder:"搜索研学路线名称","placeholder-class":"ph","confirm-type":"search",onConfirm:I},null,8,["modelValue"])]),_:1})]),_:1}),n(t,{class:"section"},{default:o(()=>[(c(!0),f(p,null,_(b.value,a=>(c(),u(t,{key:a.id,class:"tour-card",onClick:s=>{return e=a.id,void k({url:`/pages/study-tour/detail?id=${e}`});var e}},{default:o(()=>[n(t,{class:"tour-img-wrap"},{default:o(()=>[n(e,{class:"tour-img",src:a.cover_image||i(j),mode:"aspectFill"},null,8,["src"])]),_:2},1024),n(t,{class:"tour-body"},{default:o(()=>{var s;return[n(w,{class:"tour-title"},{default:o(()=>[y(h(a.name),1)]),_:2},1024),n(t,{class:"tour-stops-timeline"},{default:o(()=>[(c(!0),f(p,null,_(a.venue_names||[],(s,e)=>(c(),u(t,{key:"v-"+a.id+"-"+e,class:"tour-stop-row"},{default:o(()=>[n(t,{class:"tour-timeline-axis"},{default:o(()=>{var s;return[n(t,{class:"tour-dot-cell"},{default:o(()=>[n(t,{class:"tour-tl-dot"})]),_:1}),Number(e)<((null==(s=a.venue_names)?void 0:s.length)||0)-1?(c(),u(t,{key:0,class:"tour-tl-line"})):g("",!0)]}),_:2},1024),n(w,{class:"tour-stop-name"},{default:o(()=>[y(h(s),1)]),_:2},1024)]),_:2},1024))),128))]),_:2},1024),(null==(s=a.tags)?void 0:s.length)?(c(),u(t,{key:0,class:"tour-tags-row"},{default:o(()=>[(c(!0),f(p,null,_(a.tags,(s,e)=>(c(),u(w,{key:"t-"+a.id+"-"+e,class:"tour-tag"},{default:o(()=>[y(h(s),1)]),_:2},1024))),128))]),_:2},1024)):g("",!0)]}),_:2},1024)]),_:2},1032,["onClick"]))),128)),C.value&&!b.value.length?(c(),u(t,{key:0,class:"hint"},{default:o(()=>[y("加载中…")]),_:1})):g("",!0),C.value||b.value.length?g("",!0):(c(),u(t,{key:1,class:"hint muted"},{default:o(()=>[y("暂无研学路线")]),_:1}))]),_:1})]),_:1})}}}),[["__scopeId","data-v-cbf684f4"]]);export{C as default};
import{d as a,e as s,o as e,O as l,P as t,j as u,k as o,m as r,n as c,p as n,D as d,E as i,I as m,y as f,F as p,z as _,t as v,v as y,x as h,J as g,K as k}from"./index-DRm95jLB.js";import{c as w}from"./content.B6hfFJlR.js";import{P as j}from"./poster.DLiVsUXX.js";import{s as x}from"./search.BJnl3YRK.js";import{_ as b}from"./_plugin-vue_export-helper.BCo6x5W8.js";const C=b(a({__name:"index",setup(a){const b=s([]),C=s(!1),F=s("");async function V(){C.value=!0;try{b.value=await w({keyword:F.value.trim()||void 0})||[]}catch{b.value=[]}finally{C.value=!1}}function I(){V()}return e(()=>{V()}),l(async()=>{try{await V()}finally{t()}}),(a,s)=>{const e=d,l=m,t=r,w=v;return c(),u(t,{class:"page"},{default:o(()=>[n(t,{class:"toolbar"},{default:o(()=>[n(t,{class:"search-wrap"},{default:o(()=>[n(e,{class:"search-icon-img",src:i(x),mode:"aspectFit"},null,8,["src"]),n(l,{modelValue:F.value,"onUpdate:modelValue":s[0]||(s[0]=a=>F.value=a),class:"search-input",placeholder:"搜索研学路线名称","placeholder-class":"ph","confirm-type":"search",onConfirm:I},null,8,["modelValue"])]),_:1})]),_:1}),n(t,{class:"section"},{default:o(()=>[(c(!0),f(p,null,_(b.value,a=>(c(),u(t,{key:a.id,class:"tour-card",onClick:s=>{return e=a.id,void k({url:`/pages/study-tour/detail?id=${e}`});var e}},{default:o(()=>[n(t,{class:"tour-img-wrap"},{default:o(()=>[n(e,{class:"tour-img",src:a.cover_image||i(j),mode:"aspectFill"},null,8,["src"])]),_:2},1024),n(t,{class:"tour-body"},{default:o(()=>{var s;return[n(w,{class:"tour-title"},{default:o(()=>[y(h(a.name),1)]),_:2},1024),n(t,{class:"tour-stops-timeline"},{default:o(()=>[(c(!0),f(p,null,_(a.venue_names||[],(s,e)=>(c(),u(t,{key:"v-"+a.id+"-"+e,class:"tour-stop-row"},{default:o(()=>[n(t,{class:"tour-timeline-axis"},{default:o(()=>{var s;return[n(t,{class:"tour-dot-cell"},{default:o(()=>[n(t,{class:"tour-tl-dot"})]),_:1}),Number(e)<((null==(s=a.venue_names)?void 0:s.length)||0)-1?(c(),u(t,{key:0,class:"tour-tl-line"})):g("",!0)]}),_:2},1024),n(w,{class:"tour-stop-name"},{default:o(()=>[y(h(s),1)]),_:2},1024)]),_:2},1024))),128))]),_:2},1024),(null==(s=a.tags)?void 0:s.length)?(c(),u(t,{key:0,class:"tour-tags-row"},{default:o(()=>[(c(!0),f(p,null,_(a.tags,(s,e)=>(c(),u(w,{key:"t-"+a.id+"-"+e,class:"tour-tag"},{default:o(()=>[y(h(s),1)]),_:2},1024))),128))]),_:2},1024)):g("",!0)]}),_:2},1024)]),_:2},1032,["onClick"]))),128)),C.value&&!b.value.length?(c(),u(t,{key:0,class:"hint"},{default:o(()=>[y("加载中…")]),_:1})):g("",!0),C.value||b.value.length?g("",!0):(c(),u(t,{key:1,class:"hint muted"},{default:o(()=>[y("暂无研学路线")]),_:1}))]),_:1})]),_:1})}}}),[["__scopeId","data-v-cbf684f4"]]);export{C as default};

@ -1 +1 @@
import{d as a,e as l,Q as e,j as s,k as n,g as u,S as t,m as o,n as r,p as c,D as i,v as d,x as f,t as p,K as _}from"./index-BQvUePVO.js";import{g as v,l as m}from"./localProfile.nTeK2MPl.js";import{_ as h}from"./_plugin-vue_export-helper.BCo6x5W8.js";const k=h(a({__name:"index",setup(a){const h=l("游客"),k=l(""),g=l("");function x(a){return a&&11===a.length?`${a.slice(0,3)}****${a.slice(7)}`:a||""}function j(){_({url:"/pages/mine/profile"})}function y(){_({url:"/pages/mine/orders"})}return e(()=>{!async function(){var a;if(u(t.accessToken))try{const a=await v();return h.value=(a.real_name||a.nickname||"用户").trim()||"用户",k.value=a.phone?x(a.phone):"",void(g.value=a.avatar_url||"")}catch{}const l=m();h.value=(null==(a=null==l?void 0:l.real_name)?void 0:a.trim())||"游客",k.value=(null==l?void 0:l.phone)?x(l.phone):"",g.value=(null==l?void 0:l.avatar_url)||""}()}),(a,l)=>{const e=i,u=o,t=p;return r(),s(u,{class:"page"},{default:n(()=>[c(u,{class:"header"},{default:n(()=>[c(u,{class:"profile",onClick:j},{default:n(()=>[g.value?(r(),s(e,{key:0,class:"avatar",src:g.value,mode:"aspectFill"},null,8,["src"])):(r(),s(u,{key:1,class:"avatar placeholder"})),c(u,{class:"profile-info"},{default:n(()=>[c(u,{class:"name"},{default:n(()=>[d(f(h.value),1)]),_:1}),c(u,{class:"phone"},{default:n(()=>[d(f(k.value||"完善信息方便预约"),1)]),_:1})]),_:1})]),_:1})]),_:1}),c(u,{class:"panel"},{default:n(()=>[c(u,{class:"menu-item",onClick:j},{default:n(()=>[c(t,null,{default:n(()=>[d("我的信息")]),_:1}),c(t,null,{default:n(()=>[d(">")]),_:1})]),_:1}),c(u,{class:"menu-item",onClick:y},{default:n(()=>[c(t,null,{default:n(()=>[d("预约记录")]),_:1}),c(t,null,{default:n(()=>[d(">")]),_:1})]),_:1})]),_:1})]),_:1})}}}),[["__scopeId","data-v-0d216b84"]]);export{k as default};
import{d as a,e as l,Q as e,j as s,k as n,g as u,S as t,m as o,n as r,p as c,D as i,v as d,x as f,t as p,K as _}from"./index-DRm95jLB.js";import{g as v,l as m}from"./localProfile.xgLJTkaC.js";import{_ as h}from"./_plugin-vue_export-helper.BCo6x5W8.js";const k=h(a({__name:"index",setup(a){const h=l("游客"),k=l(""),g=l("");function x(a){return a&&11===a.length?`${a.slice(0,3)}****${a.slice(7)}`:a||""}function j(){_({url:"/pages/mine/profile"})}function y(){_({url:"/pages/mine/orders"})}return e(()=>{!async function(){var a;if(u(t.accessToken))try{const a=await v();return h.value=(a.real_name||a.nickname||"用户").trim()||"用户",k.value=a.phone?x(a.phone):"",void(g.value=a.avatar_url||"")}catch{}const l=m();h.value=(null==(a=null==l?void 0:l.real_name)?void 0:a.trim())||"游客",k.value=(null==l?void 0:l.phone)?x(l.phone):"",g.value=(null==l?void 0:l.avatar_url)||""}()}),(a,l)=>{const e=i,u=o,t=p;return r(),s(u,{class:"page"},{default:n(()=>[c(u,{class:"header"},{default:n(()=>[c(u,{class:"profile",onClick:j},{default:n(()=>[g.value?(r(),s(e,{key:0,class:"avatar",src:g.value,mode:"aspectFill"},null,8,["src"])):(r(),s(u,{key:1,class:"avatar placeholder"})),c(u,{class:"profile-info"},{default:n(()=>[c(u,{class:"name"},{default:n(()=>[d(f(h.value),1)]),_:1}),c(u,{class:"phone"},{default:n(()=>[d(f(k.value||"完善信息方便预约"),1)]),_:1})]),_:1})]),_:1})]),_:1}),c(u,{class:"panel"},{default:n(()=>[c(u,{class:"menu-item",onClick:j},{default:n(()=>[c(t,null,{default:n(()=>[d("我的信息")]),_:1}),c(t,null,{default:n(()=>[d(">")]),_:1})]),_:1}),c(u,{class:"menu-item",onClick:y},{default:n(()=>[c(t,null,{default:n(()=>[d("预约记录")]),_:1}),c(t,null,{default:n(()=>[d(">")]),_:1})]),_:1})]),_:1})]),_:1})}}}),[["__scopeId","data-v-0d216b84"]]);export{k as default};

@ -1 +0,0 @@
import{d as e,e as a,f as l,o as t,j as s,k as i,g as n,S as c,s as u,m as o,n as d,p as r,t as v,v as f,I as p,R as _,x as m,C as y,y as k,F as g,z as h,E as x,B as C,J as b,K as $,V as j}from"./index-BQvUePVO.js";import{d as w,e as V}from"./content.R922wQQ4.js";import{f as I,a as T,i as R}from"./datetime.BfIJTcZ8.js";import{_ as U}from"./_plugin-vue_export-helper.BCo6x5W8.js";const z=U(e({__name:"orders",setup(e){const U=a(""),z=a([]),B=a(!1),E=a("all"),F=l(()=>"all"===E.value?z.value:z.value.filter(e=>e.status===E.value));function J(){return!!n(c.accessToken)}function K(e){return"pending"===e?"待核销":"verified"===e?"已核销":"cancelled"===e?"已取消":"expired"===e?"已过期":e||"-"}function S(e){var a;return"pending"===(null==e?void 0:e.status)&&!R(null==(a=null==e?void 0:e.activity_day)?void 0:a.activity_date)}async function q(){const e=/^1\d{10}$/.test(U.value);if(e||J()){B.value=!0;try{z.value=await w(e?U.value:void 0)}catch(a){u({title:(null==a?void 0:a.message)||"加载失败",icon:"none"})}finally{B.value=!1}}else u({title:"请输入手机号,或先通过微信登录",icon:"none"})}return t(()=>{J()&&q()}),(e,a)=>{const l=v,t=o,n=p,c=_;return d(),s(t,{class:"page"},{default:i(()=>[r(t,{class:"notice-top"},{default:i(()=>[r(l,{class:"notice-text"},{default:i(()=>[f("请按时到场参与活动,累计 3 次无故未履约,将限制 3 个月预约资格,感谢诚信守约。")]),_:1})]),_:1}),r(t,{class:"card"},{default:i(()=>[r(t,{class:"title"},{default:i(()=>[f("我的活动预约")]),_:1}),r(t,{class:"sub"},{default:i(()=>[f("微信登录后自动展示绑定订单;也可输入预约手机号查询。")]),_:1}),r(t,{class:"row"},{default:i(()=>[r(n,{modelValue:U.value,"onUpdate:modelValue":a[0]||(a[0]=e=>U.value=e),class:"ipt",type:"number",maxlength:"11",placeholder:"预约手机号(可选,与登录二选一)"},null,8,["modelValue"]),r(c,{class:"btn",onClick:q},{default:i(()=>[f(m(B.value?"查询中":"查询"),1)]),_:1})]),_:1}),r(t,{class:"filters"},{default:i(()=>[r(t,{class:y(["chip",{active:"all"===E.value}]),onClick:a[1]||(a[1]=e=>E.value="all")},{default:i(()=>[f("全部")]),_:1},8,["class"]),r(t,{class:y(["chip",{active:"pending"===E.value}]),onClick:a[2]||(a[2]=e=>E.value="pending")},{default:i(()=>[f("待核销")]),_:1},8,["class"]),r(t,{class:y(["chip",{active:"verified"===E.value}]),onClick:a[3]||(a[3]=e=>E.value="verified")},{default:i(()=>[f("已核销")]),_:1},8,["class"]),r(t,{class:y(["chip",{active:"cancelled"===E.value}]),onClick:a[4]||(a[4]=e=>E.value="cancelled")},{default:i(()=>[f("已取消")]),_:1},8,["class"]),r(t,{class:y(["chip",{active:"expired"===E.value}]),onClick:a[5]||(a[5]=e=>E.value="expired")},{default:i(()=>[f("已过期")]),_:1},8,["class"])]),_:1})]),_:1}),(d(!0),k(g,null,h(F.value,e=>(d(),s(t,{key:e.id,class:"order-card"},{default:i(()=>[r(t,{class:"order-top"},{default:i(()=>{return[r(t,{class:"t"},{default:i(()=>{var a;return[f(m((null==(a=e.activity)?void 0:a.title)||"-"),1)]}),_:2},1024),r(t,{class:y(["status",(a=e.status,"pending"===a?"pending":"verified"===a?"verified":"expired"===a?"expired":"cancelled")])},{default:i(()=>[f(m(K(e.status)),1)]),_:2},1032,["class"])];var a}),_:2},1024),r(t,{class:"line"},{default:i(()=>{var a;return[f("订单信息:"+m(x(I)(null==(a=e.activity_day)?void 0:a.activity_date))+" "+m(e.ticket_count||1)+"人",1)]}),_:2},1024),r(t,{class:"line"},{default:i(()=>[f("联系人:"+m(e.visitor_name||"-")+" "+m(e.visitor_phone||"-"),1)]),_:2},1024),r(t,{class:"line"},{default:i(()=>[f("下单时间:"+m(x(T)(e.created_at)),1)]),_:2},1024),r(t,{class:"actions"},{default:i(()=>[S(e)?(d(),s(c,{key:0,class:"btn-light mini",onClick:C(a=>async function(e,a){const l=/^1\d{10}$/.test(U.value);if(!l&&!J())return;if(!S(a))return void u({title:"当前不可取消",icon:"none"});if((await j({title:"取消预约",content:"累计 3 次预约未履约将自动进入灰名单3 个月内将限制预约功能,请合理安排行程。\n\n确认后将取消本次预约并释放名额。",confirmText:"确认取消",cancelText:"返回",confirmColor:"#ff7d00"})).confirm)try{await V(e,l?U.value:void 0),u({title:"取消成功",icon:"success"}),await q()}catch(t){u({title:(null==t?void 0:t.message)||"取消失败",icon:"none"})}}(e.id,e),["stop"])},{default:i(()=>[f("取消")]),_:2},1032,["onClick"])):b("",!0),r(c,{class:"btn-main mini",onClick:C(a=>function(e){const a=/^1\d{10}$/.test(U.value);if(!a&&!J())return void u({title:"请输入手机号或先登录",icon:"none"});const l=a?`&phone=${encodeURIComponent(U.value)}`:"";$({url:`/pages/mine/reservation-detail?id=${e}${l}`})}(e.id),["stop"])},{default:i(()=>[f("查看详情")]),_:2},1032,["onClick"])]),_:2},1024)]),_:2},1024))),128))]),_:1})}}}),[["__scopeId","data-v-ae6fbff3"]]);export{z as default};

@ -0,0 +1 @@
import{d as e,e as a,f as t,o as l,j as s,k as i,g as n,S as c,s as u,m as o,n as d,p as r,t as v,v as f,I as _,R as p,x as m,C as g,y,F as k,z as x,E as h,B as C,J as $,K as b,V as j}from"./index-DRm95jLB.js";import{d as w,e as V}from"./content.B6hfFJlR.js";import{f as I,i as S,a as T}from"./datetime.CX3-KHA8.js";import{_ as R}from"./_plugin-vue_export-helper.BCo6x5W8.js";const U=R(e({__name:"orders",setup(e){const R=a(""),U=a([]),z=a(!1),B=a("all"),E=t(()=>"all"===B.value?U.value:U.value.filter(e=>e.status===B.value));function F(){return!!n(c.accessToken)}function J(e){return"pending"===e?"待核销":"verified"===e?"已核销":"cancelled"===e?"已取消":"expired"===e?"已过期":e||"-"}function K(e){var a;return"pending"===(null==e?void 0:e.status)&&!S(null==(a=null==e?void 0:e.activity_day)?void 0:a.activity_date)}function q(e){const a=null==e?void 0:e.activity_day;if(!a)return"-";const t=String(a.time_range_text||"").trim(),l=String(a.session_name||"").trim();return t?l?`${l} ${t}`:t:T(a.activity_date)}async function A(){const e=/^1\d{10}$/.test(R.value);if(e||F()){z.value=!0;try{U.value=await w(e?R.value:void 0)}catch(a){u({title:(null==a?void 0:a.message)||"加载失败",icon:"none"})}finally{z.value=!1}}else u({title:"请输入手机号,或先通过微信登录",icon:"none"})}return l(()=>{F()&&A()}),(e,a)=>{const t=v,l=o,n=_,c=p;return d(),s(l,{class:"page"},{default:i(()=>[r(l,{class:"notice-top"},{default:i(()=>[r(t,{class:"notice-text"},{default:i(()=>[f("请按时到场参与活动,累计 3 次无故未履约,将限制 3 个月预约资格,感谢诚信守约。")]),_:1})]),_:1}),r(l,{class:"card"},{default:i(()=>[r(l,{class:"title"},{default:i(()=>[f("我的活动预约")]),_:1}),r(l,{class:"sub"},{default:i(()=>[f("微信登录后自动展示绑定订单;也可输入预约手机号查询。")]),_:1}),r(l,{class:"row"},{default:i(()=>[r(n,{modelValue:R.value,"onUpdate:modelValue":a[0]||(a[0]=e=>R.value=e),class:"ipt",type:"number",maxlength:"11",placeholder:"预约手机号(可选,与登录二选一)"},null,8,["modelValue"]),r(c,{class:"btn",onClick:A},{default:i(()=>[f(m(z.value?"查询中":"查询"),1)]),_:1})]),_:1}),r(l,{class:"filters"},{default:i(()=>[r(l,{class:g(["chip",{active:"all"===B.value}]),onClick:a[1]||(a[1]=e=>B.value="all")},{default:i(()=>[f("全部")]),_:1},8,["class"]),r(l,{class:g(["chip",{active:"pending"===B.value}]),onClick:a[2]||(a[2]=e=>B.value="pending")},{default:i(()=>[f("待核销")]),_:1},8,["class"]),r(l,{class:g(["chip",{active:"verified"===B.value}]),onClick:a[3]||(a[3]=e=>B.value="verified")},{default:i(()=>[f("已核销")]),_:1},8,["class"]),r(l,{class:g(["chip",{active:"cancelled"===B.value}]),onClick:a[4]||(a[4]=e=>B.value="cancelled")},{default:i(()=>[f("已取消")]),_:1},8,["class"]),r(l,{class:g(["chip",{active:"expired"===B.value}]),onClick:a[5]||(a[5]=e=>B.value="expired")},{default:i(()=>[f("已过期")]),_:1},8,["class"])]),_:1})]),_:1}),(d(!0),y(k,null,x(E.value,e=>(d(),s(l,{key:e.id,class:"order-card"},{default:i(()=>[r(l,{class:"order-top"},{default:i(()=>{return[r(l,{class:"t"},{default:i(()=>{var a;return[f(m((null==(a=e.activity)?void 0:a.title)||"-"),1)]}),_:2},1024),r(l,{class:g(["status",(a=e.status,"pending"===a?"pending":"verified"===a?"verified":"expired"===a?"expired":"cancelled")])},{default:i(()=>[f(m(J(e.status)),1)]),_:2},1032,["class"])];var a}),_:2},1024),r(l,{class:"line"},{default:i(()=>[f("订单信息:"+m(q(e))+" "+m(e.ticket_count||1)+"人",1)]),_:2},1024),r(l,{class:"line"},{default:i(()=>[f("联系人:"+m(e.visitor_name||"-")+" "+m(e.visitor_phone||"-"),1)]),_:2},1024),r(l,{class:"line"},{default:i(()=>[f("下单时间:"+m(h(I)(e.created_at)),1)]),_:2},1024),r(l,{class:"actions"},{default:i(()=>[K(e)?(d(),s(c,{key:0,class:"btn-light mini",onClick:C(a=>async function(e,a){const t=/^1\d{10}$/.test(R.value);if(!t&&!F())return;if(!K(a))return void u({title:"当前不可取消",icon:"none"});if((await j({title:"取消预约",content:"累计 3 次预约未履约将自动进入灰名单3 个月内将限制预约功能,请合理安排行程。\n\n确认后将取消本次预约并释放名额。",confirmText:"确认取消",cancelText:"返回",confirmColor:"#ff7d00"})).confirm)try{await V(e,t?R.value:void 0),u({title:"取消成功",icon:"success"}),await A()}catch(l){u({title:(null==l?void 0:l.message)||"取消失败",icon:"none"})}}(e.id,e),["stop"])},{default:i(()=>[f("取消")]),_:2},1032,["onClick"])):$("",!0),r(c,{class:"btn-main mini",onClick:C(a=>function(e){const a=/^1\d{10}$/.test(R.value);if(!a&&!F())return void u({title:"请输入手机号或先登录",icon:"none"});const t=a?`&phone=${encodeURIComponent(R.value)}`:"";b({url:`/pages/mine/reservation-detail?id=${e}${t}`})}(e.id),["stop"])},{default:i(()=>[f("查看详情")]),_:2},1032,["onClick"])]),_:2},1024)]),_:2},1024))),128))]),_:1})}}}),[["__scopeId","data-v-52e9c43e"]]);export{U as default};

@ -1 +1 @@
import{d as a,e,o as l,j as s,k as t,g as n,S as u,m as r,n as o,v as c,p as v,D as i,x as d,t as p,I as _,R as m,s as f,T as h,a as y,U as k,c as b}from"./index-BQvUePVO.js";import{g,l as w,u as V,s as x}from"./localProfile.nTeK2MPl.js";import{_ as j}from"./_plugin-vue_export-helper.BCo6x5W8.js";const T=j(a({__name:"profile",setup(a){const j=e(!0),T=e(!1),U=e(!1),C=e({real_name:"",phone:"",avatar_url:""});function F(a){C.value.real_name=a.real_name||"",C.value.phone=a.phone||"",C.value.avatar_url=a.avatar_url||""}function I(){U.value?h({count:1,sizeType:["compressed"],sourceType:["album","camera"],success:async a=>{const e=a.tempFilePaths[0];if(e)try{y({title:"上传中"});const{url:a}=await k(e);C.value.avatar_url=a}catch(l){f({title:(null==l?void 0:l.message)||"上传失败",icon:"none"})}finally{b()}}}):f({title:"请先通过微信登录后再上传头像",icon:"none"})}async function P(){if(C.value.real_name.trim())if(/^1\d{10}$/.test(C.value.phone.trim())){T.value=!0;try{const a={real_name:C.value.real_name.trim(),phone:C.value.phone.trim(),avatar_url:C.value.avatar_url||void 0};U.value&&await V(a),x({real_name:a.real_name,phone:a.phone,avatar_url:a.avatar_url}),f({title:"保存成功",icon:"success"})}catch(a){f({title:(null==a?void 0:a.message)||"保存失败",icon:"none"})}finally{T.value=!1}}else f({title:"请填写11位手机号",icon:"none"});else f({title:"请填写姓名",icon:"none"})}return l(()=>{!async function(){j.value=!0,U.value=!!n(u.accessToken);try{if(U.value)try{const a=await g();C.value.real_name=a.real_name||"",C.value.phone=a.phone||"",C.value.avatar_url=a.avatar_url||""}catch{const a=w();a&&F(a)}else{const a=w();a&&F(a)}}finally{j.value=!1}}()}),(a,e)=>{const l=r,n=i,u=p,f=_,h=m;return o(),s(l,{class:"page"},{default:t(()=>[j.value?(o(),s(l,{key:0,class:"loading"},{default:t(()=>[c("加载中…")]),_:1})):(o(),s(l,{key:1,class:"content"},{default:t(()=>[v(l,{class:"avatar-block"},{default:t(()=>[v(l,{class:"avatar-wrap",onClick:I},{default:t(()=>[C.value.avatar_url?(o(),s(n,{key:0,class:"avatar",src:C.value.avatar_url,mode:"aspectFill"},null,8,["src"])):(o(),s(l,{key:1,class:"avatar placeholder"})),v(l,{class:"avatar-tip"},{default:t(()=>[c(d(U.value?"点击更换头像":"登录后可上传头像"),1)]),_:1})]),_:1})]),_:1}),v(l,{class:"card"},{default:t(()=>[v(l,{class:"row"},{default:t(()=>[v(u,{class:"label"},{default:t(()=>[c("姓名")]),_:1}),v(f,{modelValue:C.value.real_name,"onUpdate:modelValue":e[0]||(e[0]=a=>C.value.real_name=a),class:"input",placeholder:"必填","placeholder-class":"ph"},null,8,["modelValue"])]),_:1}),v(l,{class:"row last"},{default:t(()=>[v(u,{class:"label"},{default:t(()=>[c("手机号")]),_:1}),v(f,{modelValue:C.value.phone,"onUpdate:modelValue":e[1]||(e[1]=a=>C.value.phone=a),class:"input",type:"number",maxlength:"11",placeholder:"必填","placeholder-class":"ph"},null,8,["modelValue"])]),_:1})]),_:1}),v(h,{class:"btn",disabled:T.value,onClick:P},{default:t(()=>[c(d(T.value?"保存中…":"保存"),1)]),_:1},8,["disabled"])]),_:1}))]),_:1})}}}),[["__scopeId","data-v-ada2a768"]]);export{T as default};
import{d as a,e,o as l,j as s,k as t,g as n,S as u,m as r,n as o,v as c,p as v,D as i,x as d,t as p,I as _,R as m,s as f,T as h,a as y,U as k,c as b}from"./index-DRm95jLB.js";import{g,l as w,u as V,s as x}from"./localProfile.xgLJTkaC.js";import{_ as j}from"./_plugin-vue_export-helper.BCo6x5W8.js";const T=j(a({__name:"profile",setup(a){const j=e(!0),T=e(!1),U=e(!1),C=e({real_name:"",phone:"",avatar_url:""});function F(a){C.value.real_name=a.real_name||"",C.value.phone=a.phone||"",C.value.avatar_url=a.avatar_url||""}function I(){U.value?h({count:1,sizeType:["compressed"],sourceType:["album","camera"],success:async a=>{const e=a.tempFilePaths[0];if(e)try{y({title:"上传中"});const{url:a}=await k(e);C.value.avatar_url=a}catch(l){f({title:(null==l?void 0:l.message)||"上传失败",icon:"none"})}finally{b()}}}):f({title:"请先通过微信登录后再上传头像",icon:"none"})}async function P(){if(C.value.real_name.trim())if(/^1\d{10}$/.test(C.value.phone.trim())){T.value=!0;try{const a={real_name:C.value.real_name.trim(),phone:C.value.phone.trim(),avatar_url:C.value.avatar_url||void 0};U.value&&await V(a),x({real_name:a.real_name,phone:a.phone,avatar_url:a.avatar_url}),f({title:"保存成功",icon:"success"})}catch(a){f({title:(null==a?void 0:a.message)||"保存失败",icon:"none"})}finally{T.value=!1}}else f({title:"请填写11位手机号",icon:"none"});else f({title:"请填写姓名",icon:"none"})}return l(()=>{!async function(){j.value=!0,U.value=!!n(u.accessToken);try{if(U.value)try{const a=await g();C.value.real_name=a.real_name||"",C.value.phone=a.phone||"",C.value.avatar_url=a.avatar_url||""}catch{const a=w();a&&F(a)}else{const a=w();a&&F(a)}}finally{j.value=!1}}()}),(a,e)=>{const l=r,n=i,u=p,f=_,h=m;return o(),s(l,{class:"page"},{default:t(()=>[j.value?(o(),s(l,{key:0,class:"loading"},{default:t(()=>[c("加载中…")]),_:1})):(o(),s(l,{key:1,class:"content"},{default:t(()=>[v(l,{class:"avatar-block"},{default:t(()=>[v(l,{class:"avatar-wrap",onClick:I},{default:t(()=>[C.value.avatar_url?(o(),s(n,{key:0,class:"avatar",src:C.value.avatar_url,mode:"aspectFill"},null,8,["src"])):(o(),s(l,{key:1,class:"avatar placeholder"})),v(l,{class:"avatar-tip"},{default:t(()=>[c(d(U.value?"点击更换头像":"登录后可上传头像"),1)]),_:1})]),_:1})]),_:1}),v(l,{class:"card"},{default:t(()=>[v(l,{class:"row"},{default:t(()=>[v(u,{class:"label"},{default:t(()=>[c("姓名")]),_:1}),v(f,{modelValue:C.value.real_name,"onUpdate:modelValue":e[0]||(e[0]=a=>C.value.real_name=a),class:"input",placeholder:"必填","placeholder-class":"ph"},null,8,["modelValue"])]),_:1}),v(l,{class:"row last"},{default:t(()=>[v(u,{class:"label"},{default:t(()=>[c("手机号")]),_:1}),v(f,{modelValue:C.value.phone,"onUpdate:modelValue":e[1]||(e[1]=a=>C.value.phone=a),class:"input",type:"number",maxlength:"11",placeholder:"必填","placeholder-class":"ph"},null,8,["modelValue"])]),_:1})]),_:1}),v(h,{class:"btn",disabled:T.value,onClick:P},{default:t(()=>[c(d(T.value?"保存中…":"保存"),1)]),_:1},8,["disabled"])]),_:1}))]),_:1})}}}),[["__scopeId","data-v-ada2a768"]]);export{T as default};

@ -1 +1 @@
import{d as a,e as s,o as t,O as l,P as e,j as c,k as n,s as i,m as o,n as u,p as r,t as d,v as f,y as m,F as _,z as v,C as p,x as y,D as k,E as g,J as b,K as C}from"./index-BQvUePVO.js";import{a as h,g as j}from"./content.R922wQQ4.js";import{P as w}from"./poster.DLiVsUXX.js";import{_ as x}from"./_plugin-vue_export-helper.BCo6x5W8.js";const P=x(a({__name:"index",setup(a){const x=s(!0),P=s([]);async function A(){x.value=!0;try{const[a,s]=await Promise.all([h(),j().catch(()=>null)]),t=Array.isArray(a)?a:[],l=function(a){const s={};for(const t of(null==a?void 0:a.district)??[]){const a=(t.value||"").trim();a&&(s[a]=(t.label||"").trim()||a)}return s}(s);P.value=function(a,s){return a.map(a=>{const t=(a.district||"").trim(),l=t?s[t]??t:"";return{id:a.id,name:a.name||"未命名场馆",district:l,cover_image:a.cover_image||null,liveCount:0}}).sort((a,s)=>s.liveCount-a.liveCount)}(t,l)}catch(a){i({title:(null==a?void 0:a.message)||"加载失败",icon:"none"}),P.value=[]}finally{x.value=!1}}return t(()=>{A()}),l(async()=>{try{await A()}finally{e()}}),(a,s)=>{const t=o,l=d,e=k;return u(),c(t,{class:"page"},{default:n(()=>[r(t,{class:"section-title"},{default:n(()=>[r(t,{class:"bar"}),r(l,{class:"title"},{default:n(()=>[f("今日客流量统计")]),_:1})]),_:1}),x.value&&!P.value.length?(u(),c(t,{key:0,class:"state"},{default:n(()=>[f("加载中…")]),_:1})):P.value.length?(u(),c(t,{key:2,class:"list"},{default:n(()=>[(u(!0),m(_,null,v(P.value,(a,s)=>(u(),c(t,{key:a.id,class:p(["row",{"is-top1":0===s,"is-top2":1===s,"is-top3":2===s}]),onClick:s=>{var t;(t=a.id)&&C({url:`/pages/venue/detail?id=${t}`})}},{default:n(()=>[r(t,{class:"rank-wrap"},{default:n(()=>[s<3?(u(),c(t,{key:0,class:p(["medal","m"+(s+1)])},{default:n(()=>[f(y(s+1),1)]),_:2},1032,["class"])):(u(),c(l,{key:1,class:"rank-num"},{default:n(()=>[f(y(s+1),1)]),_:2},1024))]),_:2},1024),r(e,{class:"thumb",src:a.cover_image||g(w),mode:"aspectFill"},null,8,["src"]),r(t,{class:"mid"},{default:n(()=>[r(l,{class:"name"},{default:n(()=>[f(y(a.name),1)]),_:2},1024),a.district?(u(),c(l,{key:0,class:"district"},{default:n(()=>[f(y(a.district),1)]),_:2},1024)):b("",!0)]),_:2},1024),r(t,{class:"count-block"},{default:n(()=>[r(l,{class:"count-label"},{default:n(()=>[f("实时人数")]),_:1}),r(t,{class:"count-row"},{default:n(()=>[r(l,{class:"count"},{default:n(()=>[f(y(a.liveCount.toLocaleString()),1)]),_:2},1024),r(l,{class:"unit"},{default:n(()=>[f("人")]),_:1})]),_:2},1024)]),_:2},1024)]),_:2},1032,["class","onClick"]))),128))]),_:1})):(u(),c(t,{key:1,class:"state muted"},{default:n(()=>[f("暂无已上架场馆")]),_:1})),r(t,{class:"bottom-safe"})]),_:1})}}}),[["__scopeId","data-v-925a6b56"]]);export{P as default};
import{d as a,e as s,o as t,O as l,P as e,j as c,k as n,s as i,m as o,n as u,p as r,t as d,v as f,y as m,F as _,z as v,C as p,x as y,D as k,E as g,J as b,K as C}from"./index-DRm95jLB.js";import{a as h,g as j}from"./content.B6hfFJlR.js";import{P as w}from"./poster.DLiVsUXX.js";import{_ as x}from"./_plugin-vue_export-helper.BCo6x5W8.js";const P=x(a({__name:"index",setup(a){const x=s(!0),P=s([]);async function A(){x.value=!0;try{const[a,s]=await Promise.all([h(),j().catch(()=>null)]),t=Array.isArray(a)?a:[],l=function(a){const s={};for(const t of(null==a?void 0:a.district)??[]){const a=(t.value||"").trim();a&&(s[a]=(t.label||"").trim()||a)}return s}(s);P.value=function(a,s){return a.map(a=>{const t=(a.district||"").trim(),l=t?s[t]??t:"";return{id:a.id,name:a.name||"未命名场馆",district:l,cover_image:a.cover_image||null,liveCount:0}}).sort((a,s)=>s.liveCount-a.liveCount)}(t,l)}catch(a){i({title:(null==a?void 0:a.message)||"加载失败",icon:"none"}),P.value=[]}finally{x.value=!1}}return t(()=>{A()}),l(async()=>{try{await A()}finally{e()}}),(a,s)=>{const t=o,l=d,e=k;return u(),c(t,{class:"page"},{default:n(()=>[r(t,{class:"section-title"},{default:n(()=>[r(t,{class:"bar"}),r(l,{class:"title"},{default:n(()=>[f("今日客流量统计")]),_:1})]),_:1}),x.value&&!P.value.length?(u(),c(t,{key:0,class:"state"},{default:n(()=>[f("加载中…")]),_:1})):P.value.length?(u(),c(t,{key:2,class:"list"},{default:n(()=>[(u(!0),m(_,null,v(P.value,(a,s)=>(u(),c(t,{key:a.id,class:p(["row",{"is-top1":0===s,"is-top2":1===s,"is-top3":2===s}]),onClick:s=>{var t;(t=a.id)&&C({url:`/pages/venue/detail?id=${t}`})}},{default:n(()=>[r(t,{class:"rank-wrap"},{default:n(()=>[s<3?(u(),c(t,{key:0,class:p(["medal","m"+(s+1)])},{default:n(()=>[f(y(s+1),1)]),_:2},1032,["class"])):(u(),c(l,{key:1,class:"rank-num"},{default:n(()=>[f(y(s+1),1)]),_:2},1024))]),_:2},1024),r(e,{class:"thumb",src:a.cover_image||g(w),mode:"aspectFill"},null,8,["src"]),r(t,{class:"mid"},{default:n(()=>[r(l,{class:"name"},{default:n(()=>[f(y(a.name),1)]),_:2},1024),a.district?(u(),c(l,{key:0,class:"district"},{default:n(()=>[f(y(a.district),1)]),_:2},1024)):b("",!0)]),_:2},1024),r(t,{class:"count-block"},{default:n(()=>[r(l,{class:"count-label"},{default:n(()=>[f("实时人数")]),_:1}),r(t,{class:"count-row"},{default:n(()=>[r(l,{class:"count"},{default:n(()=>[f(y(a.liveCount.toLocaleString()),1)]),_:2},1024),r(l,{class:"unit"},{default:n(()=>[f("人")]),_:1})]),_:2},1024)]),_:2},1024)]),_:2},1032,["class","onClick"]))),128))]),_:1})):(u(),c(t,{key:1,class:"state muted"},{default:n(()=>[f("暂无已上架场馆")]),_:1})),r(t,{class:"bottom-safe"})]),_:1})}}}),[["__scopeId","data-v-925a6b56"]]);export{P as default};

@ -1 +1 @@
import{d as a,e,f as l,o as t,a0 as s,w as u,j as d,k as v,a6 as c,m as n,n as o,p as r,t as i,v as f,C as h,x as _,a7 as x,H as y,y as m,F as p,z as g}from"./index-BQvUePVO.js";import{_ as k}from"./_plugin-vue_export-helper.BCo6x5W8.js";const S="trafficLineChart",w=k(a({__name:"index",setup(a){const k=e("week"),w={week:[{date:"04-03",value:12358},{date:"04-04",value:15540},{date:"04-05",value:14200},{date:"04-06",value:18680},{date:"04-07",value:14820},{date:"04-08",value:20550},{date:"04-09",value:32100}],month:[{date:"04-01",value:12800},{date:"04-05",value:18800},{date:"04-10",value:17600},{date:"04-15",value:22900},{date:"04-20",value:19600},{date:"04-25",value:26400},{date:"04-30",value:30100}],year:[{date:"01月",value:268e3},{date:"03月",value:292e3},{date:"05月",value:318e3},{date:"07月",value:346e3},{date:"09月",value:332e3},{date:"11月",value:368e3},{date:"12月",value:392e3}]},b=l(()=>w[k.value]),C=l(()=>{var a,e;return`${(null==(a=b.value[0])?void 0:a.date)||"-"} 至 ${(null==(e=b.value[b.value.length-1])?void 0:e.date)||"-"}`}),T=l(()=>b.value.reduce((a,e)=>e.value>a.value?e:a,b.value[0]));function F(){const a=b.value;if(!a.length)return;const e=c(S),l=24,t=18,s=24,u=18,d=260,v=Math.min(...a.map(a=>a.value)),n=Math.max(...a.map(a=>a.value)),o=Math.max(1,n-v),r=680-u-t,i=d-l-s;e.clearRect(0,0,680,d);const f=e.createLinearGradient(0,l,0,d);f.addColorStop(0,"rgba(5,201,172,0.35)"),f.addColorStop(1,"rgba(5,201,172,0.02)");const h=a.map((e,t)=>({x:u+r*t/Math.max(1,a.length-1),y:l+(n-e.value)/o*i,value:e.value,date:e.date}));e.beginPath(),h.forEach((a,l)=>0===l?e.moveTo(a.x,a.y):e.lineTo(a.x,a.y)),e.lineTo(h[h.length-1].x,252),e.lineTo(h[0].x,252),e.closePath(),e.setFillStyle(f),e.fill(),e.beginPath(),h.forEach((a,l)=>0===l?e.moveTo(a.x,a.y):e.lineTo(a.x,a.y)),e.setStrokeStyle("#05c9ac"),e.setLineWidth(5),e.stroke(),e.setFillStyle("#ff7d00"),h.forEach(a=>{e.beginPath(),e.arc(a.x,a.y,6,0,2*Math.PI),e.fill(),e.setFillStyle("#4e5969"),e.setFontSize(20),e.fillText(a.value.toLocaleString(),a.x-34,a.y-12),e.setFillStyle("#ff7d00")}),e.draw()}return t(async()=>{await s(),F()}),u(k,async()=>{await s(),F()}),(a,e)=>{const l=n,t=i,s=x;return o(),d(l,{class:"page"},{default:v(()=>[r(l,{class:"section-title"},{default:v(()=>[r(l,{class:"bar"}),r(t,{class:"title"},{default:v(()=>[f("全市参观人数")]),_:1}),r(l,{class:"period"},{default:v(()=>[r(t,{class:h({active:"week"===k.value}),onClick:e[0]||(e[0]=a=>k.value="week")},{default:v(()=>[f("周")]),_:1},8,["class"]),r(t,{class:h({active:"month"===k.value}),onClick:e[1]||(e[1]=a=>k.value="month")},{default:v(()=>[f("月")]),_:1},8,["class"]),r(t,{class:h({active:"year"===k.value}),onClick:e[2]||(e[2]=a=>k.value="year")},{default:v(()=>[f("年")]),_:1},8,["class"])]),_:1})]),_:1}),r(l,{class:"date-range"},{default:v(()=>[f(_(C.value),1)]),_:1}),r(l,{class:"chart-card"},{default:v(()=>[r(s,{"canvas-id":S,id:S,class:"chart-canvas",style:y("width:680rpx;height:260rpx;")},null,8,["style"]),r(l,{class:"x-axis"},{default:v(()=>[(o(!0),m(p,null,g(b.value,a=>(o(),d(t,{key:a.date},{default:v(()=>[f(_(a.date),1)]),_:2},1024))),128))]),_:1})]),_:1}),r(l,{class:"list-card"},{default:v(()=>[r(l,{class:"list-title"},{default:v(()=>[f("参观人数列表")]),_:1}),(o(!0),m(p,null,g(b.value,a=>(o(),d(l,{key:a.date,class:"row"},{default:v(()=>{var e;return[r(t,{class:"d"},{default:v(()=>[f(_(a.date),1)]),_:2},1024),r(t,{class:h(["c",{hot:a.date===(null==(e=T.value)?void 0:e.date)}])},{default:v(()=>{return[f(_((e=a.value,`${e.toLocaleString()}`)),1)];var e}),_:2},1032,["class"])]}),_:2},1024))),128))]),_:1})]),_:1})}}}),[["__scopeId","data-v-bc58d322"]]);export{w as default};
import{d as a,e,f as l,o as t,a0 as s,w as u,j as d,k as v,a6 as c,m as n,n as o,p as r,t as i,v as f,C as h,x as _,a7 as x,H as y,y as m,F as p,z as g}from"./index-DRm95jLB.js";import{_ as k}from"./_plugin-vue_export-helper.BCo6x5W8.js";const S="trafficLineChart",w=k(a({__name:"index",setup(a){const k=e("week"),w={week:[{date:"04-03",value:12358},{date:"04-04",value:15540},{date:"04-05",value:14200},{date:"04-06",value:18680},{date:"04-07",value:14820},{date:"04-08",value:20550},{date:"04-09",value:32100}],month:[{date:"04-01",value:12800},{date:"04-05",value:18800},{date:"04-10",value:17600},{date:"04-15",value:22900},{date:"04-20",value:19600},{date:"04-25",value:26400},{date:"04-30",value:30100}],year:[{date:"01月",value:268e3},{date:"03月",value:292e3},{date:"05月",value:318e3},{date:"07月",value:346e3},{date:"09月",value:332e3},{date:"11月",value:368e3},{date:"12月",value:392e3}]},b=l(()=>w[k.value]),C=l(()=>{var a,e;return`${(null==(a=b.value[0])?void 0:a.date)||"-"} 至 ${(null==(e=b.value[b.value.length-1])?void 0:e.date)||"-"}`}),T=l(()=>b.value.reduce((a,e)=>e.value>a.value?e:a,b.value[0]));function F(){const a=b.value;if(!a.length)return;const e=c(S),l=24,t=18,s=24,u=18,d=260,v=Math.min(...a.map(a=>a.value)),n=Math.max(...a.map(a=>a.value)),o=Math.max(1,n-v),r=680-u-t,i=d-l-s;e.clearRect(0,0,680,d);const f=e.createLinearGradient(0,l,0,d);f.addColorStop(0,"rgba(5,201,172,0.35)"),f.addColorStop(1,"rgba(5,201,172,0.02)");const h=a.map((e,t)=>({x:u+r*t/Math.max(1,a.length-1),y:l+(n-e.value)/o*i,value:e.value,date:e.date}));e.beginPath(),h.forEach((a,l)=>0===l?e.moveTo(a.x,a.y):e.lineTo(a.x,a.y)),e.lineTo(h[h.length-1].x,252),e.lineTo(h[0].x,252),e.closePath(),e.setFillStyle(f),e.fill(),e.beginPath(),h.forEach((a,l)=>0===l?e.moveTo(a.x,a.y):e.lineTo(a.x,a.y)),e.setStrokeStyle("#05c9ac"),e.setLineWidth(5),e.stroke(),e.setFillStyle("#ff7d00"),h.forEach(a=>{e.beginPath(),e.arc(a.x,a.y,6,0,2*Math.PI),e.fill(),e.setFillStyle("#4e5969"),e.setFontSize(20),e.fillText(a.value.toLocaleString(),a.x-34,a.y-12),e.setFillStyle("#ff7d00")}),e.draw()}return t(async()=>{await s(),F()}),u(k,async()=>{await s(),F()}),(a,e)=>{const l=n,t=i,s=x;return o(),d(l,{class:"page"},{default:v(()=>[r(l,{class:"section-title"},{default:v(()=>[r(l,{class:"bar"}),r(t,{class:"title"},{default:v(()=>[f("全市参观人数")]),_:1}),r(l,{class:"period"},{default:v(()=>[r(t,{class:h({active:"week"===k.value}),onClick:e[0]||(e[0]=a=>k.value="week")},{default:v(()=>[f("周")]),_:1},8,["class"]),r(t,{class:h({active:"month"===k.value}),onClick:e[1]||(e[1]=a=>k.value="month")},{default:v(()=>[f("月")]),_:1},8,["class"]),r(t,{class:h({active:"year"===k.value}),onClick:e[2]||(e[2]=a=>k.value="year")},{default:v(()=>[f("年")]),_:1},8,["class"])]),_:1})]),_:1}),r(l,{class:"date-range"},{default:v(()=>[f(_(C.value),1)]),_:1}),r(l,{class:"chart-card"},{default:v(()=>[r(s,{"canvas-id":S,id:S,class:"chart-canvas",style:y("width:680rpx;height:260rpx;")},null,8,["style"]),r(l,{class:"x-axis"},{default:v(()=>[(o(!0),m(p,null,g(b.value,a=>(o(),d(t,{key:a.date},{default:v(()=>[f(_(a.date),1)]),_:2},1024))),128))]),_:1})]),_:1}),r(l,{class:"list-card"},{default:v(()=>[r(l,{class:"list-title"},{default:v(()=>[f("参观人数列表")]),_:1}),(o(!0),m(p,null,g(b.value,a=>(o(),d(l,{key:a.date,class:"row"},{default:v(()=>{var e;return[r(t,{class:"d"},{default:v(()=>[f(_(a.date),1)]),_:2},1024),r(t,{class:h(["c",{hot:a.date===(null==(e=T.value)?void 0:e.date)}])},{default:v(()=>{return[f(_((e=a.value,`${e.toLocaleString()}`)),1)];var e}),_:2},1032,["class"])]}),_:2},1024))),128))]),_:1})]),_:1})}}}),[["__scopeId","data-v-bc58d322"]]);export{w as default};

@ -0,0 +1 @@
.page[data-v-381e6e59]{min-height:100vh;background:#f3f5f7;padding-top:env(safe-area-inset-top);padding-bottom:calc(.75rem + env(safe-area-inset-bottom));box-sizing:border-box}.loading[data-v-381e6e59]{text-align:center;padding:1.25rem;color:#86909c;font-size:.8125rem;line-height:1.5}.addr-row[data-v-381e6e59]{margin-top:.375rem;display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem}.addr-main[data-v-381e6e59]{flex:1;min-width:0}.addr-label[data-v-381e6e59]{display:block;font-size:.8125rem;color:#86909c;line-height:1.5;margin-bottom:.1875rem}.addr-text[data-v-381e6e59]{font-size:.8125rem;color:#1d2129;line-height:1.5}.nav-btn[data-v-381e6e59]{flex-shrink:0;padding:.25rem .5625rem;border-radius:.25rem;background:#05c9ac;color:#fff;font-size:.6875rem;font-weight:400;line-height:1.35}.card[data-v-381e6e59]{background:#fff;border-radius:.4375rem;padding:.5625rem;margin:.4375rem .5rem 0;box-sizing:border-box}.title[data-v-381e6e59]{font-size:1rem;color:#1d2129;font-weight:400;line-height:1.35}.tags[data-v-381e6e59]{margin-top:.375rem;display:flex;flex-wrap:wrap;gap:.25rem}.tag[data-v-381e6e59]{font-size:.625rem;line-height:.875rem;color:#05c9ac;background:rgba(5,201,172,.12);padding:.125rem .3125rem;border-radius:.1875rem}.sec-label[data-v-381e6e59]{margin-top:.5625rem;font-size:.9375rem;font-weight:400;color:#1d2129;line-height:1.35}.sec-label[data-v-381e6e59]:first-of-type{margin-top:.5rem}.meta[data-v-381e6e59]{margin-top:.25rem;font-size:.8125rem;color:#4e5969;line-height:1.5}.sub-title[data-v-381e6e59]{font-size:.9375rem;font-weight:400;color:#1d2129;line-height:1.35;margin-bottom:.375rem}.ticket[data-v-381e6e59]{border-left:.25rem solid #05c9ac;background:#fff;border-radius:.25rem;padding:.375rem;margin-bottom:.375rem;box-shadow:0 .03125rem .125rem rgba(0,0,0,.03)}.ticket-head[data-v-381e6e59]{display:flex;justify-content:space-between;align-items:center;font-size:.8125rem;color:#4e5969;line-height:1.5}.copy[data-v-381e6e59]{color:#05c9ac}.qr[data-v-381e6e59]{width:9.375rem;height:9.375rem;margin:.375rem auto 0;display:block}.qr-name[data-v-381e6e59]{text-align:center;margin-top:.25rem;font-size:.8125rem;color:#4e5969;line-height:1.5}.tip[data-v-381e6e59]{margin-top:.25rem;text-align:center;font-size:.8125rem;color:#86909c;line-height:1.5}.action[data-v-381e6e59]{margin:.625rem .5rem 0;display:flex;justify-content:flex-end}.btn[data-v-381e6e59]{min-width:5.625rem;height:2rem;line-height:2rem;border-radius:.3125rem;border:none;background:#05c9ac;color:#fff;font-size:.8125rem;padding:0 .75rem}.btn[disabled][data-v-381e6e59]{opacity:.5}

@ -1 +0,0 @@
.page[data-v-54e24550]{min-height:100vh;background:#f3f5f7;padding-top:env(safe-area-inset-top);padding-bottom:calc(.75rem + env(safe-area-inset-bottom));box-sizing:border-box}.loading[data-v-54e24550]{text-align:center;padding:1.25rem;color:#86909c;font-size:.8125rem;line-height:1.5}.addr-row[data-v-54e24550]{margin-top:.375rem;display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem}.addr-main[data-v-54e24550]{flex:1;min-width:0}.addr-label[data-v-54e24550]{display:block;font-size:.8125rem;color:#86909c;line-height:1.5;margin-bottom:.1875rem}.addr-text[data-v-54e24550]{font-size:.8125rem;color:#1d2129;line-height:1.5}.nav-btn[data-v-54e24550]{flex-shrink:0;padding:.25rem .5625rem;border-radius:.25rem;background:#05c9ac;color:#fff;font-size:.6875rem;font-weight:400;line-height:1.35}.card[data-v-54e24550]{background:#fff;border-radius:.4375rem;padding:.5625rem;margin:.4375rem .5rem 0;box-sizing:border-box}.title[data-v-54e24550]{font-size:1rem;color:#1d2129;font-weight:400;line-height:1.35}.tags[data-v-54e24550]{margin-top:.375rem;display:flex;flex-wrap:wrap;gap:.25rem}.tag[data-v-54e24550]{font-size:.625rem;line-height:.875rem;color:#05c9ac;background:rgba(5,201,172,.12);padding:.125rem .3125rem;border-radius:.1875rem}.sec-label[data-v-54e24550]{margin-top:.5625rem;font-size:.9375rem;font-weight:400;color:#1d2129;line-height:1.35}.sec-label[data-v-54e24550]:first-of-type{margin-top:.5rem}.meta[data-v-54e24550]{margin-top:.25rem;font-size:.8125rem;color:#4e5969;line-height:1.5}.sub-title[data-v-54e24550]{font-size:.9375rem;font-weight:400;color:#1d2129;line-height:1.35;margin-bottom:.375rem}.ticket[data-v-54e24550]{border-left:.25rem solid #05c9ac;background:#fff;border-radius:.25rem;padding:.375rem;margin-bottom:.375rem;box-shadow:0 .03125rem .125rem rgba(0,0,0,.03)}.ticket-head[data-v-54e24550]{display:flex;justify-content:space-between;align-items:center;font-size:.8125rem;color:#4e5969;line-height:1.5}.copy[data-v-54e24550]{color:#05c9ac}.qr[data-v-54e24550]{width:9.375rem;height:9.375rem;margin:.375rem auto 0;display:block}.qr-name[data-v-54e24550]{text-align:center;margin-top:.25rem;font-size:.8125rem;color:#4e5969;line-height:1.5}.tip[data-v-54e24550]{margin-top:.25rem;text-align:center;font-size:.8125rem;color:#86909c;line-height:1.5}.action[data-v-54e24550]{margin:.625rem .5rem 0;display:flex;justify-content:flex-end}.btn[data-v-54e24550]{min-width:5.625rem;height:2rem;line-height:2rem;border-radius:.3125rem;border:none;background:#05c9ac;color:#fff;font-size:.8125rem;padding:0 .75rem}.btn[disabled][data-v-54e24550]{opacity:.5}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -6,7 +6,7 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>苏州市科普场馆地图</title>
<script type="module" crossorigin src="/h5/assets/index-BQvUePVO.js"></script>
<script type="module" crossorigin src="/h5/assets/index-DRm95jLB.js"></script>
<link rel="stylesheet" crossorigin href="/h5/assets/index-QCOJZRcA.css">
</head>
<body>

Loading…
Cancel
Save