西藏巴青项目

order-panel.vue 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. <template>
  2. <view class="sp-order-page">
  3. <view class="sp-tabs">
  4. <view
  5. v-for="tab in tabs"
  6. :key="tab.key"
  7. class="sp-tab"
  8. :class="{ 'sp-tab--on': activeTab === tab.key }"
  9. @tap="switchTab(tab.key)"
  10. >
  11. <text class="sp-tab__txt">{{ tab.label }}</text>
  12. </view>
  13. </view>
  14. <scroll-view
  15. scroll-y
  16. class="sp-order-scroll"
  17. enable-back-to-top
  18. :show-scrollbar="false"
  19. @scrolltolower="loadMore"
  20. >
  21. <view v-if="loading && !rows.length" class="sp-empty">
  22. <text class="sp-empty__txt">加载中…</text>
  23. </view>
  24. <view v-else-if="!rows.length" class="sp-empty">
  25. <text class="sp-empty__txt">暂无订单</text>
  26. </view>
  27. <view v-else class="sp-order-list">
  28. <view
  29. v-for="item in rows"
  30. :key="item._key"
  31. class="sp-order-card"
  32. @tap="openDetail(item)"
  33. >
  34. <view class="sp-order-card__head">
  35. <text class="sp-order-card__no">订单编号 {{ item.displayNo }}</text>
  36. <text class="sp-order-card__status" :class="item.statusClass">{{ item.statusName }}</text>
  37. </view>
  38. <view class="sp-order-card__body">
  39. <view class="sp-order-card__thumb">
  40. <text class="sp-order-card__thumb-txt">牦</text>
  41. </view>
  42. <view class="sp-order-card__info">
  43. <text class="sp-order-card__line">承销商:{{ item.partnerName }}</text>
  44. <text class="sp-order-card__line">订单支付时间:{{ item.payTime }}</text>
  45. <text class="sp-order-card__line">订单结算时间:{{ item.settleTime }}</text>
  46. </view>
  47. </view>
  48. <view class="sp-order-card__foot">
  49. <text class="sp-order-card__amount">订单合计:{{ item.amountText }}</text>
  50. <text class="sp-order-card__heads">共 {{ item.totalHeads || 0 }} 头牦牛</text>
  51. </view>
  52. </view>
  53. </view>
  54. <view v-if="rows.length && (loadingMore || noMore)" class="sp-list-foot">
  55. <text class="sp-list-foot__txt">{{ loadingMore ? '加载中…' : '没有更多了' }}</text>
  56. </view>
  57. <view class="sp-footer-spacer" />
  58. </scroll-view>
  59. </view>
  60. </template>
  61. <script>
  62. import { listSupplierOrders, listSupplierSettlements } from '@/api/supplier/order'
  63. import { DASH, formatCurrency, formatDateTime } from '@/utils/format'
  64. const TABS = [
  65. { key: 'ALL', label: '全部订单' },
  66. { key: 'PENDING', label: '待支付' },
  67. { key: 'SETTLEMENT', label: '待结算' },
  68. { key: 'COMPLETED', label: '已完成' }
  69. ]
  70. export default {
  71. data() {
  72. return {
  73. tabs: TABS,
  74. activeTab: 'ALL',
  75. rows: [],
  76. pageNum: 1,
  77. pageSize: 10,
  78. total: 0,
  79. loading: false,
  80. loadingMore: false
  81. }
  82. },
  83. computed: {
  84. noMore() {
  85. return this.rows.length > 0 && this.rows.length >= this.total
  86. }
  87. },
  88. methods: {
  89. /** Tab 页 onShow 时刷新列表 */
  90. reload() {
  91. this.reloadList()
  92. },
  93. switchTab(key) {
  94. if (this.activeTab === key) return
  95. this.activeTab = key
  96. this.reloadList()
  97. },
  98. reloadList() {
  99. this.pageNum = 1
  100. this.rows = []
  101. this.total = 0
  102. this.fetchList(true)
  103. },
  104. loadMore() {
  105. if (this.loading || this.loadingMore || this.noMore) return
  106. this.pageNum += 1
  107. this.fetchList(false)
  108. },
  109. fetchList(reset) {
  110. if (reset) {
  111. this.loading = true
  112. } else {
  113. this.loadingMore = true
  114. }
  115. const params = { pageNum: this.pageNum, pageSize: this.pageSize }
  116. const req = this.activeTab === 'SETTLEMENT'
  117. ? listSupplierSettlements(params)
  118. : listSupplierOrders({ ...params, statusTab: this.activeTab })
  119. req
  120. .then((res) => {
  121. const list = (res.rows || []).map((row) => this.mapRow(row))
  122. this.total = res.total != null ? Number(res.total) : 0
  123. this.rows = reset ? list : this.rows.concat(list)
  124. })
  125. .catch(() => {
  126. if (reset) {
  127. this.rows = []
  128. this.total = 0
  129. } else {
  130. this.pageNum -= 1
  131. }
  132. })
  133. .finally(() => {
  134. this.loading = false
  135. this.loadingMore = false
  136. })
  137. },
  138. mapRow(row) {
  139. const isSettlement = this.activeTab === 'SETTLEMENT'
  140. const statusName = isSettlement
  141. ? (row.settlementStatusName || '待结算')
  142. : (row.orderStatusName || DASH)
  143. const statusClass = this.resolveStatusClass(statusName)
  144. return {
  145. _key: `${isSettlement ? 's' : 'o'}-${row.id}`,
  146. id: row.id,
  147. kind: isSettlement ? 'settlement' : 'order',
  148. displayNo: isSettlement ? (row.settlementNo || row.orderNo) : row.orderNo,
  149. statusName,
  150. statusClass,
  151. partnerName: row.distributorName || DASH,
  152. payTime: formatDateTime(row.finishTime),
  153. settleTime: formatDateTime(row.settleFinishTime),
  154. amountText: formatCurrency(row.totalAmount),
  155. totalHeads: row.totalHeads
  156. }
  157. },
  158. resolveStatusClass(name) {
  159. const text = String(name || '')
  160. if (text.includes('完成')) return 'sp-order-card__status--done'
  161. if (text.includes('待')) return 'sp-order-card__status--pending'
  162. return ''
  163. },
  164. openDetail(item) {
  165. uni.navigateTo({
  166. url: `/pages/supplier/order-detail/index?kind=${item.kind}&id=${item.id}`
  167. })
  168. }
  169. }
  170. }
  171. </script>
  172. <style lang="scss" scoped>
  173. @import '@/styles/morandi.scss';
  174. @import '@/styles/scroll-fill.scss';
  175. .sp-order-page {
  176. @include tab-panel-root;
  177. background: $morandi-bg-page;
  178. }
  179. .sp-tabs {
  180. display: flex;
  181. flex-direction: row;
  182. background: #ffffff;
  183. border-bottom: 1rpx solid $morandi-border-soft;
  184. flex-shrink: 0;
  185. }
  186. .sp-tab {
  187. flex: 1;
  188. min-width: 0;
  189. padding: 24rpx 8rpx;
  190. display: flex;
  191. align-items: center;
  192. justify-content: center;
  193. border-bottom: 4rpx solid transparent;
  194. }
  195. .sp-tab--on {
  196. border-bottom-color: #3b82f6;
  197. }
  198. .sp-tab__txt {
  199. font-size: 26rpx;
  200. color: $morandi-text-secondary;
  201. }
  202. .sp-tab--on .sp-tab__txt {
  203. color: #2563eb;
  204. font-weight: 600;
  205. }
  206. .sp-order-scroll {
  207. @include flex-scroll-y;
  208. }
  209. .sp-order-list {
  210. padding: 16rpx 24rpx 0;
  211. display: flex;
  212. flex-direction: column;
  213. gap: 20rpx;
  214. }
  215. .sp-order-card {
  216. padding: 24rpx;
  217. border-radius: 16rpx;
  218. background: $morandi-bg-card;
  219. border: 1rpx solid $morandi-border-soft;
  220. box-sizing: border-box;
  221. }
  222. .sp-order-card__head {
  223. display: flex;
  224. flex-direction: row;
  225. align-items: center;
  226. justify-content: space-between;
  227. gap: 16rpx;
  228. margin-bottom: 20rpx;
  229. }
  230. .sp-order-card__no {
  231. flex: 1;
  232. min-width: 0;
  233. font-size: 26rpx;
  234. color: $morandi-text;
  235. word-break: break-all;
  236. }
  237. .sp-order-card__status {
  238. flex-shrink: 0;
  239. font-size: 26rpx;
  240. color: $morandi-text-secondary;
  241. }
  242. .sp-order-card__status--pending {
  243. color: #ea580c;
  244. }
  245. .sp-order-card__status--done {
  246. color: #16a34a;
  247. }
  248. .sp-order-card__body {
  249. display: flex;
  250. flex-direction: row;
  251. gap: 20rpx;
  252. margin-bottom: 20rpx;
  253. }
  254. .sp-order-card__thumb {
  255. width: 120rpx;
  256. height: 120rpx;
  257. border-radius: 12rpx;
  258. background: #e5e7eb;
  259. display: flex;
  260. align-items: center;
  261. justify-content: center;
  262. flex-shrink: 0;
  263. }
  264. .sp-order-card__thumb-txt {
  265. font-size: 40rpx;
  266. font-weight: 700;
  267. color: #6b7280;
  268. }
  269. .sp-order-card__info {
  270. flex: 1;
  271. min-width: 0;
  272. display: flex;
  273. flex-direction: column;
  274. gap: 10rpx;
  275. }
  276. .sp-order-card__line {
  277. font-size: 24rpx;
  278. color: $morandi-text-secondary;
  279. line-height: 1.45;
  280. }
  281. .sp-order-card__foot {
  282. display: flex;
  283. flex-direction: row;
  284. align-items: center;
  285. justify-content: space-between;
  286. gap: 16rpx;
  287. padding-top: 16rpx;
  288. border-top: 1rpx solid $morandi-border-soft;
  289. }
  290. .sp-order-card__amount {
  291. font-size: 28rpx;
  292. font-weight: 600;
  293. color: #dc2626;
  294. }
  295. .sp-order-card__heads {
  296. font-size: 24rpx;
  297. color: $morandi-text-muted;
  298. }
  299. .sp-empty,
  300. .sp-list-foot {
  301. padding: 48rpx 24rpx;
  302. text-align: center;
  303. }
  304. .sp-empty__txt,
  305. .sp-list-foot__txt {
  306. font-size: 26rpx;
  307. color: $morandi-text-muted;
  308. }
  309. .sp-footer-spacer {
  310. height: 40rpx;
  311. }
  312. </style>