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

365 lines
10 KiB

5 months ago
4 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 weeks ago
4 months ago
4 months ago
5 months ago
4 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 weeks ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 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. this.avatarUrl = `${config.baseUrl}/files/${realAvatar}`;
  96. } else {
  97. uni.showToast({ title: '头像上传失败', icon: 'none' });
  98. }
  99. },
  100. fail: (err) => {
  101. // console.log("上传失败", err);
  102. uni.showToast({ title: '头像上传失败', icon: 'none' });
  103. }
  104. });
  105. },
  106. // 统一监听输入(自动控制清空按钮显示隐藏)
  107. handleInput(field) {
  108. this.clearIconStatus[field] = this[field].trim().length > 0
  109. },
  110. // 统一清空输入框内容
  111. clearInput(field) {
  112. this[field] = ''
  113. this.clearIconStatus[field] = false
  114. },
  115. // 切换密码显隐
  116. togglePwd() {
  117. this.showPwd = !this.showPwd;
  118. },
  119. async getScreenSetting() {
  120. try {
  121. const res = await FetchInitScreenSetting({ libcode: config.LIB_CODE });
  122. const data = res.data;
  123. this.screenConfig = {
  124. thirdUrl: data.open_lib_http?.context || '',
  125. thirdAppid: data.open_lib_appId?.context || '',
  126. thirdSecret: data.open_lib_secret?.context || '',
  127. sm4Key: data.sm4_key?.context || ''
  128. };
  129. } catch (err) {
  130. console.error('获取配置失败:', err);
  131. }
  132. },
  133. async submit() {
  134. // 去除首尾空格
  135. this.nickName = this.nickName.trim()
  136. this.queryvalue = this.queryvalue.trim()
  137. if (!this.queryvalue || !this.rdpasswd) {
  138. uni.showToast({ title: '请输入读者证号和密码', icon: 'none' });
  139. return;
  140. }
  141. uni.showLoading({ title: '绑定中...' });
  142. try {
  143. const params = {
  144. ...this.screenConfig,
  145. selecttype: 'rdid',
  146. queryvalue: this.queryvalue,
  147. rdpasswd: this.rdpasswd,
  148. };
  149. // 420703GD0000748
  150. // {"code":200,"message":"操作成功","data":"{\"messagelist\":[{\"code\":\"R00138\",\"message\":\"未找到符合条件的读者!\"}],\"success\":false}","timestamp":1778154499544}
  151. // {"code":200,"message":"操作成功","data":"{\"success\":true,\"pagedata\":[{\"rdClusterCode\":null,\"rdlib\":\"GD\",\"rdid\":\"420105198509200438\",\"rdcfstate\":1}]}","timestamp":1778154647854}
  152. // {"code":200,"message":"操作成功","data":"{\"messageList\":[{\"R00131\":\"认证失败,系统存在该读者,密码不匹配!\"}],\"success\":true,\"pagedata\":\"\"}","timestamp":1778155520501}
  153. const res = await FetchReaderList(params);
  154. let result = {};
  155. try {
  156. result = JSON.parse(res.data);
  157. } catch (e) {
  158. uni.hideLoading();
  159. uni.showToast({ title: '数据解析失败', icon: 'none' });
  160. return;
  161. }
  162. // 统一提取错误信息
  163. let errMsg = '';
  164. if (result.messagelist?.length) {
  165. const item = result.messagelist[0];
  166. errMsg = item.message || Object.values(item)[0] || '认证失败';
  167. }
  168. if (result.messageList?.length) {
  169. const item = result.messageList[0];
  170. errMsg = item.message || Object.values(item)[0] || '认证失败';
  171. }
  172. // 成功判断
  173. const realSuccess = result.success === true && result.pagedata?.length > 0;
  174. if (realSuccess) {
  175. // 开始绑定
  176. const openId = uni.getStorageSync("wx_login_code");
  177. const bindParams = {
  178. openid: openId,
  179. bindValue: this.queryvalue,
  180. bindType: 'rdid',
  181. libcode: config.LIB_CODE,
  182. }
  183. // 调用绑定接口
  184. const bindRes = await FetchBindReadCard(bindParams);
  185. // console.log('绑定结果', bindRes);
  186. if(bindRes.code === 200 ){
  187. uni.hideLoading();
  188. uni.showToast({
  189. title: bindRes.data || '读者证绑定成功',
  190. icon: 'success'
  191. });
  192. const data = {
  193. libcode: config.LIB_CODE,
  194. openId: openId
  195. }
  196. FetchFindAllReaderBindByOpenId(data).then(res => {
  197. // console.log('获取读者证列表',res)
  198. if (res.code === 200 && res.data.length > 0) {
  199. uni.setStorageSync(STORAGE_KEYS.READER_CARD_LIST, res.data);
  200. } else {
  201. uni.setStorageSync(STORAGE_KEYS.READER_CARD_LIST, []);
  202. }
  203. })
  204. .catch(err => {
  205. console.error('获取读者证列表失败:', err);
  206. })
  207. // 绑定成功后返回上一页
  208. setTimeout(() => {
  209. uni.navigateBack();
  210. }, 1500);
  211. }else{
  212. // 绑定失败提示
  213. uni.hideLoading()
  214. uni.showToast({
  215. title: bindResult.message || '绑定失败,请重试',
  216. icon: 'none'
  217. })
  218. }
  219. } else {
  220. uni.hideLoading();
  221. uni.showToast({
  222. title: errMsg || '读者证或密码错误',
  223. icon: 'none'
  224. });
  225. }
  226. } catch (err) {
  227. console.error('绑定流程异常:', err)
  228. uni.hideLoading();
  229. uni.showToast({ title: err || '绑定失败', icon: 'none' });
  230. }
  231. },
  232. /**
  233. * 跳转到在线办证页面
  234. */
  235. goRegister() {
  236. uni.navigateTo({
  237. url: '/subpkg/pages/register/register'
  238. });
  239. }
  240. }
  241. };
  242. </script>
  243. <style lang="scss" scoped>
  244. .user-info-section {
  245. display: flex;
  246. flex-direction: column;
  247. align-items: center;
  248. padding: 30px 0 0 0;
  249. .avatar-btn {
  250. background: transparent;
  251. display: flex;
  252. flex-direction: column;
  253. align-items: center;
  254. &::after{
  255. border: none !important;
  256. }
  257. .avatar-img {
  258. width: 60px;
  259. height: 60px;
  260. border-radius: 50%;
  261. }
  262. .tip-text {
  263. font-size: 12px;
  264. color: #999;
  265. }
  266. }
  267. }
  268. .form-box {
  269. padding: 20px 15px;
  270. .item {
  271. width: 100%;
  272. min-height: 44px;
  273. border-radius: 22px;
  274. background-color: #f7f7f7;
  275. display: flex;
  276. align-items: center;
  277. margin-bottom: 15px;
  278. .input {
  279. flex: 1;
  280. padding: 10px;
  281. font-size: 14px;
  282. }
  283. }
  284. .uni-input-wrapper{
  285. flex: 1;
  286. display: flex;
  287. align-items: center;
  288. .input {
  289. flex: 1;
  290. padding: 10px;
  291. font-size: 14px;
  292. }
  293. .clear-icon{
  294. padding: 0 12px;
  295. color: #ccc;
  296. }
  297. }
  298. }
  299. .login-btn {
  300. margin-top: 10px;
  301. background-color: #01a4fe !important;
  302. border-radius: 22px;
  303. font-size: 16px;
  304. height: 44px;
  305. line-height: 44px;
  306. }
  307. .tips {
  308. margin: 30px 20px;
  309. font-size: 12px;
  310. color: #333;
  311. line-height: 20px;
  312. }
  313. .form-icon {
  314. ::v-deep .uni-icons {
  315. margin-left: 10px;
  316. color: #01a4fe !important;
  317. }
  318. }
  319. .form-right-icon {
  320. ::v-deep .uni-icons {
  321. margin-right: 10px;
  322. }
  323. }
  324. </style>