建材商城系统20241014
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.

250 lines
7.1 KiB

  1. <template>
  2. <view class="quick-order-container"
  3. :style="{bottom}"
  4. @click="handleClick"
  5. @longpress="handleLongPress">
  6. <view class="new-message" v-if="innerHasNewMessage" @click.stop="goToOrderList">
  7. 你有新的快捷下单信息
  8. </view>
  9. <view class="quick-order">
  10. <view class="number-order" v-if="innerMessageCount > 0">
  11. {{ innerMessageCount }}
  12. </view>
  13. <image :src="imageUrl" mode=""></image>
  14. <view class="long-press-hint">长按查看更多</view>
  15. </view>
  16. </view>
  17. </template>
  18. <script>
  19. export default {
  20. name: 'QuickOrderEntry',
  21. props: {
  22. // 图标路径
  23. imageUrl: {
  24. type: String,
  25. default: '/static/image/home/7.png'
  26. },
  27. // 点击跳转的页面
  28. targetUrl: {
  29. type: String,
  30. default: '/pages_order/order/fastCreateOrder'
  31. },
  32. // 是否自动获取快捷下单信息
  33. autoFetch: {
  34. type: Boolean,
  35. default: true
  36. },
  37. bottom : {
  38. default : '30vh',
  39. }
  40. },
  41. data() {
  42. return {
  43. orderInfo: null,
  44. innerHasNewMessage: false,
  45. innerMessageCount: 0,
  46. isInitialized: false
  47. }
  48. },
  49. mounted() {
  50. this.getQuickOrderInfo()
  51. },
  52. methods: {
  53. // 处理点击事件
  54. handleClick() {
  55. // 发出点击事件,便于父组件监听
  56. this.$emit('click');
  57. // 如果有订单信息,提供订单列表
  58. if (Array.isArray(this.orderInfo) && this.orderInfo.length > 0) {
  59. this.$emit('order-info', this.orderInfo);
  60. }
  61. // 如果有目标页面,则跳转
  62. if (this.targetUrl) {
  63. this.navigateTo(this.targetUrl);
  64. }
  65. },
  66. // 处理长按事件 - 跳转到快捷订单列表
  67. handleLongPress() {
  68. // 震动反馈
  69. uni.vibrateShort();
  70. // 显示操作菜单
  71. uni.showActionSheet({
  72. itemList: ['快捷下单', '我的快捷订单'],
  73. success: (res) => {
  74. if (res.tapIndex === 0) {
  75. // 跳转到快捷下单页面
  76. this.navigateTo(this.targetUrl);
  77. } else if (res.tapIndex === 1) {
  78. // 跳转到快捷订单列表
  79. this.navigateTo('/pages_order/order/fastOrderList');
  80. }
  81. }
  82. });
  83. },
  84. // 直接跳转到快捷订单列表
  85. goToOrderList() {
  86. this.navigateTo('/pages_order/order/fastOrderList');
  87. },
  88. // 获取快捷下单的信息
  89. getQuickOrderInfo() {
  90. if(!uni.getStorageSync('token')){
  91. return
  92. }
  93. // 调用接口获取快捷下单信息
  94. this.$api('getOrderInfo', {}, res => {
  95. if (res.code === 200 && res.result) {
  96. // 处理返回的订单列表
  97. const orderList = Array.isArray(res.result) ? res.result : [res.result];
  98. if (orderList.length > 0) {
  99. // 保存订单列表
  100. this.orderInfo = orderList;
  101. // 设置消息数量为订单列表长度
  102. this.innerHasNewMessage = true;
  103. this.innerMessageCount = orderList.length;
  104. // 通知父组件获取到了数据
  105. this.$emit('order-loaded', this.orderInfo);
  106. } else {
  107. this.innerHasNewMessage = false;
  108. this.innerMessageCount = 0;
  109. this.orderInfo = [];
  110. }
  111. } else {
  112. this.innerHasNewMessage = false;
  113. this.innerMessageCount = 0;
  114. this.orderInfo = [];
  115. }
  116. this.isInitialized = true;
  117. }, err => {
  118. console.error('获取快捷下单信息失败', err);
  119. this.innerHasNewMessage = false;
  120. this.innerMessageCount = 0;
  121. this.orderInfo = [];
  122. this.isInitialized = true;
  123. });
  124. },
  125. // 导航到指定页面
  126. navigateTo(url) {
  127. // 如果有订单列表,则优先使用第一个订单的ID
  128. if (Array.isArray(this.orderInfo) && this.orderInfo.length > 0 && this.orderInfo[0].id && url.indexOf('?') === -1) {
  129. url += `?orderId=${this.orderInfo[0].id}`;
  130. }
  131. this.$utils.navigateTo(url);
  132. },
  133. // 刷新快捷下单信息
  134. refresh() {
  135. this.getQuickOrderInfo();
  136. return this; // 链式调用
  137. },
  138. // 清除消息提示
  139. clearMessage() {
  140. this.innerHasNewMessage = false;
  141. this.innerMessageCount = 0;
  142. return this; // 链式调用
  143. },
  144. // 检查是否有新消息
  145. hasNewMessage() {
  146. return this.innerHasNewMessage;
  147. },
  148. // 获取消息数量
  149. getMessageCount() {
  150. return this.innerMessageCount;
  151. },
  152. },
  153. }
  154. </script>
  155. <style scoped lang="scss">
  156. .quick-order-container {
  157. position: fixed;
  158. right: 30rpx;
  159. bottom: 30vh;
  160. z-index: 99;
  161. transition: transform 0.3s;
  162. &:active {
  163. transform: scale(0.95);
  164. }
  165. .new-message {
  166. position: absolute;
  167. top: 50rpx;
  168. right: 100%;
  169. white-space: nowrap;
  170. background-color: #DC2828;
  171. border-radius: 20rpx;
  172. font-size: 25rpx;
  173. color: #ffffff;
  174. padding: 5rpx 15rpx;
  175. margin-bottom: 10rpx;
  176. box-shadow: 0 5rpx 10rpx rgba(220, 40, 40, 0.3);
  177. animation: pulse 2s infinite;
  178. }
  179. .quick-order {
  180. position: relative;
  181. width: 230rpx;
  182. height: 160rpx;
  183. image {
  184. width: 100%;
  185. height: 100%;
  186. }
  187. .number-order {
  188. background-color: #DC2828;
  189. position: absolute;
  190. font-size: 30rpx;
  191. height: 40rpx;
  192. width: 40rpx;
  193. text-align: center;
  194. border-radius: 20rpx;
  195. color: #ffffff;
  196. top: 10rpx;
  197. left: 25rpx;
  198. }
  199. .long-press-hint {
  200. position: absolute;
  201. bottom: -30rpx;
  202. left: 50%;
  203. transform: translateX(-50%);
  204. background-color: rgba(0, 0, 0, 0.7);
  205. color: #fff;
  206. font-size: 20rpx;
  207. padding: 4rpx 12rpx;
  208. border-radius: 12rpx;
  209. white-space: nowrap;
  210. opacity: 0.8;
  211. }
  212. }
  213. }
  214. @keyframes pulse {
  215. 0% {
  216. transform: scale(1);
  217. }
  218. 50% {
  219. transform: scale(1.05);
  220. }
  221. 100% {
  222. transform: scale(1);
  223. }
  224. }
  225. </style>