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.

255 lines
5.0 KiB

4 weeks ago
  1. <template>
  2. <view class="expense-container">
  3. <view class="top-bar">
  4. <view class="title">支出记录</view>
  5. </view>
  6. <view class="filter-bar">
  7. <view class="filter-item" :class="{ active: filterType === 'all' }" @click="filterType = 'all'">
  8. 全部
  9. </view>
  10. <view class="filter-item" :class="{ active: filterType === 'water' }" @click="filterType = 'water'">
  11. 水费
  12. </view>
  13. <view class="filter-item" :class="{ active: filterType === 'electric' }" @click="filterType = 'electric'">
  14. 电费
  15. </view>
  16. <view class="filter-item" :class="{ active: filterType === 'public' }" @click="filterType = 'public'">
  17. 公共支出
  18. </view>
  19. </view>
  20. <view class="list">
  21. <view class="expense-item" v-for="(item, index) in expenses" :key="index">
  22. <view class="item-header">
  23. <view class="expense-type">
  24. <text>{{ item.room }}</text>
  25. </view>
  26. <view class="expense-amount">¥{{ item.exp_amount }}</view>
  27. </view>
  28. <view class="item-body">
  29. <view class="detail-item">
  30. <view class="detail-label">支付方式</view>
  31. <view>{{ item.exp_method }}</view>
  32. </view>
  33. <view class="detail-item">
  34. <view class="detail-label">支出日期</view>
  35. <view>{{ item.exp_date }}</view>
  36. </view>
  37. <view class="detail-item">
  38. <view class="detail-label">支付人</view>
  39. <view>{{ item.username }}</view>
  40. </view>
  41. <view class="detail-item" v-if="item.remark">
  42. <view class="detail-label">备注</view>
  43. <view>{{ item.remark }}</view>
  44. </view>
  45. </view>
  46. </view>
  47. </view>
  48. </view>
  49. </template>
  50. <script setup>
  51. import { ref, computed } from 'vue'
  52. import { onShow } from '@dcloudio/uni-app'
  53. const filterType = ref('all')
  54. const expenses = ref([{
  55. id: 1,
  56. room:'706',
  57. exp_amount: 39.00,
  58. exp_date: '2025-09-08 14:27:21',
  59. username:'李慧琳',
  60. exp_method: '微信支付',
  61. exp_type: 1,
  62. remark: '电卡充值'
  63. },
  64. {
  65. id: 2,
  66. room:'706',
  67. exp_amount: 11.00,
  68. exp_date: '2025-09-08 14:28:40',
  69. username:'李慧琳',
  70. exp_method: '微信支付',
  71. exp_type: 1,
  72. remark: '电卡充值'
  73. },
  74. {
  75. id: 3,
  76. room:'706',
  77. exp_amount: 50.00,
  78. exp_date: '2025-08-15 09:20:30',
  79. username:'李慧琳',
  80. exp_method: '支付宝',
  81. exp_type: 0,
  82. remark: '8月水费'
  83. },
  84. {
  85. id: 4,
  86. room:'706',
  87. exp_amount: 120.00,
  88. exp_date: '2025-09-01 16:45:12',
  89. username:'李慧琳',
  90. exp_method: '微信支付',
  91. exp_type: 2,
  92. remark: '购买扫帚、拖把等清洁用品'
  93. },
  94. {
  95. id: 5,
  96. room:'706',
  97. exp_amount: 35.00,
  98. exp_date: '2025-08-22 11:10:25',
  99. username:'李慧琳',
  100. exp_method: '现金',
  101. exp_type: 2,
  102. remark: '购买垃圾桶2个'
  103. }
  104. ])
  105. onShow(() => {
  106. const isLogin = uni.getStorageSync('isLogin')
  107. console.log(isLogin)
  108. if (!isLogin) {
  109. uni.redirectTo({
  110. url: '/pages/login/login'
  111. })
  112. }
  113. })
  114. const res = computed(() => {
  115. switch (filterType.value) {
  116. case 'water':
  117. return expenses.value.filter(item => item.exp_type === '0')
  118. case 'electric':
  119. return expenses.value.filter(item => item.exp_type === '1')
  120. case 'public':
  121. return expenses.value.filter(item => item.exp_type === '1')
  122. default:
  123. return expenses.value
  124. }
  125. })
  126. const getTypeName = function(type) {
  127. switch (type) {
  128. case 0:
  129. return '水费';
  130. case 1:
  131. return '电费';
  132. case 2:
  133. return '公共支出';
  134. default:
  135. return '其他支出';
  136. }
  137. }
  138. const getIconClass = function(type) {
  139. switch (type) {
  140. case 0:
  141. return 'icon-water';
  142. case 1:
  143. return 'icon-electric';
  144. case 2:
  145. return 'icon-public';
  146. default:
  147. return 'icon-expense';
  148. }
  149. }
  150. </script>
  151. <style scoped>
  152. .expense-container {
  153. background-color: #f5f5f5;
  154. height: 100vh;
  155. }
  156. .top-bar {
  157. display: flex;
  158. align-items: center;
  159. padding: 30rpx 20rpx;
  160. background-color: #fff;
  161. border-bottom: 1px solid #eee;
  162. }
  163. .title {
  164. flex: 1;
  165. text-align: center;
  166. font-size: 34rpx;
  167. font-weight: bold;
  168. }
  169. .filter-bar {
  170. display: flex;
  171. background-color: #fff;
  172. padding: 15rpx 10rpx;
  173. border-bottom: 1px solid #eee;
  174. }
  175. .filter-item {
  176. display: inline-block;
  177. padding: 15rpx 25rpx;
  178. font-size: 26rpx;
  179. border-radius: 30rpx;
  180. margin: 0 5rpx;
  181. }
  182. .filter-item.active {
  183. background-color: #e6f7ff;
  184. color: #36bffa;
  185. }
  186. .list {
  187. padding: 20rpx;
  188. }
  189. .expense-item {
  190. background-color: #fff;
  191. border-radius: 16rpx;
  192. padding: 25rpx;
  193. margin-bottom: 20rpx;
  194. box-shadow: 0 5rpx 15rpx rgba(0, 0, 0, 0.05);
  195. }
  196. .item-header {
  197. display: flex;
  198. justify-content: space-between;
  199. margin-bottom: 20rpx;
  200. padding-bottom: 20rpx;
  201. border-bottom: 1px solid #f5f5f5;
  202. }
  203. .expense-type text {
  204. font-size: 30rpx;
  205. font-weight: bold;
  206. color: #333;
  207. }
  208. .expense-amount {
  209. font-size: 32rpx;
  210. font-weight: bold;
  211. color: #f5222d;
  212. }
  213. .item-body {
  214. display: flex;
  215. flex-direction: column;
  216. }
  217. .detail-item {
  218. display: flex;
  219. justify-content: space-between;
  220. padding: 15rpx 0;
  221. font-size: 28rpx;
  222. }
  223. .detail-label {
  224. color: #666;
  225. }
  226. </style>