Pārlūkot izejas kodu

fix: 商城页面日期解析改用 parseDate(iOS 兼容)

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
asus 3 mēneši atpakaļ
vecāks
revīzija
919d62534f

+ 17 - 16
cfc-frontend/pages/discover-detail/product-detail/product-detail.vue

@@ -75,26 +75,27 @@
         <text class="section-title">商品详情</text>
         <mp-html :content="product.description" />
       </view>
+    </scroll-view>
+    <view v-else class="empty-wrap">
+      <text class="empty-text">商品不存在或已下架</text>
+    </view>
 
-      <view class="bottom-bar">
-        <view class="price-info">
-          <text class="bottom-price">{{ formatPriceWithSymbol(displayPrice) }}</text>
-          <text v-if="displayMemberPrice && displayMemberPrice > 0 && !isMember" class="bottom-member">会员{{ formatPriceWithSymbol(displayMemberPrice) }}</text>
-          <text v-if="displayMemberPrice && displayMemberPrice > 0 && isMember" class="bottom-member bottom-member-highlight">会员{{ formatPriceWithSymbol(displayMemberPrice) }}</text>
+    <!-- 底部操作栏:必须与 scroll-view 平级,否则 iOS 上 position: fixed 在 scroll-view 内不生效(按钮不显示) -->
+    <view class="bottom-bar" v-if="!loading && product.id">
+      <view class="price-info">
+        <text class="bottom-price">{{ formatPriceWithSymbol(displayPrice) }}</text>
+        <text v-if="displayMemberPrice && displayMemberPrice > 0 && !isMember" class="bottom-member">会员{{ formatPriceWithSymbol(displayMemberPrice) }}</text>
+        <text v-if="displayMemberPrice && displayMemberPrice > 0 && isMember" class="bottom-member bottom-member-highlight">会员{{ formatPriceWithSymbol(displayMemberPrice) }}</text>
+      </view>
+      <view class="action-btns">
+        <view class="action-extra">
+          <button class="btn-share" @click="onShareProduct">🖼</button>
         </view>
-        <view class="action-btns">
-          <view class="action-extra">
-            <button class="btn-share" @click="onShareProduct">🖼</button>
-          </view>
-          <view class="action-extra">
-            <button class="btn-cart" :class="buyButtonDisabled ? 'btn-disabled' : ''" :disabled="buyButtonDisabled" @click="onAddToCart">{{ buyButtonDisabled ? '请选规格' : '加入购物车' }}</button>
-          </view>
-          <button class="btn-buy" :class="buyButtonDisabled ? 'btn-disabled' : ''" :disabled="buyButtonDisabled" @click="onBuy">{{ buyButtonText }}</button>
+        <view class="action-extra">
+          <button class="btn-cart" :class="buyButtonDisabled ? 'btn-disabled' : ''" :disabled="buyButtonDisabled" @click="onAddToCart">{{ buyButtonDisabled ? '请选规格' : '加入购物车' }}</button>
         </view>
+        <button class="btn-buy" :class="buyButtonDisabled ? 'btn-disabled' : ''" :disabled="buyButtonDisabled" @click="onBuy">{{ buyButtonText }}</button>
       </view>
-    </scroll-view>
-    <view v-else class="empty-wrap">
-      <text class="empty-text">商品不存在或已下架</text>
     </view>
 
     <ContentSharePoster :show="showPoster" :title="product.name" :coverImage="product.coverImage" :qrCodeBase64="posterQrCode" typeLabel="好物推荐" :dimensionCode="posterDimension" :priceText="priceText" :summary="product.intro" ctaText="长按识别二维码 · 查看商品" :inviteText="posterInviteText" @close="showPoster = false" />

+ 3 - 1
cfc-frontend/pages/shop/after-sales-detail/after-sales-detail.vue

@@ -86,6 +86,7 @@
 
 <script>
 import config from '@/config.js'
+import { parseDate } from '@/utils/format.js'
 
 export default {
   data() {
@@ -169,7 +170,8 @@ export default {
     },
     formatTime(time) {
       if (!time) return ''
-      var d = new Date(time)
+      var d = parseDate(time)
+      if (!d) return ''
       var year = d.getFullYear()
       var month = String(d.getMonth() + 1).padStart(2, '0')
       var day = String(d.getDate()).padStart(2, '0')

+ 3 - 1
cfc-frontend/pages/shop/after-sales/after-sales.vue

@@ -58,6 +58,7 @@
 
 <script>
 import config from '@/config.js'
+import { parseDate } from '@/utils/format.js'
 
 export default {
   data() {
@@ -145,7 +146,8 @@ export default {
     },
     formatTime(time) {
       if (!time) return ''
-      var d = new Date(time)
+      var d = parseDate(time)
+      if (!d) return ''
       var year = d.getFullYear()
       var month = String(d.getMonth() + 1).padStart(2, '0')
       var day = String(d.getDate()).padStart(2, '0')

+ 14 - 9
cfc-frontend/pages/shop/order-detail/order-detail.vue

@@ -84,24 +84,27 @@
         <button class="btn-logistics" @click="viewLogistics">查看物流</button>
       </view>
 
-      <view class="bottom-actions" v-if="order.status">
-        <button v-if="order.status === 'pending'" class="btn-cancel" @click="onCancel">取消订单</button>
-        <button v-if="order.status === 'pending'" class="btn-pay" @click="onPay">立即支付</button>
-        <button v-if="order.status === 'shipped'" class="btn-confirm-receive" @click="onConfirmReceive">确认收货</button>
-        <button v-if="order.status === 'paid' || order.status === 'shipped' || order.status === 'pending_receipt'" class="btn-after-sales" @click="onApplyAfterSales">申请售后</button>
-        <button v-if="order.status === 'completed'" class="btn-buy-again" @click="onBuyAgain">再次购买</button>
-        <button v-if="order.status === 'completed' || order.status === 'refunding' || order.status === 'refunded'" class="btn-after-sales" @click="onAfterSales">售后记录</button>
-      </view>
     </scroll-view>
     <view v-else class="empty-wrap">
       <text class="empty-text">订单不存在</text>
     </view>
+
+    <!-- 底部操作栏:必须与 scroll-view 平级,否则 iOS 上 position: fixed 在 scroll-view 内不生效(按钮不显示) -->
+    <view class="bottom-actions" v-if="!loading && order.id && order.status">
+      <button v-if="order.status === 'pending'" class="btn-cancel" @click="onCancel">取消订单</button>
+      <button v-if="order.status === 'pending'" class="btn-pay" @click="onPay">立即支付</button>
+      <button v-if="order.status === 'shipped'" class="btn-confirm-receive" @click="onConfirmReceive">确认收货</button>
+      <button v-if="order.status === 'paid' || order.status === 'shipped' || order.status === 'pending_receipt'" class="btn-after-sales" @click="onApplyAfterSales">申请售后</button>
+      <button v-if="order.status === 'completed'" class="btn-buy-again" @click="onBuyAgain">再次购买</button>
+      <button v-if="order.status === 'completed' || order.status === 'refunding' || order.status === 'refunded'" class="btn-after-sales" @click="onAfterSales">售后记录</button>
+    </view>
   </view>
 </template>
 
 <script>
 import { productOrderDetail, productOrderConfirm, productOrderCancel } from '@/utils/api.js'
 import config from '@/config.js'
+import { parseDate } from '@/utils/format.js'
 
 export default {
   data() {
@@ -240,7 +243,8 @@ export default {
     },
     formatTime(time) {
       if (!time) return ''
-      const d = new Date(time)
+      const d = parseDate(time)
+      if (!d) return ''
       return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0') + ' ' + String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0')
     },
     formatPriceWithSymbol(price) {
@@ -272,6 +276,7 @@ export default {
 }
 .content {
   height: calc(100vh - 120rpx);
+  padding-bottom: 120rpx;
 }
 .order-status-section {
   padding: 40rpx 30rpx;

+ 8 - 3
cfc-frontend/pages/shop/order-list/order-list.vue

@@ -109,6 +109,7 @@
 <script>
 import { productOrderMy, productOrderCounts, productOrderCancel, productOrderConfirm } from '@/utils/api.js'
 import config from '@/config.js'
+import { parseDate } from '@/utils/format.js'
 
 var TYPE_ICONS = { activity: '🎯', course: '📖', physical: '📦', digital: '💎', service: '🎓' }
 var DEFAULT_COVER = {
@@ -316,7 +317,9 @@ export default {
     formatRelativeTime(time) {
       if (!time) return ''
       var now = Date.now()
-      var ts = new Date(time).getTime()
+      var d0 = parseDate(time)
+      if (!d0) return ''
+      var ts = d0.getTime()
       var diff = now - ts
       var minute = 60 * 1000
       var hour = 60 * minute
@@ -325,12 +328,14 @@ export default {
       if (diff < hour) return Math.floor(diff / minute) + '分钟前'
       if (diff < day) return Math.floor(diff / hour) + '小时前'
       if (diff < 3 * day) return Math.floor(diff / day) + '天前'
-      var d = new Date(time)
+      var d = parseDate(time)
+      if (!d) return ''
       return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0')
     },
     formatFullTime(time) {
       if (!time) return ''
-      var d = new Date(time)
+      var d = parseDate(time)
+      if (!d) return ''
       var y = d.getFullYear()
       var mo = String(d.getMonth() + 1).padStart(2, '0')
       var da = String(d.getDate()).padStart(2, '0')