You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

350 lines
7.3 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="page-container">
<view class="page-toolbar">
<button class="btn btn-ghost back-btn" @click="backToIndex">
<uni-icons type="arrow-left" size="18" color="#1e3a8a"></uni-icons>
返回
</button>
<view class="toolbar-title-wrap">
<text class="toolbar-title">回签优先</text>
</view>
</view>
<scroll-view class="page-body" scroll-y>
<view class="tabs-bar">
<view
v-for="(item, index) in tabsData"
:key="index"
class="tab-item"
:class="{ 'tab-item-active': currentTabIndex === index }"
@click="currentTabIndex = index"
>
{{ item.text }}
</view>
</view>
<!-- 回签 -->
<view v-show="currentTabIndex === 0" class="panel panel-card">
<view class="form-item">
<text class="form-label">票号</text>
<input v-model="resumeForm.ticketNo" class="form-input" placeholder="请输入票号" />
</view>
<view class="actions">
<button class="btn btn-ghost" @click="scanTicket">
<uni-icons type="scan" size="16" color="#1e3a8a" style="margin-right: 5px;"></uni-icons>
扫码
</button>
<button class="btn btn-primary" @click="confirmResume">回签</button>
</view>
</view>
<!-- 优先 -->
<view v-show="currentTabIndex === 1" class="panel">
<view class="biz-grid">
<view
v-for="(item, index) in businessList"
:key="index"
class="biz-item"
@click="takePriorityTicket(item)"
>
<view class="biz-icon">{{ item.icon }}</view>
<view class="biz-name">{{ item.name }}</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script setup>
import { getBizList } from "@/api/index.js";
import { createJumpTicket, resumeTicket } from "@/api/ticket.js";
import { onLoad } from "@dcloudio/uni-app";
import { reactive, ref } from "vue";
const currentTabIndex = ref(0);
const tabsData = [
{ text: "回签" },
{ text: "优先" },
];
const resumeForm = reactive({
ticketNo: "",
});
const businessList = ref([]);
const backToIndex = () => {
uni.navigateBack({
fail: () => {
uni.navigateTo({ url: "/pages/index/index" });
},
});
};
const scanTicket = () => {
uni.scanCode({
success: (res) => {
resumeForm.ticketNo = String(res.result || "").trim();
if (!resumeForm.ticketNo) {
uni.showToast({ title: "未识别到票号", icon: "none" });
}
},
fail: () => {
uni.showToast({ title: "扫码失败", icon: "none" });
},
});
};
const confirmResume = () => {
const ticketNo = resumeForm.ticketNo.trim();
if (!ticketNo) {
uni.showToast({ title: "请输入票号", icon: "none" });
return;
}
uni.showModal({
title: "确认回签",
content: `确认将票号 ${ticketNo} 回签吗?`,
success: async (res) => {
if (!res.confirm) return;
try {
await resumeTicket({
resumeToken: ticketNo,
});
uni.showToast({ title: "回签成功", icon: "success" });
} catch (error) {
console.log("回签失败", error);
}
},
});
};
const loadBusinessList = async () => {
try {
const res = await getBizList();
const list = Array.isArray(res) ? res : [];
businessList.value = list.map((item, index) => ({
icon: item.icon || "🧾",
name: item.name || item.bizName || "",
value: item.value || item.uid || item.id || String(index),
}));
} catch (error) {
console.log("获取业务列表失败", error);
uni.showToast({ title: "获取业务列表失败", icon: "none" });
}
};
const takePriorityTicket = (item) => {
uni.showModal({
title: "确认优先取号",
content: `确认优先取号:${item.name}`,
success: async (res) => {
if (!res.confirm) return;
try {
const result = await createJumpTicket({
bizUid: item.value,
// 兼容当前后端必填策略,沿用已有页面默认测试字段
idCard: "412827199805026017",
rankUserName: "尹朋虎",
rankUserPhone: "15382312786",
});
const tktId = result?.tktId || result?.ticketNumber || "";
uni.showToast({
title: tktId ? `取号成功:${tktId}` : "取号成功",
icon: "success",
});
} catch (error) {
console.log("优先取号失败", error);
}
},
});
};
onLoad(() => {
loadBusinessList();
});
</script>
<style lang="scss" scoped>
.page-container {
height: var(--pad-h);
overflow: hidden;
display: flex;
flex-direction: column;
background: #eef3f9;
}
.page-toolbar {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: flex-start;
gap: 12px;
padding: calc(env(safe-area-inset-top) + 10px) 20px 10px;
background: #fff;
border-bottom: 1px solid #d7e2ee;
box-shadow: 0 8px 24px rgba(30, 58, 138, 0.06);
z-index: 20;
}
.page-toolbar button,
.page-toolbar .back-btn {
width: auto !important;
flex: none;
}
.back-btn {
width: auto;
min-width: 84px;
height: 40px;
padding: 0 14px;
margin: 0;
gap: 4px;
flex-shrink: 0;
}
.toolbar-title-wrap {
flex-shrink: 0;
padding-left: 10px;
border-left: 3px solid #1d4ed8;
}
.toolbar-title {
font-size: 18px;
font-weight: 700;
color: #1e3a8a;
}
.tabs-bar {
display: inline-flex;
align-items: center;
gap: 4px;
margin-bottom: 16px;
padding: 4px;
background: #fff;
border: 1px solid #d7e2ee;
border-radius: 12px;
}
.tab-item {
min-width: 88px;
height: 36px;
padding: 0 16px;
border-radius: 10px;
font-size: 14px;
font-weight: 600;
color: #475569;
display: flex;
align-items: center;
justify-content: center;
}
.tab-item-active {
background: #2563eb;
color: #fff;
}
.page-body {
flex: 1;
height: 0;
padding: 16px 20px;
box-sizing: border-box;
}
.panel-card {
background: #fff;
border: 1px solid #d7e2ee;
border-radius: 12px;
padding: 20px;
box-shadow: 0 10px 28px rgba(30, 58, 138, 0.05);
}
.form-item {
margin-bottom: 16px;
}
.form-label {
display: block;
font-size: 14px;
color: #475569;
font-weight: 600;
margin-bottom: 8px;
}
.form-input {
width: 100%;
height: 42px;
border: 1px solid #d7e2ee;
border-radius: 10px;
padding: 0 12px;
background: #f8fafc;
box-sizing: border-box;
}
.actions {
display: flex;
gap: 12px;
}
.btn {
min-width: 110px;
height: 42px;
border-radius: 21px;
font-size: 15px;
font-weight: 600;
border: 1px solid transparent;
display: flex;
align-items: center;
justify-content: center;
}
.back-btn {
width: auto;
min-width: 84px;
padding: 0 12px;
gap: 4px;
}
.btn-primary {
background: #2563eb;
color: #fff;
}
.btn-ghost {
background: #fff;
color: #1e3a8a;
border-color: #c7d7ea;
}
.biz-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 12px;
}
.biz-item {
border: 1px solid #d7e2ee;
border-radius: 12px;
padding: 18px 12px;
background: #fff;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
box-shadow: 0 8px 20px rgba(30, 58, 138, 0.05);
}
.biz-icon {
font-size: 24px;
margin-bottom: 8px;
}
.biz-name {
font-size: 14px;
color: #1e293b;
font-weight: 600;
text-align: center;
}
</style>