图书馆小程序
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.

364 lines
10 KiB

2 months ago
1 month ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
2 months ago
1 month ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months 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/logo.jpg" 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" custom-prefix="iconfont" type="icon-duzhezheng" size="24"></uni-icons>
  13. <view class="uni-input-wrapper">
  14. <input
  15. class="input"
  16. placeholder="请输入读者证号"
  17. v-model="queryvalue"
  18. @input="handleInput('queryvalue')"
  19. />
  20. <uni-icons
  21. class="clear-icon"
  22. v-if="clearIconStatus.queryvalue"
  23. @click="clearInput('queryvalue')"
  24. type="close"
  25. size="20"
  26. ></uni-icons>
  27. </view>
  28. </view>
  29. <view class="item">
  30. <uni-icons class="form-icon" type="locked" size="24"></uni-icons>
  31. <input class="input" placeholder="请输入密码" :password="!showPwd" v-model="rdpasswd" />
  32. <uni-icons class="form-right-icon" :type="showPwd ? 'eye' : 'eye-slash'" size="20"
  33. @click="togglePwd"></uni-icons>
  34. </view>
  35. <button class="login-btn" type="primary" @click="submit">绑定</button>
  36. </view>
  37. <view class="tips">
  38. 温馨提示<br />
  39. 1密码默认为 <text style="color:#e74c3c">身份证后6位</text>如果身份证号最后一位为XX需要大写;
  40. </view>
  41. <button class="register-btn" type="primary" @click="goRegister">在线办证</button>
  42. </view>
  43. </template>
  44. <script>
  45. // 引入绑定接口
  46. import { FetchInitScreenSetting, FetchReaderList, FetchBindReadCard,FetchFindAllReaderBindByOpenId } from '@/api/user';
  47. import config from '@/utils/config';
  48. import { STORAGE_KEYS } from '@/utils/storage';
  49. export default {
  50. data() {
  51. return {
  52. queryvalue: '',
  53. rdpasswd: '',
  54. showPwd: false,
  55. screenConfig: {},
  56. avatarUrl: '',
  57. nickName: '',
  58. // 清空按钮状态(支持多输入框)
  59. clearIconStatus: {
  60. nickName: false,
  61. queryvalue: false
  62. }
  63. };
  64. },
  65. onLoad() {
  66. this.getScreenSetting();
  67. },
  68. methods: {
  69. // 获取微信头像 + 上传到服务器
  70. onChooseAvatar(e) {
  71. // console.log('获取微信头像', e)
  72. // 临时文件路径
  73. const tempFilePath = e.detail.avatarUrl;
  74. // 开始上传
  75. uni.uploadFile({
  76. url: config.baseUrl +'/api/fileRelevant/uploadWxAvatarImg',
  77. filePath: tempFilePath,
  78. name: 'file',
  79. header: {
  80. "Content-Type": "multipart/form-data"
  81. },
  82. success: (res) => {
  83. // console.log("上传成功原始返回:", res);
  84. let realAvatar = '';
  85. try {
  86. const data = JSON.parse(res.data);
  87. // console.log('解析成功:', data)
  88. realAvatar = data.data || data.url || '';
  89. } catch (e) {
  90. realAvatar = res.data;
  91. }
  92. if (realAvatar) {
  93. // console.log("永久头像URL:", realAvatar);
  94. this.avatarUrl = config.baseUrl + '/api/fileRelevant/getImg?imgType=5&imgId=' + realAvatar
  95. } else {
  96. uni.showToast({ title: '头像上传失败', icon: 'none' });
  97. }
  98. },
  99. fail: (err) => {
  100. // console.log("上传失败", err);
  101. uni.showToast({ title: '头像上传失败', icon: 'none' });
  102. }
  103. });
  104. },
  105. // 统一监听输入(自动控制清空按钮显示隐藏)
  106. handleInput(field) {
  107. this.clearIconStatus[field] = this[field].trim().length > 0
  108. },
  109. // 统一清空输入框内容
  110. clearInput(field) {
  111. this[field] = ''
  112. this.clearIconStatus[field] = false
  113. },
  114. // 切换密码显隐
  115. togglePwd() {
  116. this.showPwd = !this.showPwd;
  117. },
  118. async getScreenSetting() {
  119. try {
  120. const res = await FetchInitScreenSetting({ libcode: config.LIB_CODE });
  121. const data = res.data;
  122. this.screenConfig = {
  123. thirdUrl: data.open_lib_http?.context || '',
  124. thirdAppid: data.open_lib_appId?.context || '',
  125. thirdSecret: data.open_lib_secret?.context || '',
  126. sm4Key: data.sm4_key?.context || ''
  127. };
  128. } catch (err) {
  129. console.error('获取配置失败:', err);
  130. }
  131. },
  132. async submit() {
  133. // 去除首尾空格
  134. this.nickName = this.nickName.trim()
  135. this.queryvalue = this.queryvalue.trim()
  136. if (!this.queryvalue || !this.rdpasswd) {
  137. uni.showToast({ title: '请输入读者证号和密码', icon: 'none' });
  138. return;
  139. }
  140. uni.showLoading({ title: '绑定中...' });
  141. try {
  142. const params = {
  143. ...this.screenConfig,
  144. selecttype: 'rdid',
  145. queryvalue: this.queryvalue,
  146. rdpasswd: this.rdpasswd,
  147. };
  148. // 420703GD0000748
  149. // {"code":200,"message":"操作成功","data":"{\"messagelist\":[{\"code\":\"R00138\",\"message\":\"未找到符合条件的读者!\"}],\"success\":false}","timestamp":1778154499544}
  150. // {"code":200,"message":"操作成功","data":"{\"success\":true,\"pagedata\":[{\"rdClusterCode\":null,\"rdlib\":\"GD\",\"rdid\":\"420105198509200438\",\"rdcfstate\":1}]}","timestamp":1778154647854}
  151. // {"code":200,"message":"操作成功","data":"{\"messageList\":[{\"R00131\":\"认证失败,系统存在该读者,密码不匹配!\"}],\"success\":true,\"pagedata\":\"\"}","timestamp":1778155520501}
  152. const res = await FetchReaderList(params);
  153. let result = {};
  154. try {
  155. result = JSON.parse(res.data);
  156. } catch (e) {
  157. uni.hideLoading();
  158. uni.showToast({ title: '数据解析失败', icon: 'none' });
  159. return;
  160. }
  161. // 统一提取错误信息
  162. let errMsg = '';
  163. if (result.messagelist?.length) {
  164. const item = result.messagelist[0];
  165. errMsg = item.message || Object.values(item)[0] || '认证失败';
  166. }
  167. if (result.messageList?.length) {
  168. const item = result.messageList[0];
  169. errMsg = item.message || Object.values(item)[0] || '认证失败';
  170. }
  171. // 成功判断
  172. const realSuccess = result.success === true && result.pagedata?.length > 0;
  173. if (realSuccess) {
  174. // 开始绑定
  175. const openId = uni.getStorageSync("wx_login_code");
  176. const bindParams = {
  177. openid: openId,
  178. bindValue: this.queryvalue,
  179. bindType: 'rdid',
  180. libcode: config.LIB_CODE,
  181. }
  182. // 调用绑定接口
  183. const bindRes = await FetchBindReadCard(bindParams);
  184. // console.log('绑定结果', bindRes);
  185. if(bindRes.code === 200 ){
  186. uni.hideLoading();
  187. uni.showToast({
  188. title: bindRes.data || '读者证绑定成功',
  189. icon: 'success'
  190. });
  191. const data = {
  192. libcode: config.LIB_CODE,
  193. openId: openId
  194. }
  195. FetchFindAllReaderBindByOpenId(data).then(res => {
  196. // console.log('获取读者证列表',res)
  197. if (res.code === 200 && res.data.length > 0) {
  198. uni.setStorageSync(STORAGE_KEYS.READER_CARD_LIST, res.data);
  199. } else {
  200. uni.setStorageSync(STORAGE_KEYS.READER_CARD_LIST, []);
  201. }
  202. })
  203. .catch(err => {
  204. console.error('获取读者证列表失败:', err);
  205. })
  206. // 绑定成功后返回上一页
  207. setTimeout(() => {
  208. uni.navigateBack();
  209. }, 1500);
  210. }else{
  211. // 绑定失败提示
  212. uni.hideLoading()
  213. uni.showToast({
  214. title: bindResult.message || '绑定失败,请重试',
  215. icon: 'none'
  216. })
  217. }
  218. } else {
  219. uni.hideLoading();
  220. uni.showToast({
  221. title: errMsg || '读者证或密码错误',
  222. icon: 'none'
  223. });
  224. }
  225. } catch (err) {
  226. console.error('绑定流程异常:', err)
  227. uni.hideLoading();
  228. uni.showToast({ title: err || '绑定失败', icon: 'none' });
  229. }
  230. },
  231. /**
  232. * 跳转到在线办证页面
  233. */
  234. goRegister() {
  235. uni.navigateTo({
  236. url: '/pages/register/register'
  237. });
  238. }
  239. }
  240. };
  241. </script>
  242. <style lang="scss" scoped>
  243. .user-info-section {
  244. display: flex;
  245. flex-direction: column;
  246. align-items: center;
  247. padding: 30px 0 0 0;
  248. .avatar-btn {
  249. background: transparent;
  250. display: flex;
  251. flex-direction: column;
  252. align-items: center;
  253. &::after{
  254. border: none !important;
  255. }
  256. .avatar-img {
  257. width: 60px;
  258. height: 60px;
  259. border-radius: 50%;
  260. }
  261. .tip-text {
  262. font-size: 12px;
  263. color: #999;
  264. }
  265. }
  266. }
  267. .form-box {
  268. padding: 20px 15px;
  269. .item {
  270. width: 100%;
  271. min-height: 44px;
  272. border-radius: 22px;
  273. background-color: #f7f7f7;
  274. display: flex;
  275. align-items: center;
  276. margin-bottom: 15px;
  277. .input {
  278. flex: 1;
  279. padding: 10px;
  280. font-size: 14px;
  281. }
  282. }
  283. .uni-input-wrapper{
  284. flex: 1;
  285. display: flex;
  286. align-items: center;
  287. .input {
  288. flex: 1;
  289. padding: 10px;
  290. font-size: 14px;
  291. }
  292. .clear-icon{
  293. padding: 0 12px;
  294. color: #ccc;
  295. }
  296. }
  297. }
  298. .login-btn {
  299. margin-top: 10px;
  300. background-color: #01a4fe !important;
  301. border-radius: 22px;
  302. font-size: 16px;
  303. height: 44px;
  304. line-height: 44px;
  305. }
  306. .tips {
  307. margin: 30px 20px;
  308. font-size: 12px;
  309. color: #333;
  310. line-height: 20px;
  311. }
  312. .form-icon {
  313. ::v-deep .uni-icons {
  314. margin-left: 10px;
  315. color: #01a4fe !important;
  316. }
  317. }
  318. .form-right-icon {
  319. ::v-deep .uni-icons {
  320. margin-right: 10px;
  321. }
  322. }
  323. </style>