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

268 lines
7.3 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. <!-- 支付分状态展示 -->
  11. <view class="pay-score-box" v-if="payScore">
  12. <view class="score-item">
  13. <uni-icons type="info" size="24" color="#01a4fe"></uni-icons>
  14. <view class="score-text">
  15. 微信支付分<text style="color:#e74c3c; font-size:16px; font-weight:bold;">{{ payScore }}</text>
  16. </view>
  17. </view>
  18. <view class="score-desc" :style="{color: payScore >= 550 ? '#07c160' : '#e74c3c'}">
  19. {{ payScore >= 550 ? '✅ 符合办证条件(≥550分)' : '❌ 支付分不足,暂无法办证' }}
  20. </view>
  21. </view>
  22. <!-- 未获取支付分时显示授权按钮 -->
  23. <view class="auth-box" v-else>
  24. <button class="auth-btn" @click="getPayScore">
  25. 授权查询微信支付分办证必备
  26. </button>
  27. </view>
  28. <!-- 表单只有支付分达标才显示 -->
  29. <view class="form-box" v-if="payScore && payScore >= 550">
  30. <view class="item">
  31. <uni-icons class="form-icon" type="person" size="24"></uni-icons>
  32. <input class="input" placeholder="请输入读者证号" v-model="cardNo" />
  33. </view>
  34. <view class="item">
  35. <uni-icons class="form-icon" type="locked" size="24"></uni-icons>
  36. <input class="input" placeholder="请输入密码" :password="!showPwd" v-model="password" />
  37. <uni-icons class="form-right-icon" :type="showPwd ? 'eye-slash' : 'eye'" size="20" @click="togglePwd"></uni-icons>
  38. </view>
  39. <button class="login-btn" type="primary" @click="submit">绑定</button>
  40. </view>
  41. <view class="tips">
  42. 温馨提示<br />
  43. 1密码默认为<text style="color:#e74c3c">身份证后6位</text>X大写<br />
  44. 2微信支付分550分方可办理读者证
  45. </view>
  46. </view>
  47. </template>
  48. <script>
  49. const TOKEN_KEY = 'token';
  50. const USER_KEY = 'user-info';
  51. export default {
  52. data() {
  53. return {
  54. cardNo: '',
  55. password: '',
  56. showPwd: false,
  57. payScore: null, // 微信支付分
  58. serviceId: '你的支付分service_id' // 微信支付分后台获取
  59. }
  60. },
  61. onLoad() {
  62. // 页面加载可自动查支付分(也可用户点击)
  63. // this.getPayScore()
  64. },
  65. methods: {
  66. togglePwd() {
  67. this.showPwd = !this.showPwd
  68. },
  69. // 1. 获取微信支付分(核心)
  70. async getPayScore() {
  71. const _this = this
  72. uni.showLoading({ title: '获取支付分中...' })
  73. // 1) 后端获取支付分授权参数(必须后端签名)
  74. uni.request({
  75. url: 'https://你的后端.com/api/pay-score/auth',
  76. method: 'POST',
  77. data: {
  78. openid: uni.getStorageSync('wxSignature') || '', // 用户openid
  79. service_id: this.serviceId
  80. },
  81. success: (res) => {
  82. if (res.data.code !== 200) {
  83. uni.showToast({ title: res.data.msg || '获取失败', icon: 'none' })
  84. return
  85. }
  86. const { package: packageStr, out_order_no } = res.data.data
  87. // 2) 前端拉起支付分授权(微信原生API)
  88. uni.requestPayment({
  89. provider: 'wxpay',
  90. type: 'payScore',
  91. timeStamp: String(Date.now()),
  92. package: packageStr,
  93. // 以下由后端返回
  94. signType: 'HMAC-SHA256',
  95. paySign: res.data.data.paySign,
  96. nonceStr: res.data.data.nonceStr,
  97. success: () => {
  98. // 3) 授权成功 → 查询分数
  99. _this.queryPayScore(out_order_no)
  100. },
  101. fail: (err) => {
  102. console.log('支付分授权失败', err)
  103. uni.showToast({ title: '授权取消或失败', icon: 'none' })
  104. },
  105. complete: () => {
  106. uni.hideLoading()
  107. }
  108. })
  109. },
  110. fail: () => {
  111. uni.hideLoading()
  112. uni.showToast({ title: '网络异常', icon: 'none' })
  113. }
  114. })
  115. },
  116. // 2. 查询支付分分数(后端接口)
  117. async queryPayScore(outOrderNo) {
  118. uni.showLoading({ title: '查询分数...' })
  119. uni.request({
  120. url: 'https://你的后端.com/api/pay-score/query',
  121. method: 'POST',
  122. data: { out_order_no: outOrderNo },
  123. success: (res) => {
  124. uni.hideLoading()
  125. if (res.data.code === 200) {
  126. this.payScore = res.data.data.score // 例如 680
  127. } else {
  128. uni.showToast({ title: '查询失败', icon: 'none' })
  129. }
  130. },
  131. fail: () => {
  132. uni.hideLoading()
  133. uni.showToast({ title: '查询失败', icon: 'none' })
  134. }
  135. })
  136. },
  137. // 3. 原绑定逻辑(增加支付分判断)
  138. async submit() {
  139. // 先判断支付分
  140. if (!this.payScore || this.payScore < 550) {
  141. uni.showToast({ title: '支付分不足550,无法办证', icon: 'none' })
  142. return
  143. }
  144. if (!this.cardNo || !this.password) {
  145. uni.showToast({ title: '请输入读者证号和密码', icon: 'none' })
  146. return
  147. }
  148. // 以下为原登录逻辑(略)
  149. uni.showLoading({ title: '绑定中...' })
  150. setTimeout(() => {
  151. const res = {
  152. token: 'login-token-' + Date.now(),
  153. user: {
  154. nickName: '读者',
  155. cardNo: this.cardNo,
  156. payScore: this.payScore // 可一并保存
  157. }
  158. }
  159. uni.setStorageSync(TOKEN_KEY, res.token)
  160. uni.setStorageSync(USER_KEY, res.user)
  161. uni.hideLoading()
  162. uni.showToast({ title: '绑定成功', icon: 'success' })
  163. uni.navigateBack()
  164. }, 800)
  165. }
  166. }
  167. }
  168. </script>
  169. <style lang="scss" scoped>
  170. .page {
  171. padding: 40px 20px;
  172. }
  173. .form-box {
  174. padding: 20px;
  175. .item {
  176. width: 100%;
  177. min-height: 42px;
  178. border-radius: 23px;
  179. background-color: #f7f7f7;
  180. border: 1px solid #f4f4f4;
  181. display: flex;
  182. flex-direction: row;
  183. align-items: center;
  184. justify-content: flex-start;
  185. margin-bottom: 20px;
  186. overflow: hidden;
  187. .t-right-icon{
  188. margin-right: 15px;
  189. margin-left: 0;
  190. }
  191. .input {
  192. flex: 1;
  193. border-radius: 8px;
  194. padding: 12px 15px;
  195. font-size: 13px;
  196. }
  197. }
  198. }
  199. .login-btn {
  200. margin-top: 20px;
  201. background-color: #01a4fe;
  202. border-radius: 23px;
  203. }
  204. .tips {
  205. margin: 50px 30px;
  206. font-size: 11px;
  207. color: #000;
  208. line-height: 22px;
  209. }
  210. .form-icon {
  211. ::v-deep .uni-icons{
  212. margin-left: 10px;
  213. color: #01a4fe !important;
  214. }
  215. }
  216. .form-right-icon{
  217. ::v-deep .uni-icons{
  218. margin-right: 10px;
  219. }
  220. }
  221. /* 新增支付分样式 */
  222. .pay-score-box {
  223. padding: 20px;
  224. margin: 10px 20px;
  225. background: #f7f9ff;
  226. border-radius: 12px;
  227. }
  228. .score-item {
  229. display: flex;
  230. align-items: center;
  231. margin-bottom: 8px;
  232. }
  233. .score-text {
  234. margin-left: 10px;
  235. font-size: 15px;
  236. }
  237. .score-desc {
  238. font-size: 13px;
  239. padding-left: 34px;
  240. }
  241. .auth-box {
  242. padding: 40px 20px;
  243. text-align: center;
  244. }
  245. .auth-btn {
  246. background: #01a4fe;
  247. color: #fff;
  248. border-radius: 23px;
  249. padding: 12px 30px;
  250. border: none;
  251. }
  252. </style>