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

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