index.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. <template>
  2. <view class="container">
  3. <!-- 固定在顶部的筛选区域 -->
  4. <view class="filter-header">
  5. <view class="filter-controls">
  6. <view class="date-picker">
  7. <picker mode="date" @change="bindStartDateChange">
  8. <view class="date-input">
  9. <text>{{startDate || '请选择'}}</text>
  10. <uni-icons
  11. v-if="startDate"
  12. type="clear"
  13. size="16"
  14. @click="clearStartDate"
  15. style="margin-left: 10rpx">
  16. </uni-icons>
  17. </view>
  18. </picker>
  19. </view>
  20. <view class="date-picker">
  21. <picker mode="date" @change="bindEndDateChange">
  22. <view class="date-input">
  23. <text>{{endDate || '请选择'}}</text>
  24. <uni-icons
  25. v-if="endDate"
  26. type="clear"
  27. size="16"
  28. @click="clearEndDate"
  29. style="margin-left: 10rpx">
  30. </uni-icons>
  31. </view>
  32. </picker>
  33. </view>
  34. <button class="filter-btn" @click="handleSearch">查询</button>
  35. </view>
  36. </view>
  37. <!-- 订单列表 -->
  38. <scroll-view
  39. scroll-y
  40. class="list-container"
  41. @scrolltolower="loadMore"
  42. :scroll-top="scrollTop"
  43. >
  44. <u-swipe-action
  45. ref="swipeAction"
  46. >
  47. <view
  48. v-for="(item, index) in orderList"
  49. :key="item.id"
  50. class="list-item"
  51. >
  52. <u-swipe-action-item
  53. :options="options"
  54. :disabled="item.status === 2"
  55. @click="handleSwipeClick(item, index)"
  56. >
  57. <!-- 原有订单内容 -->
  58. <view class="item-header">
  59. <text class="order-id">订单号:{{ item.id }}</text>
  60. <view :class="['status-badge', getStatusClass(item.status)]">
  61. {{ getStatusText(item.status) }}
  62. </view>
  63. </view>
  64. <view class="item-content" @click="checkOrder(item)">
  65. <view class="info-row">
  66. <text class="info-label">创建时间:</text>
  67. <text class="info-value">{{ formatDate(item.createTime) }}</text>
  68. </view>
  69. <view class="info-row">
  70. <text class="info-label">总数量:</text>
  71. <text class="info-value">{{ item.quantity }}条</text>
  72. </view>
  73. <view class="info-row">
  74. <text class="info-label">总金额:</text>
  75. <text class="info-value amount">¥{{ item.amount }}</text>
  76. </view>
  77. </view>
  78. </u-swipe-action-item>
  79. </view>
  80. </u-swipe-action>
  81. <!-- 加载状态提示 -->
  82. <view class="loading-tip">
  83. <text v-if="loading">加载中...</text>
  84. <text v-else-if="noMoreData">没有更多数据了</text>
  85. </view>
  86. </scroll-view>
  87. <!-- 新增按钮 -->
  88. <u-button class="add-btn" @click="goToAddPage" icon="plus"/>
  89. </view>
  90. </template>
  91. <script>
  92. import {
  93. getPageList,
  94. delGreenRecycling
  95. } from '@/api/views/recycling/index.js'
  96. export default {
  97. data() {
  98. return {
  99. options: [{
  100. text: '删除',
  101. style: {
  102. backgroundColor: '#FF7F50',
  103. color: '#fff'
  104. }
  105. }],
  106. moveIndex: -1,
  107. startDate: '',
  108. endDate: '',
  109. orderList: [],
  110. pageNum: 1,
  111. pageSize: 10,
  112. loading: false,
  113. noMoreData: false,
  114. scrollTop: 0,
  115. isSearching: false
  116. }
  117. },
  118. created() {
  119. this.fetchOrderList()
  120. },
  121. methods: {
  122. handleMove(index) {
  123. console.info('index-----', index)
  124. if (this.moveIndex === index) return;
  125. this.moveIndex = index;
  126. this.closeOtherActions();
  127. },
  128. closeOtherActions() {
  129. if (this.moveIndex !== -1) {
  130. const refName = 'swipeAction' + this.moveIndex;
  131. this.$refs[refName]?.[0]?.closeHandler();
  132. }
  133. },
  134. handleSwipeClick(item, index) {
  135. uni.showModal({
  136. title: '确认删除',
  137. content: `确定删除该回收单 ${item.id} 吗?`,
  138. success: (res) => {
  139. if (res.confirm) {
  140. delGreenRecycling(item.id).then(res => {
  141. console.info('res-----', res)
  142. uni.showToast({ title: res.msg, icon: 'success' });
  143. this.handleSearch()
  144. })
  145. }
  146. }
  147. });
  148. },
  149. clearStartDate() {
  150. this.startDate = '';
  151. // 如果需要触发change事件可以手动调用
  152. this.bindStartDateChange({detail: {value: ''}});
  153. },
  154. clearEndDate() {
  155. this.endDate = '';
  156. // 如果需要触发change事件可以手动调用
  157. this.bindEndDateChange({detail: {value: ''}});
  158. },
  159. bindStartDateChange(e) {
  160. this.startDate = e.detail.value
  161. },
  162. bindEndDateChange(e) {
  163. this.endDate = e.detail.value
  164. },
  165. checkOrder(row){
  166. uni.navigateTo({
  167. url: '/pages/views/recycling/details?id=' + row.id
  168. })
  169. },
  170. handleSearch() {
  171. this.pageNum = 1
  172. this.noMoreData = false
  173. this.isSearching = true
  174. this.scrollTop = 0
  175. this.fetchOrderList()
  176. },
  177. fetchOrderList() {
  178. if (this.loading || this.noMoreData) return
  179. this.loading = true
  180. let params = {
  181. current: this.pageNum,
  182. size: this.pageSize,
  183. startDate: this.startDate,
  184. endDate: this.endDate
  185. }
  186. getPageList(params).then(res => {
  187. if (this.isSearching) {
  188. this.orderList = res.data.records
  189. this.isSearching = false
  190. } else {
  191. this.orderList = [...this.orderList, ...res.data.records]
  192. }
  193. this.noMoreData = this.pageNum * this.pageSize >= res.data.total;
  194. this.pageNum++
  195. }).finally(() => {
  196. this.loading = false
  197. })
  198. },
  199. loadMore() {
  200. if (!this.loading && !this.noMoreData) {
  201. this.fetchOrderList()
  202. }
  203. },
  204. goToAddPage() {
  205. uni.navigateTo({
  206. url: '/pages/views/recycling/details'
  207. })
  208. },
  209. formatDate(dateStr) {
  210. return dateStr.replace(' ', ' ')
  211. },
  212. getStatusText(status) {
  213. const statusMap = {
  214. 0: '待审批',
  215. 2: '已通过',
  216. 1: '已拒绝'
  217. }
  218. return statusMap[status] || ''
  219. },
  220. getStatusClass(status) {
  221. const classMap = {
  222. 0: 'status-pending',
  223. 2: 'status-approved',
  224. 1: 'status-rejected'
  225. }
  226. return classMap[status] || ''
  227. }
  228. }
  229. }
  230. </script>
  231. <style lang="scss" scoped>
  232. .container {
  233. padding: 0;
  234. background-color: #f8f8f8;
  235. min-height: 100vh;
  236. position: relative;
  237. }
  238. /* 筛选区域优化 */
  239. .filter-header {
  240. position: sticky;
  241. top: 0;
  242. z-index: 100;
  243. background: #fff;
  244. padding: 15rpx 20rpx;
  245. border-bottom: 1rpx solid #f0f0f0;
  246. }
  247. .filter-controls {
  248. display: flex;
  249. align-items: center;
  250. gap: 15rpx;
  251. padding: 10rpx 0;
  252. }
  253. .date-picker {
  254. flex: 1;
  255. .date-input {
  256. background: #f8f8f8;
  257. border-radius: 8rpx;
  258. padding: 18rpx 20rpx;
  259. font-size: 28rpx;
  260. color: #333;
  261. text-align: center;
  262. }
  263. }
  264. .filter-btn {
  265. background: #2979ff;
  266. color: #fff;
  267. border-radius: 8rpx;
  268. padding: 0 30rpx;
  269. height: 80rpx;
  270. line-height: 80rpx;
  271. font-size: 28rpx;
  272. min-width: 120rpx;
  273. &::after {
  274. border: none;
  275. }
  276. }
  277. /* 列表区域 */
  278. .list-container {
  279. height: calc(100vh - 180rpx);
  280. padding: 10rpx;
  281. transform: translateX(15rpx); /* 强制偏移 */
  282. width: calc(100% - 30rpx);
  283. }
  284. .list-item {
  285. background-color: #fff;
  286. border-radius: 12rpx;
  287. padding: 25rpx;
  288. margin: 0 20rpx 20rpx 20rpx; /* 修改为四边统一间距 */
  289. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
  290. border: 1rpx solid #f0f0f0;
  291. }
  292. .item-header {
  293. display: flex;
  294. justify-content: space-between;
  295. align-items: center;
  296. margin-bottom: 20rpx;
  297. padding-bottom: 15rpx;
  298. border-bottom: 1rpx solid #f5f5f5;
  299. }
  300. .order-id {
  301. font-size: 28rpx;
  302. color: #666;
  303. }
  304. .status-badge {
  305. font-size: 24rpx;
  306. padding: 6rpx 16rpx;
  307. border-radius: 20rpx;
  308. &.status-pending {
  309. background-color: #fff8e6;
  310. color: #ff9900;
  311. }
  312. &.status-approved {
  313. background-color: #e6f7ff;
  314. color: #1890ff;
  315. }
  316. &.status-rejected {
  317. background-color: #fff1f0;
  318. color: #ff4d4f;
  319. }
  320. }
  321. .item-content {
  322. .info-row {
  323. display: flex;
  324. margin-bottom: 16rpx;
  325. font-size: 28rpx;
  326. &:last-child {
  327. margin-bottom: 0;
  328. }
  329. }
  330. .info-label {
  331. color: #999;
  332. width: 160rpx;
  333. }
  334. .info-value {
  335. color: #333;
  336. flex: 1;
  337. &.amount {
  338. color: #f56c6c;
  339. font-weight: 500;
  340. }
  341. }
  342. }
  343. .loading-tip {
  344. text-align: center;
  345. padding: 20rpx;
  346. font-size: 26rpx;
  347. color: #999;
  348. }
  349. /* 新增按钮 */
  350. .add-btn {
  351. position: fixed;
  352. right: 25rpx;
  353. bottom: 25rpx;
  354. width: 90rpx;
  355. height: 90rpx;
  356. background: #07C160;
  357. color: #fff;
  358. border-radius: 50%;
  359. display: flex;
  360. justify-content: center;
  361. align-items: center;
  362. box-shadow: 0 4rpx 12rpx rgba(7, 193, 96, 0.3);
  363. z-index: 99;
  364. font-size: 36rpx;
  365. font-weight: bold;
  366. /* 移除按钮默认样式 */
  367. padding: 0;
  368. border: none;
  369. outline: none;
  370. /* 动画效果 */
  371. transition: all 0.2s ease;
  372. &::after {
  373. border: none;
  374. }
  375. /* 点击反馈 */
  376. &:active {
  377. transform: scale(0.95);
  378. box-shadow: 0 2rpx 6rpx rgba(7, 193, 96, 0.3);
  379. }
  380. /* 图标样式 */
  381. .add-icon {
  382. margin-top: 4rpx; /* 微调+号位置 */
  383. }
  384. }
  385. .u-swipe-action {
  386. border-radius: 12rpx; /* 与列表项圆角一致 */
  387. overflow: hidden; /* 防止按钮溢出 */
  388. }
  389. </style>