active-people.js 12 KB

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