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.

230 lines
5.4 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 bg-white">
<TopDivBar @back="backToIndex">
<template #left>
<view class="tabs-wrap">
<tn-tabs v-model="currentTabIndex" :bottom-shadow="false" :bar="false">
<TnTabsItem v-for="(item, index) in tabsData" :key="index" :title="item.text" />
</tn-tabs>
</view>
</template>
</TopDivBar>
<!-- 回签 -->
<view v-show="currentTabIndex === 0" class="panel">
<view class="form-item">
<text class="form-label">票号</text>
<input v-model="resumeForm.ticketNo" class="form-input" placeholder="请输入票号" />
</view>
<view class="actions">
<tn-button width="110px" height="36px" :plain="true" text-color="#0099ff" @click="scanTicket">
<uni-icons type="scan" size="16" color="#0099ff" style="margin-right: 5px;"></uni-icons>扫码
</tn-button>
<tn-button width="110px" height="36px" text-color="#fff" @click="confirmResume">
回签
</tn-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>
</view>
</template>
<script setup>
import TopDivBar from "@/components/TopDivBar.vue";
import { getBizList } from "@/api/index.js";
import { createJumpTicket, resumeTicket } from "@/api/ticket.js";
import { onLoad } from "@dcloudio/uni-app";
import { reactive, ref } from "vue";
import TnTabs from "@/uni_modules/tuniaoui-vue3/components/tabs/src/tabs.vue";
import TnTabsItem from "@/uni_modules/tuniaoui-vue3/components/tabs/src/tabs-item.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 {
min-height: 100vh;
padding-top: calc(6vh + 64px);
}
.tabs-wrap {
width: 240rpx;
}
.bg-white {
background-color: #fff;
}
.panel {
padding: 14px 20px 20px;
}
.form-item {
margin-bottom: 14px;
}
.form-label {
display: block;
font-size: 14px;
color: #374151;
margin-bottom: 6px;
}
.form-input {
width: 100%;
height: 36px;
border: 1px solid #d1d5db;
border-radius: 6px;
padding: 0 10px;
box-sizing: border-box;
}
.actions {
display: flex;
gap: 12px;
}
.biz-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 12px;
}
.biz-item {
border: 1px solid #e5e7eb;
border-radius: 10px;
padding: 16px 12px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.biz-icon {
font-size: 24px;
margin-bottom: 8px;
}
.biz-name {
font-size: 14px;
color: #111827;
text-align: center;
}
</style>