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

372 lines
10 KiB

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