visit-people.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. // 调用预约API
  2. const { museumApi } = require('../../../utils/api.js');
  3. Page({
  4. data: {
  5. selectedDate: '',
  6. selectedTime: '',
  7. appointmentSlotsId: null,
  8. activityId: 0, // 活动ID,type=2时需要
  9. type: 1, // 预约类型:1-普通预约,2-活动预约
  10. visitors: [], // 参观人列表
  11. showExistingPage: false,
  12. showSuccessModal: false,
  13. isFormValid: false,
  14. idTypes: [{value: 1, name: '身份证'}],
  15. existingVisitors: [] // 我的联系人列表
  16. },
  17. onLoad(options) {
  18. this.addNewVisitor();
  19. // 获取页面参数
  20. if (options.date && options.time) {
  21. this.setData({
  22. selectedDate: options.date,
  23. selectedTime: options.time
  24. });
  25. }
  26. // 保存appointmentSlotsId用于后续提交
  27. if (options.appointmentSlotsId) {
  28. this.setData({
  29. appointmentSlotsId: options.appointmentSlotsId
  30. });
  31. }
  32. // 加载已有参观人数据
  33. this.loadExistingVisitors();
  34. },
  35. // 新增参观人
  36. addNewVisitor() {
  37. const visitors = this.data.visitors;
  38. visitors.unshift({
  39. id: 0, // 新增参观人ID为0
  40. name: '',
  41. phone: '',
  42. cardType: this.data.idTypes[0].value, // 证件类型
  43. idCard: '', // 证件号码
  44. idType: this.data.idTypes[0].name, // 用于显示
  45. idTypeIndex: 0,
  46. idCard: '', // 用于显示
  47. nameError: '',
  48. phoneError: '',
  49. idNumberError: '',
  50. isFromContacts: false // 标识是否来自联系人
  51. });
  52. this.setData({
  53. visitors: visitors
  54. });
  55. this.checkFormValid();
  56. },
  57. // 删除参观人
  58. removeVisitor(e) {
  59. const index = e.currentTarget.dataset.index;
  60. const visitors = this.data.visitors;
  61. visitors.splice(index, 1);
  62. this.setData({
  63. visitors: visitors
  64. });
  65. this.checkFormValid();
  66. },
  67. // 姓名输入
  68. onNameInput(e) {
  69. const index = e.currentTarget.dataset.index;
  70. const value = e.detail.value;
  71. const visitors = this.data.visitors;
  72. visitors[index].name = value;
  73. this.setData({
  74. visitors: visitors
  75. });
  76. },
  77. // 电话输入
  78. onPhoneInput(e) {
  79. const index = e.currentTarget.dataset.index;
  80. const value = e.detail.value;
  81. const visitors = this.data.visitors;
  82. visitors[index].phone = value;
  83. this.setData({
  84. visitors: visitors
  85. });
  86. },
  87. // 证件号码输入
  88. onIdNumberInput(e) {
  89. const index = e.currentTarget.dataset.index;
  90. const value = e.detail.value;
  91. const visitors = this.data.visitors;
  92. visitors[index].idCard = value;
  93. visitors[index].idCard = value; // 同步更新API字段
  94. this.setData({
  95. visitors: visitors
  96. });
  97. },
  98. // 证件类型选择
  99. onIdTypeChange(e) {
  100. const index = e.currentTarget.dataset.index;
  101. const value = e.detail.value;
  102. const visitors = this.data.visitors;
  103. const selectedIdType = this.data.idTypes[value];
  104. visitors[index].idTypeIndex = value;
  105. visitors[index].idType = selectedIdType.name;
  106. visitors[index].cardType = selectedIdType.value; // 同步更新API字段
  107. this.setData({
  108. visitors: visitors
  109. });
  110. },
  111. // 验证姓名
  112. validateName(e) {
  113. const index = e.currentTarget.dataset.index;
  114. const visitors = this.data.visitors;
  115. const visitor = visitors[index];
  116. if (!visitor.name.trim()) {
  117. visitor.nameError = '请输入姓名';
  118. } else if (visitor.name.length < 2) {
  119. visitor.nameError = '姓名至少2个字符';
  120. } else {
  121. visitor.nameError = '';
  122. }
  123. this.setData({
  124. visitors: visitors
  125. });
  126. this.checkFormValid();
  127. },
  128. // 验证电话
  129. validatePhone(e) {
  130. const index = e.currentTarget.dataset.index;
  131. const visitors = this.data.visitors;
  132. const visitor = visitors[index];
  133. const phoneRegex = /^1[3-9]\d{9}$/;
  134. if (!visitor.phone) {
  135. visitor.phoneError = '请输入电话号码';
  136. } else if (!phoneRegex.test(visitor.phone)) {
  137. visitor.phoneError = '请输入正确的11位手机号码';
  138. } else {
  139. visitor.phoneError = '';
  140. }
  141. this.setData({
  142. visitors: visitors
  143. });
  144. this.checkFormValid();
  145. },
  146. // 验证证件号码
  147. validateIdNumber(e) {
  148. const index = e.currentTarget.dataset.index;
  149. const visitors = this.data.visitors;
  150. const visitor = visitors[index];
  151. const idRegex = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
  152. if (!visitor.idCard) {
  153. visitor.idNumberError = '请输入证件号码';
  154. } else if (!idRegex.test(visitor.idCard)) {
  155. visitor.idNumberError = '请输入正确的18位身份证号码';
  156. } else {
  157. visitor.idNumberError = '';
  158. }
  159. this.setData({
  160. visitors: visitors
  161. });
  162. this.checkFormValid();
  163. },
  164. // 检查表单是否有效
  165. checkFormValid() {
  166. const visitors = this.data.visitors;
  167. if (visitors.length === 0) {
  168. this.setData({ isFormValid: false });
  169. return;
  170. }
  171. const isValid = visitors.every(visitor =>
  172. visitor.name &&
  173. visitor.phone &&
  174. visitor.idCard &&
  175. !visitor.nameError &&
  176. !visitor.phoneError &&
  177. !visitor.idNumberError
  178. );
  179. this.setData({ isFormValid: isValid });
  180. },
  181. // 加载已有参观人数据
  182. loadExistingVisitors() {
  183. museumApi.getMyVisitors()
  184. .then(response => {
  185. console.log('获取参观人列表成功:', response);
  186. if (response && response.length > 0) {
  187. const existingVisitors = response.map(visitor => ({
  188. id: visitor.id,
  189. name: visitor.name,
  190. idCard: visitor.idCard,
  191. phone: visitor.phone,
  192. selected: false
  193. }));
  194. this.setData({ existingVisitors });
  195. }
  196. })
  197. .catch(error => {
  198. console.error('获取参观人列表失败:', error);
  199. // 如果接口失败,可以使用模拟数据
  200. this.setData({
  201. existingVisitors: [
  202. {
  203. name: '周明明',
  204. idCard: '210112196705041430',
  205. phone: '18416573665',
  206. selected: false
  207. },
  208. {
  209. name: '李明',
  210. idCard: '621124199504251508',
  211. phone: '13902376115',
  212. selected: false
  213. }
  214. ]
  215. });
  216. });
  217. },
  218. // 显示已有参观人
  219. showExistingVisitors() {
  220. // 每次显示前重新加载数据
  221. this.loadExistingVisitors();
  222. this.setData({
  223. showExistingPage: true
  224. });
  225. },
  226. // 切换已有参观人选择状态
  227. toggleExistingVisitor(e) {
  228. const index = e.currentTarget.dataset.index;
  229. const existingVisitors = this.data.existingVisitors;
  230. existingVisitors[index].selected = !existingVisitors[index].selected;
  231. this.setData({
  232. existingVisitors: existingVisitors
  233. });
  234. },
  235. // 确认选择已有参观人
  236. confirmExistingVisitors() {
  237. const selectedVisitors = this.data.existingVisitors.filter(visitor => visitor.selected);
  238. const visitors = this.data.visitors;
  239. selectedVisitors.forEach(existingVisitor => {
  240. // if (visitors.length < 5) {
  241. visitors.unshift({
  242. id: existingVisitor.id, // 使用联系人的真实ID
  243. name: existingVisitor.name,
  244. phone: existingVisitor.phone,
  245. cardType: this.data.idTypes[0].value, // 证件类型
  246. idCard: existingVisitor.idCard, // 证件号码
  247. idType: this.data.idTypes[0].name, // 用于显示
  248. idTypeIndex: 0,
  249. idCard: existingVisitor.idCard, // 用于显示
  250. nameError: '',
  251. phoneError: '',
  252. idNumberError: '',
  253. isFromContacts: true // 标识来自联系人
  254. });
  255. // }
  256. });
  257. // 重置选择状态
  258. const existingVisitors = this.data.existingVisitors;
  259. existingVisitors.forEach(visitor => {
  260. visitor.selected = false;
  261. });
  262. this.setData({
  263. visitors: visitors,
  264. existingVisitors: existingVisitors,
  265. showExistingPage: false
  266. });
  267. this.checkFormValid();
  268. },
  269. // 提交预约
  270. submitReservation() {
  271. if (!this.data.isFormValid) {
  272. wx.showToast({
  273. title: '请完善所有参观人信息',
  274. icon: 'none'
  275. });
  276. return;
  277. }
  278. wx.showLoading({
  279. title: '提交中...',
  280. mask: true
  281. });
  282. // 构建API参数
  283. const requestData = {
  284. activityId: this.data.type === 2 ? this.data.activityId : 0,
  285. appointmentSlotsId: this.data.appointmentSlotsId || 0,
  286. appointmentTime: this.data.selectedDate,
  287. type: this.data.type,
  288. visitors: this.data.visitors.map(visitor => ({
  289. cardType: this.data.idTypes[visitor.idTypeIndex].value,
  290. id: visitor.id, // 新增参观人为0,联系人为真实ID
  291. idCard: visitor.idCard,
  292. name: visitor.name,
  293. phone: visitor.phone
  294. }))
  295. };
  296. console.log('提交预约参数:', requestData);
  297. museumApi.submitReservation(requestData)
  298. .then(response => {
  299. wx.hideLoading();
  300. console.log('预约提交成功:', response);
  301. this.setData({
  302. showSuccessModal: true
  303. });
  304. })
  305. .catch(error => {
  306. wx.hideLoading();
  307. console.error('预约提交失败:', error);
  308. wx.showToast({
  309. title: error.message || '预约失败,请重试',
  310. icon: 'none'
  311. });
  312. });
  313. },
  314. // 关闭成功弹窗
  315. closeSuccessModal() {
  316. this.setData({
  317. showSuccessModal: false
  318. });
  319. // 跳转回首页
  320. wx.switchTab({
  321. url: '/pages/index/index'
  322. });
  323. },
  324. // 阻止事件冒泡
  325. stopPropagation() {
  326. // 空函数,用于阻止事件冒泡
  327. }
  328. });