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

328 lines
8.3 KiB

2 months ago
1 month ago
2 months ago
1 month ago
1 month ago
2 months 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
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
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
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
1 month ago
1 month ago
2 months ago
1 month ago
2 months ago
  1. <template>
  2. <view class="reader-card">
  3. <image class="card-top-bg" src="@/static/images/card-img1.png" mode="widthFix" />
  4. <view class="edit-btn" @click="toggleEditMode">
  5. {{ isEditMode ? '完成' : '解绑' }}
  6. </view>
  7. <view class="card-list">
  8. <view
  9. class="card-list-item"
  10. v-for="(item, index) in cardList"
  11. :key="item.id"
  12. @click="handleSelectItem(item.bindValue)"
  13. :class="{ active: selectedValue === item.bindValue }"
  14. >
  15. <image class="card-left-img" src="@/static/images/card-img2.png" mode="widthFix" />
  16. <view class="card-right-info">
  17. <text class="info-title">读者证号</text>
  18. <text class="info-num">{{ item.bindValue }}</text>
  19. <text class="default-tag" v-if="item.bindDefault">默认证</text>
  20. </view>
  21. <radio v-if="isEditMode" :value="item.bindValue" :checked="selectedValue === item.bindValue"/>
  22. </view>
  23. <view class="add-card-btn" @click="toAddReaderCard" v-if="!isEditMode">
  24. <uni-icons type="plus" size="20" color="#01a4fe"></uni-icons>
  25. <text>新增读者证</text>
  26. </view>
  27. </view>
  28. <!-- 编辑模式显示底部解绑按钮 -->
  29. <button
  30. v-if="isEditMode"
  31. class="unbind-btn"
  32. :disabled="!selectedValue"
  33. :class="{disabled: !selectedValue}"
  34. @click="handleUnbind"
  35. >
  36. 确认解绑
  37. </button>
  38. </view>
  39. </template>
  40. <script>
  41. import {
  42. FetchFindAllReaderBindByOpenId,
  43. FetchSetDefaultReadCard,
  44. FetchUnbindReadCard
  45. } from '@/api/user';
  46. const READLIST = 'reader-card-list';
  47. export default {
  48. data() {
  49. return {
  50. isEditMode: false,
  51. selectedValue: '',
  52. cardList: [],
  53. }
  54. },
  55. onShow() {
  56. this.getBindReaderCardList();
  57. },
  58. methods: {
  59. // 切换编辑模式 + 清空选中
  60. toggleEditMode() {
  61. this.isEditMode = !this.isEditMode;
  62. this.selectedValue = '';
  63. },
  64. // 获取列表
  65. async getBindReaderCardList() {
  66. try {
  67. const openId = uni.getStorageSync('wx_login_code');
  68. if (!openId) return;
  69. const res = await FetchFindAllReaderBindByOpenId({
  70. libcode: '1201',
  71. openId: openId
  72. });
  73. if (res.code === 200 && res.data.length > 0) {
  74. this.cardList = res.data;
  75. uni.setStorageSync(READLIST, res.data);
  76. } else {
  77. this.cardList = [];
  78. this.selectedValue = '';
  79. uni.setStorageSync(READLIST, []);
  80. }
  81. } catch (err) {
  82. this.cardList = uni.getStorageSync(READLIST) || [];
  83. }
  84. },
  85. // 点击卡片
  86. handleSelectItem(value) {
  87. // 编辑模式:只做选择
  88. if (this.isEditMode) {
  89. this.selectedValue = this.selectedValue === value ? '' : value;
  90. return;
  91. }
  92. // 正常模式:切换默认
  93. const currentDefault = this.cardList.find(item => item.bindDefault === true);
  94. if (currentDefault && currentDefault.bindValue === value) {
  95. uni.showToast({
  96. title: '当前已是默认证,请勿重复操作',
  97. icon: 'none'
  98. });
  99. return;
  100. }
  101. const openId = uni.getStorageSync('wx_login_code');
  102. uni.showModal({
  103. title: '提示',
  104. content: '确定切换默认读者证吗?',
  105. success: async (res) => {
  106. if (!res.confirm) return;
  107. try {
  108. const result = await FetchSetDefaultReadCard({
  109. bindType: 'rdid',
  110. bindValue: value,
  111. libcode: '1201',
  112. openid: openId
  113. });
  114. if (result.code === 200) {
  115. uni.setStorageSync('currentReaderCard', value);
  116. await this.getBindReaderCardList();
  117. uni.showToast({ title: '默认证切换成功', icon: 'success' });
  118. }
  119. } catch (err) {
  120. uni.showToast({ title: '切换失败', icon: 'none' });
  121. }
  122. }
  123. });
  124. },
  125. // 解绑(核心逻辑)
  126. async handleUnbind() {
  127. if (!this.selectedValue) {
  128. uni.showToast({ title: '请选择要解绑的读者证', icon: 'none' });
  129. return;
  130. }
  131. const openId = uni.getStorageSync('wx_login_code');
  132. const unbindItem = this.cardList.find(item => item.bindValue === this.selectedValue);
  133. const isUnbindDefault = unbindItem?.bindDefault === true;
  134. uni.showModal({
  135. title: '提示',
  136. content: `确定要解绑读者证【${this.selectedValue}】吗?`,
  137. success: async (res) => {
  138. if (!res.confirm) return;
  139. try {
  140. const result = await FetchUnbindReadCard({
  141. bindType: "rdid",
  142. bindValue: this.selectedValue,
  143. libcode: "1201",
  144. openid: openId
  145. });
  146. if (result.code === 200) {
  147. uni.showToast({ title: '解绑成功', icon: 'success' });
  148. // 清空选中(不解绑模式自动选中第一个)
  149. this.selectedValue = '';
  150. await this.getBindReaderCardList();
  151. // ==============================================
  152. // ✅ 解绑的是默认 → 自动设置第一个为新默认(接口+缓存)
  153. // ✅ 但不解绑模式选中它
  154. // ==============================================
  155. if (isUnbindDefault && this.cardList.length > 0) {
  156. const newValue = this.cardList[0].bindValue;
  157. await FetchSetDefaultReadCard({
  158. bindType: 'rdid',
  159. bindValue: newValue,
  160. libcode: '1201',
  161. openid: openId
  162. });
  163. uni.setStorageSync('currentReaderCard', newValue);
  164. await this.getBindReaderCardList();
  165. }
  166. // 全部解绑 → 返回
  167. if (this.cardList.length === 0) {
  168. setTimeout(() => uni.navigateBack(), 1500);
  169. }
  170. }
  171. } catch (err) {
  172. uni.showToast({ title: '解绑失败', icon: 'none' });
  173. }
  174. }
  175. });
  176. },
  177. toAddReaderCard() {
  178. uni.navigateTo({ url: "/pages/login/login" });
  179. },
  180. }
  181. }
  182. </script>
  183. <style lang="scss" scoped>
  184. .reader-card{
  185. position: relative;
  186. min-height: 100vh;
  187. background-color: #f5f5f5;
  188. .card-top-bg{
  189. position: absolute;
  190. left: 0;
  191. top: 0;
  192. width: 100%;
  193. }
  194. .edit-btn{
  195. position: absolute;
  196. right: 20px;
  197. top: 20px;
  198. z-index: 100;
  199. font-size: 15px;
  200. }
  201. // 读者证列表
  202. .card-list{
  203. position: absolute;
  204. left: 0;
  205. top: 60px;
  206. width: calc(100% - 24px);
  207. height: calc(100vh - 195px);
  208. overflow-y: auto;
  209. padding: 12px;
  210. z-index: 999;
  211. .card-list-item{
  212. display: flex;
  213. justify-content: space-between;
  214. align-items: center;
  215. padding: 10px;
  216. margin-bottom: 12px;
  217. border: 2px solid #C6C6E2;
  218. border-radius: 8px;
  219. background: rgba(241,241,249,0.4);
  220. cursor: pointer;
  221. transition: all 0.2s;
  222. &.active{
  223. border-color: #01a4fe;
  224. background: rgba(1, 164, 254, 0.1);
  225. }
  226. .card-left-img{
  227. width: 80px;
  228. margin-right: 12px;
  229. display: block;
  230. }
  231. .card-right-info{
  232. flex: 1;
  233. display: flex;
  234. flex-direction: column;
  235. .info-title{
  236. font-size: 16px;
  237. color: #333;
  238. font-weight: bold;
  239. padding-bottom: 4px;
  240. }
  241. .info-num{
  242. font-size: 14px;
  243. color: #999;
  244. }
  245. .default-tag{
  246. width: 46px;
  247. font-size: 12px;
  248. color: #01a4fe;
  249. border: 1px solid #01a4fe;
  250. border-radius: 4px;
  251. padding: 2px 0;
  252. text-align: center;
  253. display: inline-block;
  254. margin-top: 4px;
  255. }
  256. }
  257. }
  258. }
  259. .add-card-btn {
  260. display: flex;
  261. align-items: center;
  262. justify-content: center;
  263. margin-top: 15px;
  264. height: 44px;
  265. border: 1px dashed #01a4fe;
  266. border-radius: 8px;
  267. color: #01a4fe;
  268. font-size: 15px;
  269. uni-icons {
  270. margin-right: 6px;
  271. }
  272. }
  273. .unbind-btn{
  274. position: fixed;
  275. bottom: 40px;
  276. left: 0;
  277. right: 0;
  278. width: calc(100% - 40px);
  279. margin: 0 auto;
  280. padding: 4px 0;
  281. color: #fff;
  282. background-color: #01a4fe;
  283. border-radius: 23px;
  284. font-size: 16px;
  285. &.disabled{
  286. background-color: #ccc;
  287. }
  288. }
  289. }
  290. </style>