소스 검색

feat: 我的订单页面

DoggyZhang 3 달 전
부모
커밋
1217a0e796
52개의 변경된 파일1864개의 추가작업 그리고 269개의 파일을 삭제
  1. 15 0
      app/src/main/java/com/adealink/weparty/commonui/widget/EvaluateView.kt
  2. 6 0
      app/src/main/java/com/adealink/weparty/module/order/Router.kt
  3. 72 0
      app/src/main/java/com/adealink/weparty/module/order/data/OrderData.kt
  4. 1 1
      app/src/main/java/com/adealink/weparty/module/profile/data/ProfileData.kt
  5. 1 1
      app/src/main/res/drawable/common_input_edit_bg.xml
  6. 4 4
      app/src/main/res/layout/dialog_wheel_date_picker.xml
  7. 2 0
      app/src/main/res/values/colors.xml
  8. 8 1
      module/im/src/main/java/com/adealink/weparty/im/IMServiceImpl.kt
  9. 5 1
      module/im/src/main/java/com/adealink/weparty/im/constant/Data.kt
  10. 7 0
      module/im/src/main/java/com/adealink/weparty/im/session/adapter/SessionAdapter.kt
  11. 14 6
      module/im/src/main/java/com/adealink/weparty/im/session/adapter/viewbinder/BaseCenterMessageViewBinder.kt
  12. 2 2
      module/im/src/main/java/com/adealink/weparty/im/session/adapter/viewbinder/OfficialImageTextMessageViewBinder.kt
  13. 50 0
      module/im/src/main/java/com/adealink/weparty/im/session/adapter/viewbinder/PlaymateOrderMessageViewBinder.kt
  14. 30 0
      module/im/src/main/java/com/adealink/weparty/im/session/mesasge/PlaymateMessageBean.kt
  15. 0 0
      module/im/src/main/res/drawable/im_message_bubble_bg.xml
  16. 1 1
      module/im/src/main/res/layout/layout_session_message_official_image_text.xml
  17. 103 0
      module/im/src/main/res/layout/layout_session_message_playmate_order.xml
  18. 1 0
      module/im/src/main/res/values/strings.xml
  19. 9 1
      module/order/src/main/AndroidManifest.xml
  20. 0 66
      module/order/src/main/java/com/adealink/weparty/order/OrderListActivity.kt
  21. 1 1
      module/order/src/main/java/com/adealink/weparty/order/OrderServiceImpl.kt
  22. 107 0
      module/order/src/main/java/com/adealink/weparty/order/PlaymateOrderListActivity.kt
  23. 140 0
      module/order/src/main/java/com/adealink/weparty/order/UserOrderListActivity.kt
  24. 130 10
      module/order/src/main/java/com/adealink/weparty/order/adapter/OrderListItemViewBinder.kt
  25. 26 0
      module/order/src/main/java/com/adealink/weparty/order/adapter/PlaymateListItemViewBinder.kt
  26. 91 5
      module/order/src/main/java/com/adealink/weparty/order/data/OrderData.kt
  27. 53 0
      module/order/src/main/java/com/adealink/weparty/order/datasource/remote/OrderHttpService.kt
  28. 99 0
      module/order/src/main/java/com/adealink/weparty/order/dialog/EvaluateOrderDialog.kt
  29. 112 0
      module/order/src/main/java/com/adealink/weparty/order/util/UIUtil.kt
  30. 0 8
      module/order/src/main/java/com/adealink/weparty/order/viewmodel/OrderViewModel.kt
  31. 5 2
      module/order/src/main/java/com/adealink/weparty/order/viewmodel/OrderViewModelFactory.kt
  32. 59 0
      module/order/src/main/java/com/adealink/weparty/order/viewmodel/PlaymateOrderViewModel.kt
  33. 102 0
      module/order/src/main/java/com/adealink/weparty/order/viewmodel/UserOrderViewModel.kt
  34. 0 10
      module/order/src/main/res/drawable/order_button_finish_bg.xml
  35. 0 8
      module/order/src/main/res/drawable/order_status_cancel_bg.xml
  36. 0 8
      module/order/src/main/res/drawable/order_status_finish_bg.xml
  37. 0 8
      module/order/src/main/res/drawable/order_status_in_progress_bg.xml
  38. 5 6
      module/order/src/main/res/layout/activity_order_detail.xml
  39. 12 2
      module/order/src/main/res/layout/activity_playmate_order_list.xml
  40. 47 0
      module/order/src/main/res/layout/activity_user_order_list.xml
  41. 138 0
      module/order/src/main/res/layout/dialog_evaluate_order.xml
  42. 69 112
      module/order/src/main/res/layout/layout_playmate_order_list_item.xml
  43. 248 0
      module/order/src/main/res/layout/layout_user_order_list_item.xml
  44. 18 2
      module/order/src/main/res/values/strings.xml
  45. 26 0
      module/profile/src/main/java/com/adealink/weparty/profile/me/comp/MeFunctionCenterComp.kt
  46. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_me_order_record_ic.png
  47. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_order_all_list_ic.png
  48. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_order_finish_list_ic.png
  49. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_order_pay_list_ic.png
  50. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_order_refund_list_ic.png
  51. 44 3
      module/profile/src/main/res/layout/layout_me_function.xml
  52. 1 0
      module/profile/src/main/res/values/strings.xml

+ 15 - 0
app/src/main/java/com/adealink/weparty/commonui/widget/EvaluateView.kt

@@ -20,6 +20,8 @@ class EvaluateView @JvmOverloads constructor(
     private var normalResourceId: Int = R.drawable.common_evaluate_star_normal_ic
     private var selectedResourceId: Int = R.drawable.common_evaluate_star_selected_ic
 
+    private var listener: OnEvaluateListener? = null
+
     init {
         context.withStyledAttributes(
             attrs,
@@ -54,6 +56,10 @@ class EvaluateView @JvmOverloads constructor(
         inflateEvaluateView()
     }
 
+    fun setListener(listener: OnEvaluateListener) {
+        this.listener = listener
+    }
+
     fun setMaxScore(score: Int) {
         if (score < 0) {
             return
@@ -80,6 +86,7 @@ class EvaluateView @JvmOverloads constructor(
                 itemView.setImageResource(normalResourceId)
             }
         }
+        listener?.onEvaluate(curScore)
     }
 
     private fun inflateEvaluateView() {
@@ -107,4 +114,12 @@ class EvaluateView @JvmOverloads constructor(
         }
     }
 
+    fun getScore(): Int {
+        return curScore
+    }
+
+    interface OnEvaluateListener {
+        fun onEvaluate(score: Int)
+    }
+
 }

+ 6 - 0
app/src/main/java/com/adealink/weparty/module/order/Router.kt

@@ -17,6 +17,12 @@ interface Order {
         }
     }
 
+    interface PlaymateList {
+        companion object {
+            const val PATH = "${Common.PATH}/playmate_list"
+        }
+    }
+
     interface Detail {
         companion object {
             const val PATH = "${Common.PATH}/detail"

+ 72 - 0
app/src/main/java/com/adealink/weparty/module/order/data/OrderData.kt

@@ -0,0 +1,72 @@
+package com.adealink.weparty.module.order.data
+
+import com.google.gson.annotations.GsonNullable
+import com.google.gson.annotations.SerializedName
+
+/**
+ *
+ */
+enum class OrderStatus(val status: Int) {
+    CREATE_ORDER(0), //创建订单(订单初始状态)
+    WAIT_FOR_ACCEPT(1), //等待接单
+
+    PLAYMATE_ACCEPT(4), //接单
+    PLAYMATE_IN_SERVICE(6), //服务中
+    PLAYMATE_END_SERVICE(7), //服务完成(陪玩触发)
+
+    PLAYMATE_REFUSE(5), //拒绝
+    COMPLETE(2), //订单完成
+    USER_REFUND(3), //退款
+    USER_CANCEL(8); //用户取消订单
+
+    companion object {
+        @JvmStatic
+        fun map(status: Int?): OrderStatus? {
+            status ?: return null
+            return entries.find { it.status == status }
+        }
+    }
+}
+
+data class PlaymateOrderDetailData(
+    @SerializedName("orderInfo") val orderInfo: PlaymateOrderData, //付费订单信息
+
+    @GsonNullable
+    @SerializedName("reason") val clientReason: String?, //客户理由
+    @GsonNullable
+    @SerializedName("attachments") val clientAttachments: List<PlaymateOrderAttachment>?, //客户附件
+    @GsonNullable
+    @SerializedName("playmateReason") val playmateReason: String?, //陪玩理由
+    @GsonNullable
+    @SerializedName("playmateAttachments") val playmateAttachments: List<PlaymateOrderAttachment>?, //陪玩附件
+)
+
+data class PlaymateOrderData(
+    @SerializedName("orderId") val orderId: String, //订单ID
+    @SerializedName("bizCategoryName") val categoryName: String, //品类名称
+    @SerializedName("categoryIcon") var categoryIcon: String, //品类图标
+    @SerializedName("price") var price: Float, //单价
+    @SerializedName("unit") var unit: String, //价格单位
+    @SerializedName("purchaseQty") var purchaseQty: String, //购买数量
+    @SerializedName("status") var status: String, //订单状态
+    @SerializedName("createTime") var createTime: String, //下单时间(时间戳, 毫秒)
+
+    @SerializedName("avatar") var avatar: String, //头像
+    @SerializedName("nickname") var nickname: String, //昵称
+    @SerializedName("gender") var gender: Int, //性别
+
+
+    @GsonNullable
+    @SerializedName("star") var star: Int?, //评分
+    @GsonNullable
+    @SerializedName("refundApply") var refundApply: Boolean?, //是否退款申请中
+    @GsonNullable
+    @SerializedName("customerRemark") var customerRemark: String?, //客户备注
+)
+
+data class PlaymateOrderAttachment(
+    @SerializedName("attachmentUrl") val attachmentUrl: String,
+    @SerializedName("type") val type: String,
+    @SerializedName("fileName") val fileName: String,
+)
+

+ 1 - 1
app/src/main/java/com/adealink/weparty/module/profile/data/ProfileData.kt

@@ -94,7 +94,7 @@ data class UserInfo(
                 && gender != null
     }
 
-    fun isFemale() = gender == Gender.FEMALE.gender
+    fun isPlaymate() = playmate == true
 
     fun isCacheValid(newAttrSet: Set<UserConfigType>?): Boolean {
 //        if (newAttrSet.isNullOrEmpty()) {

+ 1 - 1
app/src/main/res/drawable/common_input_edit_bg.xml

@@ -2,5 +2,5 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
     android:shape="rectangle">
     <solid android:color="#F1F2F5" />
-    <corners android:radius="30dp" />
+    <corners android:radius="12dp" />
 </shape>

+ 4 - 4
app/src/main/res/layout/dialog_wheel_date_picker.xml

@@ -36,11 +36,11 @@
         android:layout_marginHorizontal="16dp"
         android:layout_marginTop="24dp"
         android:gravity="center"
-        android:text="@string/commonui_confirm"
-        android:textColor="@color/white"
-        android:textSize="16sp"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/fl_date_picker" />
+        app:layout_constraintTop_toBottomOf="@id/fl_date_picker"
+        app:text="@string/commonui_confirm"
+        app:textColor="@color/white"
+        app:textSize="16sp" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 2 - 0
app/src/main/res/values/colors.xml

@@ -1189,4 +1189,6 @@
     <color name="color_FFB0F5EA">#FFB0F5EA</color>
     <color name="color_FFA3CDF9">#FFA3CDF9</color>
     <color name="color_FF1789FF">#FF1789FF</color>
+
+    <color name="color_FFFFB836">#FFFFB836</color>
 </resources>

+ 8 - 1
module/im/src/main/java/com/adealink/weparty/im/IMServiceImpl.kt

@@ -5,10 +5,12 @@ import android.app.Application
 import com.adealink.frame.router.Router
 import com.adealink.frame.spi.RegisterService
 import com.adealink.weparty.im.constant.OFFICIAL_IMAGE_TEXT_BUSINESS_ID
+import com.adealink.weparty.im.constant.PLAYMATE_ORDER_BUSINESS_ID
 import com.adealink.weparty.im.manager.login.imLoginManager
 import com.adealink.weparty.im.service.TIMAppService
 import com.adealink.weparty.im.session.mesasge.CustomMessageViewHolder
 import com.adealink.weparty.im.session.mesasge.OfficialImageTextMessageBean
+import com.adealink.weparty.im.session.mesasge.PlaymateOrderMessageBean
 import com.adealink.weparty.module.im.IIMService
 import com.adealink.weparty.module.im.IM
 import com.tencent.imsdk.v2.V2TIMConversation
@@ -31,9 +33,14 @@ class IMServiceImpl : IIMService {
             OfficialImageTextMessageBean::class.java,
             CustomMessageViewHolder::class.java
         )
+        TUIChatConfigs.registerCustomMessage(
+            PLAYMATE_ORDER_BUSINESS_ID,
+            PlaymateOrderMessageBean::class.java,
+            CustomMessageViewHolder::class.java
+        )
 
         //开启已读回执
-        TUIChatConfigs.getGeneralConfig().setMsgNeedReadReceipt(true)
+        TUIChatConfigs.getGeneralConfig().isMsgNeedReadReceipt = true
 
         imLoginManager.init(application)
         TIMAppService().init(application)

+ 5 - 1
module/im/src/main/java/com/adealink/weparty/im/constant/Data.kt

@@ -13,4 +13,8 @@ const val OFFICIAL_CONVERSATION_ID = BuildConfig.OFFICIAL_CONVERSATION_ID //官
  * 自定义消息
  * https://trtc.io/zh/document/50044?product=chat&menulabel=uikit&platform=android
  */
-const val OFFICIAL_IMAGE_TEXT_BUSINESS_ID = "official_image_text"
+//官方消息
+const val OFFICIAL_IMAGE_TEXT_BUSINESS_ID = "official_image_text"
+
+//陪玩订单消息
+const val PLAYMATE_ORDER_BUSINESS_ID = "playmate_order"

+ 7 - 0
module/im/src/main/java/com/adealink/weparty/im/session/adapter/SessionAdapter.kt

@@ -6,11 +6,13 @@ import com.adealink.weparty.commonui.recycleview.adapter.ExtMultiTypeAdapter
 import com.adealink.weparty.im.session.adapter.data.UnSupportMessageBean
 import com.adealink.weparty.im.session.adapter.viewbinder.ImageMessageViewBinder
 import com.adealink.weparty.im.session.adapter.viewbinder.OfficialImageTextMessageViewBinder
+import com.adealink.weparty.im.session.adapter.viewbinder.PlaymateOrderMessageViewBinder
 import com.adealink.weparty.im.session.adapter.viewbinder.SoundMessageViewBinder
 import com.adealink.weparty.im.session.adapter.viewbinder.TextMessageViewBinder
 import com.adealink.weparty.im.session.adapter.viewbinder.TipsMessageViewBinder
 import com.adealink.weparty.im.session.adapter.viewbinder.UnSupportMessageViewBinder
 import com.adealink.weparty.im.session.mesasge.OfficialImageTextMessageBean
+import com.adealink.weparty.im.session.mesasge.PlaymateOrderMessageBean
 import com.adealink.weparty.im.session.widget.MessageRecyclerView
 import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean
 import com.tencent.qcloud.tuikit.timcommon.component.highlight.HighlightPresenter
@@ -131,6 +133,11 @@ class SessionAdapter : ExtMultiTypeAdapter(),
         register(TipsMessageBean::class.java, TipsMessageViewBinder(onMessageItemClick))
         register(UnSupportMessageBean::class.java, UnSupportMessageViewBinder(onMessageItemClick))
 
+        //陪玩订单
+        register(PlaymateOrderMessageBean::class.java,
+            PlaymateOrderMessageViewBinder(onMessageItemClick)
+        )
+
 //        addMessageType(FaceMessageBean::class.java, FaceMessageHolder::class.java)
 //        addMessageType(FileMessageBean::class.java, FileMessageHolder::class.java)
 //        addMessageType(LocationMessageBean::class.java, LocationMessageHolder::class.java)

+ 14 - 6
module/im/src/main/java/com/adealink/weparty/im/session/adapter/viewbinder/BaseOfficialMessageViewBinder.kt → module/im/src/main/java/com/adealink/weparty/im/session/adapter/viewbinder/BaseCenterMessageViewBinder.kt

@@ -5,17 +5,17 @@ import android.view.ViewGroup
 import androidx.annotation.CallSuper
 import androidx.viewbinding.ViewBinding
 import com.adealink.frame.util.onClick
+import com.adealink.weparty.commonui.ext.gone
+import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.commonui.recycleview.adapter.BindingViewHolder
 import com.adealink.weparty.commonui.recycleview.adapter.multitype.ItemViewBinder
 import com.adealink.weparty.im.databinding.LayoutSessionMessageOfficialBaseBinding
+import com.adealink.weparty.util.getSessionTimeStr
 import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean
 import com.tencent.qcloud.tuikit.timcommon.interfaces.OnItemClickListener
 
 
-/**
- * 对照: ImageMessageHolder
- */
-abstract class BaseOfficialMessageViewBinder<T : TUIMessageBean, V : ViewBinding, MH : OfficialMessageViewHolder<T, V>>(
+abstract class BaseCenterMessageViewBinder<T : TUIMessageBean, V : ViewBinding, MH : CenterMessageViewHolder<T, V>>(
     protected var onItemClickListener: OnItemClickListener?
 ) : ItemViewBinder<T, MH>() {
 
@@ -49,7 +49,15 @@ abstract class BaseOfficialMessageViewBinder<T : TUIMessageBean, V : ViewBinding
     }
 
     private fun setTimeTitle(holder: MH, msg: T) {
-
+        val position = holder.layoutPosition
+        val last: TUIMessageBean? = adapter.items.getOrNull(position - 1) as? TUIMessageBean
+        val timeStr = getSessionTimeStr(msg.messageTime * 1000, (last?.messageTime ?: 0) * 1000)
+        if (timeStr.isNullOrEmpty()) {
+            holder.binding.tvTime.gone()
+        } else {
+            holder.binding.tvTime.show()
+            holder.binding.tvTime.text = timeStr
+        }
     }
 
     override fun onCreateViewHolder(inflater: LayoutInflater, parent: ViewGroup): MH {
@@ -65,7 +73,7 @@ abstract class BaseOfficialMessageViewBinder<T : TUIMessageBean, V : ViewBinding
 
 }
 
-abstract class OfficialMessageViewHolder<T : TUIMessageBean, V : ViewBinding>(
+abstract class CenterMessageViewHolder<T : TUIMessageBean, V : ViewBinding>(
     rootBinding: LayoutSessionMessageOfficialBaseBinding,
     val messageBinding: V
 ) : BindingViewHolder<LayoutSessionMessageOfficialBaseBinding>(rootBinding) {

+ 2 - 2
module/im/src/main/java/com/adealink/weparty/im/session/adapter/viewbinder/OfficialImageTextMessageViewBinder.kt

@@ -19,7 +19,7 @@ import com.tencent.qcloud.tuikit.timcommon.interfaces.OnItemClickListener
 class OfficialImageTextMessageViewHolder(
     rootBinding: LayoutSessionMessageOfficialBaseBinding,
     binding: LayoutSessionMessageOfficialImageTextBinding
-) : OfficialMessageViewHolder<OfficialImageTextMessageBean, LayoutSessionMessageOfficialImageTextBinding>(
+) : CenterMessageViewHolder<OfficialImageTextMessageBean, LayoutSessionMessageOfficialImageTextBinding>(
     rootBinding,
     binding
 ) {
@@ -73,7 +73,7 @@ class OfficialImageTextMessageViewHolder(
 
 class OfficialImageTextMessageViewBinder(
     onItemClickListener: OnItemClickListener
-) : BaseOfficialMessageViewBinder<OfficialImageTextMessageBean, LayoutSessionMessageOfficialImageTextBinding, OfficialImageTextMessageViewHolder>(
+) : BaseCenterMessageViewBinder<OfficialImageTextMessageBean, LayoutSessionMessageOfficialImageTextBinding, OfficialImageTextMessageViewHolder>(
     onItemClickListener
 ) {
     override fun onCreateMessageHolder(

+ 50 - 0
module/im/src/main/java/com/adealink/weparty/im/session/adapter/viewbinder/PlaymateOrderMessageViewBinder.kt

@@ -0,0 +1,50 @@
+package com.adealink.weparty.im.session.adapter.viewbinder
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import com.adealink.weparty.im.databinding.LayoutSessionMessageOfficialBaseBinding
+import com.adealink.weparty.im.databinding.LayoutSessionMessagePlaymateOrderBinding
+import com.adealink.weparty.im.session.mesasge.PlaymateOrderMessageBean
+import com.tencent.qcloud.tuikit.timcommon.interfaces.OnItemClickListener
+
+/**
+ * 对照: TextMessageHolder
+ */
+class PlaymateOrderMessageViewHolder(
+    rootBinding: LayoutSessionMessageOfficialBaseBinding,
+    binding: LayoutSessionMessagePlaymateOrderBinding
+) : CenterMessageViewHolder<PlaymateOrderMessageBean, LayoutSessionMessagePlaymateOrderBinding>(
+    rootBinding,
+    binding
+) {
+
+    override fun onBindMessage(
+        binding: LayoutSessionMessagePlaymateOrderBinding,
+        msg: PlaymateOrderMessageBean
+    ) {
+
+    }
+
+}
+
+class PlaymateOrderMessageViewBinder(
+    onItemClickListener: OnItemClickListener
+) : BaseCenterMessageViewBinder<PlaymateOrderMessageBean, LayoutSessionMessagePlaymateOrderBinding, PlaymateOrderMessageViewHolder>(
+    onItemClickListener
+) {
+    override fun onCreateMessageHolder(
+        rootBinder: LayoutSessionMessageOfficialBaseBinding,
+        inflater: LayoutInflater,
+        parent: ViewGroup
+    ): PlaymateOrderMessageViewHolder {
+        return PlaymateOrderMessageViewHolder(
+            rootBinder,
+            LayoutSessionMessagePlaymateOrderBinding.inflate(
+                inflater,
+                parent,
+                true
+            )
+        )
+    }
+
+}

+ 30 - 0
module/im/src/main/java/com/adealink/weparty/im/session/mesasge/PlaymateMessageBean.kt

@@ -0,0 +1,30 @@
+package com.adealink.weparty.im.session.mesasge
+
+import com.adealink.frame.aab.util.getCompatString
+import com.adealink.frame.data.json.froJsonErrorNull
+import com.adealink.weparty.im.R
+import com.adealink.weparty.module.order.data.PlaymateOrderData
+import com.tencent.imsdk.v2.V2TIMMessage
+import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean
+import com.tencent.qcloud.tuikit.timcommon.bean.TUIReplyQuoteBean
+import com.tencent.qcloud.tuikit.tuichat.bean.message.reply.TextReplyQuoteBean
+
+class PlaymateOrderMessageBean : TUIMessageBean() {
+
+    var data: PlaymateOrderData? = null
+    override fun onGetDisplayString(): String? {
+        return getCompatString(R.string.im_playmate_order_title)
+    }
+
+    override fun onProcessMessage(v2TIMMessage: V2TIMMessage) {
+        val byte = v2TIMMessage.customElem?.data ?: return
+        val dataStr = String(byte)
+        val playmateData = froJsonErrorNull<PlaymateOrderData>(dataStr)
+        //填充数据
+        this.data = playmateData
+    }
+
+    override fun getReplyQuoteBeanClass(): Class<out TUIReplyQuoteBean<*>?> {
+        return TextReplyQuoteBean::class.java
+    }
+}

+ 0 - 0
module/im/src/main/res/drawable/im_official_message_bubble_bg.xml → module/im/src/main/res/drawable/im_message_bubble_bg.xml


+ 1 - 1
module/im/src/main/res/layout/layout_session_message_official_image_text.xml

@@ -4,7 +4,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="@drawable/im_official_message_bubble_bg"
+    android:background="@drawable/im_message_bubble_bg"
     app:constraint_layout_round_corner="12dp">
 
     <com.adealink.frame.image.view.NetworkImageView

+ 103 - 0
module/im/src/main/res/layout/layout_session_message_playmate_order.xml

@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.adealink.weparty.commonui.widget.constrainlayout.RoundCornerConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/im_message_bubble_bg"
+    android:padding="12dp"
+    app:constraint_layout_round_corner="12dp">
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/iv_status"
+        android:layout_width="20dp"
+        android:layout_height="20dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="6dp"
+        android:fontFamily="@font/poppins_semibold"
+        android:gravity="start"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="14sp"
+        app:layout_constraintBottom_toBottomOf="@id/iv_status"
+        app:layout_constraintEnd_toStartOf="@id/iv_go"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintStart_toEndOf="@id/iv_status"
+        app:layout_constraintTop_toTopOf="@id/iv_status"
+        tools:text="Order Success" />
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/iv_go"
+        android:layout_width="16dp"
+        android:layout_height="16dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:srcCompat="@drawable/common_go_ic" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_desc"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="6dp"
+        android:gravity="start"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_FF86909C"
+        android:textSize="11sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/iv_status"
+        tools:text="Waiting for the playmate to accept the order. If the playmate does not reply within 1 hour" />
+
+    <View
+        android:layout_width="0dp"
+        android:layout_height="1dp"
+        android:layout_marginTop="6dp"
+        android:background="@color/color_FFF2F3F5"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_desc" />
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/iv_category"
+        android:layout_width="20dp"
+        android:layout_height="20dp"
+        android:layout_marginTop="12dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_desc" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_category"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="6dp"
+        android:ellipsize="end"
+        android:gravity="start"
+        android:includeFontPadding="false"
+        android:singleLine="true"
+        android:textColor="@color/color_FF4E5969"
+        android:textSize="12sp"
+        app:layout_constraintBottom_toBottomOf="@id/iv_category"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintStart_toEndOf="@id/iv_category"
+        app:layout_constraintTop_toTopOf="@id/iv_category"
+        tools:text="Lol" />
+
+    <com.adealink.weparty.commonui.widget.CommonButton
+        android:id="@+id/btn_complete"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/common_button_height"
+        android:layout_marginTop="12dp"
+        android:visibility="gone"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/iv_category"
+        tools:visibility="visible" />
+
+</com.adealink.weparty.commonui.widget.constrainlayout.RoundCornerConstraintLayout>

+ 1 - 0
module/im/src/main/res/values/strings.xml

@@ -16,4 +16,5 @@
     <string name="im_setting_mark">备注</string>
     <string name="im_setting_black">拉黑</string>
     <string name="im_setting_report">举报</string>
+    <string name="im_playmate_order_title">陪玩订单</string>
 </resources>

+ 9 - 1
module/order/src/main/AndroidManifest.xml

@@ -17,7 +17,15 @@
 
     <application>
         <activity
-            android:name=".OrderListActivity"
+            android:name=".UserOrderListActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme" />
+        <activity
+            android:name=".PlaymateOrderListActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme" />
+        <activity
+            android:name=".OrderDetailActivity"
             android:screenOrientation="portrait"
             android:theme="@style/AppTheme" />
     </application>

+ 0 - 66
module/order/src/main/java/com/adealink/weparty/order/OrderListActivity.kt

@@ -1,66 +0,0 @@
-package com.adealink.weparty.order
-
-import androidx.constraintlayout.widget.ConstraintLayout
-import androidx.core.view.updateLayoutParams
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import com.adealink.frame.base.fastLazy
-import com.adealink.frame.mvvm.view.viewBinding
-import com.adealink.frame.router.Router
-import com.adealink.frame.router.annotation.RouterUri
-import com.adealink.frame.util.statusBarHeight
-import com.adealink.weparty.commonui.BaseActivity
-import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
-import com.adealink.weparty.module.order.Order
-import com.adealink.weparty.order.adapter.OrderListItemViewBinder
-import com.adealink.weparty.order.data.OrderData
-import com.adealink.weparty.order.data.OrderListItemData
-import com.adealink.weparty.order.databinding.ActivityOrderListBinding
-
-@RouterUri(path = [Order.List.PATH], desc = "订单列表")
-class OrderListActivity : BaseActivity(), OrderListItemViewBinder.OrderListListener {
-
-    companion object {
-        private const val TAG = "OrderListActivity"
-    }
-
-    private val binding by viewBinding(ActivityOrderListBinding::inflate)
-
-    private val listAdapter by fastLazy { MultiTypeListAdapter<OrderListItemData>() }
-
-    override fun onBeforeCreate() {
-        super.onBeforeCreate()
-        Router.bind(this)
-    }
-
-    override fun initViews() {
-        super.initViews()
-        setContentView(binding.root)
-        binding.topBar.updateLayoutParams<ConstraintLayout.LayoutParams> {
-            topMargin = this@OrderListActivity.statusBarHeight()
-        }
-
-        listAdapter.register(OrderListItemViewBinder())
-        binding.rvOrder.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
-        binding.rvOrder.adapter = listAdapter
-    }
-
-    override fun loadData() {
-        super.loadData()
-        listAdapter.submitList(
-            listOf(
-                OrderListItemData(OrderData("")),
-                OrderListItemData(OrderData("")),
-                OrderListItemData(OrderData("")),
-                OrderListItemData(OrderData("")),
-                OrderListItemData(OrderData(""))
-            )
-        )
-    }
-
-    override fun showOrderDetail() {
-
-    }
-
-
-}

+ 1 - 1
module/order/src/main/java/com/adealink/weparty/order/OrderServiceImpl.kt

@@ -7,7 +7,7 @@ import com.adealink.weparty.module.order.IOrderService
 class OrderServiceImpl : IOrderService {
 
     override fun logout() {
-        TODO("Not yet implemented")
+
     }
 
     override fun getService(): IOrderService {

+ 107 - 0
module/order/src/main/java/com/adealink/weparty/order/PlaymateOrderListActivity.kt

@@ -0,0 +1,107 @@
+package com.adealink.weparty.order
+
+import androidx.activity.viewModels
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.view.updateLayoutParams
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.adealink.frame.base.fastLazy
+import com.adealink.frame.mvvm.view.viewBinding
+import com.adealink.frame.router.Router
+import com.adealink.frame.router.annotation.RouterUri
+import com.adealink.frame.util.statusBarHeight
+import com.adealink.weparty.commonui.BaseActivity
+import com.adealink.weparty.commonui.ext.dp
+import com.adealink.weparty.commonui.ext.gone
+import com.adealink.weparty.commonui.ext.show
+import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
+import com.adealink.weparty.commonui.recycleview.itemdecoration.VerticalSpaceItemDecoration
+import com.adealink.weparty.commonui.toast.util.showFailedToast
+import com.adealink.weparty.module.order.Order
+import com.adealink.weparty.order.adapter.PlaymateListItemViewBinder
+import com.adealink.weparty.order.data.PlaymateOrderListItemData
+import com.adealink.weparty.order.databinding.ActivityPlaymateOrderListBinding
+import com.adealink.weparty.order.viewmodel.OrderViewModelFactory
+import com.adealink.weparty.order.viewmodel.PlaymateOrderViewModel
+import com.scwang.smart.refresh.layout.api.RefreshLayout
+import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener
+import com.adealink.weparty.R as APP_R
+
+@RouterUri(path = [Order.PlaymateList.PATH], desc = "陪玩列表")
+class PlaymateOrderListActivity : BaseActivity() {
+
+    companion object {
+        private const val TAG = "PlaymateOrderListActivity"
+    }
+
+    private val binding by viewBinding(ActivityPlaymateOrderListBinding::inflate)
+
+    private val viewModel by viewModels<PlaymateOrderViewModel> { OrderViewModelFactory() }
+
+    private val listAdapter by fastLazy { MultiTypeListAdapter<PlaymateOrderListItemData>() }
+
+    override fun onBeforeCreate() {
+        super.onBeforeCreate()
+        Router.bind(this)
+    }
+
+    override fun initViews() {
+        super.initViews()
+        setContentView(binding.root)
+        binding.topBar.updateLayoutParams<ConstraintLayout.LayoutParams> {
+            topMargin = this@PlaymateOrderListActivity.statusBarHeight()
+        }
+
+        binding.vRefresh.setEnableRefresh(true)
+        binding.vRefresh.setEnableLoadMore(true)
+        binding.vRefresh.setEnableAutoLoadMore(true)
+        binding.vRefresh.setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener {
+            override fun onRefresh(refreshLayout: RefreshLayout) {
+                viewModel.pullOrderList()
+            }
+
+
+            override fun onLoadMore(refreshLayout: RefreshLayout) {
+                viewModel.loadMoreOrderList()
+            }
+        })
+
+        listAdapter.register(PlaymateListItemViewBinder())
+        binding.rvOrder.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
+        binding.rvOrder.adapter = listAdapter
+        binding.rvOrder.addItemDecoration(
+            VerticalSpaceItemDecoration(
+                20.dp(),
+                firstSpaceHeight = 16.dp()
+            )
+        )
+    }
+
+    override fun loadData() {
+        super.loadData()
+        viewModel.pullOrderList()
+    }
+
+    override fun observeViewModel() {
+        super.observeViewModel()
+        viewModel.orderListLD.observe(this) {
+            listAdapter.submitList(it)
+            if (it.isNullOrEmpty()) {
+                binding.rvOrder.gone()
+                binding.vErrorView.show(
+                    errorEmptyResId = APP_R.drawable.common_list_empty_ic,
+                    title = APP_R.string.commonui_list_empty
+                )
+            } else {
+                binding.rvOrder.show()
+                binding.vErrorView.gone()
+            }
+        }
+        viewModel.orderListRltLD.observe(this) { rlt ->
+            binding.vRefresh.finishRefresh()
+            binding.vRefresh.finishLoadMore()
+            showFailedToast(rlt)
+        }
+    }
+
+}

+ 140 - 0
module/order/src/main/java/com/adealink/weparty/order/UserOrderListActivity.kt

@@ -0,0 +1,140 @@
+package com.adealink.weparty.order
+
+import androidx.activity.viewModels
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.view.updateLayoutParams
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.adealink.frame.base.fastLazy
+import com.adealink.frame.mvvm.view.viewBinding
+import com.adealink.frame.router.Router
+import com.adealink.frame.router.annotation.RouterUri
+import com.adealink.frame.util.statusBarHeight
+import com.adealink.weparty.commonui.BaseActivity
+import com.adealink.weparty.commonui.ext.dp
+import com.adealink.weparty.commonui.ext.gone
+import com.adealink.weparty.commonui.ext.show
+import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
+import com.adealink.weparty.commonui.recycleview.itemdecoration.VerticalSpaceItemDecoration
+import com.adealink.weparty.commonui.toast.util.showFailedToast
+import com.adealink.weparty.module.order.Order
+import com.adealink.weparty.order.adapter.OrderListItemViewBinder
+import com.adealink.weparty.order.data.UserOrderData
+import com.adealink.weparty.order.data.UserOrderListItemData
+import com.adealink.weparty.order.databinding.ActivityUserOrderListBinding
+import com.adealink.weparty.order.dialog.EvaluateOrderDialog
+import com.adealink.weparty.order.viewmodel.OrderViewModelFactory
+import com.adealink.weparty.order.viewmodel.UserOrderViewModel
+import com.scwang.smart.refresh.layout.api.RefreshLayout
+import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener
+import com.adealink.weparty.R as APP_R
+
+@RouterUri(path = [Order.List.PATH], desc = "用户订单列表")
+class UserOrderListActivity : BaseActivity(), OrderListItemViewBinder.OrderListListener {
+
+    companion object {
+        private const val TAG = "UserOrderListActivity"
+    }
+
+    private val binding by viewBinding(ActivityUserOrderListBinding::inflate)
+
+    private val viewModel by viewModels<UserOrderViewModel> { OrderViewModelFactory() }
+
+    private val listAdapter by fastLazy { MultiTypeListAdapter<UserOrderListItemData>() }
+
+    override fun onBeforeCreate() {
+        super.onBeforeCreate()
+        Router.bind(this)
+    }
+
+    override fun initViews() {
+        super.initViews()
+        setContentView(binding.root)
+        binding.topBar.updateLayoutParams<ConstraintLayout.LayoutParams> {
+            topMargin = this@UserOrderListActivity.statusBarHeight()
+        }
+
+        binding.vRefresh.setEnableRefresh(true)
+        binding.vRefresh.setEnableLoadMore(true)
+        binding.vRefresh.setEnableAutoLoadMore(true)
+        binding.vRefresh.setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener {
+            override fun onRefresh(refreshLayout: RefreshLayout) {
+                viewModel.pullOrderList()
+            }
+
+
+            override fun onLoadMore(refreshLayout: RefreshLayout) {
+                viewModel.loadMoreOrderList()
+            }
+        })
+
+        listAdapter.register(OrderListItemViewBinder(this))
+        binding.rvOrder.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
+        binding.rvOrder.adapter = listAdapter
+        binding.rvOrder.addItemDecoration(
+            VerticalSpaceItemDecoration(
+                20.dp(),
+                firstSpaceHeight = 16.dp()
+            )
+        )
+    }
+
+    override fun loadData() {
+        super.loadData()
+        viewModel.pullOrderList()
+    }
+
+    override fun observeViewModel() {
+        super.observeViewModel()
+        viewModel.orderListLD.observe(this) {
+            listAdapter.submitList(it)
+            if (it.isNullOrEmpty()) {
+                binding.rvOrder.gone()
+                binding.vErrorView.show(
+                    errorEmptyResId = APP_R.drawable.common_list_empty_ic,
+                    title = APP_R.string.commonui_list_empty
+                )
+            } else {
+                binding.rvOrder.show()
+                binding.vErrorView.gone()
+            }
+        }
+        viewModel.orderListRltLD.observe(this) { rlt ->
+            binding.vRefresh.finishRefresh()
+            binding.vRefresh.finishLoadMore()
+            showFailedToast(rlt)
+        }
+    }
+
+    override fun showOrderDetail(item: UserOrderData) {
+        Router.build(this, Order.Detail.PATH).start()
+    }
+
+    override fun cancelOrder(item: UserOrderData) {
+        viewModel.cancelOrder(item).observe(this) {
+            showFailedToast(it)
+        }
+    }
+
+    override fun completeOrder(item: UserOrderData) {
+        viewModel.completeOrder(item).observe(this) {
+            showFailedToast(it)
+        }
+    }
+
+    override fun evaluateOrder(item: UserOrderData) {
+        EvaluateOrderDialog().apply {
+            setOrderInfo(item)
+            setListener(object : EvaluateOrderDialog.OnEvaluateListener {
+                override fun onEvaluate(star: Int, comment: String) {
+                    viewModel.evaluateOrder(item, star, comment)
+                        .observe(this@UserOrderListActivity) {
+                            showFailedToast(it)
+                        }
+                }
+            })
+        }.show(supportFragmentManager, "EvaluateOrderDialog")
+    }
+
+
+}

+ 130 - 10
module/order/src/main/java/com/adealink/weparty/order/adapter/OrderListItemViewBinder.kt

@@ -1,30 +1,150 @@
 package com.adealink.weparty.order.adapter
 
+import android.annotation.SuppressLint
 import android.view.LayoutInflater
 import android.view.ViewGroup
+import com.adealink.frame.util.onClick
+import com.adealink.weparty.commonui.ext.gone
+import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.commonui.recycleview.adapter.BindingViewHolder
 import com.adealink.weparty.commonui.recycleview.adapter.multitype.ItemViewBinder
-import com.adealink.weparty.order.data.OrderListItemData
-import com.adealink.weparty.order.databinding.LayoutOrderListItemBinding
+import com.adealink.weparty.module.order.data.OrderStatus
+import com.adealink.weparty.order.data.UserOrderData
+import com.adealink.weparty.order.data.UserOrderListItemData
+import com.adealink.weparty.order.databinding.LayoutUserOrderListItemBinding
+import com.adealink.weparty.order.util.getOrderAllCost
+import com.adealink.weparty.order.util.setUserOrderStatusText
+import com.adealink.weparty.util.formatTimeStr
 
-class OrderListItemViewBinder :
-    ItemViewBinder<OrderListItemData, BindingViewHolder<LayoutOrderListItemBinding>>() {
+/**
+ * 用户订单列表状态
+ * https://mimolive.sg.larksuite.com/wiki/PX4Qw1N1viFjpSkt0qmlLeTGgqh
+ */
+class OrderListItemViewBinder(
+    val listener: OrderListListener
+) : ItemViewBinder<UserOrderListItemData, BindingViewHolder<LayoutUserOrderListItemBinding>>() {
 
+    @SuppressLint("SetTextI18n")
     override fun onBindViewHolder(
-        holder: BindingViewHolder<LayoutOrderListItemBinding>,
-        item: OrderListItemData,
+        holder: BindingViewHolder<LayoutUserOrderListItemBinding>,
+        item: UserOrderListItemData,
     ) {
+        holder.binding.root.onClick {
+            listener.showOrderDetail(item.data)
+        }
 
+        holder.binding.tvTime.text = item.data.createTime.formatTimeStr()
+        val status = OrderStatus.map(item.data.status)
+        setUserOrderStatusText(holder.binding.tvOrderStatus, status, item.data.refundApply)
+
+        holder.binding.ivAvatar.setImageUrl(item.data.avatar)
+        holder.binding.tvName.text = item.data.nickname
+        holder.binding.tvDesc.text = item.data.bizCategoryName
+        holder.binding.tvPrice.text = item.data.price.toString()
+        holder.binding.tvCount.text = "${item.data.unit} x${item.data.purchaseQty}"
+        holder.binding.tvOrderAllCost.text = getOrderAllCost(item.data.price, item.data.purchaseQty)
+
+        when {
+            item.data.refundApply -> {
+                holder.binding.btnComplete.gone()
+                holder.binding.btnCancel.gone()
+                holder.binding.btnEvaluate.gone()
+                holder.binding.tvRefunded.gone()
+            }
+
+            status == OrderStatus.CREATE_ORDER -> {
+                holder.binding.btnComplete.gone()
+                holder.binding.btnCancel.onClick {
+                    listener.cancelOrder(item.data)
+                }
+                holder.binding.btnEvaluate.gone()
+                holder.binding.tvRefunded.gone()
+            }
+
+            status == OrderStatus.WAIT_FOR_ACCEPT -> {
+                holder.binding.btnComplete.gone()
+                holder.binding.btnCancel.show()
+                holder.binding.btnCancel.onClick {
+                    listener.cancelOrder(item.data)
+                }
+                holder.binding.btnEvaluate.gone()
+                holder.binding.tvRefunded.gone()
+            }
+
+            status == OrderStatus.USER_CANCEL -> {
+                holder.binding.btnComplete.gone()
+                holder.binding.btnCancel.gone()
+                holder.binding.btnEvaluate.gone()
+                holder.binding.tvRefunded.gone()
+            }
+
+            status == OrderStatus.PLAYMATE_IN_SERVICE -> {
+                holder.binding.btnComplete.show()
+                holder.binding.btnComplete.onClick {
+                    listener.completeOrder(item.data)
+                }
+                holder.binding.btnCancel.gone()
+                holder.binding.btnEvaluate.gone()
+                holder.binding.tvRefunded.gone()
+            }
+
+            status == OrderStatus.PLAYMATE_REFUSE -> {
+                holder.binding.btnComplete.gone()
+                holder.binding.btnCancel.gone()
+                holder.binding.btnEvaluate.gone()
+                holder.binding.tvRefunded.gone()
+            }
+
+            status == OrderStatus.PLAYMATE_ACCEPT -> {
+                holder.binding.btnComplete.gone()
+                holder.binding.btnCancel.gone()
+                holder.binding.btnEvaluate.gone()
+                holder.binding.tvRefunded.gone()
+            }
+
+            status == OrderStatus.USER_REFUND -> {
+                holder.binding.btnComplete.gone()
+                holder.binding.btnCancel.gone()
+                holder.binding.btnEvaluate.gone()
+                holder.binding.tvRefunded.gone()
+            }
+
+            status == OrderStatus.PLAYMATE_END_SERVICE -> {
+                holder.binding.btnComplete.show()
+                holder.binding.btnComplete.onClick{
+
+                }
+                holder.binding.btnCancel.gone()
+                holder.binding.btnEvaluate.gone()
+                holder.binding.tvRefunded.gone()
+            }
+
+            status == OrderStatus.COMPLETE -> {
+                holder.binding.btnComplete.show()
+                holder.binding.btnComplete.onClick{
+
+                }
+                holder.binding.btnCancel.gone()
+                holder.binding.btnEvaluate.gone()
+                holder.binding.tvRefunded.gone()
+            }
+        }
     }
 
     override fun onCreateViewHolder(
         inflater: LayoutInflater,
         parent: ViewGroup,
-    ): BindingViewHolder<LayoutOrderListItemBinding> {
-        return BindingViewHolder(LayoutOrderListItemBinding.inflate(inflater, parent, false))
+    ): BindingViewHolder<LayoutUserOrderListItemBinding> {
+        return BindingViewHolder(LayoutUserOrderListItemBinding.inflate(inflater, parent, false))
     }
 
-    interface OrderListListener{
-        fun showOrderDetail()
+    interface OrderListListener {
+        fun showOrderDetail(item: UserOrderData)
+
+        fun cancelOrder(item: UserOrderData)
+
+        fun completeOrder(item: UserOrderData)
+
+        fun evaluateOrder(item: UserOrderData)
     }
 }

+ 26 - 0
module/order/src/main/java/com/adealink/weparty/order/adapter/PlaymateListItemViewBinder.kt

@@ -0,0 +1,26 @@
+package com.adealink.weparty.order.adapter
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import com.adealink.weparty.commonui.recycleview.adapter.BindingViewHolder
+import com.adealink.weparty.commonui.recycleview.adapter.multitype.ItemViewBinder
+import com.adealink.weparty.order.data.UserOrderListItemData
+import com.adealink.weparty.order.databinding.LayoutPlaymateOrderListItemBinding
+
+class PlaymateListItemViewBinder(
+) : ItemViewBinder<UserOrderListItemData, BindingViewHolder<LayoutPlaymateOrderListItemBinding>>() {
+
+    override fun onBindViewHolder(
+        holder: BindingViewHolder<LayoutPlaymateOrderListItemBinding>,
+        item: UserOrderListItemData,
+    ) {
+    }
+
+    override fun onCreateViewHolder(
+        inflater: LayoutInflater,
+        parent: ViewGroup,
+    ): BindingViewHolder<LayoutPlaymateOrderListItemBinding> {
+        return BindingViewHolder(LayoutPlaymateOrderListItemBinding.inflate(inflater, parent, false))
+    }
+
+}

+ 91 - 5
module/order/src/main/java/com/adealink/weparty/order/data/OrderData.kt

@@ -1,10 +1,96 @@
 package com.adealink.weparty.order.data
 
+import com.adealink.frame.network.data.PageReq
+import com.google.gson.annotations.GsonNullable
+import com.google.gson.annotations.SerializedName
 
-data class OrderData(
-    val id: String
+
+data class PlaymateOrderListReq(
+    @SerializedName("status") val status: Int = -1, //-1:全部状态
+    @SerializedName("page") val page: PageReq,
+)
+
+
+data class PlaymateOrderListRes(
+    @SerializedName("list") val list: List<PlaymateOrderData>,
+    @GsonNullable
+    @SerializedName("next") val next: String?,
+)
+
+data class PlaymateOrderData(
+    @SerializedName("orderId") val orderId: String, //订单ID
+    @SerializedName("avatar") val avatar: String, //
+    @SerializedName("nickname") val nickname: String, //昵称
+    @SerializedName("gender") val gender: Int, //性别
+    @SerializedName("bizCategoryName") val bizCategoryName: String, //品类名称
+    @SerializedName("categoryIcon") val categoryIcon: String, //品类图标
+    @SerializedName("price") val price: Float, //单价
+    @SerializedName("unit") val unit: String, //单位
+    @SerializedName("purchaseQty") val purchaseQty: Int, //购买数量
+    @SerializedName("status") val status: Int, //状态
+    @SerializedName("createTime") val createTime: Long, //下单时间
+    @GsonNullable
+    @SerializedName("star") val star: Int?, //评分
+    @SerializedName("refundApply") val refundApply: Boolean, //是否退款申请中
+    @SerializedName("customerRemark") val customerRemark: String, //客户备注
+)
+
+
+data class PlaymateOrderListItemData(
+    val data: PlaymateOrderData
+)
+
+
+data class UserOrderListReq(
+    @SerializedName("status") val status: Int = -1, //-1:全部状态
+    @SerializedName("page") val page: PageReq,
+)
+
+
+data class UserOrderListRes(
+    @SerializedName("list") val list: List<UserOrderData>,
+    @GsonNullable
+    @SerializedName("next") val next: String?,
+)
+
+data class UserOrderData(
+    @SerializedName("orderId") val orderId: String, //订单ID
+    @SerializedName("avatar") val avatar: String, //
+    @SerializedName("nickname") val nickname: String, //昵称
+    @SerializedName("gender") val gender: Int, //性别
+    @SerializedName("bizCategoryName") val bizCategoryName: String, //品类名称
+    @SerializedName("categoryIcon") val categoryIcon: String, //品类图标
+    @SerializedName("price") val price: Float, //单价
+    @SerializedName("unit") val unit: String, //单位
+    @SerializedName("purchaseQty") val purchaseQty: Int, //购买数量
+    @SerializedName("status") val status: Int, //状态
+    @SerializedName("createTime") val createTime: Long, //下单时间
+    @GsonNullable
+    @SerializedName("star") val star: Int?, //评分
+    @SerializedName("refundApply") val refundApply: Boolean, //是否退款申请中
+    @SerializedName("customerRemark") val customerRemark: String, //客户备注
+)
+
+data class UserOrderListItemData(
+    val data: UserOrderData
+)
+
+
+
+data class CompleteOrderReq(
+    @SerializedName("id") val id: String, //订单ID
+)
+
+data class CancelOrderReq(
+    @SerializedName("id") val id: String, //订单ID
 )
 
-data class OrderListItemData(
-    val data: OrderData
-)
+data class RefundApplyReq(
+    @SerializedName("id") val id: String, //订单ID
+)
+
+data class EvaluateOrderReq(
+    @SerializedName("orderId") val id: String, //订单ID
+    @SerializedName("star") val star: Int, //评分
+    @SerializedName("comment") val comment: String, //评价
+)

+ 53 - 0
module/order/src/main/java/com/adealink/weparty/order/datasource/remote/OrderHttpService.kt

@@ -1,5 +1,58 @@
 package com.adealink.weparty.order.datasource.remote
 
+import com.adealink.frame.base.Rlt
+import com.adealink.frame.network.data.Res
+import com.adealink.weparty.order.data.CancelOrderReq
+import com.adealink.weparty.order.data.CompleteOrderReq
+import com.adealink.weparty.order.data.EvaluateOrderReq
+import com.adealink.weparty.order.data.PlaymateOrderListReq
+import com.adealink.weparty.order.data.PlaymateOrderListRes
+import com.adealink.weparty.order.data.RefundApplyReq
+import com.adealink.weparty.order.data.UserOrderListReq
+import com.adealink.weparty.order.data.UserOrderListRes
+import retrofit2.http.Body
+import retrofit2.http.Core
+import retrofit2.http.POST
+
 interface OrderHttpService {
 
+    @Core
+    @POST("playmate/order/list")
+    suspend fun pullPlaymateOrderList(@Body req: PlaymateOrderListReq): Rlt<Res<PlaymateOrderListRes>>
+
+    @Core
+    @POST("skill/order/list")
+    suspend fun pullUserOrderList(@Body req: UserOrderListReq): Rlt<Res<UserOrderListRes>>
+
+    /**
+     * 用户完成订单
+     */
+    @Core
+    @POST("skill/order/finish")
+    suspend fun userCompleteOrder(@Body req: CompleteOrderReq): Rlt<Res<Any>>
+
+
+    /**
+     * 用户取消订单
+     */
+    @Core
+    @POST("skill/order/canecl")
+    suspend fun userCancelOrder(@Body req: CancelOrderReq): Rlt<Res<Any>>
+
+
+    /**
+     * 用户申请退款
+     */
+    @Core
+    @POST("skill/order/refund/apply")
+    suspend fun userRefundApply(@Body req: RefundApplyReq): Rlt<Res<Any>>
+
+    /**
+     * 用户评分
+     */
+    @Core
+    @POST("skill/order/star")
+    suspend fun userEvaluate(@Body req: EvaluateOrderReq): Rlt<Res<Any>>
+
+
 }

+ 99 - 0
module/order/src/main/java/com/adealink/weparty/order/dialog/EvaluateOrderDialog.kt

@@ -0,0 +1,99 @@
+package com.adealink.weparty.order.dialog
+
+import android.annotation.SuppressLint
+import android.text.Editable
+import android.text.TextWatcher
+import com.adealink.frame.aab.util.getCompatColor
+import com.adealink.frame.mvvm.view.viewBinding
+import com.adealink.frame.util.onClick
+import com.adealink.weparty.commonui.widget.BottomDialogFragment
+import com.adealink.weparty.commonui.widget.EvaluateView
+import com.adealink.weparty.order.R
+import com.adealink.weparty.order.data.UserOrderData
+import com.adealink.weparty.order.databinding.DialogEvaluateOrderBinding
+import com.adealink.weparty.R as APP_R
+
+class EvaluateOrderDialog : BottomDialogFragment(R.layout.dialog_evaluate_order) {
+
+    companion object {
+        private const val MAX_INPUT_COUNT = 200
+    }
+
+    private val binding by viewBinding(DialogEvaluateOrderBinding::bind)
+    private var orderInfo: UserOrderData? = null
+
+    private var listener: OnEvaluateListener? = null
+
+    fun setOrderInfo(data: UserOrderData?) {
+        this.orderInfo = data
+    }
+
+    fun setListener(listener: OnEvaluateListener?) {
+        this.listener = listener
+    }
+
+    override fun initViews() {
+        super.initViews()
+        binding.ivAvatar.setImageUrl(orderInfo?.avatar)
+
+        binding.vEvaluate.setListener(object : EvaluateView.OnEvaluateListener {
+            override fun onEvaluate(score: Int) {
+                updateEvaluate(score)
+            }
+        })
+        updateEvaluate(binding.vEvaluate.getScore())
+
+        binding.etInput.addTextChangedListener(object : TextWatcher {
+            override fun beforeTextChanged(
+                s: CharSequence?,
+                start: Int,
+                count: Int,
+                after: Int
+            ) {
+            }
+
+            override fun onTextChanged(
+                s: CharSequence?,
+                start: Int,
+                before: Int,
+                count: Int
+            ) {
+            }
+
+            @SuppressLint("SetTextI18n")
+            override fun afterTextChanged(s: Editable?) {
+                val input = s?.trim()?.toString()
+                if (input.isNullOrEmpty()) {
+                    binding.btnSubmit.isEnabled = false
+                    binding.tvInputCount.text = "0/${MAX_INPUT_COUNT}"
+                } else {
+                    binding.btnSubmit.isEnabled = true
+                    binding.tvInputCount.text = "${input.length}/${MAX_INPUT_COUNT}"
+                }
+            }
+        })
+
+        binding.btnSubmit.onClick {
+            listener?.onEvaluate(
+                binding.vEvaluate.getScore(),
+                binding.etInput.text?.trim()?.toString() ?: ""
+            )
+            dismiss()
+        }
+    }
+
+    private fun updateEvaluate(star: Int) {
+        if (star > 0) {
+            binding.vEvaluateLeft.setTextColor(getCompatColor(APP_R.color.color_FFCDCFD9))
+            binding.vEvaluateRight.setTextColor(getCompatColor(APP_R.color.color_FFCDCFD9))
+        } else {
+            binding.vEvaluateLeft.setTextColor(getCompatColor(APP_R.color.color_CC1D2129))
+            binding.vEvaluateRight.setTextColor(getCompatColor(APP_R.color.color_CC1D2129))
+        }
+    }
+
+
+    interface OnEvaluateListener {
+        fun onEvaluate(star: Int, comment: String)
+    }
+}

+ 112 - 0
module/order/src/main/java/com/adealink/weparty/order/util/UIUtil.kt

@@ -0,0 +1,112 @@
+package com.adealink.weparty.order.util
+
+import android.graphics.Typeface
+import android.os.Build
+import android.text.SpannableStringBuilder
+import android.text.style.AbsoluteSizeSpan
+import android.text.style.TypefaceSpan
+import androidx.appcompat.widget.AppCompatTextView
+import com.adealink.frame.aab.util.getCompatColor
+import com.adealink.frame.aab.util.getCompatDrawable
+import com.adealink.frame.aab.util.getCompatString
+import com.adealink.frame.ext.findAndSetSpan
+import com.adealink.weparty.commonui.DEFAULT_FONT_BOLD
+import com.adealink.weparty.commonui.ext.sp
+import com.adealink.weparty.commonui.widget.CenterImageSpan
+import com.adealink.weparty.module.order.data.OrderStatus
+import com.adealink.weparty.order.R
+import com.adealink.weparty.R as APP_R
+
+fun setUserOrderStatusText(
+    textView: AppCompatTextView,
+    status: OrderStatus?,
+    isRefundApply: Boolean? //是否处于申请退款中
+) {
+    if (isRefundApply == true) {
+        textView.text =
+            getCompatString(R.string.user_order_status_refund_under_review_desc)
+        textView.setTextColor(getCompatColor(APP_R.color.color_FFFFB836))
+        return
+    }
+    when (status) {
+        OrderStatus.CREATE_ORDER -> {
+            textView.text =
+                getCompatString(R.string.user_order_status_create_order_desc)
+            textView.setTextColor(getCompatColor(APP_R.color.color_FFFFB836))
+        }
+
+        OrderStatus.WAIT_FOR_ACCEPT -> {
+            textView.text =
+                getCompatString(R.string.user_order_status_create_order_desc)
+            textView.setTextColor(getCompatColor(APP_R.color.color_FF3FBFBD))
+        }
+
+        OrderStatus.PLAYMATE_ACCEPT -> {
+            textView.text =
+                getCompatString(R.string.user_order_status_create_order_desc)
+            textView.setTextColor(getCompatColor(APP_R.color.color_FFFFB836))
+        }
+
+        OrderStatus.PLAYMATE_IN_SERVICE -> {
+            textView.text =
+                getCompatString(R.string.user_order_status_create_order_desc)
+            textView.setTextColor(getCompatColor(APP_R.color.color_FFFFB836))
+        }
+
+        OrderStatus.PLAYMATE_END_SERVICE -> {
+            textView.text =
+                getCompatString(R.string.user_order_status_create_order_desc)
+            textView.setTextColor(getCompatColor(APP_R.color.color_FFFFB836))
+        }
+
+        OrderStatus.PLAYMATE_REFUSE -> {
+            textView.text =
+                getCompatString(R.string.user_order_status_create_order_desc)
+            textView.setTextColor(getCompatColor(APP_R.color.color_FF1D2129))
+        }
+
+        OrderStatus.COMPLETE -> {
+            textView.text =
+                getCompatString(R.string.user_order_status_create_order_desc)
+            textView.setTextColor(getCompatColor(APP_R.color.color_FF3FBFBD))
+        }
+
+        OrderStatus.USER_REFUND -> {
+            textView.text =
+                getCompatString(R.string.user_order_status_create_order_desc)
+            textView.setTextColor(getCompatColor(APP_R.color.color_FF1D2129))
+        }
+
+        OrderStatus.USER_CANCEL -> {
+            textView.text =
+                getCompatString(R.string.user_order_status_create_order_desc)
+            textView.setTextColor(getCompatColor(APP_R.color.color_FF1D2129))
+        }
+
+        null -> {
+            textView.text = null
+        }
+    }
+}
+
+
+fun getOrderAllCost(price: Float, count: Int): SpannableStringBuilder {
+    val cost = (price * count).toString()
+    val text = getCompatString(R.string.order_all_cost, cost)
+    return SpannableStringBuilder(text).apply {
+        findAndSetSpan(
+            CenterImageSpan(getCompatDrawable(APP_R.drawable.common_wallet_coin_32_ic)),
+            "[currency]"
+        )
+        findAndSetSpan(
+            AbsoluteSizeSpan(16.sp()),
+            cost
+        )
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+            findAndSetSpan(
+                TypefaceSpan(Typeface.create(DEFAULT_FONT_BOLD, Typeface.BOLD)),
+                cost
+            )
+        }
+    }
+}

+ 0 - 8
module/order/src/main/java/com/adealink/weparty/order/viewmodel/OrderViewModel.kt

@@ -1,8 +0,0 @@
-package com.adealink.weparty.order.viewmodel
-
-import com.adealink.frame.mvvm.viewmodel.BaseViewModel
-import com.adealink.weparty.module.activity.viewmodel.IActivityViewModel
-
-class OrderViewModel : BaseViewModel(), IActivityViewModel {
-
-}

+ 5 - 2
module/order/src/main/java/com/adealink/weparty/order/viewmodel/OrderViewModelFactory.kt

@@ -9,8 +9,11 @@ class OrderViewModelFactory : ViewModelProvider.NewInstanceFactory() {
     override fun <T : ViewModel> create(modelClass: Class<T>): T {
         return with(modelClass) {
             when {
-                isAssignableFrom(OrderViewModel::class.java) ->
-                    OrderViewModel()
+                isAssignableFrom(UserOrderViewModel::class.java) ->
+                    UserOrderViewModel()
+
+                isAssignableFrom(PlaymateOrderViewModel::class.java) ->
+                    PlaymateOrderViewModel()
 
                 else ->
                     throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")

+ 59 - 0
module/order/src/main/java/com/adealink/weparty/order/viewmodel/PlaymateOrderViewModel.kt

@@ -0,0 +1,59 @@
+package com.adealink.weparty.order.viewmodel
+
+import androidx.lifecycle.MutableLiveData
+import com.adealink.frame.base.Rlt
+import com.adealink.frame.mvvm.livedata.ExtMutableLiveData
+import com.adealink.frame.mvvm.viewmodel.BaseViewModel
+import com.adealink.frame.network.data.PageReq
+import com.adealink.weparty.App
+import com.adealink.weparty.order.data.PlaymateOrderListItemData
+import com.adealink.weparty.order.data.PlaymateOrderListReq
+import com.adealink.weparty.order.datasource.remote.OrderHttpService
+import com.adealink.weparty.util.PageHandler
+import kotlinx.coroutines.launch
+
+class PlaymateOrderViewModel : BaseViewModel() {
+    private val orderHttpService by lazy {
+        App.instance.networkService.getHttpService(OrderHttpService::class.java)
+    }
+    private val orderList = mutableListOf<PlaymateOrderListItemData>()
+    private val orderIds = mutableSetOf<String>()
+    private val pageHandler = PageHandler()
+
+    val orderListRltLD = ExtMutableLiveData<Rlt<Any>>()
+    val orderListLD = MutableLiveData<List<PlaymateOrderListItemData>>()
+    fun pullOrderList() {
+        orderList.clear()
+        orderIds.clear()
+        pageHandler.reset()
+        loadMoreOrderList()
+    }
+
+    fun loadMoreOrderList() {
+        viewModelScope.launch {
+            val rlt = orderHttpService.pullPlaymateOrderList(
+                PlaymateOrderListReq(
+                    page = PageReq(size = pageHandler.pageSize, next = pageHandler.currentPage)
+                )
+            )
+            when (rlt) {
+                is Rlt.Failed -> {
+                    orderListRltLD.send(rlt)
+                }
+
+                is Rlt.Success -> {
+                    pageHandler.nextPage(rlt.data.data?.next)
+                    rlt.data.data?.list?.forEach {
+                        if (!orderIds.contains(it.orderId)) {
+                            orderList.add(PlaymateOrderListItemData(it))
+                            orderIds.add(it.orderId)
+                        }
+                    }
+                    orderListRltLD.send(rlt)
+                    orderListLD.send(orderList)
+                }
+            }
+        }
+    }
+
+}

+ 102 - 0
module/order/src/main/java/com/adealink/weparty/order/viewmodel/UserOrderViewModel.kt

@@ -0,0 +1,102 @@
+package com.adealink.weparty.order.viewmodel
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import com.adealink.frame.base.Rlt
+import com.adealink.frame.mvvm.livedata.ExtMutableLiveData
+import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
+import com.adealink.frame.mvvm.viewmodel.BaseViewModel
+import com.adealink.frame.network.data.PageReq
+import com.adealink.weparty.App
+import com.adealink.weparty.order.data.CancelOrderReq
+import com.adealink.weparty.order.data.CompleteOrderReq
+import com.adealink.weparty.order.data.EvaluateOrderReq
+import com.adealink.weparty.order.data.UserOrderData
+import com.adealink.weparty.order.data.UserOrderListItemData
+import com.adealink.weparty.order.data.UserOrderListReq
+import com.adealink.weparty.order.datasource.remote.OrderHttpService
+import com.adealink.weparty.util.PageHandler
+import kotlinx.coroutines.launch
+
+class UserOrderViewModel : BaseViewModel() {
+
+    private val orderHttpService by lazy {
+        App.instance.networkService.getHttpService(OrderHttpService::class.java)
+    }
+    private val orderList = mutableListOf<UserOrderListItemData>()
+    private val orderIds = mutableSetOf<String>()
+    private val pageHandler = PageHandler()
+
+    val orderListRltLD = ExtMutableLiveData<Rlt<Any>>()
+    val orderListLD = MutableLiveData<List<UserOrderListItemData>>()
+    fun pullOrderList() {
+        orderList.clear()
+        orderIds.clear()
+        pageHandler.reset()
+        loadMoreOrderList()
+    }
+
+    fun loadMoreOrderList() {
+        viewModelScope.launch {
+            val rlt = orderHttpService.pullUserOrderList(
+                UserOrderListReq(
+                    page = PageReq(size = pageHandler.pageSize, next = pageHandler.currentPage)
+                )
+            )
+            when (rlt) {
+                is Rlt.Failed -> {
+                    orderListRltLD.send(rlt)
+                }
+
+                is Rlt.Success -> {
+                    pageHandler.nextPage(rlt.data.data?.next)
+                    rlt.data.data?.list?.forEach {
+                        if (!orderIds.contains(it.orderId)) {
+                            orderList.add(UserOrderListItemData(it))
+                            orderIds.add(it.orderId)
+                        }
+                    }
+                    orderListRltLD.send(rlt)
+                    orderListLD.send(orderList)
+                }
+            }
+        }
+    }
+
+    fun cancelOrder(item: UserOrderData): LiveData<Rlt<Any>> {
+        val livedata = OnceMutableLiveData<Rlt<Any>>()
+        viewModelScope.launch {
+            livedata.send(orderHttpService.userCancelOrder(CancelOrderReq(item.orderId)))
+        }
+        return livedata
+    }
+
+    fun completeOrder(item: UserOrderData): LiveData<Rlt<Any>> {
+        val livedata = OnceMutableLiveData<Rlt<Any>>()
+        viewModelScope.launch {
+            livedata.send(orderHttpService.userCompleteOrder(CompleteOrderReq(item.orderId)))
+        }
+        return livedata
+    }
+
+    fun evaluateOrder(
+        item: UserOrderData,
+        star: Int,
+        comment: String
+    ): LiveData<Rlt<Any>> {
+        val livedata = OnceMutableLiveData<Rlt<Any>>()
+        viewModelScope.launch {
+            livedata.send(
+                orderHttpService.userEvaluate(
+                    EvaluateOrderReq(
+                        item.orderId,
+                        star,
+                        comment
+                    )
+                )
+            )
+        }
+        return livedata
+    }
+
+}

+ 0 - 10
module/order/src/main/res/drawable/order_button_finish_bg.xml

@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-
-    <corners android:radius="20dp" />
-    <gradient
-        android:endColor="#B1EF5D"
-        android:startColor="#4ED2FF" />
-
-</shape>

+ 0 - 8
module/order/src/main/res/drawable/order_status_cancel_bg.xml

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-
-    <corners android:radius="20dp" />
-    <solid android:color="#C9CDD4" />
-
-</shape>

+ 0 - 8
module/order/src/main/res/drawable/order_status_finish_bg.xml

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-
-    <corners android:radius="20dp" />
-    <solid android:color="#5BD6E9" />
-
-</shape>

+ 0 - 8
module/order/src/main/res/drawable/order_status_in_progress_bg.xml

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-
-    <corners android:radius="20dp" />
-    <solid android:color="#FFC760" />
-
-</shape>

+ 5 - 6
module/order/src/main/res/layout/activity_order_detail.xml

@@ -393,26 +393,25 @@
             app:layout_constraintTop_toTopOf="parent" />
 
         <!-- 完成订单 -->
-        <androidx.appcompat.widget.AppCompatTextView
+        <com.adealink.weparty.commonui.widget.CommonButton
             android:id="@+id/btn_finish"
             android:layout_width="0dp"
             android:layout_height="48dp"
             android:layout_marginEnd="16dp"
-            android:background="@drawable/order_button_finish_bg"
             android:fontFamily="@font/poppins_semibold"
             android:gravity="center"
             android:includeFontPadding="false"
             android:minWidth="60dp"
             android:paddingHorizontal="6dp"
             android:paddingVertical="3dp"
-            android:text="@string/order_btn_finish"
-            android:textColor="@color/white"
-            android:textSize="16sp"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintHorizontal_weight="18"
             app:layout_constraintStart_toEndOf="@id/btn_refund"
-            app:layout_constraintTop_toTopOf="parent" />
+            app:layout_constraintTop_toTopOf="parent"
+            app:text="@string/order_btn_finish"
+            app:textColor="@color/white"
+            app:textSize="16sp" />
 
     </androidx.constraintlayout.widget.ConstraintLayout>
 

+ 12 - 2
module/order/src/main/res/layout/activity_order_list.xml → module/order/src/main/res/layout/activity_playmate_order_list.xml

@@ -15,7 +15,7 @@
         app:top_bar_title="@string/order_list_title" />
 
     <com.scwang.smart.refresh.layout.SmartRefreshLayout
-        android:id="@+id/refresh_layout"
+        android:id="@+id/v_refresh"
         android:layout_width="0dp"
         android:layout_height="0dp"
         android:background="@color/color_FFF1F2F5"
@@ -30,8 +30,18 @@
             android:layout_height="match_parent"
             android:layout_marginHorizontal="16dp"
             tools:itemCount="3"
-            tools:listitem="@layout/layout_order_list_item" />
+            tools:listitem="@layout/layout_user_order_list_item" />
 
     </com.scwang.smart.refresh.layout.SmartRefreshLayout>
 
+    <com.adealink.weparty.commonui.widget.CommonEmptyErrorView
+        android:id="@+id/v_error_view"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="@id/v_refresh"
+        app:layout_constraintEnd_toEndOf="@id/v_refresh"
+        app:layout_constraintStart_toStartOf="@id/v_refresh"
+        app:layout_constraintTop_toTopOf="@id/v_refresh" />
+
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 47 - 0
module/order/src/main/res/layout/activity_user_order_list.xml

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <com.adealink.weparty.commonui.widget.CommonTopBar
+        android:id="@+id/top_bar"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/common_top_bar_height"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:top_bar_title="@string/order_list_title" />
+
+    <com.scwang.smart.refresh.layout.SmartRefreshLayout
+        android:id="@+id/v_refresh"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="@color/color_FFF1F2F5"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/top_bar">
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/rv_order"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginHorizontal="16dp"
+            tools:itemCount="3"
+            tools:listitem="@layout/layout_user_order_list_item" />
+
+    </com.scwang.smart.refresh.layout.SmartRefreshLayout>
+
+    <com.adealink.weparty.commonui.widget.CommonEmptyErrorView
+        android:id="@+id/v_error_view"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="@id/v_refresh"
+        app:layout_constraintEnd_toEndOf="@id/v_refresh"
+        app:layout_constraintStart_toStartOf="@id/v_refresh"
+        app:layout_constraintTop_toTopOf="@id/v_refresh" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 138 - 0
module/order/src/main/res/layout/dialog_evaluate_order.xml

@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    tools:background="@color/black">
+
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="17dp"
+        android:background="@drawable/common_bottom_dialog_bg"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_title"
+            android:layout_width="wrap_content"
+            android:layout_height="40dp"
+            android:layout_marginTop="43dp"
+            android:fontFamily="@font/poppins_semibold"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:text="@string/order_evaluate_title"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="16sp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/v_evaluate_left"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:fontFamily="@font/poppins_semibold"
+            android:includeFontPadding="false"
+            android:text="@string/order_evaluate_left_title"
+            android:textColor="@color/color_FFC9CDD4"
+            android:textSize="12sp"
+            app:layout_constraintBottom_toBottomOf="@id/v_evaluate"
+            app:layout_constraintEnd_toStartOf="@id/v_evaluate"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="@id/v_evaluate" />
+
+        <com.adealink.weparty.commonui.widget.EvaluateView
+            android:id="@+id/v_evaluate"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="5dp"
+            app:evaluate_current="0"
+            app:evaluate_divide="12dp"
+            app:evaluate_max="5"
+            app:evaluate_width="30dp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/tv_title"
+            tools:evaluate_current="3" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/v_evaluate_right"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:fontFamily="@font/poppins_semibold"
+            android:includeFontPadding="false"
+            android:text="@string/order_evaluate_right_title"
+            android:textColor="@color/color_FFC9CDD4"
+            android:textSize="12sp"
+            app:layout_constraintBottom_toBottomOf="@id/v_evaluate"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@id/v_evaluate"
+            app:layout_constraintTop_toTopOf="@id/v_evaluate" />
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/cl_input"
+            android:layout_width="match_parent"
+            android:layout_height="90dp"
+            android:layout_marginHorizontal="16dp"
+            android:layout_marginTop="12dp"
+            android:background="@drawable/common_input_edit_bg"
+            android:paddingHorizontal="12dp"
+            android:paddingVertical="8dp"
+            app:layout_constraintTop_toBottomOf="@id/v_evaluate">
+
+            <androidx.appcompat.widget.AppCompatEditText
+                android:id="@+id/et_input"
+                android:layout_width="0dp"
+                android:layout_height="36dp"
+                android:background="@null"
+                android:fontFamily="@font/poppins_semibold"
+                android:gravity="start|center_vertical"
+                android:includeFontPadding="false"
+                android:textColor="@color/color_FF1D2129"
+                android:textColorHint="@color/color_FFC9CDD4"
+                android:textSize="14sp"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent" />
+
+            <androidx.appcompat.widget.AppCompatTextView
+                android:id="@+id/tv_input_count"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:gravity="end|center"
+                android:includeFontPadding="false"
+                android:textColor="@color/color_FFCDCFD9"
+                android:textSize="14sp"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                tools:text="0/200" />
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+        <com.adealink.weparty.commonui.widget.CommonButton
+            android:id="@+id/btn_submit"
+            android:layout_width="0dp"
+            android:layout_height="@dimen/common_button_height"
+            android:layout_marginHorizontal="16dp"
+            android:layout_marginTop="16dp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/cl_input"
+            app:text="@string/common_submit"
+            app:textSize="16sp" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <com.adealink.weparty.commonui.imageview.AvatarView
+        android:id="@+id/iv_avatar"
+        android:layout_width="60dp"
+        android:layout_height="60dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:roundingBorderColor="@color/white"
+        app:roundingBorderWidth="1dp" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 69 - 112
module/order/src/main/res/layout/layout_order_list_item.xml → module/order/src/main/res/layout/layout_playmate_order_list_item.xml

@@ -19,7 +19,7 @@
         app:layout_constraintTop_toTopOf="parent">
 
         <androidx.appcompat.widget.AppCompatTextView
-            android:id="@+id/tv_order_id"
+            android:id="@+id/tv_time"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:includeFontPadding="false"
@@ -28,23 +28,20 @@
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent"
-            tools:text="订单号: 12345656" />
+            tools:text="20/12/2025" />
 
         <androidx.appcompat.widget.AppCompatTextView
             android:id="@+id/tv_order_status"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:background="@drawable/order_status_in_progress_bg"
             android:fontFamily="@font/poppins_semibold"
             android:includeFontPadding="false"
-            android:paddingHorizontal="6dp"
-            android:paddingVertical="3dp"
-            android:textColor="@color/white"
-            android:textSize="11sp"
+            android:textSize="12sp"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintTop_toTopOf="parent"
-            tools:text="进行中" />
+            tools:text="进行中"
+            tools:textColor="@color/color_FFFFB836" />
 
         <View
             android:layout_width="match_parent"
@@ -64,9 +61,9 @@
 
         <com.adealink.weparty.commonui.imageview.AvatarView
             android:id="@+id/iv_avatar"
-            android:layout_width="40dp"
-            android:layout_height="40dp"
-            android:layout_marginTop="6dp"
+            android:layout_width="36dp"
+            android:layout_height="36dp"
+            android:layout_marginTop="10dp"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent" />
 
@@ -81,7 +78,7 @@
             android:includeFontPadding="false"
             android:singleLine="true"
             android:textColor="@color/color_FF1D2129"
-            android:textSize="18sp"
+            android:textSize="14sp"
             app:layout_constrainedWidth="true"
             app:layout_constraintEnd_toStartOf="@id/cl_right"
             app:layout_constraintHorizontal_bias="0"
@@ -164,115 +161,75 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@id/cl_order_info">
 
-        <!-- 订单进行中 -->
-        <androidx.constraintlayout.widget.ConstraintLayout
-            android:id="@+id/cl_order_in_progress"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:visibility="gone"
-            app:layout_constraintBottom_toTopOf="@id/cl_order_finish"
+        <!-- 完成订单 -->
+        <com.adealink.weparty.commonui.widget.CommonButton
+            android:id="@+id/btn_finish"
+            android:layout_width="wrap_content"
+            android:layout_height="30dp"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:minWidth="80dp"
+            android:paddingHorizontal="6dp"
+            app:layout_constraintBottom_toTopOf="@id/btn_cancel"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent"
             app:layout_constraintVertical_chainStyle="packed"
-            tools:visibility="visible">
-            <!-- 完成订单 -->
-            <androidx.appcompat.widget.AppCompatTextView
-                android:id="@+id/btn_finish"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:background="@drawable/order_button_finish_bg"
-                android:gravity="center"
-                android:includeFontPadding="false"
-                android:minWidth="60dp"
-                android:paddingHorizontal="6dp"
-                android:paddingVertical="3dp"
-                android:text="@string/order_btn_finish"
-                android:textColor="@color/white"
-                android:textSize="12sp"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toTopOf="parent" />
+            app:text="@string/order_btn_finish"
+            app:textColor="@color/white"
+            app:textSize="12sp" />
 
-            <!-- 退款 -->
-            <androidx.appcompat.widget.AppCompatTextView
-                android:id="@+id/btn_refund"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:background="@drawable/order_button_refund_bg"
-                android:gravity="center"
-                android:includeFontPadding="false"
-                android:minWidth="60dp"
-                android:paddingHorizontal="6dp"
-                android:paddingVertical="3dp"
-                android:text="@string/order_btn_refund"
-                android:textColor="@color/color_FF86909C"
-                android:textSize="12sp"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintStart_toEndOf="@id/btn_finish"
-                app:layout_constraintTop_toTopOf="parent" />
-
-        </androidx.constraintlayout.widget.ConstraintLayout>
-
-        <!-- 订单已完成 -->
-        <androidx.constraintlayout.widget.ConstraintLayout
-            android:id="@+id/cl_order_finish"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:visibility="gone"
-            app:layout_constraintBottom_toTopOf="@id/cl_order_cancel"
+        <!-- 取消订单 -->
+        <com.adealink.weparty.commonui.widget.CommonButton
+            android:id="@+id/btn_cancel"
+            android:layout_width="wrap_content"
+            android:layout_height="30dp"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:minWidth="80dp"
+            android:paddingHorizontal="6dp"
+            app:common_button_type="cancel"
+            app:layout_constraintBottom_toTopOf="@id/btn_evaluate"
             app:layout_constraintStart_toStartOf="parent"
-            tools:layout_constraintTop_toBottomOf="@id/cl_order_in_progress"
-            tools:visibility="visible">
-
-            <!-- 去评价 -->
-            <androidx.appcompat.widget.AppCompatTextView
-                android:id="@+id/btn_evaluate"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:background="@drawable/order_button_evaluate_bg"
-                android:gravity="center"
-                android:includeFontPadding="false"
-                android:minWidth="60dp"
-                android:paddingHorizontal="6dp"
-                android:paddingVertical="3dp"
-                android:text="@string/order_btn_evaluate"
-                android:textColor="@color/color_FF3FBFBD"
-                android:textSize="12sp"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toTopOf="parent" />
+            app:layout_constraintTop_toBottomOf="@id/btn_finish"
+            app:text="@string/commonui_cancel"
+            app:textColor="@color/white"
+            app:textSize="12sp" />
 
-        </androidx.constraintlayout.widget.ConstraintLayout>
+        <!-- 去评价 -->
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/btn_evaluate"
+            android:layout_width="wrap_content"
+            android:layout_height="30dp"
+            android:background="@drawable/order_button_evaluate_bg"
+            android:fontFamily="@font/poppins_semibold"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:minWidth="80dp"
+            android:paddingHorizontal="6dp"
+            android:paddingVertical="3dp"
+            android:text="@string/order_btn_evaluate"
+            android:textColor="@color/color_FF3FBFBD"
+            android:textSize="12sp"
+            app:layout_constraintBottom_toTopOf="@id/tv_refunded"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/btn_cancel" />
 
-        <!-- 订单已取消/退款 -->
-        <androidx.constraintlayout.widget.ConstraintLayout
-            android:id="@+id/cl_order_cancel"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:visibility="gone"
+        <!-- 退款 -->
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_refunded"
+            android:layout_width="wrap_content"
+            android:layout_height="30dp"
+            android:gravity="start|center_vertical"
+            android:includeFontPadding="false"
+            android:minWidth="80dp"
+            android:paddingHorizontal="6dp"
+            android:paddingVertical="3dp"
+            android:text="@string/order_refunded_success"
+            android:textColor="@color/color_FF86909C"
+            android:textSize="11sp"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@id/cl_order_finish"
-            tools:visibility="visible">
-
-            <!-- 删除 -->
-            <androidx.appcompat.widget.AppCompatTextView
-                android:id="@+id/btn_cancel"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:background="@drawable/order_button_refund_bg"
-                android:gravity="center"
-                android:includeFontPadding="false"
-                android:minWidth="60dp"
-                android:paddingHorizontal="6dp"
-                android:paddingVertical="3dp"
-                android:text="@string/order_btn_remove"
-                android:textColor="@color/color_FF86909C"
-                android:textSize="12sp"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toTopOf="parent" />
-        </androidx.constraintlayout.widget.ConstraintLayout>
+            app:layout_constraintTop_toBottomOf="@id/btn_evaluate" />
 
         <androidx.appcompat.widget.AppCompatTextView
             android:id="@+id/tv_order_all_cost"

+ 248 - 0
module/order/src/main/res/layout/layout_user_order_list_item.xml

@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/order_list_item_bg"
+    android:paddingHorizontal="12dp"
+    android:paddingTop="6dp"
+    android:paddingBottom="8dp">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_top"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:minHeight="32dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_time"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:includeFontPadding="false"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="11sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:text="20/12/2025" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_order_status"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:fontFamily="@font/poppins_semibold"
+            android:includeFontPadding="false"
+            android:textSize="12sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:text="进行中"
+            tools:textColor="@color/color_FFFFB836" />
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="0.5dp"
+            android:background="@color/color_FFF2F3F5"
+            app:layout_constraintBottom_toBottomOf="parent" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_order_info"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/cl_top">
+
+        <com.adealink.weparty.commonui.imageview.AvatarView
+            android:id="@+id/iv_avatar"
+            android:layout_width="36dp"
+            android:layout_height="36dp"
+            android:layout_marginTop="10dp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="8dp"
+            android:layout_marginEnd="40dp"
+            android:ellipsize="end"
+            android:fontFamily="@font/poppins_semibold"
+            android:includeFontPadding="false"
+            android:singleLine="true"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintEnd_toStartOf="@id/cl_right"
+            app:layout_constraintHorizontal_bias="0"
+            app:layout_constraintHorizontal_chainStyle="packed"
+            app:layout_constraintStart_toEndOf="@id/iv_avatar"
+            app:layout_constraintTop_toTopOf="@id/iv_avatar"
+            app:layout_constraintVertical_chainStyle="packed"
+            tools:text="Super Beautiful Girl Super Beautiful Girl Super Beautiful Girl" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_desc"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="40dp"
+            android:ellipsize="end"
+            android:includeFontPadding="false"
+            android:singleLine="true"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="12sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintBottom_toBottomOf="@id/iv_avatar"
+            app:layout_constraintEnd_toStartOf="@id/cl_right"
+            app:layout_constraintHorizontal_bias="0"
+            app:layout_constraintStart_toStartOf="@id/tv_name"
+            app:layout_constraintTop_toBottomOf="@id/tv_name"
+            tools:text="LOL Mobile" />
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/cl_right"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            app:layout_constraintBottom_toBottomOf="@id/iv_avatar"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="@id/iv_avatar">
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:layout_width="14dp"
+                android:layout_height="14dp"
+                android:layout_marginEnd="2dp"
+                app:layout_constraintBottom_toBottomOf="@id/tv_price"
+                app:layout_constraintEnd_toStartOf="@id/tv_price"
+                app:layout_constraintTop_toTopOf="@id/tv_price"
+                app:srcCompat="@drawable/common_wallet_coin_16_ic" />
+
+            <androidx.appcompat.widget.AppCompatTextView
+                android:id="@+id/tv_price"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:includeFontPadding="false"
+                android:textColor="@color/color_FF1D2129"
+                android:textSize="12sp"
+                app:layout_constraintBottom_toTopOf="@id/tv_count"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                tools:text="16000" />
+
+            <androidx.appcompat.widget.AppCompatTextView
+                android:id="@+id/tv_count"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:includeFontPadding="false"
+                android:textColor="@color/color_FF1D2129"
+                android:textSize="12sp"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintTop_toBottomOf="@id/tv_price"
+                tools:text="x1" />
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_bottom"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:minHeight="40dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/cl_order_info">
+
+        <!-- 完成订单 -->
+        <com.adealink.weparty.commonui.widget.CommonButton
+            android:id="@+id/btn_complete"
+            android:layout_width="wrap_content"
+            android:layout_height="30dp"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:minWidth="80dp"
+            android:paddingHorizontal="6dp"
+            app:layout_constraintBottom_toTopOf="@id/btn_cancel"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_chainStyle="packed"
+            app:text="@string/order_btn_finish"
+            app:textColor="@color/white"
+            app:textSize="12sp" />
+
+        <!-- 取消订单 -->
+        <com.adealink.weparty.commonui.widget.CommonButton
+            android:id="@+id/btn_cancel"
+            android:layout_width="wrap_content"
+            android:layout_height="30dp"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:minWidth="80dp"
+            android:paddingHorizontal="6dp"
+            app:common_button_type="cancel"
+            app:layout_constraintBottom_toTopOf="@id/btn_evaluate"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/btn_complete"
+            app:text="@string/commonui_cancel"
+            app:textColor="@color/white"
+            app:textSize="12sp" />
+
+        <!-- 去评价 -->
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/btn_evaluate"
+            android:layout_width="wrap_content"
+            android:layout_height="30dp"
+            android:background="@drawable/order_button_evaluate_bg"
+            android:fontFamily="@font/poppins_semibold"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:minWidth="80dp"
+            android:paddingHorizontal="6dp"
+            android:paddingVertical="3dp"
+            android:text="@string/order_btn_evaluate"
+            android:textColor="@color/color_FF3FBFBD"
+            android:textSize="12sp"
+            app:layout_constraintBottom_toTopOf="@id/tv_refunded"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/btn_cancel" />
+
+        <!-- 退款 -->
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_refunded"
+            android:layout_width="wrap_content"
+            android:layout_height="30dp"
+            android:gravity="start|center_vertical"
+            android:includeFontPadding="false"
+            android:minWidth="80dp"
+            android:paddingHorizontal="6dp"
+            android:paddingVertical="3dp"
+            android:text="@string/order_refunded_success"
+            android:textColor="@color/color_FF86909C"
+            android:textSize="11sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/btn_evaluate" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_order_all_cost"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:includeFontPadding="false"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="12sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:text="共计: 16000" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 18 - 2
module/order/src/main/res/values/strings.xml

@@ -1,13 +1,29 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
     <string name="order_list_title">我的订单</string>
-    <string name="order_btn_finish">完成订单</string>
+    <string name="order_btn_finish">完成</string>
     <string name="order_btn_refund">退款</string>
     <string name="order_btn_evaluate">评价</string>
-    <string name="order_btn_remove">删除</string>
+    <string name="order_refunded_success">金额已退还至您的钱包</string>
     <string name="order_detail_title">我的订单</string>
     <string name="order_product_type">产品类型</string>
     <string name="order_buy_count">购买数量</string>
     <string name="order_id">订单编号</string>
     <string name="order_time">购买时间</string>
+
+    <string name="user_order_status_refund_under_review_desc">退款审核中</string>
+    <string name="user_order_status_create_order_desc">等待处理</string>
+    <string name="user_order_status_wait_accept_desc">订单已接受</string>
+    <string name="user_order_status_accept_desc">已接受</string>
+    <string name="user_order_status_in_service_desc">服务中</string>
+    <string name="user_order_status_end_service_desc">服务完成</string>
+    <string name="user_order_status_playmate_refuse_desc">拒绝</string>
+    <string name="user_order_status_complete_desc">完成</string>
+    <string name="user_order_status_user_refund_desc">接单</string>
+    <string name="user_order_status_user_cancel_desc">取消</string>
+
+    <string name="order_all_cost">共计[currency]%s</string>
+    <string name="order_evaluate_title">您对陪玩师满意吗?</string>
+    <string name="order_evaluate_left_title">Overall</string>
+    <string name="order_evaluate_right_title">Rate</string>
 </resources>

+ 26 - 0
module/profile/src/main/java/com/adealink/weparty/profile/me/comp/MeFunctionCenterComp.kt

@@ -2,26 +2,35 @@ package com.adealink.weparty.profile.me.comp
 
 import androidx.lifecycle.LifecycleOwner
 import com.adealink.frame.mvvm.view.ViewComponent
+import com.adealink.frame.mvvm.viewmodel.activityViewModels
 import com.adealink.frame.router.Router
 import com.adealink.frame.util.onClick
+import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.module.order.Order
 import com.adealink.weparty.module.setting.Setting
 import com.adealink.weparty.profile.databinding.LayoutMeFunctionBinding
+import com.adealink.weparty.profile.viewmodel.ProfileViewModel
 
 class MeFunctionCenterComp(
     lifecycleOwner: LifecycleOwner,
     val binding: LayoutMeFunctionBinding
 ) : ViewComponent(lifecycleOwner) {
 
+    private val profileViewModel by activityViewModels<ProfileViewModel>()
+
     override fun onCreate() {
         super.onCreate()
         initView()
+        observeViewModel()
     }
 
     private fun initView() {
         binding.clOrder.onClick {
             goOrderList()
         }
+        binding.clPlaymateOrder.onClick {
+            goPlaymateOrderList()
+        }
         binding.clHelpCenter.onClick {
             goHelpCenter()
         }
@@ -30,12 +39,29 @@ class MeFunctionCenterComp(
         }
     }
 
+    private fun observeViewModel() {
+        profileViewModel.userInfoLD.observe(viewLifecycleOwner) {
+//            if(it?.isPlaymate() == true){
+//                binding.clPlaymateOrder.show()
+//            }else{
+//                binding.clPlaymateOrder.gone()
+//            }
+            binding.clPlaymateOrder.show()
+        }
+    }
+
     private fun goOrderList() {
         activity?.let { act ->
             Router.build(act, Order.List.PATH).start()
         }
     }
 
+    private fun goPlaymateOrderList() {
+        activity?.let { act ->
+            Router.build(act, Order.PlaymateList.PATH).start()
+        }
+    }
+
     private fun goHelpCenter() {
         activity?.let { act ->
             Router.build(act, Setting.HelpCenter.PATH).start()

BIN
module/profile/src/main/res/drawable-xhdpi/profile_me_order_record_ic.png


BIN
module/profile/src/main/res/drawable-xhdpi/profile_order_all_list_ic.png


BIN
module/profile/src/main/res/drawable-xhdpi/profile_order_finish_list_ic.png


BIN
module/profile/src/main/res/drawable-xhdpi/profile_order_pay_list_ic.png


BIN
module/profile/src/main/res/drawable-xhdpi/profile_order_refund_list_ic.png


+ 44 - 3
module/profile/src/main/res/layout/layout_me_function.xml

@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="@drawable/profile_me_item_bg"
@@ -19,14 +20,14 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
 
-    <!--订单-->
+    <!--我的订单-->
     <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/cl_order"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:paddingTop="10dp"
         android:paddingBottom="16dp"
-        app:layout_constraintEnd_toStartOf="@id/cl_help_center"
+        app:layout_constraintEnd_toStartOf="@id/cl_playmate_order"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@id/tv_wallet">
 
@@ -57,6 +58,46 @@
 
     </androidx.constraintlayout.widget.ConstraintLayout>
 
+    <!--接单记录-->
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_playmate_order"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:paddingTop="10dp"
+        android:paddingBottom="16dp"
+        android:visibility="gone"
+        app:layout_constraintEnd_toStartOf="@id/cl_help_center"
+        app:layout_constraintStart_toEndOf="@id/cl_order"
+        app:layout_constraintTop_toBottomOf="@id/tv_wallet"
+        tools:visibility="visible">
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:layout_width="24dp"
+            android:layout_height="24dp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/profile_me_order_record_ic" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="4dp"
+            android:layout_marginTop="32dp"
+            android:ellipsize="end"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:singleLine="true"
+            android:text="@string/profile_playmate_order"
+            android:textColor="@color/color_FF4E5969"
+            android:textSize="12sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
     <!--帮助中心-->
     <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/cl_help_center"
@@ -65,7 +106,7 @@
         android:paddingTop="10dp"
         android:paddingBottom="16dp"
         app:layout_constraintEnd_toStartOf="@id/cl_setting"
-        app:layout_constraintStart_toEndOf="@id/cl_order"
+        app:layout_constraintStart_toEndOf="@id/cl_playmate_order"
         app:layout_constraintTop_toBottomOf="@id/tv_wallet">
 
         <androidx.appcompat.widget.AppCompatImageView

+ 1 - 0
module/profile/src/main/res/values/strings.xml

@@ -12,6 +12,7 @@
     <string name="profile_me_share_your_qrcode">Share your QR Code</string>
     <string name="profile_wallet">My Wallet</string>
     <string name="profile_order">My Order</string>
+    <string name="profile_playmate_order">Order Record</string>
     <string name="profile_order_pay_list">待付款</string>
     <string name="profile_order_finish_list">已经完成</string>
     <string name="profile_order_refund_list">退款</string>