order-alist.vue 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. <template>
  2. <view class="page-container">
  3. <!-- 导航栏 -->
  4. <u-navbar :autoBack="true" :placeholder="true" :border-bottom="false">
  5. <view class="navbar-title">团餐订单</view>
  6. <view slot="right" class="navbar-right">
  7. <text class="nav-btn" @click="goToDetail">订单明细</text>
  8. <!-- <text class="nav-btn manage-btn" v-if="currentStatusTab == 0" @click="toggleManageMode">{{ isManaging ? '退出管理' : '批量管理' }}</text> -->
  9. </view>
  10. </u-navbar>
  11. <!-- 搜索框 -->
  12. <view class="search-bar">
  13. <u-search bg-color="#F7F8FC" placeholder="请输入套餐名称或团长名" search-icon-color="#999"
  14. :showAction="true" actionText="搜索"
  15. :actionStyle="{
  16. width: 'auto',
  17. color: '#333',
  18. padding: '0 20rpx',
  19. borderLeft: '1rpx solid #DDDDDD'
  20. }"
  21. @search="onSearch" @custom="onSearch"
  22. ></u-search>
  23. </view>
  24. <!-- 状态Tabs -->
  25. <u-tabs :list="statusTabs"
  26. :current="currentStatusTab"
  27. inactive-color="#666666"
  28. :bar-width="72"
  29. :bar-style="{
  30. bottom: '20rpx',
  31. marginLeft: '-12rpx',
  32. background: 'linear-gradient(90deg, #82BCFF 0%, rgba(130,188,255,0) 100%)'
  33. }"
  34. :active-item-style="{
  35. fontWeight: '600',
  36. fontSize: '32rpx',
  37. color: '#000000',
  38. }"
  39. @change="onTabChange"
  40. ></u-tabs>
  41. <!-- 订单列表 -->
  42. <view class="order-scroll-view" >
  43. <ListScrollView ref="listScroll"
  44. :api="api"
  45. :init="{
  46. ...initParams,
  47. }">
  48. <template v-slot:list="{ data }">
  49. <u-checkbox-group width="40rpx" inactiveColor="#fff" placement="column"
  50. v-model="selectedOrders"
  51. @change="onSelect"
  52. >
  53. <view class="order-item" v-for="item in data" :key="item.orderId">
  54. <view class="order-header">
  55. <view class="location-box">
  56. <view class="location-info">
  57. <view class="name">
  58. <!-- <u-image width="40rpx" height="40rpx" src="/static/groupMeal/icon_user.png"></u-image> -->
  59. <u-icon name="account" color="#000000" size="30"></u-icon>
  60. <text>{{ item.headName }}</text>
  61. </view>
  62. <view class="desc">
  63. <text>合计份数:</text>
  64. <text class="val">{{ item.buyNumber }}份</text>
  65. </view>
  66. </view>
  67. <view class="location-address">
  68. <view class="atext">{{ item.address }}</view>
  69. <view class="btext">{{ item.region }}</view>
  70. </view>
  71. </view>
  72. <view class="order-actions" >
  73. <u-checkbox :name="item.orderId" shape="circle" v-model="item.checked"></u-checkbox>
  74. </view>
  75. </view>
  76. <ListExpand :items="item.merchantPackageOrderDTOS">
  77. <template v-slot:="{ items }">
  78. <view class="order-card" v-for="(eItem, ei) in items" :key="ei">
  79. <!-- <u-image width="84rpx" height="84rpx" border-radius="12rpx" :src="eItem.productImage && `${$config.apiUrl}/${eItem.productImage.split(',')[0]}`" mode="aspectFill"></u-image> -->
  80. <u-image width="84rpx" height="84rpx" border-radius="12rpx" :src="eItem.productImage" mode="aspectFill"></u-image>
  81. <view class="order-info">
  82. <view class="order-title">{{ eItem.packageName }}</view>
  83. <view class="order-line">
  84. <view class="leader-name">{{ eItem.dishName }}</view>
  85. <view class="quantity-tag">{{ eItem.numberUserCount }}份</view>
  86. </view>
  87. </view>
  88. </view>
  89. </template>
  90. </ListExpand>
  91. </view>
  92. </u-checkbox-group>
  93. </template>
  94. </ListScrollView>
  95. </view>
  96. <!-- 批量操作底部栏 -->
  97. <view class="footer-bar" >
  98. <u-checkbox-group v-model="isAllSelected" placement="row">
  99. <u-checkbox name="all" shape="circle" v-model="isAllSelected" @change="onSelectAll">全选</u-checkbox>
  100. </u-checkbox-group>
  101. <view class="action-buttons">
  102. <u-button type="primary" @click="handleBatchAction">出餐</u-button>
  103. </view>
  104. </view>
  105. <Tabbar />
  106. <!-- 弹窗 -->
  107. <Modal ref="myModal"
  108. :title="modalText.title"
  109. :content="modalText.content"
  110. />
  111. </view>
  112. </template>
  113. <script>
  114. import Modal from '@/components/modal/index.vue';
  115. import Tabbar from '@/pages/groupMeal/tabbar/index.vue';
  116. import ListExpand from '@/components/list-scroll-view/list-expand.vue';
  117. import ListScrollView from '@/components/list-scroll-view/index.vue';
  118. export default {
  119. components: {
  120. Modal,
  121. Tabbar,
  122. ListExpand,
  123. ListScrollView
  124. },
  125. data() {
  126. return {
  127. api: {
  128. url: '/groupmeal/merchantPackageOrder/pageList',
  129. method: 'POST',
  130. },
  131. isManaging: false,
  132. statusTabs: [{ name: '待出餐' }, { name: '已出餐' }],
  133. currentStatusTab: 0,
  134. selectedOrders: [],
  135. isAllSelected: false,
  136. // 弹窗
  137. modalText: {
  138. title: '提示',
  139. btntext: '好的',
  140. content: ''
  141. },
  142. };
  143. },
  144. computed: {
  145. // 数据参数
  146. initParams() {
  147. let params = {
  148. // 订单状态 0 未成团 1 已成团 2 已出餐 3 已送达
  149. orderStatus: 0,
  150. }
  151. // 待出餐
  152. if (this.currentStatusTab == 0) {
  153. params = {
  154. ...params,
  155. orderStatus: 1,
  156. }
  157. }
  158. // 已出餐
  159. else if (this.currentStatusTab == 1) {
  160. params = {
  161. ...params,
  162. orderStatus: 2,
  163. }
  164. }
  165. return params;
  166. }
  167. },
  168. onLoad() {
  169. },
  170. methods: {
  171. goToDetail() {
  172. uni.navigateTo({
  173. url: '/pages/groupMeal/orders/order-blist'
  174. });
  175. },
  176. toggleManageMode() {
  177. this.isManaging = !this.isManaging;
  178. this.onClearSel();
  179. },
  180. onTabChange(e) {
  181. this.currentStatusTab = e;
  182. // 清除已选数据
  183. this.onClearSel();
  184. // 关闭批量
  185. this.isManaging = false;
  186. // 触发更新
  187. this.$nextTick(() => {
  188. this.$refs.listScroll.downCallback();
  189. });
  190. },
  191. onSearch(value) {
  192. this.$refs[`listScroll`].reloadList({
  193. queryName: value,
  194. });
  195. },
  196. onSelect(e) {
  197. this.selectedOrders = e;
  198. // 控制全选
  199. this.isAllSelected = e.length === this.$refs.listScroll.dataList.length;
  200. },
  201. onSelectAll(e) {
  202. let allOrders = this.$refs.listScroll.dataList;
  203. if (e.value) {
  204. this.selectedOrders = allOrders.map(order => order.orderId);
  205. } else {
  206. this.selectedOrders = [];
  207. }
  208. allOrders.forEach(item => {
  209. item.checked = e.value;
  210. });
  211. },
  212. // 完成某种操作后,清空数据
  213. onClearSel() {
  214. this.selectedOrders = [];
  215. this.isAllSelected = false;
  216. },
  217. handleBatchAction() {
  218. if (this.selectedOrders.length === 0) {
  219. this.$tip.toast("请先选择订单")
  220. return;
  221. }
  222. this.modalText.content = '是否确认已经出餐?';
  223. this.$refs.myModal.onOpen(false, () => {
  224. let params = {
  225. orderId: this.selectedOrders.join()
  226. };
  227. this.$http.get('/groupmeal/merchantPackageOrder/orderReady', {params}).then(res => {
  228. if (res.data.code === 200) {
  229. // this.$tip.success(res.data.message);
  230. uni.showToast({
  231. icon:'success',
  232. title:res.data.message
  233. })
  234. // 触发更新
  235. this.isManaging = false;
  236. this.currentStatusTab = 1;
  237. this.onClearSel();
  238. this.$nextTick(() => {
  239. this.$refs.listScroll.downCallback();
  240. });
  241. } else {
  242. // this.$tip.error(res.data.message);
  243. uni.showToast({
  244. icon:'none',
  245. title:res.data.message
  246. })
  247. }
  248. });
  249. });
  250. }
  251. }
  252. };
  253. </script>
  254. <style lang="scss" scoped>
  255. .page-container {
  256. height: 100vh;
  257. display: flex;
  258. flex-direction: column;
  259. .navbar-title {
  260. font-weight: 500;
  261. font-size: 36rpx;
  262. color: #333333;
  263. }
  264. .navbar-right {
  265. padding: 0 24rpx;
  266. display: flex;
  267. align-items: center;
  268. .nav-btn {
  269. font-weight: 500;
  270. font-size: 28rpx;
  271. color: #333333;
  272. }
  273. .manage-btn {
  274. margin-left: 24rpx;
  275. }
  276. }
  277. .search-bar {
  278. padding: 12rpx 32rpx;
  279. background-color: #fff;
  280. .u-search {
  281. border-radius: 8rpx;
  282. background-color: #F7F8FC;
  283. }
  284. }
  285. .order-scroll-view {
  286. flex: 1;
  287. height: 0;
  288. padding: 20rpx 24rpx;
  289. background-color: #F7F8FC;
  290. .u-checkbox-group {
  291. width: 100%;
  292. }
  293. .order-item {
  294. width: 100%;
  295. margin-bottom: 24rpx;
  296. background: #fff;
  297. .order-actions {
  298. }
  299. }
  300. .order-header {
  301. gap: 24rpx;
  302. padding: 24rpx;
  303. display: flex;
  304. align-items: center;
  305. background: linear-gradient(90deg, #FDFDFF 0%, #E3F0FF 100%);
  306. .location-box {
  307. flex: 1;
  308. }
  309. .location-info {
  310. display: flex;
  311. align-items: center;
  312. justify-content: space-between;
  313. .name {
  314. font-weight: 500;
  315. font-size: 28rpx;
  316. color: #333333;
  317. display: flex;
  318. align-items: center;
  319. text {
  320. padding-left: 10rpx;
  321. }
  322. }
  323. .desc {
  324. font-weight: 400;
  325. font-size: 24rpx;
  326. color: #666666;
  327. .val {
  328. color: #449AFF;
  329. }
  330. }
  331. }
  332. .location-address {
  333. margin-top: 10rpx;
  334. .atext {
  335. font-weight: 500;
  336. font-size: 26rpx;
  337. color: #333333;
  338. }
  339. .btext {
  340. font-weight: 400;
  341. font-size: 26rpx;
  342. color: #666666;
  343. }
  344. }
  345. }
  346. .order-card {
  347. width: 100%;
  348. padding: 24rpx;
  349. display: flex;
  350. align-items: center;
  351. border-bottom: 1rpx solid #f0f0f0;
  352. .order-info {
  353. flex: 1;
  354. margin-left: 20rpx;
  355. .order-title {
  356. font-size: 26rpx;
  357. font-weight: 500;
  358. color: #303133;
  359. font-weight: bold;
  360. display: -webkit-box;
  361. -webkit-line-clamp: 1;
  362. -webkit-box-orient: vertical;
  363. overflow: hidden;
  364. }
  365. .order-line {
  366. margin-top: 8rpx;
  367. display: flex;
  368. align-items: center;
  369. .leader-name {
  370. flex: 1;
  371. font-weight: 400;
  372. font-size: 22rpx;
  373. color: #8A91A8;
  374. }
  375. .quantity-tag {
  376. font-size: 24rpx;
  377. color: #333333;
  378. }
  379. }
  380. }
  381. }
  382. }
  383. }
  384. .footer-bar {
  385. bottom: 50px;
  386. padding-bottom: 20px;
  387. .action-buttons {
  388. display: flex;
  389. gap: 20rpx;
  390. ::v-deep .u-btn {
  391. height: 69rpx;
  392. border-radius: 49rpx;
  393. }
  394. }
  395. }
  396. </style>