图书馆小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 lines
6.9 KiB

1 month ago
  1. <template>
  2. <view style="background-color: #fff; height: calc(100vh);">
  3. <view class="top-bar">
  4. <image class="top-bar-bg" src="@/static/images/mingqi-beij@2x.png" mode="aspectFill"></image>
  5. <view class="library-info">
  6. <image class="avatar" src="@/static/images/avatar.png" mode="aspectFill"></image>
  7. <view class="library-name">葛店经济技术开发区图书馆</view>
  8. </view>
  9. </view>
  10. <view class="form-box">
  11. <view class="item">
  12. <uni-icons class="form-icon" type="person" size="24"></uni-icons>
  13. <input class="input" placeholder="请输入读者证号" v-model="queryvalue" />
  14. </view>
  15. <view class="item">
  16. <uni-icons class="form-icon" type="locked" size="24"></uni-icons>
  17. <input class="input" placeholder="请输入密码" :password="!showPwd" v-model="rdpasswd" />
  18. <uni-icons class="form-right-icon" :type="showPwd ? 'eye-slash' : 'eye'" size="20"
  19. @click="togglePwd"></uni-icons>
  20. </view>
  21. <button class="login-btn" type="primary" @click="submit">绑定</button>
  22. </view>
  23. <view class="tips">
  24. 温馨提示<br />
  25. 1密码默认为 <text style="color:#e74c3c">身份证后6位</text>如果身份证号最后一位为XX需要大写;
  26. </view>
  27. </view>
  28. </template>
  29. <script>
  30. import { FetchInitScreenSetting, FetchReaderList } from '@/api/user';
  31. const TOKEN_KEY = 'token';
  32. const USER_KEY = 'user-info';
  33. export default {
  34. data() {
  35. return {
  36. queryvalue: '',
  37. rdpasswd: '',
  38. showPwd: false,
  39. screenConfig: {}
  40. };
  41. },
  42. onLoad() {
  43. this.getScreenSetting();
  44. },
  45. methods: {
  46. // 切换密码显隐
  47. togglePwd() {
  48. this.showPwd = !this.showPwd;
  49. },
  50. // 1: 页面加载时先获取大屏配置
  51. async getScreenSetting() {
  52. try {
  53. const res = await FetchInitScreenSetting({ libcode: '1201' });
  54. const data = res.data;
  55. // 自动取出 4 个必须参数
  56. this.screenConfig = {
  57. thirdUrl: data.open_lib_http?.context || '',
  58. thirdAppid: data.open_lib_appId?.context || '',
  59. thirdSecret: data.open_lib_secret?.context || '',
  60. sm4Key: data.sm4_key?.context || ''
  61. };
  62. console.log('已获取第三方配置:', this.screenConfig);
  63. } catch (err) {
  64. console.error('获取配置失败:', err);
  65. }
  66. },
  67. // {"code":200,"message":"操作成功","data":"{\"messagelist\":[{\"code\":\"R00138\",\"message\":\"未找到符合条件的读者!\"}],\"success\":false}","timestamp":1778154499544}
  68. // {"code":200,"message":"操作成功","data":"{\"success\":true,\"pagedata\":[{\"rdClusterCode\":null,\"rdlib\":\"GD\",\"rdid\":\"420105198509200438\",\"rdcfstate\":1}]}","timestamp":1778154647854}
  69. // {"code":200,"message":"操作成功","data":"{\"messageList\":[{\"R00131\":\"认证失败,系统存在该读者,密码不匹配!\"}],\"success\":true,\"pagedata\":\"\"}","timestamp":1778155520501}
  70. // 2:点击绑定 → 调用读者登录接口
  71. async submit() {
  72. if (!this.queryvalue || !this.rdpasswd) {
  73. uni.showToast({ title: '请输入读者证号和密码', icon: 'none' });
  74. return;
  75. }
  76. if (!this.screenConfig.thirdUrl) {
  77. uni.showToast({ title: '图书馆配置加载中,请稍候重试', icon: 'none' });
  78. return;
  79. }
  80. uni.showLoading({ title: '绑定中...' });
  81. try {
  82. const params = {
  83. ...this.screenConfig,
  84. selecttype: 'rdid',
  85. queryvalue: this.queryvalue,
  86. rdpasswd: this.rdpasswd,
  87. havecluster: ''
  88. };
  89. const res = await FetchReaderList(params);
  90. // 1. 解析返回的JSON字符串
  91. let result = {};
  92. try {
  93. result = JSON.parse(res.data);
  94. } catch (e) {
  95. uni.hideLoading();
  96. uni.showToast({ title: '数据解析失败', icon: 'none' });
  97. return;
  98. }
  99. // 2. 统一提取错误信息(兼容大小写、各种格式)
  100. let errMsg = '';
  101. // 兼容小写 messagelist
  102. if (result.messagelist && result.messagelist.length > 0) {
  103. const item = result.messagelist[0];
  104. errMsg = item.message || Object.values(item)[0] || '绑定失败';
  105. }
  106. // 兼容大写 messageList
  107. if (result.messageList && result.messageList.length > 0) {
  108. const item = result.messageList[0];
  109. errMsg = item.message || Object.values(item)[0] || '绑定失败';
  110. }
  111. // 3. 真正的成功判断:必须 success=true 并且 pagedata 有值
  112. const realSuccess = result.success === true && result.pagedata && result.pagedata.length > 0;
  113. if (realSuccess) {
  114. const wxUser = uni.getStorageSync('wxUserInfo') || {};
  115. const loginRes = {
  116. token: 'reader-token-' + Date.now(),
  117. user: {
  118. nickName: wxUser.nickName || '读者',
  119. avatarUrl: wxUser.avatarUrl || '',
  120. cardNo: this.queryvalue
  121. }
  122. };
  123. uni.setStorageSync('token', loginRes.token);
  124. uni.setStorageSync('user-info', loginRes.user);
  125. uni.hideLoading();
  126. uni.showToast({ title: '绑定成功', icon: 'success' });
  127. setTimeout(() => {
  128. uni.navigateBack();
  129. }, 1500);
  130. } else {
  131. uni.hideLoading();
  132. uni.showToast({
  133. title: errMsg || '读者证或密码错误',
  134. icon: 'none'
  135. });
  136. }
  137. } catch (err) {
  138. uni.hideLoading();
  139. console.error('绑定异常:', err);
  140. uni.showToast({ title: '网络异常,请稍后重试', icon: 'none' });
  141. }
  142. }
  143. }
  144. };
  145. </script>
  146. <style lang="scss" scoped>
  147. .top-bar {
  148. position: relative;
  149. width: 100%;
  150. height: 220rpx;
  151. .top-bar-bg {
  152. position: absolute;
  153. width: 100%;
  154. height: 100%;
  155. }
  156. .library-info {
  157. position: relative;
  158. display: flex;
  159. flex-direction: column;
  160. align-items: center;
  161. padding-top: 30rpx;
  162. .avatar {
  163. width: 100rpx;
  164. height: 100rpx;
  165. border-radius: 50%;
  166. }
  167. .library-name {
  168. margin-top: 10rpx;
  169. color: #fff;
  170. font-size: 30rpx;
  171. }
  172. }
  173. }
  174. .form-box {
  175. padding: 40rpx 30rpx;
  176. .item {
  177. width: 100%;
  178. min-height: 80rpx;
  179. border-radius: 40rpx;
  180. background-color: #f7f7f7;
  181. display: flex;
  182. align-items: center;
  183. margin-bottom: 30rpx;
  184. .input {
  185. flex: 1;
  186. padding: 20rpx 20rpx;
  187. font-size: 28rpx;
  188. }
  189. }
  190. }
  191. .login-btn {
  192. margin-top: 20rpx;
  193. background-color: #01a4fe !important;
  194. border-radius: 40rpx;
  195. font-size: 30rpx;
  196. }
  197. .tips {
  198. margin: 60rpx 40rpx;
  199. font-size: 24rpx;
  200. color: #333;
  201. line-height: 40rpx;
  202. }
  203. .form-icon {
  204. ::v-deep .uni-icons {
  205. margin-left: 20rpx;
  206. color: #01a4fe !important;
  207. }
  208. }
  209. .form-right-icon {
  210. ::v-deep .uni-icons {
  211. margin-right: 20rpx;
  212. }
  213. }
  214. </style>