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.

351 lines
7.3 KiB

3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
  1. <template>
  2. <view class="gold-detail-container">
  3. <!-- 顶部导航栏 -->
  4. <view class="top-bar">
  5. <view class="title">金币明细</view>
  6. </view>
  7. <!-- 总金币数 -->
  8. <view class="total-gold">
  9. <view class="total-label">总金币数</
  10. view>
  11. <view class="total-value">{{ totalGold }}</view>
  12. </view>
  13. <!-- 列表容器 -->
  14. <view class="list-container">
  15. <!-- 错误提示 -->
  16. <view class="error" v-if="errorMsg">
  17. <text>{{ errorMsg }}</text>
  18. <button @click="fetchData">重新加载</button>
  19. </view>
  20. <!-- 列表为空 -->
  21. <view class="empty" v-if="!loading && !errorMsg && goldList.length === 0">
  22. <text>暂无金币明细数据</text>
  23. </view>
  24. <!-- 金币明细列表 -->
  25. <view class="gold-item" v-for="(item, index) in goldList" :key="index">
  26. <view class="item-header">
  27. <view class="user-info">
  28. <view class="name">{{ item.name }}</view>
  29. <view class="jwcode">ID: {{ item.jwcode }}</view>
  30. </view>
  31. <view class="gold-amount">
  32. <text class="amount">+{{ item.sumGold }}</text>
  33. <text class="unit">金币</text>
  34. </view>
  35. </view>
  36. <view class="item-body">
  37. <view class="detail-item">
  38. <text class="label">市场</text>
  39. <text class="value">{{ item.market }}</text>
  40. </view>
  41. <view class="detail-item">
  42. <text class="label">平台</text>
  43. <text class="value">{{ item.payPlatform }}</text>
  44. </view>
  45. <view class="detail-item">
  46. <text class="label">商品</text>
  47. <text class="value">{{ item.goodsName }}</text>
  48. </view>
  49. <view class="detail-item">
  50. <text class="label">时间</text>
  51. <text class="value">{{ item.auditTime }}</text>
  52. </view>
  53. <view class="detail-item" v-if="item.orderCode">
  54. <text class="label">订单号</text>
  55. <text class="value">{{ item.orderCode }}</text>
  56. </view>
  57. </view>
  58. <view class="item-footer">
  59. <view class="gold-breakdown">
  60. <text>永久金币{{ item.permanentGold }}</text>
  61. <text>免费金币{{ item.freeGold }}</text>
  62. </view>
  63. </view>
  64. </view>
  65. </view>
  66. <!-- 下拉加载更多提示 -->
  67. <view class="load-more" v-if="hasMore && !loading">
  68. <text>上拉加载更多</text>
  69. </view>
  70. </view>
  71. </template>
  72. <script setup>
  73. // 修正生命周期导入来源(uni-app的生命周期需从@dcloudio/uni-app导入)
  74. import { ref } from 'vue'
  75. import { onLoad, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app'
  76. // 数据状态
  77. const goldList = ref([])
  78. const totalGold = ref(0)
  79. const loading = ref(false)
  80. const errorMsg = ref('')
  81. const page = ref(1)
  82. const pageSize = ref(10)
  83. const hasMore = ref(true)
  84. // 接口地址
  85. const API_URL = 'https://hwjb.homilychart.com/dev/admin/goldDetail/getGoldDetail'
  86. // 获取数据
  87. const fetchData = async (isLoadMore = false) => {
  88. // 如果是加载更多且没有更多数据,直接返回
  89. if (isLoadMore && !hasMore.value) return
  90. // 如果正在加载,直接返回
  91. if (loading.value) return
  92. // 显示加载状态(使用uni-app内置API)
  93. loading.value = true
  94. uni.showLoading({
  95. title: '加载中...',
  96. mask: true
  97. })
  98. errorMsg.value = ''
  99. try {
  100. // 发起请求
  101. const res = await uni.request({
  102. url: API_URL,
  103. method: 'GET',
  104. data: {
  105. page: page.value,
  106. pageSize: pageSize.value
  107. }
  108. })
  109. // 处理响应
  110. if (res[1].code === 200) {
  111. const result = res[1].data
  112. if (result.code === 200) {
  113. // 更新总金币数
  114. totalGold.value = result.data.total
  115. // 如果是加载更多,追加数据,否则替换数据
  116. if (isLoadMore) {
  117. goldList.value = [...goldList.value, ...result.data.list]
  118. } else {
  119. goldList.value = result.data.list
  120. }
  121. // 判断是否还有更多数据
  122. hasMore.value = result.data.list.length >= pageSize.value
  123. // 加载更多时页码加1
  124. if (isLoadMore) {
  125. page.value++
  126. }
  127. } else {
  128. errorMsg.value = `获取数据失败: ${result.msg}`
  129. }
  130. } else {
  131. errorMsg.value = `请求失败: ${res[1].statusCode}`
  132. }
  133. } catch (err) {
  134. errorMsg.value = `网络错误: ${err.message}`
  135. } finally {
  136. // 隐藏加载状态
  137. loading.value = false
  138. uni.hideLoading() // 关闭内置加载提示
  139. }
  140. }
  141. // 页面加载时获取数据
  142. onLoad(() => {
  143. fetchData()
  144. })
  145. // 下拉加载更多
  146. onReachBottom(() => {
  147. if (!loading.value && hasMore.value) {
  148. fetchData(true)
  149. }
  150. })
  151. // 下拉刷新
  152. onPullDownRefresh(() => {
  153. // 重置页码和数据
  154. page.value = 1
  155. hasMore.value = true
  156. fetchData().then(() => {
  157. uni.stopPullDownRefresh()
  158. })
  159. })
  160. </script>
  161. <style scoped>
  162. .gold-detail-container {
  163. background-color: #f5f5f5;
  164. min-height: 100vh;
  165. }
  166. /* 顶部导航 */
  167. .top-bar {
  168. display: flex;
  169. align-items: center;
  170. justify-content: center;
  171. padding: 30rpx 20rpx;
  172. background-color: #fff;
  173. border-bottom: 1px solid #eee;
  174. }
  175. .title {
  176. font-size: 34rpx;
  177. font-weight: bold;
  178. color: #333;
  179. }
  180. /* 总金币数 */
  181. .total-gold {
  182. background-color: #fff;
  183. padding: 40rpx 30rpx;
  184. margin-bottom: 20rpx;
  185. text-align: center;
  186. }
  187. .total-label {
  188. font-size: 28rpx;
  189. color: #666;
  190. margin-bottom: 15rpx;
  191. }
  192. .total-value {
  193. font-size: 48rpx;
  194. font-weight: bold;
  195. color: #ff7d00;
  196. }
  197. /* 列表容器 */
  198. .list-container {
  199. padding: 0 20rpx;
  200. }
  201. /* 错误提示 */
  202. .error {
  203. display: flex;
  204. flex-direction: column;
  205. align-items: center;
  206. padding: 60rpx 0;
  207. }
  208. .error text {
  209. font-size: 28rpx;
  210. color: #f5222d;
  211. margin-bottom: 20rpx;
  212. }
  213. .error button {
  214. background-color: #36bffa;
  215. color: #fff;
  216. border-radius: 30rpx;
  217. padding: 10rpx 30rpx;
  218. font-size: 26rpx;
  219. }
  220. /* 空状态 */
  221. .empty {
  222. display: flex;
  223. justify-content: center;
  224. padding: 100rpx 0;
  225. color: #999;
  226. font-size: 28rpx;
  227. }
  228. /* 列表项 */
  229. .gold-item {
  230. background-color: #fff;
  231. border-radius: 16rpx;
  232. padding: 25rpx;
  233. margin-bottom: 20rpx;
  234. box-shadow: 0 5rpx 15rpx rgba(0, 0, 0, 0.05);
  235. }
  236. .item-header {
  237. display: flex;
  238. justify-content: space-between;
  239. margin-bottom: 20rpx;
  240. padding-bottom: 20rpx;
  241. border-bottom: 1px solid #f5f5f5;
  242. }
  243. .user-info .name {
  244. font-size: 30rpx;
  245. font-weight: bold;
  246. color: #333;
  247. margin-bottom: 5rpx;
  248. }
  249. .user-info .jwcode {
  250. font-size: 24rpx;
  251. color: #999;
  252. }
  253. .gold-amount {
  254. text-align: right;
  255. }
  256. .gold-amount .amount {
  257. font-size: 32rpx;
  258. font-weight: bold;
  259. color: #00b42a;
  260. }
  261. .gold-amount .unit {
  262. font-size: 26rpx;
  263. color: #00b42a;
  264. margin-left: 5rpx;
  265. }
  266. .item-body {
  267. margin-bottom: 20rpx;
  268. }
  269. .detail-item {
  270. display: flex;
  271. margin-bottom: 15rpx;
  272. font-size: 26rpx;
  273. }
  274. .detail-item:last-child {
  275. margin-bottom: 0;
  276. }
  277. .detail-item .label {
  278. color: #666;
  279. width: 120rpx;
  280. }
  281. .detail-item .value {
  282. flex: 1;
  283. color: #333;
  284. word-break: break-all;
  285. }
  286. .item-footer {
  287. padding-top: 15rpx;
  288. border-top: 1px dashed #f5f5f5;
  289. }
  290. .gold-breakdown {
  291. display: flex;
  292. justify-content: space-between;
  293. font-size: 24rpx;
  294. color: #999;
  295. }
  296. /* 加载更多 */
  297. .load-more {
  298. text-align: center;
  299. padding: 30rpx 0;
  300. color: #999;
  301. font-size: 26rpx;
  302. }
  303. </style>