1.以G71列車為例,首先對車次站臺進行占位編碼(從1開始到最后一站遞加)
對以上占位簡單描述以下:G71總共18個站點那么我們的單個座位的座位標識可以用十八位長度的二進制字符串表示10000000000000000每一位代表一個站點,每天放票前初始化到下面的訂票表中,數據如下余票根據座位標識中的0的個數決定最大余票數量
訂票表中的始發受限站點和終到受限站點可以靈活搭配(這個就可以實現限制站點發售)
2.查詢余票
如果我們要查詢日期為2016-06-11,始發站保定東站(3)到韶關站(15)的G71二等座F座位余票情況只需要執行如下sql(該SQL可以實現選座位和選車廂等功能)
select GUID,車次編碼,車次類型,座位類型,車廂號碼,座位編碼,座位位置 from 訂票表
where to_number(substring(座位標識,3,15))=0
and 發車日期='2016-06-11'
and 車次編碼='G71'
and substring(始發受限車站,3,4)=1
and substring(終到受限車站,15,16)=1
and 車票狀態='待售'
and 車次類型='二等座'
and 座位位置='F'
3.預定票
3.1根據第二步中查詢條件獲取一條記錄然后將車票狀態改為鎖定
3.2待鎖定成功后進行支付
3.2支付成功后然后將保定到韶關的票(000111111111111000這里的始發站標記為0)與原有的票進行或運算,并將車票狀態改為待售
100000000000000000 | 000111111111111000 = 100111111111111000 這個時候的余票標識即為動態余票
3.3如果指定時間沒有支付,那么可以將這條記錄的車票狀態恢復為待售
100111111111111000^000111111111111000 = 100000000000000000 這個時候的余票及自動還原回去了
4.退票
獲得該車次保定到韶關的票 (000111111111111000)與對應的票進行非運算,則即可回歸票池子了
以下為相關java代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
import java.math.BigDecimal; public class MainTest { public static void main(String[] args) { String ticketFlag = "" ; int beginStation = ; int endStation = ; long beginTime = System.currentTimeMillis(); String result = orderTicket(ticketFlag, beginStation, endStation); if (result.equals(ticketFlag)) { System.out.println( "訂票失敗" ); } else { System.out.println( "訂票后的結果:" + result); // 如果要取消的話,就進行這個操作 String b = buildTicket(ticketFlag.length(), beginStation, endStation); System.out.println( "釋放后的結果:" + releaseTicket(ticketFlag, b)); } long endTime = System.currentTimeMillis(); System.out.println( "耗時:" + (endTime - beginTime)); } /** * 訂票 * * @param ticketFlag * @param beginStation * @param endStation * @return */ private static String orderTicket(String ticketFlag, int beginStation, int endStation) { String result = "" ; if (checkCanTicket(ticketFlag, beginStation, endStation)) { String b = buildTicket(ticketFlag.length(), beginStation, endStation); String currentTicked = toTicket(ticketFlag, b); System.out.println( "預占票前結果:" + ticketFlag); result = currentTicked; } else { result = ticketFlag; } ; return result; } /** * 取消已定票 * * @param ticketFlag * @param b * @return */ private static String releaseTicket(String ticketFlag, String b) { StringBuilder tempSt = new StringBuilder( "" ); int length = ticketFlag.length(); for ( int i = ; i < length; i++) { char tempA = ticketFlag.charAt(i); char tempB = b.charAt(i); if (tempA == '' && tempB == '' ) { tempSt.append( "" ); } else { tempSt.append(tempA); } } return tempSt.toString(); } /** * 創建區間占位票 * * @param length * @param beginStation * @param endStation * @return */ private static String buildTicket( int length, int beginStation, int endStation) { StringBuilder st = new StringBuilder( "" ); for ( int i = ; i < length; i++) { if (i >= beginStation && i < endStation) { st.append( "" ); } else { st.append( "" ); } } System.out.println( "創建區間票:" + st.toString()); return st.toString(); } /** * 生成訂票后的結果 * * @param ticketFlag * @param b * @return */ private static String toTicket(String ticketFlag, String b) { StringBuilder tempSt = new StringBuilder( "" ); int length = ticketFlag.length(); for ( int i = ; i < length; i++) { char tempA = ticketFlag.charAt(i); char tempB = b.charAt(i); if (tempA == '' || tempB == '' ) { tempSt.append( "" ); } else { tempSt.append(tempA); } } return tempSt.toString(); } /** * 是否可以訂票 * * @param ticketFlag * @param beginStation * @param endStation * @return */ private static boolean checkCanTicket(String ticketFlag, int beginStation, int endStation) { boolean result = false ; String tempTicket = ticketFlag.substring(beginStation, endStation); BigDecimal b = new BigDecimal(tempTicket); if (b.equals( new BigDecimal( "" ))) { result = true ; } return result; } } |