张田田 2 miesięcy temu
rodzic
commit
427bd59847
24 zmienionych plików z 2238 dodań i 1 usunięć
  1. 6 1
      miniprogram/app.json
  2. 9 0
      miniprogram/module/order/pages/goods-evaluate/goods-evaluate.json
  3. 215 0
      miniprogram/module/order/pages/goods-evaluate/goods-evaluate.scss
  4. 123 0
      miniprogram/module/order/pages/goods-evaluate/goods-evaluate.ts
  5. 69 0
      miniprogram/module/order/pages/goods-evaluate/goods-evaluate.wxml
  6. 8 0
      miniprogram/module/order/pages/goods-evaluateDetail/goods-evaluateDetail.json
  7. 350 0
      miniprogram/module/order/pages/goods-evaluateDetail/goods-evaluateDetail.scss
  8. 106 0
      miniprogram/module/order/pages/goods-evaluateDetail/goods-evaluateDetail.ts
  9. 57 0
      miniprogram/module/order/pages/goods-evaluateDetail/goods-evaluateDetail.wxml
  10. 8 0
      miniprogram/module/order/pages/offline-evaluate/offline-evaluate.json
  11. 240 0
      miniprogram/module/order/pages/offline-evaluate/offline-evaluate.scss
  12. 165 0
      miniprogram/module/order/pages/offline-evaluate/offline-evaluate.ts
  13. 104 0
      miniprogram/module/order/pages/offline-evaluate/offline-evaluate.wxml
  14. 8 0
      miniprogram/module/order/pages/offline-evaluateDetail/offline-evaluateDetail.json
  15. 413 0
      miniprogram/module/order/pages/offline-evaluateDetail/offline-evaluateDetail.scss
  16. 112 0
      miniprogram/module/order/pages/offline-evaluateDetail/offline-evaluateDetail.ts
  17. 120 0
      miniprogram/module/order/pages/offline-evaluateDetail/offline-evaluateDetail.wxml
  18. 29 0
      miniprogram/module/order/pages/other-detail/other-detail.scss
  19. 39 0
      miniprogram/module/order/pages/other-detail/other-detail.ts
  20. 15 0
      miniprogram/module/order/pages/other-detail/other-detail.wxml
  21. 7 0
      miniprogram/module/order/pages/test/test.json
  22. 11 0
      miniprogram/module/order/pages/test/test.scss
  23. 17 0
      miniprogram/module/order/pages/test/test.ts
  24. 7 0
      miniprogram/module/order/pages/test/test.wxml

+ 6 - 1
miniprogram/app.json

@@ -95,7 +95,12 @@
         "pages/other-detail/other-detail",
         "pages/confirme-order/confirme-order",
         "pages/appointment/appointment",
-        "pages/appointment-success/appointment-success"
+        "pages/appointment-success/appointment-success",
+        "pages/goods-evaluate/goods-evaluate",
+        "pages/goods-evaluateDetail/goods-evaluateDetail",
+        "pages/offline-evaluate/offline-evaluate",
+        "pages/offline-evaluateDetail/offline-evaluateDetail",
+        "pages/test/test"
       ]
     }
   ],

+ 9 - 0
miniprogram/module/order/pages/goods-evaluate/goods-evaluate.json

@@ -0,0 +1,9 @@
+{
+  "renderer": "skyline",
+  "usingComponents": {
+    "t-navbar": "tdesign-miniprogram/navbar/navbar",
+    "t-icon": "tdesign-miniprogram/icon/icon",
+    "t-rate": "tdesign-miniprogram/rate/rate",
+    "van-rate": "@vant/weapp/rate/index"
+  }
+}

+ 215 - 0
miniprogram/module/order/pages/goods-evaluate/goods-evaluate.scss

@@ -0,0 +1,215 @@
+@import "../../../../themes/page.scss";
+
+.page-scroll__container {
+  flex: 0 1 auto;
+  height: var(--page-container-safeHeight, 100vh);
+  background: #f7f8fa;
+  padding-bottom: 140rpx;
+}
+
+.evaluate-container {
+  background: #fff;
+  margin: 24rpx;
+  border-radius: 16rpx;
+  padding: 32rpx;
+}
+
+.product-card {
+  display: flex;
+  align-items: center;
+  padding-bottom: 32rpx;
+  margin-bottom: 24rpx;
+  border-bottom: 1rpx solid #eee;
+}
+
+.product-img {
+  width: 120rpx;
+  height: 120rpx;
+  border-radius: 12rpx;
+  background: #f5f5f5;
+  flex-shrink: 0;
+}
+
+.product-info {
+  flex: 1;
+  margin-left: 24rpx;
+  min-width: 0;
+  display: flex;
+  flex-direction: column;
+  gap: 8rpx;
+}
+
+.product-name {
+  font-size: 30rpx;
+  color: #333;
+  font-weight: 500;
+}
+
+.product-spec {
+  font-size: 26rpx;
+  color: #999;
+}
+
+.product-close {
+  flex-shrink: 0;
+  padding: 16rpx;
+}
+
+.rate-row {
+  display: flex;
+  align-items: center;
+  // justify-content: space-between;
+  margin-bottom: 32rpx;
+}
+
+.rate-label {
+  font-size: 30rpx;
+  color: #333;
+  margin-right: 20px;
+}
+
+.rate-wrap {
+  display: flex;
+  align-items: center;
+  gap: 16rpx;
+}
+
+.rate-score {
+  font-size: 26rpx;
+  color: #999;
+  min-width: 48rpx;
+  margin-left: 20px;
+}
+
+.comment-section {
+  position: relative;
+  margin-bottom: 32rpx;
+}
+
+.comment-input {
+  width: 100%;
+  min-height: 200rpx;
+  padding: 24rpx;
+  font-size: 28rpx;
+  color: #333;
+  background: #f7f8fa;
+  border-radius: 12rpx;
+  box-sizing: border-box;
+}
+
+.comment-placeholder {
+  color: #999;
+}
+
+.comment-count {
+  position: absolute;
+  top: 24rpx;
+  right: 24rpx;
+  font-size: 24rpx;
+  color: #999;
+}
+
+.upload-section {
+  margin-bottom: 24rpx;
+}
+
+/* 一行 4 个,文件之间 24rpx 缝隙 */
+.media-grid {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 24rpx;
+}
+
+.media-item {
+  position: relative;
+  width: 142rpx;
+  height: 142rpx;
+  flex-shrink: 0;
+  border-radius: 12rpx;
+  overflow: hidden;
+  background: #f5f5f5;
+  margin-right: 5px;
+  margin-bottom: 10px;
+}
+
+.upload-trigger {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  width: 142rpx;
+  height: 142rpx;
+  flex-shrink: 0;
+  background: #f7f8fa;
+  border-radius: 12rpx;
+  border: 2rpx dashed #ddd;
+}
+
+.upload-label {
+  font-size: 24rpx;
+  color: #999;
+  margin-top: 12rpx;
+}
+
+.media-thumb {
+  width: 100%;
+  height: 100%;
+  display: block;
+}
+
+.media-item-video {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .media-thumb {
+    display: block;
+  }
+}
+
+.media-item-play {
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  transform: translate(-50%, -50%);
+  pointer-events: none;
+}
+
+.media-delete {
+  position: absolute;
+  top: 0;
+  right: 0;
+  width: 48rpx;
+  height: 48rpx;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border-radius: 0 12rpx 0 12rpx;
+}
+
+.publish-footer {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background: #fff;
+  padding: 20rpx 32rpx;
+  box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
+  z-index: 100;
+}
+
+.publish-btn {
+  height: 88rpx;
+  line-height: 88rpx;
+  text-align: center;
+  font-size: 32rpx;
+  font-weight: 500;
+  color: #fff;
+  background: #1976d2;
+  border-radius: 44rpx;
+}
+
+.publish-btn.disabled {
+  background: #e8e8e8;
+  color: #999;
+}

+ 123 - 0
miniprogram/module/order/pages/goods-evaluate/goods-evaluate.ts

@@ -0,0 +1,123 @@
+import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
+
+Page({
+  behaviors: [PageContainerBehavior],
+  data: {
+    orderId: "",
+    product: {} as { name: string; image: string; description?: string },
+    score: 0,
+    rateColor: "#F7BA2A",
+    content: "",
+    mediaList: [] as { path: string; type: "image" | "video" }[],
+    canPublish: false,
+    videoFullscreen: false,
+  },
+  onLoad(options: Record<string, string>) {
+    console.log(options, "options===");
+    // const orderId = options.orderId || options.id || "";
+    let product: { name: string; image: string; description?: string } = {
+      name: "",
+      image: "",
+      description: "",
+    };
+    if (options.goodsInfo) {
+        const goods = JSON.parse(decodeURIComponent(options.goodsInfo));
+        product = {
+          name: goods.name || "",
+          image: goods.image || "",
+          description: goods.description || "",
+        };
+    }
+    this.setData({
+      // orderId,
+      product,
+      canPublish: this._checkCanPublish(0, ""),
+    });
+  },
+  _checkCanPublish(score: number, _content: string): boolean {
+    return score > 0;
+  },
+  onScoreChange(e: WechatMiniprogram.CustomEvent<{ value: number }>) {
+    const score = e.detail?.value ?? 0;
+    this.setData({
+      score,
+      canPublish: this._checkCanPublish(score, this.data.content),
+    });
+  },
+  onContentInput(e: WechatMiniprogram.Input) {
+    const content = e.detail?.value ?? "";
+    this.setData({
+      content,
+      canPublish: this._checkCanPublish(this.data.score, content),
+    });
+  },
+  onChooseMedia() {
+    const current = this.data.mediaList.length;
+    if (current >= 9) {
+      wx.showToast({ title: "图片和视频总数不能超过9个", icon: "none" });
+      return;
+    }
+    const remain = 9 - current;
+    wx.chooseMedia({
+      count: remain,
+      mediaType: ["image", "video"],
+      sourceType: ["album", "camera"],
+      maxDuration: 30,
+      camera: "back",
+      success: (res) => {
+        const list = res.tempFiles.map((f) => ({
+          path: f.tempFilePath,
+          type: (f.fileType === "video" ? "video" : "image") as "image" | "video",
+        }));
+        const next = [...this.data.mediaList, ...list].slice(0, 9);
+        this.setData({ mediaList: next });
+      },
+    });
+  },
+  onRemoveMedia(e: WechatMiniprogram.TouchEvent) {
+    const index = e.currentTarget.dataset.index as number;
+    const mediaList = this.data.mediaList.filter((_, i) => i !== index);
+    this.setData({ mediaList });
+  },
+  onPreviewImage(e: WechatMiniprogram.TouchEvent) {
+    const url = e.currentTarget.dataset.url as string;
+    const urls = this.data.mediaList.filter((m) => m.type === "image").map((m) => m.path);
+    if (url && urls.length) {
+      wx.previewImage({ current: url, urls });
+    }
+  },
+  onPreviewVideo(e: WechatMiniprogram.TouchEvent) {
+    const index = e.currentTarget.dataset.index as number;
+    const videoContext = wx.createVideoContext("goods-video-" + index, this);
+    videoContext.requestFullScreen({});
+  },
+  onVideoFullscreenChange(e: WechatMiniprogram.VideoFullScreenChange) {
+    const fullScreen = !!(e.detail && e.detail.fullScreen);
+    this.setData({ videoFullscreen: fullScreen });
+  },
+  onRemoveProduct() {
+    this.setData({
+      product: { name: "", image: "", description: "" },
+    });
+  },
+  onPublish() {
+    if (!this.data.canPublish) {
+      wx.showToast({ title: "请先完成评分", icon: "none" });
+      return;
+    }
+    const { orderId } = this.data;
+    // TODO: 调用评价提交接口,将 this.data.score、content、mediaList 上传
+    wx.showLoading({ title: "发布中..." });
+    setTimeout(() => {
+      wx.hideLoading();
+      wx.showToast({ title: "发布成功", icon: "success" });
+      if (orderId) {
+        wx.redirectTo({
+          url: `/module/order/pages/other-detail/other-detail?id=${orderId}`,
+        });
+      } else {
+        wx.navigateBack();
+      }
+    }, 500);
+  },
+});

+ 69 - 0
miniprogram/module/order/pages/goods-evaluate/goods-evaluate.wxml

@@ -0,0 +1,69 @@
+<!--module/order/pages/evaluate/evaluate.wxml 评价页-->
+<t-navbar wx:if="{{!videoFullscreen}}" title="评价" left-arrow />
+<scroll-view class="page-scroll__container" type="list" scroll-y style="{{containerStyle}}">
+  <view class="evaluate-container">
+    <!-- 商品信息 -->
+    <view class="product-card" wx:if="{{product.name}}">
+      <image class="product-img" src="{{product.image}}" mode="aspectFill" />
+      <view class="product-info">
+        <text class="product-name">{{product.name}}</text>
+        <text class="product-spec" wx:if="{{product.spec}}">{{product.spec}}</text>
+      </view>
+    </view>
+
+    <!-- 描述相符 评分(半星) -->
+    <view class="rate-row">
+      <text class="rate-label">描述相符</text>
+      <view class="rate-wrap">
+        <t-rate
+          value="{{score}}"
+          count="{{5}}"
+          color="{{rateColor}}"
+          show-text="{{false}}"
+          placement=""
+          bind:change="onScoreChange"
+        />
+        <text class="rate-score">{{score || '0'}}分</text>
+      </view>
+    </view>
+
+    <!-- 评价输入 -->
+    <view class="comment-section">
+      <textarea
+        class="comment-input"
+        placeholder="展开说说对商品的想法吧"
+        placeholder-class="comment-placeholder"
+        value="{{content}}"
+        bindinput="onContentInput"
+        maxlength="{{500}}"
+        show-confirm-bar="{{false}}"
+      />
+      <view class="comment-count" wx:if="{{content.length > 0}}">{{content.length}}/500</view>
+    </view>
+
+    <!-- 图/视频 上传(图片+视频总数不超过9个,添加按钮在最后,一行4个) -->
+    <view class="upload-section">
+      <view class="media-grid">
+        <view class="media-item" wx:for="{{mediaList}}" wx:key="path">
+          <image wx:if="{{item.type === 'image'}}" class="media-thumb" src="{{item.path}}" mode="aspectFill" bindtap="onPreviewImage" data-url="{{item.path}}" />
+          <view wx:else class="media-item-video" bindtap="onPreviewVideo" data-index="{{index}}">
+            <video id="goods-video-{{index}}" class="media-thumb" src="{{item.path}}" show-center-play-btn="{{true}}" object-fit="cover" controls="{{true}}" bindfullscreenchange="onVideoFullscreenChange" />
+            <view class="media-item-play"><t-icon name="play-circle-filled" size="56rpx" color="rgba(255,255,255,0.95)" /></view>
+          </view>
+          <view class="media-delete" catchtap="onRemoveMedia" data-index="{{index}}">
+            <t-icon name="close" size="32rpx" color="#fff" />
+          </view>
+        </view>
+        <view class="upload-trigger" wx:if="{{mediaList.length < 9}}" bindtap="onChooseMedia">
+          <t-icon name="add" size="48rpx" color="#999" />
+          <text class="upload-label">图/视频</text>
+        </view>
+      </view>
+    </view>
+  </view>
+</scroll-view>
+
+<!-- 发布按钮(视频全屏时隐藏,避免遮挡进度条) -->
+<view class="publish-footer" wx:if="{{!videoFullscreen}}" style="padding-bottom: {{container.safeBottomOffset}}px;">
+  <view class="publish-btn {{canPublish ? '' : 'disabled'}}" bindtap="onPublish">发布</view>
+</view>

+ 8 - 0
miniprogram/module/order/pages/goods-evaluateDetail/goods-evaluateDetail.json

@@ -0,0 +1,8 @@
+{
+  "renderer": "skyline",
+  "usingComponents": {
+    "t-navbar": "tdesign-miniprogram/navbar/navbar",
+    "t-icon": "tdesign-miniprogram/icon/icon",
+    "t-rate": "tdesign-miniprogram/rate/rate"
+  }
+}

+ 350 - 0
miniprogram/module/order/pages/goods-evaluateDetail/goods-evaluateDetail.scss

@@ -0,0 +1,350 @@
+@import "../../../../themes/page.scss";
+
+.page-scroll__container {
+  flex: 0 1 auto;
+  height: var(--page-container-safeHeight, 100vh);
+  background: #f7f8fa;
+  padding-bottom: 140rpx;
+}
+
+.evaluate-container {
+  background: #fff;
+  margin: 24rpx;
+  border-radius: 16rpx;
+  padding: 32rpx;
+}
+
+.product-card {
+  position: relative;
+  display: flex;
+  align-items: center;
+  padding-bottom: 32rpx;
+  margin-bottom: 24rpx;
+  border-bottom: 1rpx solid #eee;
+}
+
+.product-img {
+  width: 120rpx;
+  height: 120rpx;
+  border-radius: 12rpx;
+  background: #f5f5f5;
+  flex-shrink: 0;
+}
+
+.product-info {
+  flex: 1;
+  margin-left: 24rpx;
+  min-width: 0;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.product-name-row {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+  gap: 8rpx;
+}
+
+.product-name {
+  font-size: 30rpx;
+  color: #333;
+  font-weight: 500;
+}
+
+.product-divider {
+  font-size: 28rpx;
+  color: #dcdcdc;
+  margin: 0 30rpx;
+}
+
+.product-spec {
+  font-size: 26rpx;
+  color: #999;
+}
+
+.product-close {
+  position: absolute;
+  top: 0;
+  right: 0;
+  padding: 16rpx;
+  z-index: 1;
+}
+
+.rate-row {
+  display: flex;
+  align-items: center;
+  // justify-content: space-between;
+  margin-bottom: 32rpx;
+}
+
+.rate-label {
+  font-size: 30rpx;
+  color: #333;
+  margin-right: 20px;
+}
+
+.rate-wrap {
+  display: flex;
+  align-items: center;
+  gap: 16rpx;
+}
+
+.rate-score {
+  font-size: 28rpx;
+  color: #333;
+  min-width: 56rpx;
+  margin-left: 20px;
+}
+
+.comment-section {
+  position: relative;
+  margin-bottom: 32rpx;
+}
+
+.comment-display {
+  width: 100%;
+  min-height: 120rpx;
+  padding: 24rpx;
+  font-size: 28rpx;
+  color: #333;
+  background: #f7f8fa;
+  border-radius: 12rpx;
+  box-sizing: border-box;
+  line-height: 1.5;
+  white-space: pre-wrap;
+  word-break: break-all;
+}
+
+.comment-input {
+  width: 100%;
+  min-height: 200rpx;
+  padding: 24rpx;
+  font-size: 28rpx;
+  color: #333;
+  background: #f7f8fa;
+  border-radius: 12rpx;
+  box-sizing: border-box;
+}
+
+.comment-placeholder {
+  color: #999;
+}
+
+.comment-count {
+  position: absolute;
+  top: 24rpx;
+  right: 24rpx;
+  font-size: 24rpx;
+  color: #999;
+}
+
+.upload-section {
+  margin-bottom: 24rpx;
+}
+
+.upload-section .empty-media {
+  font-size: 26rpx;
+  color: #999;
+  margin-top: 8rpx;
+  display: block;
+}
+
+.section-label {
+  font-size: 28rpx;
+  color: #666;
+  margin-bottom: 16rpx;
+}
+
+.upload-row {
+  display: flex;
+  gap: 20rpx;
+  flex-wrap: wrap;
+}
+
+.upload-trigger {
+  display: inline-flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  width: 160rpx;
+  height: 160rpx;
+  border-radius: 12rpx;
+  border: 2rpx dashed #ddd;
+}
+
+.upload-trigger--image {
+  background: #f2f2f2;
+}
+
+.upload-trigger--video {
+  background: #4a4a4a;
+  border-color: #333;
+}
+
+.upload-label {
+  font-size: 26rpx;
+  color: #999;
+  margin-top: 12rpx;
+}
+
+.upload-label--light {
+  color: rgba(255, 255, 255, 0.9);
+}
+
+.upload-trigger .t-icon {
+  display: block;
+}
+
+/* 一行 4 个,与评价页一致 */
+.media-grid {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 24rpx;
+}
+
+.media-list--readonly .media-item {
+  .media-delete {
+    display: none;
+  }
+}
+
+.media-item {
+  position: relative;
+  width: 142rpx;
+  height: 142rpx;
+  flex-shrink: 0;
+  border-radius: 12rpx;
+  overflow: hidden;
+  background: #f5f5f5;
+  margin-right: 5px;
+  margin-bottom: 10px;
+}
+
+.media-thumb {
+  width: 100%;
+  height: 100%;
+  display: block;
+}
+
+.media-item-video {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .media-thumb {
+    display: block;
+  }
+}
+
+.media-item-play {
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  transform: translate(-50%, -50%);
+  pointer-events: none;
+}
+
+.media-delete {
+  position: absolute;
+  top: 0;
+  right: 0;
+  width: 48rpx;
+  height: 48rpx;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border-radius: 0 12rpx 0 12rpx;
+}
+
+.publish-footer {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background: #fff;
+  padding: 20rpx 32rpx;
+  box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
+  z-index: 100;
+}
+
+.publish-btn {
+  height: 88rpx;
+  line-height: 88rpx;
+  text-align: center;
+  font-size: 32rpx;
+  font-weight: 500;
+  color: #fff;
+  background: #1976d2;
+  border-radius: 44rpx;
+}
+
+.publish-btn.disabled {
+  background: #e8e8e8;
+  color: #999;
+}
+
+/* 全屏轮播层:图片+视频一起,轮播到视频自动播放 */
+.media-carousel-overlay {
+  position: fixed;
+  left: 0;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 1000;
+  background: #000;
+}
+
+.media-carousel-swiper {
+  width: 100%;
+  height: 100%;
+}
+
+.media-carousel-item {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.media-carousel-image-wrap {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.media-carousel-image {
+  width: 100%;
+  height: 100%;
+  display: block;
+  object-position: center;
+}
+
+.media-carousel-video-wrap {
+  width: 100%;
+  height: 100%;
+}
+
+.media-carousel-video {
+  width: 100%;
+  height: 100%;
+  display: block;
+}
+
+.media-carousel-close {
+  position: absolute;
+  top: calc(var(--status-bar-height, 0px) + 24rpx);
+  right: 24rpx;
+  width: 80rpx;
+  height: 80rpx;
+  border-radius: 50%;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 1001;
+}

+ 106 - 0
miniprogram/module/order/pages/goods-evaluateDetail/goods-evaluateDetail.ts

@@ -0,0 +1,106 @@
+import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
+
+Page({
+  behaviors: [PageContainerBehavior],
+  data: {
+    orderId: "",
+    product: {} as { name: string; image: string;  description?: string },
+    score: 5,
+    rateColor: "#F7BA2A",
+    content: "描述相符,商品质量很好,包装完整,会回购。",
+    mediaList: [] as { path: string; type: "image" | "video" }[],
+    videoFullscreen: false,
+    showMediaCarousel: false,
+    mediaCarouselCurrent: 0,
+  },
+  onLoad(options: Record<string, string>) {
+    const orderId = options.orderId || options.id || "";
+    let product: { name: string; image: string;  description?: string } = {
+      name: "",
+      image: "",
+      description: "",
+    };
+    console.log(options, "options.goodsInfo===");
+    if (options.goodsInfo) {
+      try {
+        const goods = JSON.parse(decodeURIComponent(options.goodsInfo));
+        product = {
+          name: goods.name || "",
+          image: goods.image || "",
+          description: goods.description || "",
+        };
+      } catch (_) {}
+    }
+console.log(product, "product===");
+    // 若传入评价详情数据则使用,否则用默认展示内容(含示例图片)
+    let score = 5;
+    let content = "描述相符,商品质量很好,包装完整,会回购。";
+    let mediaList: { path: string; type: "image" | "video" }[] = [
+      { path: "https://wx.hzliuzhi.com/media/healthManager/wx/share.jpg", type: "image" },
+      { path: "https://www.bing.com/ck/a?!&&p=7a26e0938030f722bac8864df3c965e36cf2569da9cb49288cb379ee8c3a662eJmltdHM9MTc3MjY2ODgwMA&ptn=3&ver=2&hsh=4&fclid=0f40599a-c9c4-6515-0a75-4f28c8bc64d0&u=a1L3ZpZGVvcy9yaXZlcnZpZXcvcmVsYXRlZHZpZGVvP3E9MTBzJWU4JWE3JTg2JWU5JWEyJTkxJiZtaWQ9MTcxMjQxNTk0MzFFQ0Y3OTFDNEExNzEyNDE1OTQzMUVDRjc5MUM0QSZGT1JNPVZBTUdaQw", type: "video" },
+      { path: "https://wx.hzliuzhi.com/media/healthManager/wx/share.jpg", type: "image" },
+      { path: "https://www.bing.com/ck/a?!&&p=7a26e0938030f722bac8864df3c965e36cf2569da9cb49288cb379ee8c3a662eJmltdHM9MTc3MjY2ODgwMA&ptn=3&ver=2&hsh=4&fclid=0f40599a-c9c4-6515-0a75-4f28c8bc64d0&u=a1L3ZpZGVvcy9yaXZlcnZpZXcvcmVsYXRlZHZpZGVvP3E9MTBzJWU4JWE3JTg2JWU5JWEyJTkxJiZtaWQ9MTcxMjQxNTk0MzFFQ0Y3OTFDNEExNzEyNDE1OTQzMUVDRjc5MUM0QSZGT1JNPVZBTUdaQw", type: "video" },
+      { path: "https://wx.hzliuzhi.com/media/healthManager/wx/share.jpg", type: "image" },
+      { path: "https://www.bing.com/ck/a?!&&p=7a26e0938030f722bac8864df3c965e36cf2569da9cb49288cb379ee8c3a662eJmltdHM9MTc3MjY2ODgwMA&ptn=3&ver=2&hsh=4&fclid=0f40599a-c9c4-6515-0a75-4f28c8bc64d0&u=a1L3ZpZGVvcy9yaXZlcnZpZXcvcmVsYXRlZHZpZGVvP3E9MTBzJWU4JWE3JTg2JWU5JWEyJTkxJiZtaWQ9MTcxMjQxNTk0MzFFQ0Y3OTFDNEExNzEyNDE1OTQzMUVDRjc5MUM0QSZGT1JNPVZBTUdaQw", type: "video" },
+    ];
+    // if (options.evaluateInfo) {
+    //   try {
+    //     const info = JSON.parse(decodeURIComponent(options.evaluateInfo));
+    //     if (info.score != null) score = Number(info.score);
+    //     if (info.content != null) content = info.content;
+    //     if (Array.isArray(info.mediaList) && info.mediaList.length > 0) mediaList = info.mediaList;
+    //   } catch (_) {}
+    // }
+    this.setData({
+      orderId,
+      product,
+      score,
+      content,
+      mediaList,
+    });
+  },
+  onBack() {
+    wx.navigateBack();
+  },
+  /** 打开图片/视频统一轮播,从指定下标开始;轮播到视频时自动播放 */
+  onPreviewMedia(e: WechatMiniprogram.TouchEvent) {
+    const index = e.currentTarget.dataset.index as number;
+    const { mediaList } = this.data;
+    if (index < 0 || index >= mediaList.length) return;
+    this.setData(
+      { showMediaCarousel: true, mediaCarouselCurrent: index },
+      () => {
+        this._playVideoAtCarouselIndex(index);
+      }
+    );
+  },
+  /** 轮播切换:暂停所有视频,若当前项是视频则播放 */
+  onMediaCarouselChange(e: WechatMiniprogram.SwiperChange) {
+    const current = e.detail?.current ?? 0;
+    this.setData({ mediaCarouselCurrent: current });
+    this._pauseAllCarouselVideos();
+    this._playVideoAtCarouselIndex(current);
+  },
+  onCloseMediaCarousel() {
+    this._pauseAllCarouselVideos();
+    this.setData({ showMediaCarousel: false });
+  },
+  _playVideoAtCarouselIndex(index: number) {
+    const list = this.data.mediaList;
+    if (index < 0 || index >= list.length || list[index].type !== "video") return;
+    const ctx = wx.createVideoContext("preview-video-" + index, this);
+    ctx.play();
+  },
+  _pauseAllCarouselVideos() {
+    this.data.mediaList.forEach((item, i) => {
+      if (item.type === "video") {
+        const ctx = wx.createVideoContext("preview-video-" + i, this);
+        ctx.pause();
+      }
+    });
+  },
+  onVideoFullscreenChange(e: WechatMiniprogram.VideoFullScreenChange) {
+    const fullScreen = !!(e.detail && e.detail.fullScreen);
+    this.setData({ videoFullscreen: fullScreen });
+  },
+});

+ 57 - 0
miniprogram/module/order/pages/goods-evaluateDetail/goods-evaluateDetail.wxml

@@ -0,0 +1,57 @@
+<!--module/order/pages/goods-evaluateDetail/goods-evaluateDetail.wxml 评价详情(只读)-->
+<t-navbar wx:if="{{!videoFullscreen}}" title="评价" left-arrow />
+<scroll-view class="page-scroll__container" type="list" scroll-y style="{{containerStyle}}">
+  <view class="evaluate-container">
+    <!-- 商品信息:仅展示 -->
+    <view class="product-card" wx:if="{{product.name}}">
+      <image class="product-img" src="{{product.image}}" mode="aspectFill" />
+      <view class="product-info">
+        <view class="product-name-row">
+          <text class="product-name">{{product.name}}</text>
+          <text class="product-divider" wx:if="{{product.description}}">|</text>
+          <text class="product-spec" wx:if="{{product.description}}">{{product.description}}</text>
+        </view>
+      </view>
+    </view>
+
+    <!-- 描述相符 评分(只读展示) -->
+    <view class="rate-row">
+      <text class="rate-label">描述相符</text>
+      <view class="rate-wrap">
+        <t-rate
+          value="{{score}}"
+          count="{{5}}"
+          color="{{rateColor}}"
+          show-text="{{false}}"
+          disabled="{{true}}"
+        />
+        <text class="rate-score">{{score || '0'}}分</text>
+      </view>
+    </view>
+
+    <!-- 评价内容:只读展示 -->
+    <view class="comment-section">
+      <view class="comment-display">{{content || '暂无评价内容'}}</view>
+    </view>
+
+    <!-- 图片/视频:一行4个,可点击预览,视频全屏时隐藏导航和底部 -->
+    <view class="upload-section">
+      <view class="media-grid media-list--readonly" wx:if="{{mediaList.length > 0}}">
+        <view class="media-item" wx:for="{{mediaList}}" wx:key="path">
+          <image wx:if="{{item.type === 'image'}}" class="media-thumb" src="{{item.path}}" mode="aspectFill" bindtap="onPreviewImage" data-url="{{item.path}}" />
+          <view wx:else class="media-item-video" bindtap="onPreviewVideo" data-index="{{index}}">
+            <video id="goods-detail-video-{{index}}" class="media-thumb" src="{{item.path}}" show-center-play-btn="{{true}}" object-fit="cover" controls="{{true}}" bindfullscreenchange="onVideoFullscreenChange" />
+            <view class="media-item-play"><t-icon name="play-circle-filled" size="56rpx" color="rgba(255,255,255,0.95)" /></view>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</scroll-view>
+
+<!-- 底部返回(视频全屏时隐藏,避免遮挡) -->
+<view class="publish-footer" wx:if="{{!videoFullscreen}}" style="padding-bottom: {{container.safeBottomOffset}}px;">
+  <view class="publish-btn" bindtap="onBack">返回</view>
+</view>
+
+

+ 8 - 0
miniprogram/module/order/pages/offline-evaluate/offline-evaluate.json

@@ -0,0 +1,8 @@
+{
+  "renderer": "skyline",
+  "usingComponents": {
+    "t-navbar": "tdesign-miniprogram/navbar/navbar",
+    "t-icon": "tdesign-miniprogram/icon/icon",
+    "t-rate": "tdesign-miniprogram/rate/rate"
+  }
+}

+ 240 - 0
miniprogram/module/order/pages/offline-evaluate/offline-evaluate.scss

@@ -0,0 +1,240 @@
+@import "../../../../themes/page.scss";
+
+.page-scroll__container {
+  flex: 0 1 auto;
+  height: var(--page-container-safeHeight, 100vh);
+  background: #f7f8fa;
+  padding-bottom: 140rpx;
+}
+
+.evaluate-container {
+  background: #fff;
+  margin: 24rpx;
+  border-radius: 16rpx;
+  padding: 32rpx;
+}
+
+.service-card {
+  position: relative;
+  display: flex;
+  align-items: flex-start;
+  padding-bottom: 32rpx;
+  margin-bottom: 24rpx;
+  border-bottom: 1rpx solid #eee;
+}
+
+.service-img {
+  width: 120rpx;
+  height: 120rpx;
+  border-radius: 12rpx;
+  background: #f5f5f5;
+  flex-shrink: 0;
+}
+
+.service-info {
+  flex: 1;
+  margin-left: 24rpx;
+  min-width: 0;
+  display: flex;
+  flex-direction: column;
+  gap: 12rpx;
+}
+
+.service-name-row {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+  margin-bottom: 10px;
+}
+
+.service-name {
+  font-size: 30rpx;
+  color: #333;
+  font-weight: 500;
+}
+
+.service-divider {
+  font-size: 28rpx;
+  color: #dcdcdc;
+  margin: 0 10rpx;
+}
+
+.service-date,
+.service-time {
+  font-size: 26rpx;
+  color: #666;
+}
+
+.service-row {
+  font-size: 26rpx;
+  color: #666;
+  margin-bottom: 10px;
+}
+
+.service-close {
+  position: absolute;
+  top: 0;
+  right: 0;
+  padding: 16rpx;
+  z-index: 1;
+}
+
+.rate-row {
+  display: flex;
+  align-items: center;
+  // justify-content: space-between;
+  margin-bottom: 28rpx;
+}
+
+.rate-label {
+  font-size: 30rpx;
+  color: #333;
+  min-width: 140rpx;
+  margin-right: 10px;
+}
+
+.rate-wrap {
+  display: flex;
+  align-items: center;
+  gap: 16rpx;
+}
+
+.rate-score {
+  font-size: 28rpx;
+  color: #333;
+  min-width: 56rpx;
+  margin-left: 20px;
+}
+
+.comment-section {
+  position: relative;
+  margin-bottom: 32rpx;
+}
+
+.comment-input {
+  width: 100%;
+  min-height: 200rpx;
+  padding: 24rpx;
+  font-size: 28rpx;
+  color: #333;
+  background: #f7f8fa;
+  border-radius: 12rpx;
+  box-sizing: border-box;
+}
+
+.comment-placeholder {
+  color: #999;
+}
+
+.comment-count {
+  position: absolute;
+  top: 24rpx;
+  right: 24rpx;
+  font-size: 24rpx;
+  color: #999;
+}
+
+.upload-section {
+  margin-bottom: 24rpx;
+}
+
+/* 一行 4 个,文件之间 24rpx 缝隙,与 goods-evaluate 一致 */
+.media-grid {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 24rpx;
+}
+
+.media-item {
+  position: relative;
+  width: 142rpx;
+  height: 142rpx;
+  flex-shrink: 0;
+  border-radius: 12rpx;
+  overflow: hidden;
+  background: #f5f5f5;
+  margin-right: 5px;
+  margin-bottom: 10px;
+}
+
+.upload-trigger {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  width: 142rpx;
+  height: 142rpx;
+  flex-shrink: 0;
+  background: #f7f8fa;
+  border-radius: 12rpx;
+  border: 2rpx dashed #ddd;
+}
+
+.upload-label {
+  font-size: 24rpx;
+  color: #999;
+  margin-top: 12rpx;
+}
+
+.media-thumb {
+  width: 100%;
+  height: 100%;
+  display: block;
+}
+
+.media-item-video {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .media-thumb {
+    display: block;
+  }
+}
+
+.media-item-play {
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  transform: translate(-50%, -50%);
+  pointer-events: none;
+}
+
+.media-delete {
+  position: absolute;
+  top: 0;
+  right: 0;
+  width: 48rpx;
+  height: 48rpx;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border-radius: 0 12rpx 0 12rpx;
+}
+
+.publish-footer {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background: #fff;
+  padding: 20rpx 32rpx;
+  box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
+  z-index: 100;
+}
+
+.publish-btn {
+  height: 88rpx;
+  line-height: 88rpx;
+  text-align: center;
+  font-size: 32rpx;
+  font-weight: 500;
+  color: #fff;
+  background: #1976d2;
+  border-radius: 44rpx;
+}
+
+.publish-btn.disabled {
+  background: #e8e8e8;
+  color: #999;
+}

+ 165 - 0
miniprogram/module/order/pages/offline-evaluate/offline-evaluate.ts

@@ -0,0 +1,165 @@
+import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
+
+Page({
+  behaviors: [PageContainerBehavior],
+  data: {
+    orderId: "",
+    service: {
+      name: "穴位按摩",
+      date: "2025-02-4",
+      time: "15:45:12",
+      operator: "黄医生",
+      institution: "余杭区第一人民医院",
+      image: "/assets/bg/bg_dialog@2x.png",
+    } as {
+      name: string;
+      date: string;
+      time: string;
+      operator: string;
+      institution: string;
+      image: string;
+    },
+    scoreServiceQuality: 0,
+    scoreAttitude: 0,
+    scoreEnvironment: 0,
+    rateColor: "#F7BA2A",
+    content: "",
+    mediaList: [] as { path: string; type: "image" | "video" }[],
+    canPublish: false,
+    videoFullscreen: false,
+  },
+  onLoad(options: Record<string, string>) {
+    const orderId = options.orderId || options.id || "";
+    let service = this.data.service;
+    if (options.serviceInfo) {
+      try {
+        const info = JSON.parse(decodeURIComponent(options.serviceInfo));
+        service = {
+          name: info.name ?? service.name,
+          date: info.date ?? service.date,
+          time: info.time ?? service.time,
+          operator: info.operator ?? service.operator,
+          institution: info.institution ?? service.institution,
+          image: info.image ?? service.image,
+        };
+      } catch (_) {}
+    }
+    this.setData({
+      orderId,
+      service,
+      canPublish: this._checkCanPublish(
+        this.data.scoreServiceQuality,
+        this.data.scoreAttitude,
+        this.data.scoreEnvironment
+      ),
+    });
+  },
+  _checkCanPublish(
+    quality: number,
+    attitude: number,
+    environment: number
+  ): boolean {
+    return quality > 0 && attitude > 0 && environment > 0;
+  },
+  _updateCanPublish() {
+    const { scoreServiceQuality, scoreAttitude, scoreEnvironment } = this.data;
+    this.setData({
+      canPublish: this._checkCanPublish(
+        scoreServiceQuality,
+        scoreAttitude,
+        scoreEnvironment
+      ),
+    });
+  },
+  onScoreServiceQuality(e: WechatMiniprogram.CustomEvent<{ value: number }>) {
+    const scoreServiceQuality = e.detail?.value ?? 0;
+    this.setData({ scoreServiceQuality }, () => this._updateCanPublish());
+  },
+  onScoreAttitude(e: WechatMiniprogram.CustomEvent<{ value: number }>) {
+    const scoreAttitude = e.detail?.value ?? 0;
+    this.setData({ scoreAttitude }, () => this._updateCanPublish());
+  },
+  onScoreEnvironment(e: WechatMiniprogram.CustomEvent<{ value: number }>) {
+    const scoreEnvironment = e.detail?.value ?? 0;
+    this.setData({ scoreEnvironment }, () => this._updateCanPublish());
+  },
+  onContentInput(e: WechatMiniprogram.Input) {
+    const content = e.detail?.value ?? "";
+    this.setData({ content });
+  },
+  onChooseMedia() {
+    const current = this.data.mediaList.length;
+    if (current >= 9) {
+      wx.showToast({ title: "图片和视频总数不能超过9个", icon: "none" });
+      return;
+    }
+    const remain = 9 - current;
+    wx.chooseMedia({
+      count: remain,
+      mediaType: ["image", "video"],
+      sourceType: ["album", "camera"],
+      maxDuration: 30,
+      camera: "back",
+      success: (res) => {
+        const list = res.tempFiles.map((f) => ({
+          path: f.tempFilePath,
+          type: (f.fileType === "video" ? "video" : "image") as "image" | "video",
+        }));
+        const next = [...this.data.mediaList, ...list].slice(0, 9);
+        this.setData({ mediaList: next });
+      },
+    });
+  },
+  onRemoveMedia(e: WechatMiniprogram.TouchEvent) {
+    const index = e.currentTarget.dataset.index as number;
+    const mediaList = this.data.mediaList.filter((_, i) => i !== index);
+    this.setData({ mediaList });
+  },
+  onPreviewImage(e: WechatMiniprogram.TouchEvent) {
+    const url = e.currentTarget.dataset.url as string;
+    const urls = this.data.mediaList.filter((m) => m.type === "image").map((m) => m.path);
+    if (url && urls.length) {
+      wx.previewImage({ current: url, urls });
+    }
+  },
+  onPreviewVideo(e: WechatMiniprogram.TouchEvent) {
+    const index = e.currentTarget.dataset.index as number;
+    const videoContext = wx.createVideoContext("offline-video-" + index, this);
+    videoContext.requestFullScreen({});
+  },
+  onVideoFullscreenChange(e: WechatMiniprogram.VideoFullScreenChange) {
+    const fullScreen = !!(e.detail && e.detail.fullScreen);
+    this.setData({ videoFullscreen: fullScreen });
+  },
+  onRemoveService() {
+    this.setData({
+      service: {
+        name: "",
+        date: "",
+        time: "",
+        operator: "",
+        institution: "",
+        image: "",
+      },
+    });
+  },
+  onPublish() {
+    if (!this.data.canPublish) {
+      wx.showToast({ title: "请完成三项评分", icon: "none" });
+      return;
+    }
+    const { orderId } = this.data;
+    wx.showLoading({ title: "发布中..." });
+    setTimeout(() => {
+      wx.hideLoading();
+      wx.showToast({ title: "发布成功", icon: "success" });
+      if (orderId) {
+        wx.redirectTo({
+          url: `/module/order/pages/other-detail/other-detail?id=${orderId}`,
+        });
+      } else {
+        wx.navigateBack();
+      }
+    }, 500);
+  },
+});

+ 104 - 0
miniprogram/module/order/pages/offline-evaluate/offline-evaluate.wxml

@@ -0,0 +1,104 @@
+<!--module/order/pages/offline-evaluate/offline-evaluate.wxml 线下服务评价-->
+<t-navbar wx:if="{{!videoFullscreen}}" title="评价" left-arrow />
+<scroll-view class="page-scroll__container" type="list" scroll-y style="{{containerStyle}}">
+  <view class="evaluate-container">
+    <!-- 服务信息卡片:缩略图 + 服务名|日期 时间 + 操作人 + 机构,右上角关闭 -->
+    <view class="service-card" wx:if="{{service.name}}">
+      <image class="service-img" src="{{service.image}}" mode="aspectFill" />
+      <view class="service-info">
+        <view class="service-name-row">
+          <text class="service-name">{{service.name}}</text>
+          <text class="service-divider">|</text>
+          <text class="service-date">{{service.date}}</text>
+          <text class="service-time">{{service.time}}</text>
+        </view>
+        <view class="service-row" wx:if="{{service.operator}}">操作人: {{service.operator}}</view>
+        <view class="service-row" wx:if="{{service.institution}}">机构: {{service.institution}}</view>
+      </view>
+    </view>
+
+    <!-- 服务质量 评分 -->
+    <view class="rate-row">
+      <text class="rate-label">服务质量</text>
+      <view class="rate-wrap">
+        <t-rate
+          value="{{scoreServiceQuality}}"
+          count="{{5}}"
+          color="{{rateColor}}"
+          placement=""
+          bind:change="onScoreServiceQuality"
+        />
+        <text class="rate-score">{{scoreServiceQuality || '0'}}分</text>
+      </view>
+    </view>
+
+    <!-- 服务态度 评分 -->
+    <view class="rate-row">
+      <text class="rate-label">服务态度</text>
+      <view class="rate-wrap">
+        <t-rate
+          value="{{scoreAttitude}}"
+          count="{{5}}"
+          color="{{rateColor}}"
+          placement=""
+          bind:change="onScoreAttitude"
+        />
+        <text class="rate-score">{{scoreAttitude || '0'}}分</text>
+      </view>
+    </view>
+
+    <!-- 环境 评分 -->
+    <view class="rate-row">
+      <text class="rate-label">环 境</text>
+      <view class="rate-wrap">
+        <t-rate
+          value="{{scoreEnvironment}}"
+          count="{{5}}"
+          color="{{rateColor}}"
+          placement=""
+          bind:change="onScoreEnvironment"
+        />
+        <text class="rate-score">{{scoreEnvironment || '0'}}分</text>
+      </view>
+    </view>
+
+    <!-- 评价输入 -->
+    <view class="comment-section">
+      <textarea
+        class="comment-input"
+        placeholder="展开说说对商品的想法吧"
+        placeholder-class="comment-placeholder"
+        value="{{content}}"
+        bindinput="onContentInput"
+        maxlength="{{500}}"
+        show-confirm-bar="{{false}}"
+      />
+      <view class="comment-count" wx:if="{{content.length > 0}}">{{content.length}}/500</view>
+    </view>
+
+    <!-- 图/视频 上传(图片+视频总数不超过9个,添加按钮在最后,一行4个) -->
+    <view class="upload-section">
+      <view class="media-grid">
+        <view class="media-item" wx:for="{{mediaList}}" wx:key="path">
+          <image wx:if="{{item.type === 'image'}}" class="media-thumb" src="{{item.path}}" mode="aspectFill" bindtap="onPreviewImage" data-url="{{item.path}}" />
+          <view wx:else class="media-item-video" bindtap="onPreviewVideo" data-index="{{index}}">
+            <video id="offline-video-{{index}}" class="media-thumb" src="{{item.path}}" show-center-play-btn="{{true}}" object-fit="cover" controls="{{true}}" bindfullscreenchange="onVideoFullscreenChange" />
+            <view class="media-item-play"><t-icon name="play-circle-filled" size="56rpx" color="rgba(255,255,255,0.95)" /></view>
+          </view>
+          <view class="media-delete" catchtap="onRemoveMedia" data-index="{{index}}">
+            <t-icon name="close" size="32rpx" color="#fff" />
+          </view>
+        </view>
+        <view class="upload-trigger" wx:if="{{mediaList.length < 9}}" bindtap="onChooseMedia">
+          <t-icon name="add" size="48rpx" color="#999" />
+          <text class="upload-label">图/视频</text>
+        </view>
+      </view>
+    </view>
+  </view>
+</scroll-view>
+
+<!-- 发布按钮(视频全屏时隐藏,避免遮挡进度条) -->
+<view class="publish-footer" wx:if="{{!videoFullscreen}}" style="padding-bottom: {{container.safeBottomOffset}}px;">
+  <view class="publish-btn {{canPublish ? '' : 'disabled'}}" bindtap="onPublish">发布</view>
+</view>

+ 8 - 0
miniprogram/module/order/pages/offline-evaluateDetail/offline-evaluateDetail.json

@@ -0,0 +1,8 @@
+{
+  "renderer": "skyline",
+  "usingComponents": {
+    "t-navbar": "tdesign-miniprogram/navbar/navbar",
+    "t-icon": "tdesign-miniprogram/icon/icon",
+    "t-rate": "tdesign-miniprogram/rate/rate"
+  }
+}

+ 413 - 0
miniprogram/module/order/pages/offline-evaluateDetail/offline-evaluateDetail.scss

@@ -0,0 +1,413 @@
+@import "../../../../themes/page.scss";
+
+.page-scroll__container {
+  flex: 0 1 auto;
+  height: var(--page-container-safeHeight, 100vh);
+  background: #f7f8fa;
+  padding-bottom: 140rpx;
+}
+
+.evaluate-container {
+  background: #fff;
+  margin: 24rpx;
+  border-radius: 16rpx;
+  padding: 32rpx;
+}
+
+.evaluate-container--readonly {
+  user-select: none;
+  -webkit-user-select: none;
+}
+.service-card {
+  position: relative;
+  display: flex;
+  align-items: flex-start;
+  padding-bottom: 32rpx;
+  margin-bottom: 24rpx;
+  border-bottom: 1rpx solid #eee;
+}
+
+.service-img {
+  width: 120rpx;
+  height: 120rpx;
+  border-radius: 12rpx;
+  background: #f5f5f5;
+  flex-shrink: 0;
+}
+
+.service-info {
+  flex: 1;
+  margin-left: 24rpx;
+  min-width: 0;
+  display: flex;
+  flex-direction: column;
+  gap: 12rpx;
+}
+
+.service-name-row {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+  margin-bottom: 10px;
+}
+
+.service-name {
+  font-size: 30rpx;
+  color: #333;
+  font-weight: 500;
+}
+
+.service-divider {
+  font-size: 28rpx;
+  color: #dcdcdc;
+  margin: 0 10rpx;
+}
+
+.service-date,
+.service-time {
+  font-size: 26rpx;
+  color: #666;
+  margin-right: 10px;
+}
+
+.service-row {
+  font-size: 26rpx;
+  color: #666;
+  margin-bottom: 10px;
+}
+
+.product-card {
+  position: relative;
+  display: flex;
+  align-items: center;
+  padding-bottom: 32rpx;
+  margin-bottom: 24rpx;
+  border-bottom: 1rpx solid #eee;
+}
+
+.product-img {
+  width: 120rpx;
+  height: 120rpx;
+  border-radius: 12rpx;
+  background: #f5f5f5;
+  flex-shrink: 0;
+}
+
+.product-info {
+  flex: 1;
+  margin-left: 24rpx;
+  min-width: 0;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.product-name-row {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+  gap: 8rpx;
+}
+
+.product-name {
+  font-size: 30rpx;
+  color: #333;
+  font-weight: 500;
+}
+
+.product-divider {
+  font-size: 28rpx;
+  color: #dcdcdc;
+  margin: 0 30rpx;
+}
+
+.product-spec {
+  font-size: 26rpx;
+  color: #999;
+}
+
+.product-close {
+  position: absolute;
+  top: 0;
+  right: 0;
+  padding: 16rpx;
+  z-index: 1;
+}
+
+.rate-row {
+  display: flex;
+  align-items: center;
+  // justify-content: space-between;
+  margin-bottom: 32rpx;
+}
+
+.rate-label {
+  font-size: 30rpx;
+  color: #333;
+  margin-right: 20px;
+  min-width: 60px;
+}
+
+.rate-wrap {
+  display: flex;
+  align-items: center;
+  gap: 16rpx;
+}
+
+.rate-score {
+  font-size: 28rpx;
+  color: #333;
+  min-width: 56rpx;
+  margin-left: 20px;
+}
+
+.comment-section {
+  position: relative;
+  margin-bottom: 32rpx;
+}
+
+.comment-display {
+  width: 100%;
+  min-height: 120rpx;
+  padding: 24rpx;
+  font-size: 28rpx;
+  color: #333;
+  background: #f7f8fa;
+  border-radius: 12rpx;
+  box-sizing: border-box;
+  line-height: 1.5;
+  white-space: pre-wrap;
+  word-break: break-all;
+}
+
+.comment-input {
+  width: 100%;
+  min-height: 200rpx;
+  padding: 24rpx;
+  font-size: 28rpx;
+  color: #333;
+  background: #f7f8fa;
+  border-radius: 12rpx;
+  box-sizing: border-box;
+}
+
+.comment-placeholder {
+  color: #999;
+}
+
+.comment-count {
+  position: absolute;
+  top: 24rpx;
+  right: 24rpx;
+  font-size: 24rpx;
+  color: #999;
+}
+
+.upload-section {
+  margin-bottom: 24rpx;
+}
+
+.upload-section .empty-media {
+  font-size: 26rpx;
+  color: #999;
+  margin-top: 8rpx;
+  display: block;
+}
+
+.section-label {
+  font-size: 28rpx;
+  color: #666;
+  margin-bottom: 16rpx;
+}
+
+.upload-row {
+  display: flex;
+  gap: 20rpx;
+  flex-wrap: wrap;
+}
+
+.upload-trigger {
+  display: inline-flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  width: 160rpx;
+  height: 160rpx;
+  border-radius: 12rpx;
+  border: 2rpx dashed #ddd;
+}
+
+.upload-trigger--image {
+  background: #f2f2f2;
+}
+
+.upload-trigger--video {
+  background: #4a4a4a;
+  border-color: #333;
+}
+
+.upload-label {
+  font-size: 26rpx;
+  color: #999;
+  margin-top: 12rpx;
+}
+
+.upload-label--light {
+  color: rgba(255, 255, 255, 0.9);
+}
+
+.upload-trigger .t-icon {
+  display: block;
+}
+
+/* 一行 4 个,与 goods-evaluateDetail 一致 */
+.media-grid {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 24rpx;
+}
+
+.media-list--readonly .media-item {
+  .media-delete {
+    display: none;
+  }
+}
+
+.media-item {
+  position: relative;
+  width: 142rpx;
+  height: 142rpx;
+  flex-shrink: 0;
+  border-radius: 12rpx;
+  overflow: hidden;
+  background: #f5f5f5;
+  margin-right: 5px;
+  margin-bottom: 10px;
+}
+
+.media-thumb {
+  width: 100%;
+  height: 100%;
+  display: block;
+}
+
+.media-item-video {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .media-thumb {
+    display: block;
+  }
+}
+
+.media-item-play {
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  transform: translate(-50%, -50%);
+  pointer-events: none;
+}
+
+.media-delete {
+  position: absolute;
+  top: 0;
+  right: 0;
+  width: 48rpx;
+  height: 48rpx;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border-radius: 0 12rpx 0 12rpx;
+}
+
+.publish-footer {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background: #fff;
+  padding: 20rpx 32rpx;
+  box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
+  z-index: 100;
+}
+
+.publish-btn {
+  height: 88rpx;
+  line-height: 88rpx;
+  text-align: center;
+  font-size: 32rpx;
+  font-weight: 500;
+  color: #fff;
+  background: #1976d2;
+  border-radius: 44rpx;
+}
+
+.publish-btn.disabled {
+  background: #e8e8e8;
+  color: #999;
+}
+
+/* 全屏轮播层:图片+视频一起,轮播到视频自动播放 */
+.media-carousel-overlay {
+  position: fixed;
+  left: 0;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 1000;
+  background: #000;
+}
+
+.media-carousel-swiper {
+  width: 100%;
+  height: 100%;
+}
+
+.media-carousel-item {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.media-carousel-image-wrap {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.media-carousel-image {
+  width: 100%;
+  height: 100%;
+  display: block;
+  object-position: center;
+}
+
+.media-carousel-video-wrap {
+  width: 100%;
+  height: 100%;
+}
+
+.media-carousel-video {
+  width: 100%;
+  height: 100%;
+  display: block;
+}
+
+.media-carousel-close {
+  position: absolute;
+  top: calc(var(--status-bar-height, 0px) + 24rpx);
+  right: 24rpx;
+  width: 80rpx;
+  height: 80rpx;
+  border-radius: 50%;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 1001;
+}

+ 112 - 0
miniprogram/module/order/pages/offline-evaluateDetail/offline-evaluateDetail.ts

@@ -0,0 +1,112 @@
+import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
+
+Page({
+  behaviors: [PageContainerBehavior],
+  data: {
+    orderId: "",
+    service: {} as { name: string; image: string; description?: string; date?: string; time?: string; operator?: string; institution?: string },
+    scoreServiceQuality: 5,
+    scoreAttitude: 5,
+    scoreEnvironment: 5,
+    rateColor: "#F7BA2A",
+    content: "描述相符,商品质量很好,包装完整,会回购。",
+    mediaList: [] as { path: string; type: "image" | "video" }[],
+    showMediaCarousel: false,
+    mediaCarouselCurrent: 0,
+  },
+  onLoad(options: Record<string, string>) {
+    const orderId = options.orderId || options.id || "";
+    let service: { name: string; image: string;  description?: string } = {
+      name: "",
+      image: "",
+      description: "",
+      date: "",
+      time: "",
+      operator: "",
+      institution: "",
+    };
+    console.log(options, "options.goodsInfo===");
+    if (options.goodsInfo) {
+      try {
+        const goods = JSON.parse(decodeURIComponent(options.goodsInfo));
+        service = {
+          name: goods.name || "",
+          image: goods.image || "",
+          description: goods.description || "",
+          date: "2026-03-05",
+          time: "10:00:00",
+          operator: "张三",
+          institution: "杭州第一人民医院",
+        };
+      } catch (_) {}
+    }
+console.log(service, "service===");
+    // 若传入评价详情数据则使用,否则用默认展示内容(含示例图片)
+    let scoreServiceQuality = 2;
+    let scoreAttitude = 4;
+    let scoreEnvironment = 3;
+    let content = "描述相符,商品质量很好,包装完整,会回购。";
+    let mediaList: { path: string; type: "image" | "video" }[] = [
+      { path: "/assets/bg/bg_dialog@2x.png", type: "image" },
+    ];
+    if (options.evaluateInfo) {
+      try {
+        const info = JSON.parse(decodeURIComponent(options.evaluateInfo));
+        if (info.scoreServiceQuality != null) scoreServiceQuality = Number(info.scoreServiceQuality);
+        if (info.scoreAttitude != null) scoreAttitude = Number(info.scoreAttitude);
+        if (info.scoreEnvironment != null) scoreEnvironment = Number(info.scoreEnvironment);
+        if (info.content != null) content = info.content;
+        if (Array.isArray(info.mediaList) && info.mediaList.length > 0) mediaList = info.mediaList;
+      } catch (_) {}
+    }
+    this.setData({
+      orderId,
+      service,
+      scoreServiceQuality,
+      scoreAttitude,
+      scoreEnvironment,
+      content,
+      mediaList,
+    });
+  },
+  onBack() {
+    wx.navigateBack();
+  },
+  /** 打开图片/视频统一轮播,从指定下标开始;轮播到视频时自动播放 */
+  onPreviewMedia(e: WechatMiniprogram.TouchEvent) {
+    const index = e.currentTarget.dataset.index as number;
+    const { mediaList } = this.data;
+    if (index < 0 || index >= mediaList.length) return;
+    this.setData(
+      { showMediaCarousel: true, mediaCarouselCurrent: index },
+      () => {
+        this._playVideoAtCarouselIndex(index);
+      }
+    );
+  },
+  /** 轮播切换:暂停所有视频,若当前项是视频则播放 */
+  onMediaCarouselChange(e: WechatMiniprogram.SwiperChange) {
+    const current = e.detail?.current ?? 0;
+    this.setData({ mediaCarouselCurrent: current });
+    this._pauseAllCarouselVideos();
+    this._playVideoAtCarouselIndex(current);
+  },
+  onCloseMediaCarousel() {
+    this._pauseAllCarouselVideos();
+    this.setData({ showMediaCarousel: false });
+  },
+  _playVideoAtCarouselIndex(index: number) {
+    const list = this.data.mediaList;
+    if (index < 0 || index >= list.length || list[index].type !== "video") return;
+    const ctx = wx.createVideoContext("preview-video-" + index, this);
+    ctx.play();
+  },
+  _pauseAllCarouselVideos() {
+    this.data.mediaList.forEach((item, i) => {
+      if (item.type === "video") {
+        const ctx = wx.createVideoContext("preview-video-" + i, this);
+        ctx.pause();
+      }
+    });
+  },
+});

+ 120 - 0
miniprogram/module/order/pages/offline-evaluateDetail/offline-evaluateDetail.wxml

@@ -0,0 +1,120 @@
+<!-- 线下评价详情:整页只读,不允许用户修改,仅支持查看与返回 -->
+<t-navbar title="评价" left-arrow />
+<scroll-view class="page-scroll__container" type="list" scroll-y style="{{containerStyle}}">
+  <view class="evaluate-container evaluate-container--readonly">
+    <!-- 商品信息:仅展示 -->
+    <view class="service-card" wx:if="{{service.name}}">
+      <image class="service-img" src="{{service.image}}" mode="aspectFill" />
+      <view class="service-info">
+        <view class="service-name-row">
+          <text class="service-name">{{service.name}}</text>
+          <text class="service-divider">|</text>
+          <text class="service-date">{{service.date}}</text>
+          <text class="service-time">{{service.time}}</text>
+        </view>
+        <view class="service-row" wx:if="{{service.operator}}">操作人: {{service.operator}}</view>
+        <view class="service-row" wx:if="{{service.institution}}">机构: {{service.institution}}</view>
+      </view>
+    </view>
+
+ <!-- 服务质量 评分(只读) -->
+    <view class="rate-row">
+      <text class="rate-label">服务质量</text>
+      <view class="rate-wrap">
+        <t-rate
+          value="{{scoreServiceQuality}}"
+          count="{{5}}"
+          color="{{rateColor}}"
+          placement=""
+          disabled="{{true}}"
+        />
+        <text class="rate-score">{{scoreServiceQuality || '0'}}分</text>
+      </view>
+    </view>
+
+    <!-- 服务态度 评分(只读) -->
+    <view class="rate-row">
+      <text class="rate-label">服务态度</text>
+      <view class="rate-wrap">
+        <t-rate
+          value="{{scoreAttitude}}"
+          count="{{5}}"
+          color="{{rateColor}}"
+          placement=""
+          disabled="{{true}}"
+        />
+        <text class="rate-score">{{scoreAttitude || '0'}}分</text>
+      </view>
+    </view>
+
+    <!-- 环境 评分(只读) -->
+    <view class="rate-row">
+      <text class="rate-label">环   境</text>
+      <view class="rate-wrap">
+        <t-rate
+          value="{{scoreEnvironment}}"
+          count="{{5}}"
+          color="{{rateColor}}"
+          placement=""
+          disabled="{{true}}"
+        />
+        <text class="rate-score">{{scoreEnvironment || '0'}}分</text>
+      </view>
+    </view>
+
+    <!-- 评价内容:只读展示 -->
+    <view class="comment-section">
+      <view class="comment-display">{{content || '暂无评价内容'}}</view>
+    </view>
+
+    <!-- 图片/视频:一行4个,点击进入统一轮播,轮播到视频自动播放 -->
+    <view class="upload-section">
+      <view class="media-grid media-list--readonly" wx:if="{{mediaList.length > 0}}">
+        <view class="media-item" wx:for="{{mediaList}}" wx:key="path">
+          <image wx:if="{{item.type === 'image'}}" class="media-thumb" src="{{item.path}}" mode="aspectFill" bindtap="onPreviewMedia" data-index="{{index}}" />
+          <view wx:else class="media-item-video" bindtap="onPreviewMedia" data-index="{{index}}">
+            <video id="offline-detail-video-{{index}}" class="media-thumb" src="{{item.path}}" show-center-play-btn="{{true}}" object-fit="cover" controls="{{true}}" />
+            <view class="media-item-play"><t-icon name="play-circle-filled" size="56rpx" color="rgba(255,255,255,0.95)" /></view>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</scroll-view>
+
+<!-- 底部返回 -->
+<view class="publish-footer" style="padding-bottom: {{container.safeBottomOffset}}px;">
+  <view class="publish-btn" bindtap="onBack">返回</view>
+</view>
+
+<!-- 全屏轮播:图片+视频一起,轮播到视频自动播放 -->
+<view class="media-carousel-overlay" wx:if="{{showMediaCarousel}}">
+  <swiper
+    class="media-carousel-swiper"
+    current="{{mediaCarouselCurrent}}"
+    duration="300"
+    circular="{{true}}"
+    bindchange="onMediaCarouselChange"
+  >
+    <swiper-item wx:for="{{mediaList}}" wx:key="path" class="media-carousel-item">
+      <view wx:if="{{item.type === 'image'}}" class="media-carousel-image-wrap">
+        <image class="media-carousel-image" src="{{item.path}}" mode="aspectFit" />
+      </view>
+      <view wx:else class="media-carousel-video-wrap">
+        <video
+          id="preview-video-{{index}}"
+          class="media-carousel-video"
+          src="{{item.path}}"
+          controls="{{true}}"
+          object-fit="contain"
+          show-center-play-btn="{{true}}"
+        />
+      </view>
+    </swiper-item>
+  </swiper>
+  <view class="media-carousel-close" bindtap="onCloseMediaCarousel">
+    <t-icon name="close" size="48rpx" color="#fff" />
+  </view>
+</view>
+
+

+ 29 - 0
miniprogram/module/order/pages/other-detail/other-detail.scss

@@ -259,6 +259,35 @@
   }
 }
 
+// 申请售后 + 评价 按钮行(图示样式:左灰底、右白底蓝框)
+.action-btns {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: flex-end;
+  margin-top: 16rpx;
+}
+
+.btn-aftersale {
+  padding: 12rpx 28rpx;
+  border-radius: 12rpx;
+  font-size: 26rpx;
+  text-align: center;
+  background-color: #e8e8e8;
+  color: #666;
+}
+
+.btn-review {
+  padding: 12rpx 28rpx;
+  border-radius: 12rpx;
+  font-size: 26rpx;
+  text-align: center;
+  background-color: #fff;
+  color: #1976d2;
+  border: 1px solid #1976d2;
+  margin-left: 20rpx;
+}
+
 .quantity-selector {
   display: flex;
   align-items: center;

+ 39 - 0
miniprogram/module/order/pages/other-detail/other-detail.ts

@@ -258,6 +258,45 @@ Page({
     });
   },
 
+  preventTap() {
+    // 仅用于 catchtap 阻止冒泡,避免触发父级 goAppointment
+  },
+  onApplyAfterSale(_e: any) {
+    wx.showToast({ title: "申请售后", icon: "none" });
+  },
+  onReview(e: WechatMiniprogram.TouchEvent) {
+    // const orderId = this.data.id || "";
+    console.log(e.currentTarget.dataset);
+    // const { name = "", image = "", description = ''} = (e.currentTarget.dataset.goods || {}) as {
+    //   name?: string;
+    //   image?: string;
+    //   description?: string;
+    // };
+    // const parts: string[] = [];
+    // if (orderId) parts.push(`orderId=${encodeURIComponent(orderId)}`);
+    // if (name) parts.push(`name=${encodeURIComponent(name)}`);
+    // if (image) parts.push(`image=${encodeURIComponent(image)}`);
+    // if (description != null) parts.push(`description=${encodeURIComponent(description.toString())}`);
+    // const query = parts.length ? "?" + parts.join("&") : "";
+    if (false) {
+      wx.navigateTo({
+        url: `/module/order/pages/goods-evaluate/goods-evaluate?goodsInfo=${encodeURIComponent(JSON.stringify(e.currentTarget.dataset.goods))}`,
+      });
+    } else {
+      // 单商品评价详情
+      wx.navigateTo({
+        url: `/module/order/pages/goods-evaluateDetail/goods-evaluateDetail?goodsInfo=${encodeURIComponent(JSON.stringify(e.currentTarget.dataset.goods))}`,
+      });
+      // 线下服务评价
+      // wx.navigateTo({
+      //   url: `/module/order/pages/offline-evaluate/offline-evaluate?goodsInfo=${encodeURIComponent(JSON.stringify(e.currentTarget.dataset.goods))}`,
+      // });
+      // 线下服务评价详情
+      // wx.navigateTo({
+      //   url: `/module/order/pages/offline-evaluateDetail/offline-evaluateDetail?goodsInfo=${encodeURIComponent(JSON.stringify(e.currentTarget.dataset.goods))}`,
+      // });
+    }
+  },
   // 复制订单号
   copyOrderNo(e: any) {
     const orderNo = e.currentTarget.dataset.orderno;

+ 15 - 0
miniprogram/module/order/pages/other-detail/other-detail.wxml

@@ -41,6 +41,11 @@
               <view class="confirm-receipt-btn" wx:if="{{goods.receiptStatus === '1'}}" bindtap="onConfirmReceipt" data-patientConditioningRecordId="{{goods.patientConditioningRecordId}}" data-index="{{goodsIndex}}">
                 确认收货
               </view>
+              <!-- 申请售后 + 评价 -->
+              <view class="action-btns">
+                <view class="btn-aftersale" catchtap="onApplyAfterSale">申请售后</view>
+                <view class="btn-review" catchtap="onReview" data-goods="{{goods}}">评价</view>
+              </view>
             </view>
           </view>
         </view>
@@ -67,6 +72,11 @@
                 <view class="goods-desc" wx:if="{{goods.description}}">{{goods.description}}</view>
                 <view class="quantity-text">x{{goods.quantity}}</view>
               </view>
+              <!-- 申请售后 + 评价 -->
+              <view class="action-btns" catchtap="preventTap">
+                <view class="btn-aftersale" catchtap="onApplyAfterSale">申请售后</view>
+                  <view class="btn-review" catchtap="onReview" data-goods="{{goods}}">评价</view>
+              </view>
             </view>
           </view>
         </view>
@@ -93,6 +103,11 @@
                 <view class="goods-desc" wx:if="{{goods.description}}">{{goods.description}}</view>
                 <view class="quantity-text">x{{goods.quantity}}</view>
               </view>
+              <!-- 申请售后 + 评价 -->
+              <view class="action-btns">
+                <view class="btn-aftersale" catchtap="onApplyAfterSale">申请售后</view>
+                  <view class="btn-review" catchtap="onReview" data-goods="{{goods}}">评价</view>
+              </view>
             </view>
           </view>
         </view>

+ 7 - 0
miniprogram/module/order/pages/test/test.json

@@ -0,0 +1,7 @@
+{
+  "renderer": "skyline",
+  "component": true,
+  "usingComponents": {
+    "t-navbar": "tdesign-miniprogram/navbar/navbar"
+  }
+}

+ 11 - 0
miniprogram/module/order/pages/test/test.scss

@@ -0,0 +1,11 @@
+@import "../../../../themes/t.cell.scss";
+@import "../../../../themes/page.scss";
+
+/* module/order/pages/confirme-order/confirme-order.wxss */
+.page-scroll__container {
+  flex: 0 1 auto;
+  height: var(--page-container-safeHeight, 100vh);
+  background: #f2f2f2;
+  padding-bottom: 120rpx;
+  padding-top: 20rpx;
+}

+ 17 - 0
miniprogram/module/order/pages/test/test.ts

@@ -0,0 +1,17 @@
+import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
+import DictionariesBehavior from "../../../../core/behavior/dictionaries.behavior";
+import tickleBehavior from "../../../../core/behavior/tickle.behavior";
+
+// module/order/pages/appointment-success/appointment-success.ts
+Page({
+  behaviors: [PageContainerBehavior, DictionariesBehavior, tickleBehavior],
+  data: {
+    appointmentInfo: {
+    },
+  },
+  onLoad(options: any) {
+  
+    
+  },
+
+})

+ 7 - 0
miniprogram/module/order/pages/test/test.wxml

@@ -0,0 +1,7 @@
+<!--module/order/pages/confirme-success/confirme-success.wxml-->
+<t-navbar title="瀑布流布局" left-arrow />
+<scroll-view class="page-scroll__container" type="list" scroll-y style="{{containerStyle}}">
+  <view class="success-container">
+瀑布流布局
+  </view>
+</scroll-view>