混凝土运输管理微信小程序、替班
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.

528 lines
12 KiB

2 weeks ago
  1. <template>
  2. <view class="content">
  3. <!-- 顶部搜索和筛选 -->
  4. <view class="head flex-sb sticky box-shadow-light">
  5. <view class="flex" @click="showFilter">
  6. <view class="mr5">
  7. <uv-icon v-if="showFilterIcon" name="funnel" size="24" color="#666"></uv-icon>
  8. </view>
  9. <view v-if="showFilterText" style="font-size:28rpx">筛选</view>
  10. <input
  11. :class="['search-input', searchActive && 'active']"
  12. maxlength="10"
  13. type="text"
  14. confirm-type="search"
  15. @confirm="onSearch"
  16. v-model="searchValue"
  17. @input="onInput"
  18. placeholder="搜索区域订单"
  19. />
  20. </view>
  21. <view class="flex status">
  22. <view :class="[allActive && 'active']" @click="setAllStatus">全部</view>
  23. <view :class="[pendingActive && 'active']" @click="setPendingStatus">待审核</view>
  24. <view :class="[approvedActive && 'active']" @click="setApprovedStatus">已通过</view>
  25. <view :class="[rejectedActive && 'active']" @click="setRejectedStatus">已拒绝</view>
  26. </view>
  27. </view>
  28. <!-- 统计信息 -->
  29. <view class="stats-container">
  30. <view class="stats-item">
  31. <view class="stats-number">{{ totalOrders }}</view>
  32. <view class="stats-label">总订单数</view>
  33. </view>
  34. <view class="stats-item">
  35. <view class="stats-number">{{ pendingOrders }}</view>
  36. <view class="stats-label">待审核</view>
  37. </view>
  38. <view class="stats-item">
  39. <view class="stats-number">{{ todayOrders }}</view>
  40. <view class="stats-label">今日订单</view>
  41. </view>
  42. </view>
  43. <!-- 全部订单列表 -->
  44. <view v-if="showAllList" class="m20">
  45. <view v-if="allEmpty" class="re-empty">
  46. <view>暂无数据</view>
  47. </view>
  48. <view v-for="(item, index) in allOrdersList" :key="index" class="b-relative item-card mb20">
  49. <view class="m10 flex-sb">
  50. <view class="ellipsis">{{ item.title }}</view>
  51. <view class="item-time">{{ item.time }}</view>
  52. </view>
  53. <view>企业{{ item.company }}</view>
  54. <view>区域{{ item.region }}</view>
  55. <view>数量{{ item.quantity }}m³</view>
  56. <view :class="['item-status', item.status]">{{ getStatusText(item.status) }}</view>
  57. <view class="item-button" @click="viewOrder(item)">查看</view>
  58. </view>
  59. </view>
  60. <!-- 待审核订单列表 -->
  61. <view v-if="showPendingList" class="m20">
  62. <view v-if="pendingEmpty" class="re-empty">
  63. <view>暂无数据</view>
  64. </view>
  65. <view v-for="(item, index) in pendingOrdersList" :key="index" class="b-relative item-card mb20">
  66. <view class="m10 flex-sb">
  67. <view class="ellipsis">{{ item.title }}</view>
  68. <view class="item-time">{{ item.time }}</view>
  69. </view>
  70. <view>企业{{ item.company }}</view>
  71. <view>区域{{ item.region }}</view>
  72. <view>数量{{ item.quantity }}m³</view>
  73. <view class="item-status pending">待审核</view>
  74. <view class="action-buttons">
  75. <view class="approve-btn" @click="approveOrder(item)">通过</view>
  76. <view class="reject-btn" @click="rejectOrder(item)">拒绝</view>
  77. </view>
  78. </view>
  79. </view>
  80. <!-- 已通过订单列表 -->
  81. <view v-if="showApprovedList" class="m20">
  82. <view v-if="approvedEmpty" class="re-empty">
  83. <view>暂无数据</view>
  84. </view>
  85. <view v-for="(item, index) in approvedOrdersList" :key="index" class="b-relative item-card mb20">
  86. <view class="m10 flex-sb">
  87. <view class="ellipsis">{{ item.title }}</view>
  88. <view class="item-time">{{ item.time }}</view>
  89. </view>
  90. <view>企业{{ item.company }}</view>
  91. <view>区域{{ item.region }}</view>
  92. <view>数量{{ item.quantity }}m³</view>
  93. <view>审核时间{{ item.approveTime }}</view>
  94. <view class="item-status approved">已通过</view>
  95. <view class="item-button" @click="viewOrder(item)">查看</view>
  96. </view>
  97. </view>
  98. <!-- 已拒绝订单列表 -->
  99. <view v-if="showRejectedList" class="m20">
  100. <view v-if="rejectedEmpty" class="re-empty">
  101. <view>暂无数据</view>
  102. </view>
  103. <view v-for="(item, index) in rejectedOrdersList" :key="index" class="b-relative item-card mb20">
  104. <view class="m10 flex-sb">
  105. <view class="ellipsis">{{ item.title }}</view>
  106. <view class="item-time">{{ item.time }}</view>
  107. </view>
  108. <view>企业{{ item.company }}</view>
  109. <view>区域{{ item.region }}</view>
  110. <view>数量{{ item.quantity }}m³</view>
  111. <view>拒绝原因{{ item.rejectReason }}</view>
  112. <view class="item-status rejected">已拒绝</view>
  113. <view class="item-button" @click="viewOrder(item)">查看</view>
  114. </view>
  115. </view>
  116. </view>
  117. </template>
  118. <script>
  119. export default {
  120. name: 'RegionHall',
  121. data() {
  122. return {
  123. showFilterIcon: true,
  124. showFilterText: true,
  125. searchActive: false,
  126. searchValue: '',
  127. allActive: true,
  128. pendingActive: false,
  129. approvedActive: false,
  130. rejectedActive: false,
  131. showAllList: true,
  132. showPendingList: false,
  133. showApprovedList: false,
  134. showRejectedList: false,
  135. allEmpty: false,
  136. pendingEmpty: false,
  137. approvedEmpty: false,
  138. rejectedEmpty: false,
  139. // 统计数据
  140. totalOrders: 156,
  141. pendingOrders: 8,
  142. todayOrders: 23,
  143. // 全部订单
  144. allOrdersList: [
  145. {
  146. id: 1,
  147. title: '雨花区建设项目混凝土需求',
  148. time: '2024-01-15 08:00',
  149. company: '长沙建设集团',
  150. region: '雨花区',
  151. quantity: '200',
  152. status: 'approved'
  153. },
  154. {
  155. id: 2,
  156. title: '岳麓区商业中心项目',
  157. time: '2024-01-15 10:00',
  158. company: '湖南建工',
  159. region: '岳麓区',
  160. quantity: '150',
  161. status: 'pending'
  162. },
  163. {
  164. id: 3,
  165. title: '开福区住宅项目',
  166. time: '2024-01-14 14:00',
  167. company: '中建五局',
  168. region: '开福区',
  169. quantity: '300',
  170. status: 'rejected'
  171. }
  172. ],
  173. // 待审核订单
  174. pendingOrdersList: [
  175. {
  176. id: 2,
  177. title: '岳麓区商业中心项目',
  178. time: '2024-01-15 10:00',
  179. company: '湖南建工',
  180. region: '岳麓区',
  181. quantity: '150'
  182. }
  183. ],
  184. // 已通过订单
  185. approvedOrdersList: [
  186. {
  187. id: 1,
  188. title: '雨花区建设项目混凝土需求',
  189. time: '2024-01-15 08:00',
  190. company: '长沙建设集团',
  191. region: '雨花区',
  192. quantity: '200',
  193. approveTime: '2024-01-15 09:30'
  194. }
  195. ],
  196. // 已拒绝订单
  197. rejectedOrdersList: [
  198. {
  199. id: 3,
  200. title: '开福区住宅项目',
  201. time: '2024-01-14 14:00',
  202. company: '中建五局',
  203. region: '开福区',
  204. quantity: '300',
  205. rejectReason: '区域配额已满'
  206. }
  207. ]
  208. }
  209. },
  210. methods: {
  211. showFilter() {
  212. console.log('显示筛选');
  213. },
  214. onSearch() {
  215. console.log('搜索:', this.searchValue);
  216. },
  217. onInput() {
  218. this.searchActive = this.searchValue.length > 0;
  219. },
  220. setAllStatus() {
  221. this.allActive = true;
  222. this.pendingActive = false;
  223. this.approvedActive = false;
  224. this.rejectedActive = false;
  225. this.showAllList = true;
  226. this.showPendingList = false;
  227. this.showApprovedList = false;
  228. this.showRejectedList = false;
  229. },
  230. setPendingStatus() {
  231. this.allActive = false;
  232. this.pendingActive = true;
  233. this.approvedActive = false;
  234. this.rejectedActive = false;
  235. this.showAllList = false;
  236. this.showPendingList = true;
  237. this.showApprovedList = false;
  238. this.showRejectedList = false;
  239. },
  240. setApprovedStatus() {
  241. this.allActive = false;
  242. this.pendingActive = false;
  243. this.approvedActive = true;
  244. this.rejectedActive = false;
  245. this.showAllList = false;
  246. this.showPendingList = false;
  247. this.showApprovedList = true;
  248. this.showRejectedList = false;
  249. },
  250. setRejectedStatus() {
  251. this.allActive = false;
  252. this.pendingActive = false;
  253. this.approvedActive = false;
  254. this.rejectedActive = true;
  255. this.showAllList = false;
  256. this.showPendingList = false;
  257. this.showApprovedList = false;
  258. this.showRejectedList = true;
  259. },
  260. viewOrder(item) {
  261. uni.navigateTo({
  262. url: `/pages_order/order/orderDetail?id=${item.id}`
  263. });
  264. },
  265. approveOrder(item) {
  266. uni.showModal({
  267. title: '确认通过',
  268. content: `确定通过订单:${item.title} 吗?`,
  269. success: (res) => {
  270. if (res.confirm) {
  271. uni.showToast({
  272. title: '审核通过',
  273. icon: 'success'
  274. });
  275. // 移除待审核列表中的订单
  276. const index = this.pendingOrdersList.findIndex(order => order.id === item.id);
  277. if (index > -1) {
  278. this.pendingOrdersList.splice(index, 1);
  279. }
  280. // 更新统计数据
  281. this.pendingOrders--;
  282. }
  283. }
  284. });
  285. },
  286. rejectOrder(item) {
  287. uni.showModal({
  288. title: '确认拒绝',
  289. content: `确定拒绝订单:${item.title} 吗?`,
  290. success: (res) => {
  291. if (res.confirm) {
  292. uni.showToast({
  293. title: '已拒绝',
  294. icon: 'success'
  295. });
  296. // 移除待审核列表中的订单
  297. const index = this.pendingOrdersList.findIndex(order => order.id === item.id);
  298. if (index > -1) {
  299. this.pendingOrdersList.splice(index, 1);
  300. }
  301. // 更新统计数据
  302. this.pendingOrders--;
  303. }
  304. }
  305. });
  306. },
  307. getStatusText(status) {
  308. switch(status) {
  309. case 'pending': return '待审核';
  310. case 'approved': return '已通过';
  311. case 'rejected': return '已拒绝';
  312. default: return '未知状态';
  313. }
  314. },
  315. // 供外部调用的方法
  316. loadPage() {
  317. console.log('区域管理员订单页面刷新');
  318. }
  319. }
  320. }
  321. </script>
  322. <style scoped lang="scss">
  323. .content {
  324. padding: 20rpx;
  325. height: 100%;
  326. box-sizing: border-box;
  327. overflow-y: auto;
  328. }
  329. .head {
  330. background-color: #fff;
  331. padding: 20rpx;
  332. border-radius: 10rpx;
  333. margin-bottom: 20rpx;
  334. }
  335. .sticky {
  336. position: sticky;
  337. top: 0;
  338. z-index: 999;
  339. }
  340. .box-shadow-light {
  341. box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
  342. }
  343. .flex {
  344. display: flex;
  345. align-items: center;
  346. }
  347. .flex-sb {
  348. display: flex;
  349. justify-content: space-between;
  350. align-items: center;
  351. }
  352. .mr5 {
  353. margin-right: 5rpx;
  354. }
  355. .search-input {
  356. flex: 1;
  357. height: 60rpx;
  358. padding: 0 20rpx;
  359. border: 1rpx solid #e0e0e0;
  360. border-radius: 30rpx;
  361. margin-left: 20rpx;
  362. font-size: 28rpx;
  363. &.active {
  364. border-color: #007AFF;
  365. }
  366. }
  367. .status {
  368. margin-top: 20rpx;
  369. gap: 20rpx;
  370. view {
  371. padding: 12rpx 20rpx;
  372. border-radius: 25rpx;
  373. font-size: 24rpx;
  374. color: #666;
  375. background-color: #f8f8f8;
  376. transition: all 0.3s;
  377. &.active {
  378. color: #007AFF;
  379. background-color: #e6f3ff;
  380. border: 1rpx solid #007AFF;
  381. }
  382. }
  383. }
  384. .stats-container {
  385. display: flex;
  386. background-color: #fff;
  387. border-radius: 10rpx;
  388. margin: 0 20rpx 20rpx;
  389. padding: 30rpx 0;
  390. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
  391. }
  392. .stats-item {
  393. flex: 1;
  394. text-align: center;
  395. .stats-number {
  396. font-size: 48rpx;
  397. font-weight: bold;
  398. color: #007AFF;
  399. margin-bottom: 10rpx;
  400. }
  401. .stats-label {
  402. font-size: 24rpx;
  403. color: #666;
  404. }
  405. }
  406. .m20 {
  407. margin: 20rpx;
  408. }
  409. .mb20 {
  410. margin-bottom: 20rpx;
  411. }
  412. .m10 {
  413. margin: 10rpx;
  414. }
  415. .item-card {
  416. background-color: #fff;
  417. border-radius: 10rpx;
  418. padding: 20rpx;
  419. position: relative;
  420. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
  421. }
  422. .ellipsis {
  423. overflow: hidden;
  424. white-space: nowrap;
  425. text-overflow: ellipsis;
  426. font-weight: bold;
  427. font-size: 30rpx;
  428. }
  429. .item-time {
  430. font-size: 24rpx;
  431. color: #999;
  432. }
  433. .item-status {
  434. position: absolute;
  435. top: 20rpx;
  436. right: 20rpx;
  437. padding: 8rpx 16rpx;
  438. border-radius: 20rpx;
  439. font-size: 22rpx;
  440. color: #fff;
  441. &.pending {
  442. background-color: #ff9500;
  443. }
  444. &.approved {
  445. background-color: #34c759;
  446. }
  447. &.rejected {
  448. background-color: #ff3b30;
  449. }
  450. }
  451. .item-button {
  452. position: absolute;
  453. bottom: 20rpx;
  454. right: 20rpx;
  455. padding: 10rpx 20rpx;
  456. background-color: #007AFF;
  457. color: #fff;
  458. border-radius: 20rpx;
  459. font-size: 24rpx;
  460. }
  461. .action-buttons {
  462. position: absolute;
  463. bottom: 20rpx;
  464. right: 20rpx;
  465. display: flex;
  466. gap: 10rpx;
  467. }
  468. .approve-btn {
  469. padding: 10rpx 20rpx;
  470. background-color: #34c759;
  471. color: #fff;
  472. border-radius: 20rpx;
  473. font-size: 24rpx;
  474. }
  475. .reject-btn {
  476. padding: 10rpx 20rpx;
  477. background-color: #ff3b30;
  478. color: #fff;
  479. border-radius: 20rpx;
  480. font-size: 24rpx;
  481. }
  482. .re-empty {
  483. text-align: center;
  484. padding: 100rpx 0;
  485. color: #999;
  486. font-size: 28rpx;
  487. }
  488. .b-relative {
  489. position: relative;
  490. }
  491. </style>