1
Showing
12 changed files
with
1237 additions
and
87 deletions
| ... | @@ -514,6 +514,12 @@ export const constantRoutes = [ | ... | @@ -514,6 +514,12 @@ export const constantRoutes = [ |
| 514 | meta: { title: '购票详情' } | 514 | meta: { title: '购票详情' } |
| 515 | }, | 515 | }, |
| 516 | { | 516 | { |
| 517 | path: 'seat_picker', | ||
| 518 | name: 'seat_picker', | ||
| 519 | component: () => import('@/viewsPc/seat/seat-picker'), | ||
| 520 | meta: { title: '选座' } | ||
| 521 | }, | ||
| 522 | { | ||
| 517 | path: 'order', | 523 | path: 'order', |
| 518 | name: 'seat_order', | 524 | name: 'seat_order', |
| 519 | component: () => import('@/viewsPc/seat/order-list'), | 525 | component: () => import('@/viewsPc/seat/order-list'), | ... | ... |
| 1 | <script setup></script> | 1 | <script setup> |
| 2 | import { ElMessage } from "element-plus"; | ||
| 3 | import { addViewPeople } from "./api/index.js"; | ||
| 4 | |||
| 5 | const router = useRouter(); | ||
| 6 | |||
| 7 | const people = reactive({ | ||
| 8 | form: { | ||
| 9 | name: "", | ||
| 10 | idCard: "", | ||
| 11 | }, | ||
| 12 | type: "身份证", | ||
| 13 | onConfirm() { | ||
| 14 | if (!people.form.name) | ||
| 15 | return ElMessage({ type: "warning", message: "请输入姓名" }); | ||
| 16 | if (!people.form.idCard) | ||
| 17 | return ElMessage({ type: "warning", message: "请输入证件号" }); | ||
| 18 | |||
| 19 | // 使用正则验证身份证号码格式 | ||
| 20 | const idCardRegex = | ||
| 21 | /^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[\dXx]$/; | ||
| 22 | if (!idCardRegex.test(people.form.idCard)) | ||
| 23 | return ElMessage({ type: "warning", message: "身份证号格式不正确" }); | ||
| 24 | |||
| 25 | addViewPeople(people.form).then((res) => { | ||
| 26 | ElMessage({ type: "success", message: "操作成功" }); | ||
| 27 | router.go(-2); | ||
| 28 | }); | ||
| 29 | }, | ||
| 30 | }); | ||
| 31 | </script> | ||
| 2 | 32 | ||
| 3 | <template> | 33 | <template> |
| 4 | <div class="container"> | 34 | <div class="container"> |
| ... | @@ -8,15 +38,15 @@ | ... | @@ -8,15 +38,15 @@ |
| 8 | <div> | 38 | <div> |
| 9 | <div class="label">姓名</div> | 39 | <div class="label">姓名</div> |
| 10 | <el-input | 40 | <el-input |
| 11 | v-model="input" | 41 | v-model="people.form.name" |
| 12 | style="width: 570px" | 42 | style="width: 570px" |
| 13 | placeholder="Please input" | 43 | placeholder="请输入姓名" |
| 14 | /> | 44 | /> |
| 15 | </div> | 45 | </div> |
| 16 | <div> | 46 | <div> |
| 17 | <div class="label">证件类型</div> | 47 | <div class="label">证件类型</div> |
| 18 | <el-input | 48 | <el-input |
| 19 | v-model="input" | 49 | v-model="people.type" |
| 20 | style="width: 570px" | 50 | style="width: 570px" |
| 21 | placeholder="Please input" | 51 | placeholder="Please input" |
| 22 | readonly | 52 | readonly |
| ... | @@ -27,9 +57,9 @@ | ... | @@ -27,9 +57,9 @@ |
| 27 | <div> | 57 | <div> |
| 28 | <div class="label">身份证号</div> | 58 | <div class="label">身份证号</div> |
| 29 | <el-input | 59 | <el-input |
| 30 | v-model="input" | 60 | v-model="people.form.idCard" |
| 31 | style="width: 570px" | 61 | style="width: 570px" |
| 32 | placeholder="Please input" | 62 | placeholder="请输入身份证号" |
| 33 | /> | 63 | /> |
| 34 | </div> | 64 | </div> |
| 35 | </div> | 65 | </div> |
| ... | @@ -37,7 +67,7 @@ | ... | @@ -37,7 +67,7 @@ |
| 37 | 67 | ||
| 38 | <div class="footer"> | 68 | <div class="footer"> |
| 39 | <div class="can_pay">取消</div> | 69 | <div class="can_pay">取消</div> |
| 40 | <div class="pay">确认</div> | 70 | <div class="pay" @click="people.onConfirm()">确认</div> |
| 41 | </div> | 71 | </div> |
| 42 | </div> | 72 | </div> |
| 43 | </template> | 73 | </template> | ... | ... |
src/viewsPc/seat/api/index.js
0 → 100644
| 1 | import request from "../utils/request"; | ||
| 2 | |||
| 3 | export const loginFree = (data) => request("POST", "/login/loginFree", data); | ||
| 4 | /** 活动详情 */ | ||
| 5 | export const activityDetail = (data) => | ||
| 6 | request("GET", `/api/activity/detail/${data.actId}`, data); | ||
| 7 | /** 场次详情 */ | ||
| 8 | export const sessionDetail = (data) => | ||
| 9 | request("GET", `/api/activity/sessionDetail/${data.actId}`, data); | ||
| 10 | /** 获取场馆信息 */ | ||
| 11 | export const getSitePlaceInfo = (data) => | ||
| 12 | request("GET", `/api/activity/getSitePlaceInfo`, data); | ||
| 13 | /** 获取票档信息 */ | ||
| 14 | export const getPriceLevelInfo = (data) => | ||
| 15 | request("GET", `/api/activity/getPriceLevelInfo`, data); | ||
| 16 | /** 获取座位信息 */ | ||
| 17 | export const getSiteConfig = (data) => | ||
| 18 | request("GET", `/api/activity/getSiteConfig`, data); | ||
| 19 | /** 确认订单 */ | ||
| 20 | export const confirmOrder = (data) => | ||
| 21 | request("POST", `/api/order/confirmOrder`, data); | ||
| 22 | /** 订单支付 */ | ||
| 23 | export const payOrder = (data) => | ||
| 24 | request("POST", `/api/order/payment`, data); | ||
| 25 | /** 观众列表 */ | ||
| 26 | export const viewPeopleList = (data) => | ||
| 27 | request("GET", `/api/customer/list`, data); | ||
| 28 | /** 删除观众 */ | ||
| 29 | export const deleteViewPeople = (data) => | ||
| 30 | request("POST", `/api/customer/delete/${data.id}`, data); | ||
| 31 | /** 新增观众 */ | ||
| 32 | export const addViewPeople = (data) => | ||
| 33 | request("POST", `/api/customer/add`, data); | ||
| 34 | /** 订单列表 */ | ||
| 35 | export const getOrderList = (data) => | ||
| 36 | request("GET", `/api/order/list`, data); | ||
| 37 | /** 立即支付 */ | ||
| 38 | export const immediatePay = (data) => | ||
| 39 | request("POST", `/api/order/immediatePay`, data); | ||
| 40 | /** 取消支付 */ | ||
| 41 | export const cancelPay = (data) => | ||
| 42 | request("POST", `/api/order/cancelPay/${data.orderSn}`, data); | ||
| 43 | /** 退单 */ | ||
| 44 | export const cancelOrder = (data) => | ||
| 45 | request("POST", `/api/order/cancelOrder/${data.orderSn}`, data); | ||
| 46 | /** 订单详情 */ | ||
| 47 | export const getOrderDetail = (data) => | ||
| 48 | request("GET", `/api/order/detail/${data.orderSn}`, data); |
src/viewsPc/seat/components/qrCodeDialog.vue
0 → 100644
| 1 | <script setup> | ||
| 2 | const props = defineProps({ | ||
| 3 | showCodeDialog: { | ||
| 4 | type: Boolean, | ||
| 5 | default: false, | ||
| 6 | }, | ||
| 7 | qrCode: { | ||
| 8 | type: String, | ||
| 9 | default: '' | ||
| 10 | } | ||
| 11 | }); | ||
| 12 | </script> | ||
| 13 | |||
| 14 | <template> | ||
| 15 | <div> | ||
| 16 | <el-dialog v-model="props.showCodeDialog" title="支付" width="300"> | ||
| 17 | <div> | ||
| 18 | <img class="qrcode" :src="props.qrCode" /> | ||
| 19 | </div> | ||
| 20 | </el-dialog> | ||
| 21 | </div> | ||
| 22 | </template> | ||
| 23 | |||
| 24 | <style scoped lang="scss"> | ||
| 25 | .qrcode { | ||
| 26 | width: 150px; | ||
| 27 | height: 150px; | ||
| 28 | background-color: #8623fc; | ||
| 29 | margin: 0 auto; | ||
| 30 | } | ||
| 31 | </style> |
| 1 | <script setup></script> | 1 | <script setup> |
| 2 | import { confirmOrder } from "./api/index.js"; | ||
| 3 | import { ElMessage } from "element-plus"; | ||
| 4 | import { payOrder, viewPeopleList } from "./api/index.js"; | ||
| 5 | import { reactive } from "vue"; | ||
| 6 | import qrCodeDialog from "./components/qrCodeDialog.vue"; | ||
| 7 | |||
| 8 | const route = useRoute(); | ||
| 9 | const router = useRouter(); | ||
| 10 | |||
| 11 | const payment = reactive({ | ||
| 12 | showCodeDialog: false, | ||
| 13 | btn_loading: false, | ||
| 14 | form: { | ||
| 15 | viewers: [], | ||
| 16 | phone: "", | ||
| 17 | }, | ||
| 18 | qrInfo: {}, | ||
| 19 | paymentHandle() { | ||
| 20 | if (payment.form.viewers.length != order.data?.seatInfo?.length) | ||
| 21 | return ElMessage({ type: "warning", message: "观看人与购买票数不符" }); | ||
| 22 | if (!payment.form.phone) | ||
| 23 | return ElMessage({ type: "warning", message: "请输入联系人电话" }); | ||
| 24 | payOrder({ | ||
| 25 | contactPhone: payment.form.phone, | ||
| 26 | customerIds: payment.form.viewers, | ||
| 27 | orderToken: order.data?.orderToken, | ||
| 28 | payType: 1, | ||
| 29 | paymentAmount: order.data?.paymentAmount, | ||
| 30 | }).then((res) => { | ||
| 31 | // TODO: 这里有一个二维码 | ||
| 32 | payment.qrInfo = res.data; | ||
| 33 | payment.showCodeDialog = true; | ||
| 34 | router.push({ | ||
| 35 | path: "/seat/order", | ||
| 36 | }); | ||
| 37 | }); | ||
| 38 | }, | ||
| 39 | }); | ||
| 40 | |||
| 41 | const order = reactive({ | ||
| 42 | data: null, | ||
| 43 | fetchData() { | ||
| 44 | confirmOrder({ | ||
| 45 | actId: route.query.actId ?? 1, | ||
| 46 | openType: route.query.openType, | ||
| 47 | sessionId: route.query.sessionId, | ||
| 48 | sitePlace: route.query.sitePlace, | ||
| 49 | ticketType: route.query.ticketType, | ||
| 50 | seatIds: route.query.seatIds.split(","), | ||
| 51 | }).then((res) => { | ||
| 52 | this.data = res.data; | ||
| 53 | }); | ||
| 54 | }, | ||
| 55 | }); | ||
| 56 | |||
| 57 | const audience = reactive({ | ||
| 58 | data: [], | ||
| 59 | fetchData() { | ||
| 60 | viewPeopleList().then((res) => { | ||
| 61 | audience.data = res.data; | ||
| 62 | }); | ||
| 63 | }, | ||
| 64 | }); | ||
| 65 | |||
| 66 | audience.fetchData(); | ||
| 67 | order.fetchData(); | ||
| 68 | </script> | ||
| 2 | 69 | ||
| 3 | <template> | 70 | <template> |
| 4 | <div class="container"> | 71 | <div class="container"> |
| ... | @@ -6,8 +73,8 @@ | ... | @@ -6,8 +73,8 @@ |
| 6 | <div class="content"> | 73 | <div class="content"> |
| 7 | <div class="left"> | 74 | <div class="left"> |
| 8 | <div class="info"> | 75 | <div class="info"> |
| 9 | <div class="name">2024亚洲舞蹈比赛无锡站</div> | 76 | <div class="name">{{ order.data?.activityName }}</div> |
| 10 | <div class="address">无锡会展中心</div> | 77 | <div class="address">{{ order.data?.placeName }}</div> |
| 11 | </div> | 78 | </div> |
| 12 | 79 | ||
| 13 | <div class="ticket_info"> | 80 | <div class="ticket_info"> |
| ... | @@ -19,27 +86,39 @@ | ... | @@ -19,27 +86,39 @@ |
| 19 | <div class="form"> | 86 | <div class="form"> |
| 20 | <el-form> | 87 | <el-form> |
| 21 | <el-form-item label="联系人"> | 88 | <el-form-item label="联系人"> |
| 22 | <el-input placeholder="请输入手机号" style="width: 260px" /> | 89 | <el-input |
| 90 | v-model="payment.form.phone" | ||
| 91 | placeholder="请输入联系人电话" | ||
| 92 | style="width: 260px" | ||
| 93 | /> | ||
| 23 | </el-form-item> | 94 | </el-form-item> |
| 24 | <el-form-item label="观看人"> | 95 | <el-form-item label="观看人"> |
| 25 | <div class="p_box"> | 96 | <div class="p_box"> |
| 26 | <div class="people"> | 97 | <div class="people"> |
| 27 | <el-checkbox-group @change=""> | 98 | <el-checkbox-group |
| 99 | v-model="payment.form.viewers" | ||
| 100 | :max="order.data?.seatInfo?.length" | ||
| 101 | > | ||
| 28 | <div | 102 | <div |
| 29 | v-for="(it, index) in 5" | 103 | v-for="(it, index) in audience.data" |
| 30 | :key="index" | 104 | :key="index" |
| 31 | class="prople_item" | 105 | class="prople_item" |
| 32 | > | 106 | > |
| 33 | <div> | 107 | <div> |
| 34 | <div class="name">张三</div> | 108 | <div class="name">{{ it.name }}</div> |
| 35 | <div class="idcard">412************073</div> | 109 | <div class="idcard">{{ it.idCard }}</div> |
| 36 | </div> | 110 | </div> |
| 37 | <el-checkbox> </el-checkbox> | 111 | <el-checkbox :value="it.id"> </el-checkbox> |
| 38 | </div> | 112 | </div> |
| 39 | </el-checkbox-group> | 113 | </el-checkbox-group> |
| 40 | </div> | 114 | </div> |
| 41 | <!-- button --> | 115 | <!-- button --> |
| 42 | <div class="btn">新增</div> | 116 | <div |
| 117 | class="btn" | ||
| 118 | @click="$router.push({ path: '/seat/people_manage' })" | ||
| 119 | > | ||
| 120 | 新增 | ||
| 121 | </div> | ||
| 43 | </div> | 122 | </div> |
| 44 | </el-form-item> | 123 | </el-form-item> |
| 45 | </el-form> | 124 | </el-form> |
| ... | @@ -55,17 +134,28 @@ | ... | @@ -55,17 +134,28 @@ |
| 55 | 134 | ||
| 56 | <div class="detail"> | 135 | <div class="detail"> |
| 57 | <div class="detail_top"> | 136 | <div class="detail_top"> |
| 58 | <div class="time">2024.03.03 周六</div> | 137 | <div class="time">{{ order.data?.dateStr }}</div> |
| 59 | <div class="ticket">80.00元票档 X2张</div> | 138 | <div class="ticket"> |
| 139 | {{ order.data?.singlePrice }}元票档 x{{ | ||
| 140 | order.data?.seatInfo?.length | ||
| 141 | }}张 | ||
| 142 | </div> | ||
| 60 | </div> | 143 | </div> |
| 61 | <div class="detail_center"> | 144 | <div class="detail_center"> |
| 62 | <div v-for="(it, index) in 4" :key="index" class="ticket"> | 145 | <div |
| 63 | A区 6排14座 (B6馆) | 146 | v-for="(it, index) in order.data?.seatInfo" |
| 147 | :key="index" | ||
| 148 | class="ticket" | ||
| 149 | > | ||
| 150 | <span v-if="it.venueId == 1">{{ it.area }}区</span> | ||
| 151 | {{ it.pai }}排{{ it.no }}座 ({{ | ||
| 152 | it.venueId == 1 ? "B6" : "B4" | ||
| 153 | }}馆) | ||
| 64 | </div> | 154 | </div> |
| 65 | </div> | 155 | </div> |
| 66 | <div class="detail_b"> | 156 | <div class="detail_b"> |
| 67 | <div class="sum_txt">共计</div> | 157 | <div class="sum_txt">共计</div> |
| 68 | <div class="price_num">¥160.00</div> | 158 | <div class="price_num">¥{{ order.data?.paymentAmount }}</div> |
| 69 | </div> | 159 | </div> |
| 70 | </div> | 160 | </div> |
| 71 | </div> | 161 | </div> |
| ... | @@ -74,8 +164,13 @@ | ... | @@ -74,8 +164,13 @@ |
| 74 | <div> | 164 | <div> |
| 75 | <span class="label">共计金额:</span><span class="value">¥900.00</span> | 165 | <span class="label">共计金额:</span><span class="value">¥900.00</span> |
| 76 | </div> | 166 | </div> |
| 77 | <div class="pay">立即支付</div> | 167 | <div class="pay" @click="payment.paymentHandle()">立即支付</div> |
| 78 | </div> | 168 | </div> |
| 169 | |||
| 170 | <qrCodeDialog | ||
| 171 | :showCodeDialog="payment.showCodeDialog" | ||
| 172 | :qrCode="payment.qrInfo?.scanCodeUrl" | ||
| 173 | /> | ||
| 79 | </div> | 174 | </div> |
| 80 | </template> | 175 | </template> |
| 81 | 176 | ||
| ... | @@ -83,6 +178,12 @@ | ... | @@ -83,6 +178,12 @@ |
| 83 | div { | 178 | div { |
| 84 | box-sizing: border-box; | 179 | box-sizing: border-box; |
| 85 | } | 180 | } |
| 181 | .qrcode { | ||
| 182 | width: 150px; | ||
| 183 | height: 150px; | ||
| 184 | background-color: #8623fc; | ||
| 185 | margin: 0 auto; | ||
| 186 | } | ||
| 86 | .container { | 187 | .container { |
| 87 | padding: 20px 0; | 188 | padding: 20px 0; |
| 88 | width: 1200px; | 189 | width: 1200px; | ... | ... |
| 1 | <script setup></script> | 1 | <script setup> |
| 2 | import { reactive } from "vue"; | ||
| 3 | import { cancelOrder, getOrderDetail } from "./api/index.js"; | ||
| 4 | import qrCodeDialog from "./components/qrCodeDialog.vue"; | ||
| 5 | import { ElMessageBox, ElMessage } from "element-plus"; | ||
| 6 | |||
| 7 | const route = useRoute(); | ||
| 8 | const router = useRouter(); | ||
| 9 | |||
| 10 | const status = reactive({ | ||
| 11 | 0: { | ||
| 12 | txt: "待支付", | ||
| 13 | color: "#F740A6", | ||
| 14 | bgColor: "#FFE2F2", | ||
| 15 | }, | ||
| 16 | 1: { | ||
| 17 | txt: "已支付", | ||
| 18 | color: "#757575", | ||
| 19 | bgColor: "#DDDDDD", | ||
| 20 | }, | ||
| 21 | 2: { | ||
| 22 | txt: "未支付", | ||
| 23 | color: "#34C759", | ||
| 24 | bgColor: "#D2FFDD", | ||
| 25 | }, | ||
| 26 | 3: { | ||
| 27 | txt: "已退款", | ||
| 28 | color: "#FFCC00", | ||
| 29 | bgColor: "#FFF7D9", | ||
| 30 | }, | ||
| 31 | }); | ||
| 32 | |||
| 33 | const detail = reactive({ | ||
| 34 | data: null, | ||
| 35 | fetchData() { | ||
| 36 | getOrderDetail({ orderSn: route.query.orderSn }).then((res) => { | ||
| 37 | detail.data = res.data; | ||
| 38 | }); | ||
| 39 | }, | ||
| 40 | }); | ||
| 41 | |||
| 42 | detail.fetchData(); | ||
| 43 | </script> | ||
| 2 | 44 | ||
| 3 | <template> | 45 | <template> |
| 4 | <div class="container"> | 46 | <div class="container"> |
| ... | @@ -14,11 +56,17 @@ | ... | @@ -14,11 +56,17 @@ |
| 14 | </div> | 56 | </div> |
| 15 | <div class="line"></div> | 57 | <div class="line"></div> |
| 16 | <div class="tr"> | 58 | <div class="tr"> |
| 17 | <div style="width: 30%" class="td">2024年亚洲舞蹈大赛无锡站</div> | 59 | <div style="width: 30%" class="td">{{ detail.data?.name }}</div> |
| 18 | <div style="width: 25%" class="td">无锡太湖国际博览中心</div> | 60 | <div style="width: 25%" class="td">{{ detail.data?.placeName }}</div> |
| 19 | <div style="width: 20%" class="td">¥80.00</div> | 61 | <div style="width: 20%" class="td"> |
| 20 | <div style="width: 12%" class="td">x3</div> | 62 | ¥{{ detail.data?.singlePrice }} |
| 21 | <div style="width: 13%; text-align: right" class="td">¥240.00</div> | 63 | </div> |
| 64 | <div style="width: 12%" class="td"> | ||
| 65 | x{{ detail.data?.seatList?.length }} | ||
| 66 | </div> | ||
| 67 | <div style="width: 13%; text-align: right" class="td"> | ||
| 68 | ¥{{ detail.data?.payAmount }} | ||
| 69 | </div> | ||
| 22 | </div> | 70 | </div> |
| 23 | </div> | 71 | </div> |
| 24 | <!-- 座位 --> | 72 | <!-- 座位 --> |
| ... | @@ -30,17 +78,20 @@ | ... | @@ -30,17 +78,20 @@ |
| 30 | </div> | 78 | </div> |
| 31 | <div class="tr"> | 79 | <div class="tr"> |
| 32 | <div style="width: 30.33%" class="td flex-col"> | 80 | <div style="width: 30.33%" class="td flex-col"> |
| 33 | <div>2024.05.03 周六</div> | 81 | <div>{{ detail.data?.dateStr }}</div> |
| 34 | <div>A区 6排16座 (B6馆)</div> | 82 | <div v-for="(it, index) in detail.data?.seatList" :key="index"> |
| 35 | <div>A区 6排16座 (B6馆)</div> | 83 | <span v-if="it.venueId == 1">{{ it.area }}区</span |
| 36 | <div>A区 6排16座 (B6馆)</div> | 84 | >{{ it.pai }}排{{ it.no }}座 ({{ |
| 85 | it.venueId == 1 ? "B6" : "B4" | ||
| 86 | }}馆) | ||
| 87 | </div> | ||
| 37 | </div> | 88 | </div> |
| 38 | <div style="width: 30.33%" class="td flex-col"> | 89 | <div style="width: 30.33%" class="td flex-col"> |
| 39 | <div>订单编号:12783893435</div> | 90 | <div>订单编号:{{ detail.data?.orderSn }}</div> |
| 40 | <div>创建时间:2024.05.07 16:3</div> | 91 | <div>创建时间:{{ detail.data?.orderTime }}</div> |
| 41 | </div> | 92 | </div> |
| 42 | <div style="width: 30.33%" class="td"> | 93 | <div style="width: 30.33%" class="td"> |
| 43 | <div>联系电话:12783893435</div> | 94 | <div>联系电话:{{ detail.data?.contactPhone }}</div> |
| 44 | </div> | 95 | </div> |
| 45 | </div> | 96 | </div> |
| 46 | </div> | 97 | </div> |
| ... | @@ -48,9 +99,13 @@ | ... | @@ -48,9 +99,13 @@ |
| 48 | <div class="pay_ticket"> | 99 | <div class="pay_ticket"> |
| 49 | <div class="title">购票人</div> | 100 | <div class="title">购票人</div> |
| 50 | <div class="people"> | 101 | <div class="people"> |
| 51 | <div v-for="(it, index) in 4" :key="index" class="p_info"> | 102 | <div |
| 52 | <div>张三</div> | 103 | v-for="(it, index) in detail.data?.customerList" |
| 53 | <div class="idcard">身份证:244************0</div> | 104 | :key="index" |
| 105 | class="p_info" | ||
| 106 | > | ||
| 107 | <div>{{ it.name }}</div> | ||
| 108 | <div class="idcard">身份证:{{ it.idCard }}</div> | ||
| 54 | </div> | 109 | </div> |
| 55 | </div> | 110 | </div> |
| 56 | </div> | 111 | </div> |
| ... | @@ -61,19 +116,31 @@ | ... | @@ -61,19 +116,31 @@ |
| 61 | <div class="title">结算信息</div> | 116 | <div class="title">结算信息</div> |
| 62 | <div class="cell"> | 117 | <div class="cell"> |
| 63 | <div class="label">订单状态</div> | 118 | <div class="label">订单状态</div> |
| 64 | <div class="value">待支付</div> | 119 | <div class="value">{{ status[detail.data?.state]?.txt }}</div> |
| 65 | </div> | 120 | </div> |
| 66 | <div class="cell"> | 121 | <div class="cell"> |
| 67 | <div class="label">订单金额</div> | 122 | <div class="label">订单金额</div> |
| 68 | <div class="value">待支付</div> | 123 | <div class="value">¥{{ detail.data?.payAmount }}</div> |
| 69 | </div> | 124 | </div> |
| 70 | <!-- button --> | 125 | <!-- button --> |
| 71 | <div class="btn_box"> | 126 | <div v-if="detail.data?.state == 0" class="btn_box"> |
| 72 | <div class="can_pay">取消支付</div> | 127 | <div class="can_pay">取消支付</div> |
| 73 | <div class="pay">立即支付</div> | 128 | <div class="pay">立即支付</div> |
| 74 | </div> | 129 | </div> |
| 130 | <div v-else> | ||
| 131 | <div v-if="detail.data?.state == 1 && detail.data?.isRefund" class="btn_box"> | ||
| 132 | <div class="can_pay">取消购票</div> | ||
| 133 | <div class="pay">再来一单</div> | ||
| 134 | </div> | ||
| 135 | |||
| 136 | <div v-else class="btn_box"> | ||
| 137 | <div class="pay_dis">请联系工作人员</div> | ||
| 138 | </div> | ||
| 139 | </div> | ||
| 140 | </div> | ||
| 141 | <div v-if="detail.data?.state == 0" class="tip"> | ||
| 142 | 请尽快完成支付,还剩15分00秒 | ||
| 75 | </div> | 143 | </div> |
| 76 | <div class="tip">请尽快完成支付,还剩15分00秒</div> | ||
| 77 | </div> | 144 | </div> |
| 78 | </div> | 145 | </div> |
| 79 | </template> | 146 | </template> |
| ... | @@ -216,6 +283,18 @@ | ... | @@ -216,6 +283,18 @@ |
| 216 | padding-top: 20px; | 283 | padding-top: 20px; |
| 217 | display: flex; | 284 | display: flex; |
| 218 | gap: 20px; | 285 | gap: 20px; |
| 286 | .pay_dis { | ||
| 287 | width: 360px; | ||
| 288 | height: 40px; | ||
| 289 | background: #A09DFF; | ||
| 290 | border-radius: 20px; | ||
| 291 | font-weight: 500; | ||
| 292 | font-size: 16px; | ||
| 293 | color: #ffffff; | ||
| 294 | line-height: 40px; | ||
| 295 | text-align: center; | ||
| 296 | cursor: pointer; | ||
| 297 | } | ||
| 219 | .pay { | 298 | .pay { |
| 220 | width: 170px; | 299 | width: 170px; |
| 221 | height: 40px; | 300 | height: 40px; | ... | ... |
| 1 | <script setup> | 1 | <script setup> |
| 2 | import { getOrderList, immediatePay, cancelPay } from "./api/index.js"; | ||
| 3 | import qrCodeDialog from "./components/qrCodeDialog.vue"; | ||
| 4 | import { ElMessageBox, ElMessage } from "element-plus"; | ||
| 5 | |||
| 2 | const status = reactive({ | 6 | const status = reactive({ |
| 3 | 0: { | 7 | 0: { |
| 4 | txt: "待支付", | 8 | txt: "待支付", |
| ... | @@ -21,47 +25,121 @@ const status = reactive({ | ... | @@ -21,47 +25,121 @@ const status = reactive({ |
| 21 | bgColor: "#FFF7D9", | 25 | bgColor: "#FFF7D9", |
| 22 | }, | 26 | }, |
| 23 | }); | 27 | }); |
| 28 | |||
| 29 | const order = reactive({ | ||
| 30 | showCodeDialog: false, | ||
| 31 | qrInfo: {}, | ||
| 32 | pay_loading: false, | ||
| 33 | pageNo: 1, | ||
| 34 | pageSize: 10, | ||
| 35 | total: 0, | ||
| 36 | data: [], | ||
| 37 | fetchData() { | ||
| 38 | getOrderList({ pageNo: order.pageNo, pageSize: order.pageSize }).then( | ||
| 39 | (res) => { | ||
| 40 | order.data = res.data.lists; | ||
| 41 | order.total = res.data.count; | ||
| 42 | } | ||
| 43 | ); | ||
| 44 | }, | ||
| 45 | payment(it) { | ||
| 46 | if (order.pay_loading) return; | ||
| 47 | order.pay_loading = true; | ||
| 48 | immediatePay({ orderSn: it.orderSn, payType: 1 }) | ||
| 49 | .then((res) => { | ||
| 50 | order.qrInfo = res.data; | ||
| 51 | order.showCodeDialog = true; | ||
| 52 | }) | ||
| 53 | .finally(() => (order.pay_loading = false)); | ||
| 54 | }, | ||
| 55 | cancelPayment(it) { | ||
| 56 | ElMessageBox.confirm("确定取消支付吗?", "Warning", { | ||
| 57 | confirmButtonText: "确认", | ||
| 58 | cancelButtonText: "取消", | ||
| 59 | type: "warning", | ||
| 60 | draggable: true, | ||
| 61 | }) | ||
| 62 | .then(() => { | ||
| 63 | cancelPay({ orderSn: it.orderSn }).then(() => { | ||
| 64 | order.fetchData(); | ||
| 65 | ElMessage({ | ||
| 66 | type: "success", | ||
| 67 | message: "操作成功", | ||
| 68 | }); | ||
| 69 | }); | ||
| 70 | }) | ||
| 71 | .catch(() => {}); | ||
| 72 | }, | ||
| 73 | }); | ||
| 74 | |||
| 75 | order.fetchData(); | ||
| 24 | </script> | 76 | </script> |
| 25 | 77 | ||
| 26 | <template> | 78 | <template> |
| 27 | <div class="container"> | 79 | <div class="container"> |
| 28 | <div | 80 | <div |
| 29 | v-for="(it, index) in 10" | 81 | v-for="(it, index) in order.data" |
| 30 | :key="index" | 82 | :key="index" |
| 31 | @click="$router.push({ path: '/seat/order_detail' })" | 83 | @click=" |
| 84 | $router.push({ | ||
| 85 | path: '/seat/order_detail', | ||
| 86 | query: { orderSn: it.orderSn }, | ||
| 87 | }) | ||
| 88 | " | ||
| 32 | class="order-item" | 89 | class="order-item" |
| 33 | > | 90 | > |
| 34 | <div class="info_box"> | 91 | <div class="info_box"> |
| 35 | <img class="cover_img" /> | 92 | <img class="cover_img" :src="it.coverImg" /> |
| 36 | <div class="info"> | 93 | <div class="info"> |
| 37 | <div class="title">2024年亚洲舞蹈大赛无锡站</div> | 94 | <div class="title">{{ it.name }}</div> |
| 38 | <div class="common">时间:2024.05.06 周六</div> | 95 | <div class="common">时间:{{ it.dateStr }}</div> |
| 39 | <div class="common">地址:无锡太湖博览中心</div> | 96 | <div class="common">地址:{{ it.placeName }}</div> |
| 40 | <div class="common">订单编号:739274039504</div> | 97 | <div class="common">订单编号:{{ it.orderSn }}</div> |
| 41 | <div class="common">张数:2张</div> | 98 | <div class="common">张数:{{ it.ticketNum }}张</div> |
| 42 | <div class="common">金额:¥728.00</div> | 99 | <div class="common">金额:¥{{ it.payAmount }}</div> |
| 43 | <div class="status"> | 100 | <div class="status"> |
| 44 | <div class="label">订单状态:</div> | 101 | <div class="label">订单状态:</div> |
| 45 | <div class="value"> | 102 | <div class="value"> |
| 46 | <div | 103 | <div |
| 47 | :style="{ | 104 | :style="{ |
| 48 | borderColor: status[0].color, | 105 | borderColor: status[it.state].color, |
| 49 | background: status[0].bgColor, | 106 | background: status[it.state].bgColor, |
| 50 | color: status[0].color, | 107 | color: status[it.state].color, |
| 51 | }" | 108 | }" |
| 52 | class="tag" | 109 | class="tag" |
| 53 | > | 110 | > |
| 54 | {{ status[0].txt }} | 111 | {{ status[it.state].txt }} |
| 55 | </div> | 112 | </div> |
| 56 | <div v-if="true" class="tip">请尽快完成支付,还剩15分00秒</div> | 113 | <div v-if="it.state == 0" class="tip"> |
| 114 | 请尽快完成支付,还剩15分00秒 | ||
| 57 | </div> | 115 | </div> |
| 58 | </div> | 116 | </div> |
| 59 | </div> | 117 | </div> |
| 60 | </div> | 118 | </div> |
| 61 | <div class="btn_box"> | ||
| 62 | <div class="pay">立即支付</div> | ||
| 63 | <div class="can_pay">取消支付</div> | ||
| 64 | </div> | 119 | </div> |
| 120 | <div v-if="it.state == 0" class="btn_box"> | ||
| 121 | <div class="pay" @click.stop="order.payment(it)">立即支付</div> | ||
| 122 | <div class="can_pay" @click.stop="order.cancelPayment(it)"> | ||
| 123 | 取消支付 | ||
| 124 | </div> | ||
| 125 | </div> | ||
| 126 | </div> | ||
| 127 | |||
| 128 | <qrCodeDialog | ||
| 129 | :showCodeDialog="order.showCodeDialog" | ||
| 130 | :qrCode="order.qrInfo?.scanCodeUrl" | ||
| 131 | /> | ||
| 132 | |||
| 133 | <div class="pagination"> | ||
| 134 | <el-pagination | ||
| 135 | v-show="order.total > 0" | ||
| 136 | v-model:current-page="order.pageNo" | ||
| 137 | v-model:page-size="order.pageSize" | ||
| 138 | background | ||
| 139 | layout="prev, pager, next" | ||
| 140 | :total="order.total" | ||
| 141 | @current-change="order.fetchData()" | ||
| 142 | /> | ||
| 65 | </div> | 143 | </div> |
| 66 | </div> | 144 | </div> |
| 67 | </template> | 145 | </template> |
| ... | @@ -87,6 +165,7 @@ const status = reactive({ | ... | @@ -87,6 +165,7 @@ const status = reactive({ |
| 87 | .cover_img { | 165 | .cover_img { |
| 88 | width: 155px; | 166 | width: 155px; |
| 89 | height: 200px; | 167 | height: 200px; |
| 168 | object-fit: fill; | ||
| 90 | } | 169 | } |
| 91 | .info { | 170 | .info { |
| 92 | .title { | 171 | .title { |
| ... | @@ -163,4 +242,9 @@ const status = reactive({ | ... | @@ -163,4 +242,9 @@ const status = reactive({ |
| 163 | } | 242 | } |
| 164 | } | 243 | } |
| 165 | } | 244 | } |
| 245 | |||
| 246 | .pagination { | ||
| 247 | display: flex; | ||
| 248 | justify-content: center; | ||
| 249 | } | ||
| 166 | </style> | 250 | </style> | ... | ... |
| 1 | <script setup></script> | 1 | <script setup> |
| 2 | import { deleteViewPeople, viewPeopleList } from "./api/index.js"; | ||
| 3 | import { ElMessageBox, ElMessage } from "element-plus"; | ||
| 4 | |||
| 5 | |||
| 6 | const audience = reactive({ | ||
| 7 | data: [], | ||
| 8 | fetchData() { | ||
| 9 | viewPeopleList().then((res) => { | ||
| 10 | audience.data = res.data; | ||
| 11 | }); | ||
| 12 | }, | ||
| 13 | |||
| 14 | deletePeople(id) { | ||
| 15 | ElMessageBox.confirm("确定删除该观看人吗?", "Warning", { | ||
| 16 | confirmButtonText: "确认", | ||
| 17 | cancelButtonText: "取消", | ||
| 18 | type: "warning", | ||
| 19 | draggable: true, | ||
| 20 | }) | ||
| 21 | .then(() => { | ||
| 22 | deleteViewPeople({ id }).then(() => { | ||
| 23 | audience.fetchData(); | ||
| 24 | ElMessage({ | ||
| 25 | type: "success", | ||
| 26 | message: "操作成功", | ||
| 27 | }); | ||
| 28 | }); | ||
| 29 | }) | ||
| 30 | .catch(() => {}); | ||
| 31 | }, | ||
| 32 | }); | ||
| 33 | |||
| 34 | audience.fetchData(); | ||
| 35 | </script> | ||
| 2 | 36 | ||
| 3 | <template> | 37 | <template> |
| 4 | <div class="container"> | 38 | <div class="container"> |
| 5 | <div class="title">观影人管理</div> | 39 | <div class="title"> |
| 40 | <div | ||
| 41 | class="add_btn" | ||
| 42 | @click="$router.push({ path: '/seat/add_watch_people' })" | ||
| 43 | > | ||
| 44 | 新增 | ||
| 45 | </div> | ||
| 46 | 观影人管理 | ||
| 47 | </div> | ||
| 6 | <div class="content"> | 48 | <div class="content"> |
| 7 | <div class="people_box"> | 49 | <div class="people_box"> |
| 8 | <div v-for="(it, index) in 10" :key="index" class="people_item"> | 50 | <div |
| 9 | <div class="name">朱育杰</div> | 51 | v-for="(it, index) in audience.data" |
| 10 | <div class="idcard">身份证:244************074</div> | 52 | :key="index" |
| 11 | <div class="btn">删除</div> | 53 | class="people_item" |
| 54 | > | ||
| 55 | <div class="name">{{ it.name }}</div> | ||
| 56 | <div class="idcard">身份证:{{ it.idCard }}</div> | ||
| 57 | <div class="btn" @click="audience.deletePeople(it.id)">删除</div> | ||
| 12 | </div> | 58 | </div> |
| 13 | </div> | 59 | </div> |
| 14 | </div> | 60 | </div> |
| ... | @@ -25,11 +71,30 @@ div { | ... | @@ -25,11 +71,30 @@ div { |
| 25 | margin: 0 auto; | 71 | margin: 0 auto; |
| 26 | 72 | ||
| 27 | .title { | 73 | .title { |
| 74 | position: relative; | ||
| 28 | padding: 11px; | 75 | padding: 11px; |
| 29 | text-align: center; | 76 | text-align: center; |
| 30 | background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%); | 77 | background: linear-gradient(270deg, #493ceb 0%, #8623fc 100%); |
| 31 | font-size: 18px; | 78 | font-size: 18px; |
| 32 | color: #ffffff; | 79 | color: #ffffff; |
| 80 | .add_btn { | ||
| 81 | position: absolute; | ||
| 82 | left: 20px; | ||
| 83 | top: 50%; | ||
| 84 | transform: translateY(-50%); | ||
| 85 | width: 68px; | ||
| 86 | height: 24px; | ||
| 87 | border-radius: 12px; | ||
| 88 | border: 1px solid #ffffff; | ||
| 89 | font-weight: 400; | ||
| 90 | font-size: 12px; | ||
| 91 | color: #ffffff; | ||
| 92 | text-align: center; | ||
| 93 | line-height: 24px; | ||
| 94 | box-sizing: border-box; | ||
| 95 | user-select: none; | ||
| 96 | cursor: pointer; | ||
| 97 | } | ||
| 33 | } | 98 | } |
| 34 | 99 | ||
| 35 | .content { | 100 | .content { | ... | ... |
src/viewsPc/seat/seat-picker.vue
0 → 100644
| 1 | <script setup> | ||
| 2 | import { ElMessage } from "element-plus"; | ||
| 3 | import { getPriceLevelInfo, getSiteConfig } from "./api/index.js"; | ||
| 4 | const route = useRoute(); | ||
| 5 | const router = useRouter() | ||
| 6 | |||
| 7 | const iframeRef = ref(); | ||
| 8 | |||
| 9 | // 获取票档 | ||
| 10 | const price = reactive({ | ||
| 11 | curPriceId: route.query.ticket_block, | ||
| 12 | data: [], | ||
| 13 | |||
| 14 | fetchData() { | ||
| 15 | getPriceLevelInfo({ | ||
| 16 | actId: route.query?.actId ?? 1, | ||
| 17 | sessionId: route.query.sessionId, | ||
| 18 | openType: route.query.openType, | ||
| 19 | sitePlace: route.query.sitePlace, | ||
| 20 | ticketType: route.query.ticketType, | ||
| 21 | }).then((res) => { | ||
| 22 | this.data = res.data; | ||
| 23 | // price.curPriceId = route.query.ticket_block | ||
| 24 | }); | ||
| 25 | }, | ||
| 26 | onClickPrice(e) { | ||
| 27 | // if (selectedSeats.value?.length) { | ||
| 28 | // return ElMessage({ type: "warning", message: "请先取消已选座位" }); | ||
| 29 | // } | ||
| 30 | price.curPriceId = e.priceId; | ||
| 31 | }, | ||
| 32 | }); | ||
| 33 | |||
| 34 | // 座位禁用时图标地址 | ||
| 35 | const disabledIconUrl = | ||
| 36 | "http://book.xiaojinyu.games/api/uploads/image/20240511/unselect_default.png"; | ||
| 37 | |||
| 38 | const siteConfig = reactive({ | ||
| 39 | loading: false, | ||
| 40 | data: [], | ||
| 41 | fetchData() { | ||
| 42 | return getSiteConfig({ | ||
| 43 | actId: route.query.actId ?? 1, | ||
| 44 | openType: route.query.openType, | ||
| 45 | sessionId: route.query.sessionId, | ||
| 46 | sitePlace: route.query.sitePlace, | ||
| 47 | ticketType: route.query.ticketType, | ||
| 48 | }).then((res) => { | ||
| 49 | const gridSize = 40; | ||
| 50 | const seat_arr = res.data.map((it, index) => { | ||
| 51 | return { | ||
| 52 | ...it, | ||
| 53 | // 这几个是iframe引擎渲染座位必须的属性,规定好的 | ||
| 54 | x: gridSize * it.x, | ||
| 55 | y: gridSize * it.y, | ||
| 56 | w: gridSize, | ||
| 57 | h: gridSize, | ||
| 58 | icon: it.state == 1 ? it.selectIcon : disabledIconUrl, // 图片的url | ||
| 59 | active: 0, // 是否选中 | ||
| 60 | priceId: route.query.openType == 0 ? it.dayPriceId : it.nightPriceId, | ||
| 61 | }; | ||
| 62 | }); | ||
| 63 | siteConfig.data = seat_arr; | ||
| 64 | return seat_arr; | ||
| 65 | }); | ||
| 66 | }, | ||
| 67 | }); | ||
| 68 | |||
| 69 | watch( | ||
| 70 | () => price.curPriceId, | ||
| 71 | (priceId) => { | ||
| 72 | siteConfig.data.forEach((it) => { | ||
| 73 | sendMsg("update-seat", { | ||
| 74 | id: it.id, | ||
| 75 | data: { | ||
| 76 | icon: | ||
| 77 | it.state == 1 && priceId == it.priceId | ||
| 78 | ? it.active | ||
| 79 | ? it.unSelectIcon | ||
| 80 | : it.selectIcon | ||
| 81 | : disabledIconUrl, | ||
| 82 | }, | ||
| 83 | }); | ||
| 84 | }); | ||
| 85 | console.log("update完成"); | ||
| 86 | }, | ||
| 87 | { immediate: true } | ||
| 88 | ); | ||
| 89 | |||
| 90 | const sendMsg = (type, data) => | ||
| 91 | iframeRef.value?.contentWindow.postMessage({ type: type, data: data }, "*"); | ||
| 92 | |||
| 93 | /** | ||
| 94 | * 1. 加載iframe 3. 请求API的数据 | ||
| 95 | * 2. 等待iframe里面资源加载完毕并触发picker-ready事件 | ||
| 96 | * 4. 传递数据给iframe,等待渲染 | ||
| 97 | */ | ||
| 98 | |||
| 99 | window.addEventListener("message", (e) => { | ||
| 100 | const data = e.data; | ||
| 101 | console.log("[parent]", data); | ||
| 102 | |||
| 103 | if (data.type == "picker-ready") { | ||
| 104 | // apiPromise.then(() => {}) | ||
| 105 | |||
| 106 | siteConfig.fetchData().then((res) => { | ||
| 107 | const seat_arr = res.map((it) => { | ||
| 108 | return { | ||
| 109 | ...it, | ||
| 110 | active: 0, | ||
| 111 | icon: | ||
| 112 | it.state == 1 && price.curPriceId == it.priceId | ||
| 113 | ? it.selectIcon | ||
| 114 | : disabledIconUrl, | ||
| 115 | }; | ||
| 116 | }); | ||
| 117 | // 子页面加载完毕,这里iframeRef一定ok | ||
| 118 | iframeRef.value.contentWindow.postMessage( | ||
| 119 | { | ||
| 120 | type: "load-seats", | ||
| 121 | data: seat_arr, | ||
| 122 | }, | ||
| 123 | "*" | ||
| 124 | ); | ||
| 125 | }); | ||
| 126 | } else if (data.type == "seat-click") { | ||
| 127 | // 子页面点击了座位 | ||
| 128 | const seatData = data.data; | ||
| 129 | console.log("座位点击", seatData); | ||
| 130 | |||
| 131 | // 如果座位处于不可点击状态,就return | ||
| 132 | if (seatData.state != 1) return; | ||
| 133 | |||
| 134 | // 如果当前筛选了某种座位,点击的不是这种座位,也返回 | ||
| 135 | if (price.curPriceId && seatData.priceId != price.curPriceId) return; | ||
| 136 | |||
| 137 | const newActive = seatData.active == 0 ? 1 : 0; | ||
| 138 | const siteConfigItem = siteConfig.data.find((it) => it.id == seatData.id); | ||
| 139 | if (siteConfigItem) { | ||
| 140 | siteConfigItem.active = newActive; | ||
| 141 | } | ||
| 142 | sendMsg("update-seat", { | ||
| 143 | id: seatData.id, | ||
| 144 | data: { | ||
| 145 | active: newActive, | ||
| 146 | icon: newActive ? seatData.unSelectIcon : seatData.selectIcon, | ||
| 147 | }, | ||
| 148 | }); | ||
| 149 | } | ||
| 150 | }); | ||
| 151 | const deleteSiteConfigItem = (seatData) => { | ||
| 152 | const newActive = seatData.active == 0 ? 1 : 0; | ||
| 153 | const siteConfigItem = siteConfig.data.find((it) => it.id == seatData.id); | ||
| 154 | if (siteConfigItem) { | ||
| 155 | siteConfigItem.active = newActive; | ||
| 156 | } | ||
| 157 | sendMsg("update-seat", { | ||
| 158 | id: seatData.id, | ||
| 159 | data: { icon: newActive ? seatData.unSelectIcon : seatData.selectIcon }, | ||
| 160 | }); | ||
| 161 | }; | ||
| 162 | |||
| 163 | /** 所选座位 */ | ||
| 164 | const selectedSeats = | ||
| 165 | computed(() => siteConfig.data.filter((it) => it.active == 1)) ?? []; | ||
| 166 | |||
| 167 | /** 所选座位价格 */ | ||
| 168 | const sumPrice = computed(() => { | ||
| 169 | return selectedSeats.value.reduce((total, item) => { | ||
| 170 | const price = | ||
| 171 | route.query.openType == 0 | ||
| 172 | ? Number(item.dayPrice) | ||
| 173 | : Number(item.nightPrice); | ||
| 174 | return total + price; | ||
| 175 | }, 0); | ||
| 176 | }); | ||
| 177 | |||
| 178 | const toConfirmOrder = () => { | ||
| 179 | const seatIds = selectedSeats.value.map((it) => it.id); | ||
| 180 | if (!seatIds.length) | ||
| 181 | return ElMessage({ type: "warning", message: "请先选择座位" }); | ||
| 182 | |||
| 183 | router.push({ | ||
| 184 | path: "/seat/confirm_order", | ||
| 185 | query: { | ||
| 186 | openType: route.query.openType, | ||
| 187 | sessionId: route.query.sessionId, | ||
| 188 | sitePlace: route.query.sitePlace, | ||
| 189 | ticketType: route.query.ticketType, | ||
| 190 | seatIds: seatIds.join(","), | ||
| 191 | }, | ||
| 192 | }); | ||
| 193 | }; | ||
| 194 | |||
| 195 | price.fetchData(); | ||
| 196 | </script> | ||
| 197 | |||
| 198 | <template> | ||
| 199 | <div class="container"> | ||
| 200 | <div class="top"> | ||
| 201 | <div class="time"> | ||
| 202 | <span>{{ route.query?.time_txt }}</span> | ||
| 203 | <span class="place">{{ route.query.sitePlace }}</span> | ||
| 204 | </div> | ||
| 205 | <div class="price_tab"> | ||
| 206 | <div | ||
| 207 | v-for="(it, index) in price.data" | ||
| 208 | class="tab_item" | ||
| 209 | :class="{ tabActive: it.priceId == price.curPriceId }" | ||
| 210 | @click="price.onClickPrice(it)" | ||
| 211 | > | ||
| 212 | <img class="seat" :src="it.selectIcon" /> | ||
| 213 | <span class="price">{{ it.price }}¥</span> | ||
| 214 | </div> | ||
| 215 | </div> | ||
| 216 | </div> | ||
| 217 | |||
| 218 | <div v-if="selectedSeats?.length" class="bottom"> | ||
| 219 | <div class="seat_box"> | ||
| 220 | <!-- v-for="(it, index) in selectedSeats" --> | ||
| 221 | <div v-for="(it, index) in selectedSeats" class="seat_item"> | ||
| 222 | <img class="seat_icon" :src="it.selectIcon" /> | ||
| 223 | <span class="num">{{ it.area }}区 {{ it.pai }}排{{ it.no }}座</span> | ||
| 224 | <el-icon | ||
| 225 | style="cursor: pointer" | ||
| 226 | color="#ccc" | ||
| 227 | @click="deleteSiteConfigItem(it)" | ||
| 228 | ><CircleCloseFilled | ||
| 229 | /></el-icon> | ||
| 230 | </div> | ||
| 231 | </div> | ||
| 232 | <div class="pay"> | ||
| 233 | <div class="sum">¥{{ sumPrice?.toFixed(2) }}</div> | ||
| 234 | <div class="pay_btn" @click="toConfirmOrder()">立即购买</div> | ||
| 235 | </div> | ||
| 236 | </div> | ||
| 237 | |||
| 238 | <div class="iframeBox"> | ||
| 239 | <iframe | ||
| 240 | ref="iframeRef" | ||
| 241 | class="iframe" | ||
| 242 | id="iframe" | ||
| 243 | src="http://seat-choose.parent4relax.com/#/seat-picker" | ||
| 244 | ></iframe> | ||
| 245 | </div> | ||
| 246 | </div> | ||
| 247 | </template> | ||
| 248 | |||
| 249 | <style scoped lang="scss"> | ||
| 250 | .container { | ||
| 251 | width: 1200px; | ||
| 252 | margin: 0 auto; | ||
| 253 | padding: 20px; | ||
| 254 | |||
| 255 | .top { | ||
| 256 | width: 100%; | ||
| 257 | background-color: #fff; | ||
| 258 | padding: 20px; | ||
| 259 | margin-bottom: 10px; | ||
| 260 | border-radius: 6px; | ||
| 261 | .time { | ||
| 262 | font-size: 18px; | ||
| 263 | font-weight: 600; | ||
| 264 | margin-bottom: 10px; | ||
| 265 | .place { | ||
| 266 | color: #7e8489; | ||
| 267 | margin-left: 15px; | ||
| 268 | } | ||
| 269 | } | ||
| 270 | |||
| 271 | .price_tab { | ||
| 272 | display: flex; | ||
| 273 | align-items: center; | ||
| 274 | flex-wrap: wrap; | ||
| 275 | gap: 10px; | ||
| 276 | .tabActive { | ||
| 277 | background: #eeeeee !important; | ||
| 278 | border: 2px solid #7e8489 !important; | ||
| 279 | } | ||
| 280 | .tab_item { | ||
| 281 | display: flex; | ||
| 282 | align-items: center; | ||
| 283 | padding: 10px 14px; | ||
| 284 | background: #f5f7f8; | ||
| 285 | border-radius: 30px; | ||
| 286 | border: 2px solid #dcdedf; | ||
| 287 | font-size: 16px; | ||
| 288 | color: #646666; | ||
| 289 | cursor: pointer; | ||
| 290 | user-select: none; | ||
| 291 | |||
| 292 | .seat { | ||
| 293 | width: 14px; | ||
| 294 | height: 14px; | ||
| 295 | margin-right: 5px; | ||
| 296 | } | ||
| 297 | } | ||
| 298 | } | ||
| 299 | } | ||
| 300 | |||
| 301 | .iframeBox { | ||
| 302 | border-radius: 6px; | ||
| 303 | background-color: #fff; | ||
| 304 | padding: 20px; | ||
| 305 | margin-bottom: 20px; | ||
| 306 | } | ||
| 307 | |||
| 308 | .iframe { | ||
| 309 | width: 100%; | ||
| 310 | height: 500px; | ||
| 311 | border: none; | ||
| 312 | background-color: #f7f8fa; | ||
| 313 | } | ||
| 314 | |||
| 315 | .bottom { | ||
| 316 | border-radius: 6px; | ||
| 317 | background-color: #fff; | ||
| 318 | padding: 20px; | ||
| 319 | margin-bottom: 20px; | ||
| 320 | .seat_box { | ||
| 321 | display: flex; | ||
| 322 | flex-wrap: wrap; | ||
| 323 | gap: 10px; | ||
| 324 | width: 100%; | ||
| 325 | .seat_item { | ||
| 326 | display: flex; | ||
| 327 | align-items: center; | ||
| 328 | padding: 10px 14px; | ||
| 329 | font-size: 16px; | ||
| 330 | color: #29343c; | ||
| 331 | background: #eeeeee; | ||
| 332 | border-radius: 30px; | ||
| 333 | border: 2px solid #7e8489; | ||
| 334 | user-select: none; | ||
| 335 | .seat_icon { | ||
| 336 | width: 14px; | ||
| 337 | height: 14px; | ||
| 338 | margin-right: 5px; | ||
| 339 | } | ||
| 340 | .num { | ||
| 341 | margin-right: 5px; | ||
| 342 | } | ||
| 343 | } | ||
| 344 | } | ||
| 345 | |||
| 346 | .pay { | ||
| 347 | display: flex; | ||
| 348 | justify-content: space-between; | ||
| 349 | align-items: center; | ||
| 350 | margin-top: 10px; | ||
| 351 | .sum { | ||
| 352 | font-weight: 600; | ||
| 353 | font-size: 22px; | ||
| 354 | color: #493ceb; | ||
| 355 | } | ||
| 356 | .pay_btn { | ||
| 357 | width: 200px; | ||
| 358 | height: 40px; | ||
| 359 | background: #493ceb; | ||
| 360 | border-radius: 20px; | ||
| 361 | margin-top: 10px; | ||
| 362 | font-size: 14px; | ||
| 363 | color: #fff; | ||
| 364 | line-height: 40px; | ||
| 365 | text-align: center; | ||
| 366 | cursor: pointer; | ||
| 367 | font-weight: 600; | ||
| 368 | user-select: none; | ||
| 369 | } | ||
| 370 | } | ||
| 371 | } | ||
| 372 | } | ||
| 373 | </style> |
| 1 | <script setup></script> | 1 | <script setup> |
| 2 | import dayjs from "dayjs"; | ||
| 3 | import useUserStore from "@/store/modules/user"; | ||
| 4 | import { setToken, getToken } from "./utils/local-store.js"; | ||
| 5 | import { | ||
| 6 | loginFree, | ||
| 7 | activityDetail, | ||
| 8 | sessionDetail, | ||
| 9 | getSitePlaceInfo, | ||
| 10 | getPriceLevelInfo, | ||
| 11 | } from "./api/index.js"; | ||
| 12 | import { ElMessage } from "element-plus"; | ||
| 13 | import { reactive } from "vue"; | ||
| 14 | |||
| 15 | const route = useRoute(); | ||
| 16 | const router = useRouter(); | ||
| 17 | const userStore = useUserStore(); | ||
| 18 | const actId = 1; | ||
| 19 | |||
| 20 | // 用户免登录 | ||
| 21 | const login = () => { | ||
| 22 | return new Promise((resolve, reject) => { | ||
| 23 | return loginFree({ | ||
| 24 | userId: 1, | ||
| 25 | sign: "e00363b5016dbb6ee6cf78626a149f9c", | ||
| 26 | }).then((res) => { | ||
| 27 | setToken(res.data.token); | ||
| 28 | resolve(res.data); | ||
| 29 | }); | ||
| 30 | }); | ||
| 31 | }; | ||
| 32 | |||
| 33 | const select_form = reactive({ | ||
| 34 | venueItem: { | ||
| 35 | id: 0, | ||
| 36 | dateStr: "", | ||
| 37 | dayOpen: 1, | ||
| 38 | nightOpen: 1, | ||
| 39 | type: 0, | ||
| 40 | }, // 所选场次 | ||
| 41 | session: -1, // 日/夜场 0:日场 1:夜场 | ||
| 42 | place: "", // 场馆 | ||
| 43 | ticket_block: 0, // 票档 | ||
| 44 | onClickVenue(e, index) { | ||
| 45 | if (e.state == 1) return; // 表示 | ||
| 46 | select_form.venueItem = e; | ||
| 47 | if ( | ||
| 48 | (e.dayOpen == 0 && select_form.session == 0) || | ||
| 49 | (e.nightOpen == 0 && select_form.session == 1) | ||
| 50 | ) { | ||
| 51 | select_form.session = -1; | ||
| 52 | select_form.place = ""; | ||
| 53 | select_form.ticket_block = 0; | ||
| 54 | } | ||
| 55 | }, | ||
| 56 | // 选择日/夜场 | ||
| 57 | onClickSession(e) { | ||
| 58 | if ( | ||
| 59 | (e == 0 && select_form.venueItem?.dayOpen == 1) || | ||
| 60 | (e == 1 && select_form.venueItem?.nightOpen == 1) | ||
| 61 | ) { | ||
| 62 | select_form.session = e; | ||
| 63 | // select_form.place = ""; | ||
| 64 | select_form.ticket_block = 0; | ||
| 65 | } | ||
| 66 | }, | ||
| 67 | // 选择场馆 | ||
| 68 | onClickPlace(e) { | ||
| 69 | if (e.state == 1) return; | ||
| 70 | select_form.place = e.placeName; | ||
| 71 | select_form.ticket_block = 0; | ||
| 72 | }, | ||
| 73 | // 选择票档 | ||
| 74 | onClickPrice(e) { | ||
| 75 | if (e.state == 1) return; | ||
| 76 | select_form.ticket_block = e.priceId; | ||
| 77 | }, | ||
| 78 | // 去选座 | ||
| 79 | toSelectSeat() { | ||
| 80 | if (!select_form.venueItem?.id) | ||
| 81 | return ElMessage({ type: "warning", message: "请选择时间" }); | ||
| 82 | if (select_form.session == -1) | ||
| 83 | return ElMessage({ type: "warning", message: "请选择场次" }); | ||
| 84 | if (!select_form.place) | ||
| 85 | return ElMessage({ type: "warning", message: "请选择场馆" }); | ||
| 86 | if (!select_form.ticket_block) | ||
| 87 | return ElMessage({ type: "warning", message: "请选择票档" }); | ||
| 88 | |||
| 89 | router.push({ | ||
| 90 | path: "/seat/seat_picker", | ||
| 91 | query: { | ||
| 92 | openType: select_form.session, | ||
| 93 | sessionId: select_form.venueItem?.id, | ||
| 94 | sitePlace: select_form.place, | ||
| 95 | ticketType: select_form.venueItem?.type, | ||
| 96 | ticket_block: select_form.ticket_block, | ||
| 97 | time_txt: select_form.venueItem?.dateStr, | ||
| 98 | }, | ||
| 99 | }); | ||
| 100 | }, | ||
| 101 | }); | ||
| 102 | |||
| 103 | // 活动详情 | ||
| 104 | const detail = reactive({ | ||
| 105 | loading: false, | ||
| 106 | data: null, | ||
| 107 | fetchData() { | ||
| 108 | this.loading = true; | ||
| 109 | activityDetail({ actId: route.query?.actId ?? actId }) | ||
| 110 | .then((res) => { | ||
| 111 | this.data = res.data; | ||
| 112 | }) | ||
| 113 | .finally(() => (this.loding = false)); | ||
| 114 | }, | ||
| 115 | }); | ||
| 116 | |||
| 117 | // 获取场次信息 | ||
| 118 | const timeVenue = reactive({ | ||
| 119 | loading: false, | ||
| 120 | data: [], | ||
| 121 | fetchData() { | ||
| 122 | this.loading = true; | ||
| 123 | sessionDetail({ actId: route.query?.actId ?? actId }) | ||
| 124 | .then((res) => { | ||
| 125 | this.data = res.data; | ||
| 126 | }) | ||
| 127 | .finally(() => (this.loading = false)); | ||
| 128 | }, | ||
| 129 | }); | ||
| 130 | |||
| 131 | // 获取场馆 | ||
| 132 | const sitePlaceInfo = reactive({ | ||
| 133 | data: [ | ||
| 134 | { placeName: "B4", state: "0" }, | ||
| 135 | { placeName: "B6", state: "0" }, | ||
| 136 | ], | ||
| 137 | fetchData() { | ||
| 138 | console.log(select_form.venueItem?.id, select_form.session); | ||
| 139 | getSitePlaceInfo({ | ||
| 140 | sessionId: select_form.venueItem?.id, | ||
| 141 | openType: select_form.session, | ||
| 142 | }).then((res) => { | ||
| 143 | this.data = res.data; | ||
| 144 | }); | ||
| 145 | }, | ||
| 146 | }); | ||
| 147 | |||
| 148 | // 获取票档 | ||
| 149 | const price = reactive({ | ||
| 150 | data: [], | ||
| 151 | fetchData() { | ||
| 152 | getPriceLevelInfo({ | ||
| 153 | actId: route.query?.actId ?? actId, | ||
| 154 | sessionId: select_form.venueItem?.id, | ||
| 155 | openType: select_form.session, | ||
| 156 | sitePlace: select_form.place, | ||
| 157 | ticketType: select_form.venueItem?.type, | ||
| 158 | }).then((res) => { | ||
| 159 | this.data = res.data; | ||
| 160 | }); | ||
| 161 | }, | ||
| 162 | }); | ||
| 163 | |||
| 164 | watchEffect(() => { | ||
| 165 | if (select_form.session != -1 && select_form.venueItem?.id) { | ||
| 166 | if (select_form.session == 1 && select_form.place == "B4") { | ||
| 167 | select_form.place = ""; | ||
| 168 | } | ||
| 169 | sitePlaceInfo.fetchData(); | ||
| 170 | } | ||
| 171 | }); | ||
| 172 | |||
| 173 | watchEffect(() => { | ||
| 174 | if ( | ||
| 175 | select_form.venueItem?.id && | ||
| 176 | select_form.session != -1 && | ||
| 177 | select_form.place | ||
| 178 | ) { | ||
| 179 | price.fetchData(); | ||
| 180 | } | ||
| 181 | }); | ||
| 182 | |||
| 183 | login().then((res) => { | ||
| 184 | detail.fetchData(); | ||
| 185 | timeVenue.fetchData(); | ||
| 186 | }); | ||
| 187 | </script> | ||
| 2 | 188 | ||
| 3 | <template> | 189 | <template> |
| 4 | <div> | 190 | <div> |
| 5 | <!-- top --> | 191 | <!-- top --> |
| 6 | <div class="container top"> | 192 | <div class="container top"> |
| 7 | <img class="cover_img" /> | 193 | <img class="cover_img" :src="detail.data?.coverImg" /> |
| 8 | <div class="info"> | 194 | <div class="info"> |
| 9 | <div class="title">2024年亚洲舞蹈大赛无锡站</div> | 195 | <div class="title">{{ detail.data?.name }}</div> |
| 10 | <div class="time">时间:2024.05.02 周六 — 2024.05.08 周一</div> | 196 | <div class="time"> |
| 11 | <div class="address">地址:无锡太湖博览中心</div> | 197 | 时间:{{ |
| 198 | detail.data?.startTime | ||
| 199 | ? dayjs(detail.data?.startTime).format("YYYY.MM.DD") | ||
| 200 | : "" | ||
| 201 | }} | ||
| 202 | {{ detail.data?.startTime ? dayjs().format("ddd") : "" }} — | ||
| 203 | {{ | ||
| 204 | detail.data?.endTime | ||
| 205 | ? dayjs(detail.data?.endTime).format("YYYY.MM.DD") | ||
| 206 | : "" | ||
| 207 | }} | ||
| 208 | {{ | ||
| 209 | detail.data?.endTime | ||
| 210 | ? dayjs(detail.data?.endTime).format("ddd") | ||
| 211 | : "" | ||
| 212 | }} | ||
| 213 | </div> | ||
| 214 | <div class="address">地址:{{ detail.data?.address }}</div> | ||
| 12 | <!-- 时间 --> | 215 | <!-- 时间 --> |
| 13 | <div class="select_item_box"> | 216 | <div class="select_item_box"> |
| 14 | <div class="label">时间</div> | 217 | <div class="label">时间</div> |
| 15 | <div class="select_item"> | 218 | <div class="select_item"> |
| 16 | <div | 219 | <div |
| 17 | v-for="(it, index) in 4" | 220 | v-for="(it, index) in timeVenue.data" |
| 18 | :key="index" | 221 | :key="index" |
| 19 | :class="[false ? 'tagActive' : 'tag']" | 222 | :class="[ |
| 223 | it.id == select_form.venueItem?.id ? 'tagActive' : 'tag', | ||
| 224 | ]" | ||
| 225 | @click="select_form.onClickVenue(it)" | ||
| 20 | > | 226 | > |
| 21 | 2024.05.02 周六 | 227 | {{ it.dateStr }} |
| 228 | <div v-if="it.type == 1" class="tag_t">套票</div> | ||
| 22 | </div> | 229 | </div> |
| 23 | </div> | 230 | </div> |
| 24 | </div> | 231 | </div> |
| ... | @@ -26,11 +233,29 @@ | ... | @@ -26,11 +233,29 @@ |
| 26 | <div class="select_item_box"> | 233 | <div class="select_item_box"> |
| 27 | <div class="label">场次</div> | 234 | <div class="label">场次</div> |
| 28 | <div class="select_item"> | 235 | <div class="select_item"> |
| 29 | <div :class="[true ? 'tagDisabled' : false ? 'tagActive' : 'tag']"> | 236 | <div |
| 237 | :class="[ | ||
| 238 | select_form.venueItem?.dayOpen == 1 | ||
| 239 | ? select_form.session == 0 | ||
| 240 | ? 'tagActive' | ||
| 241 | : 'tag' | ||
| 242 | : 'tagDisabled', | ||
| 243 | ]" | ||
| 244 | @click="select_form.onClickSession(0)" | ||
| 245 | > | ||
| 30 | 日场 | 246 | 日场 |
| 31 | </div> | 247 | </div> |
| 32 | <div :class="[true ? 'tagDisabled' : false ? 'tagActive' : 'tag']"> | 248 | <div |
| 33 | 日场 | 249 | :class="[ |
| 250 | select_form.venueItem?.nightOpen == 1 | ||
| 251 | ? select_form.session == 1 | ||
| 252 | ? 'tagActive' | ||
| 253 | : 'tag' | ||
| 254 | : 'tagDisabled', | ||
| 255 | ]" | ||
| 256 | @click="select_form.onClickSession(1)" | ||
| 257 | > | ||
| 258 | 夜场 | ||
| 34 | </div> | 259 | </div> |
| 35 | </div> | 260 | </div> |
| 36 | </div> | 261 | </div> |
| ... | @@ -39,39 +264,56 @@ | ... | @@ -39,39 +264,56 @@ |
| 39 | <div class="label">场馆</div> | 264 | <div class="label">场馆</div> |
| 40 | <div class="select_item"> | 265 | <div class="select_item"> |
| 41 | <div | 266 | <div |
| 42 | v-for="(it, index) in 2" | 267 | v-for="(it, index) in sitePlaceInfo.data" |
| 43 | :key="index" | 268 | :key="index" |
| 44 | :class="[true ? 'tagDisabled' : false ? 'tagActive' : 'tag']" | 269 | :class="[ |
| 270 | it.state == 0 | ||
| 271 | ? it.placeName == select_form.place | ||
| 272 | ? 'tagActive' | ||
| 273 | : 'tag' | ||
| 274 | : 'tagDisabled', | ||
| 275 | ]" | ||
| 276 | @click="select_form.onClickPlace(it)" | ||
| 45 | > | 277 | > |
| 46 | B6 | 278 | {{ it.placeName }} |
| 47 | </div> | 279 | </div> |
| 48 | </div> | 280 | </div> |
| 49 | </div> | 281 | </div> |
| 50 | <!-- 票档 --> | 282 | <!-- 票档 --> |
| 51 | <div class="select_item_box"> | 283 | <div |
| 284 | v-if="price.data?.length && select_form.place" | ||
| 285 | class="select_item_box" | ||
| 286 | > | ||
| 52 | <div class="label">票档</div> | 287 | <div class="label">票档</div> |
| 53 | <div class="select_item"> | 288 | <div class="select_item"> |
| 54 | <div | 289 | <div |
| 55 | v-for="(it, index) in 3" | 290 | v-for="(it, index) in price.data" |
| 56 | :key="index" | 291 | :key="index" |
| 57 | :class="[true ? 'tagDisabled' : false ? 'tagActive' : 'tag']" | 292 | :class="[ |
| 293 | it.state == 0 | ||
| 294 | ? it.priceId == select_form.ticket_block | ||
| 295 | ? 'tagActive' | ||
| 296 | : 'tag' | ||
| 297 | : 'tagDisabled', | ||
| 298 | ]" | ||
| 299 | @click="select_form.onClickPrice(it)" | ||
| 58 | > | 300 | > |
| 59 | 200.00元 | 301 | {{ it.price }}元 |
| 60 | </div> | 302 | </div> |
| 61 | </div> | 303 | </div> |
| 62 | </div> | 304 | </div> |
| 63 | <!-- button --> | 305 | <!-- button --> |
| 64 | <div class="btn">选座购票</div> | 306 | <div class="btn" @click="select_form.toSelectSeat()">选座购票</div> |
| 65 | </div> | 307 | </div> |
| 66 | </div> | 308 | </div> |
| 67 | 309 | ||
| 68 | <!-- bottom --> | 310 | <!-- bottom --> |
| 69 | <div class="container bottom"> | 311 | <div class="container bottom"> |
| 70 | <div class="title">活动介绍</div> | 312 | <div class="title">活动介绍</div> |
| 71 | <div class="rich_content" v-html="'123123123123123123'"></div> | 313 | <div class="rich_content" v-html="detail.data?.introduceInfo"></div> |
| 72 | 314 | ||
| 73 | <div class="title" style="margin-top: 30px">购票须知</div> | 315 | <div class="title" style="margin-top: 30px">购票须知</div> |
| 74 | <div class="rich_content" v-html="'123123123123123123'"></div> | 316 | <div class="rich_content" v-html="detail.data?.buyNotice"></div> |
| 75 | </div> | 317 | </div> |
| 76 | </div> | 318 | </div> |
| 77 | </template> | 319 | </template> |
| ... | @@ -142,7 +384,18 @@ | ... | @@ -142,7 +384,18 @@ |
| 142 | display: flex; | 384 | display: flex; |
| 143 | flex-wrap: wrap; | 385 | flex-wrap: wrap; |
| 144 | gap: 10px; | 386 | gap: 10px; |
| 387 | user-select: none; | ||
| 388 | .tag_t { | ||
| 389 | padding: 1px 15px; | ||
| 390 | font-weight: 400; | ||
| 391 | font-size: 14px; | ||
| 392 | color: #493ceb; | ||
| 393 | border-radius: 6px; | ||
| 394 | border: 1px solid #453dea; | ||
| 395 | margin-left: 5px; | ||
| 396 | } | ||
| 145 | .tag { | 397 | .tag { |
| 398 | display: flex; | ||
| 146 | padding: 12px 18px; | 399 | padding: 12px 18px; |
| 147 | background: #eeeeee; | 400 | background: #eeeeee; |
| 148 | border-radius: 4px; | 401 | border-radius: 4px; |
| ... | @@ -151,7 +404,9 @@ | ... | @@ -151,7 +404,9 @@ |
| 151 | color: #4a4a4a; | 404 | color: #4a4a4a; |
| 152 | cursor: pointer; | 405 | cursor: pointer; |
| 153 | } | 406 | } |
| 407 | |||
| 154 | .tagActive { | 408 | .tagActive { |
| 409 | display: flex; | ||
| 155 | padding: 12px 18px; | 410 | padding: 12px 18px; |
| 156 | background: #fff; | 411 | background: #fff; |
| 157 | border-radius: 4px; | 412 | border-radius: 4px; | ... | ... |
src/viewsPc/seat/utils/local-store.js
0 → 100644
| 1 | /** 用户登录token储存的key */ | ||
| 2 | export const TOKEN_KEY = "SEAT_TOKEN"; | ||
| 3 | |||
| 4 | /** 设置token */ | ||
| 5 | export const setToken = (token) => localStorage.setItem(TOKEN_KEY, token); | ||
| 6 | |||
| 7 | /** | ||
| 8 | * 获取登录token | ||
| 9 | * @param drop 是否清空 | ||
| 10 | */ | ||
| 11 | export const getToken = (drop = false) => { | ||
| 12 | let token = localStorage.getItem(TOKEN_KEY); | ||
| 13 | if (!token) return null; | ||
| 14 | if (drop) localStorage.removeItem(TOKEN_KEY); | ||
| 15 | return token; | ||
| 16 | }; |
src/viewsPc/seat/utils/request.js
0 → 100644
| 1 | // http.js | ||
| 2 | |||
| 3 | import axios from "axios"; | ||
| 4 | import { getToken } from "./local-store"; | ||
| 5 | import { ElMessage } from "element-plus"; | ||
| 6 | |||
| 7 | const baseURL = "http://101.43.15.205:8084"; //"http://book.xiaojinyu.games"; // 这里填入你的基础 API URL | ||
| 8 | const timeout = 15000; // 请求超时时间 | ||
| 9 | |||
| 10 | const http = axios.create({ | ||
| 11 | baseURL, | ||
| 12 | timeout, | ||
| 13 | headers: { | ||
| 14 | "Content-Type": "application/json", | ||
| 15 | }, | ||
| 16 | }); | ||
| 17 | |||
| 18 | // 请求拦截器 | ||
| 19 | http.interceptors.request.use( | ||
| 20 | (config) => { | ||
| 21 | // 在发送请求之前做些什么 | ||
| 22 | const TOKEN = getToken(); | ||
| 23 | config.headers.Authorization = TOKEN; | ||
| 24 | if (config.method == "get") config.params = config.data; | ||
| 25 | return config; | ||
| 26 | }, | ||
| 27 | (error) => { | ||
| 28 | return Promise.reject(error); | ||
| 29 | } | ||
| 30 | ); | ||
| 31 | |||
| 32 | // 响应拦截器 | ||
| 33 | http.interceptors.response.use( | ||
| 34 | (response) => { | ||
| 35 | // 判断是否有异常 | ||
| 36 | let error = null; // 若无异常此值为null | ||
| 37 | if (response.status !== 200) { | ||
| 38 | error = Error(`Request failed with statuCode ${response.status}`); | ||
| 39 | } | ||
| 40 | |||
| 41 | if (response.data.code != 200) { | ||
| 42 | return ElMessage({ type: "error", message: response.data.msg }); | ||
| 43 | } | ||
| 44 | |||
| 45 | return response.data; | ||
| 46 | }, | ||
| 47 | (error) => { | ||
| 48 | // 对响应错误做点什么 | ||
| 49 | return Promise.reject(error); | ||
| 50 | } | ||
| 51 | ); | ||
| 52 | |||
| 53 | // 封装请求函数 | ||
| 54 | const request = (method, url, data = null) => { | ||
| 55 | return http({ | ||
| 56 | method, | ||
| 57 | url, | ||
| 58 | data, | ||
| 59 | }); | ||
| 60 | }; | ||
| 61 | |||
| 62 | export default request; |
-
Please register or sign in to post a comment