Przeglądaj źródła

我的股票修改

Zhangbw 3 miesięcy temu
rodzic
commit
66413375f0
29 zmienionych plików z 1090 dodań i 1644 usunięć
  1. 51 0
      dist/dev/mp-weixin/components/HistorySearchCard.js
  2. 4 0
      dist/dev/mp-weixin/components/HistorySearchCard.json
  3. 1 0
      dist/dev/mp-weixin/components/HistorySearchCard.wxml
  4. 67 0
      dist/dev/mp-weixin/components/HistorySearchCard.wxss
  5. 21 0
      dist/dev/mp-weixin/components/PerformanceCard.js
  6. 4 0
      dist/dev/mp-weixin/components/PerformanceCard.json
  7. 1 0
      dist/dev/mp-weixin/components/PerformanceCard.wxml
  8. 35 0
      dist/dev/mp-weixin/components/PerformanceCard.wxss
  9. 36 0
      dist/dev/mp-weixin/components/PurchaseModal.js
  10. 4 0
      dist/dev/mp-weixin/components/PurchaseModal.json
  11. 1 0
      dist/dev/mp-weixin/components/PurchaseModal.wxml
  12. 102 0
      dist/dev/mp-weixin/components/PurchaseModal.wxss
  13. 39 65
      dist/dev/mp-weixin/pages/pool/pool.js
  14. 5 1
      dist/dev/mp-weixin/pages/pool/pool.json
  15. 0 0
      dist/dev/mp-weixin/pages/pool/pool.wxml
  16. 0 229
      dist/dev/mp-weixin/pages/pool/pool.wxss
  17. 21 12
      dist/dev/mp-weixin/pages/rank/rank.js
  18. 0 0
      dist/dev/mp-weixin/pages/rank/rank.wxml
  19. 9 0
      dist/dev/mp-weixin/pages/rank/rank.wxss
  20. 46 93
      dist/dev/mp-weixin/pages/strong/strong.js
  21. 5 1
      dist/dev/mp-weixin/pages/strong/strong.json
  22. 0 0
      dist/dev/mp-weixin/pages/strong/strong.wxml
  23. 39 277
      dist/dev/mp-weixin/pages/strong/strong.wxss
  24. 166 0
      src/components/HistorySearchCard.vue
  25. 67 0
      src/components/PerformanceCard.vue
  26. 164 0
      src/components/PurchaseModal.vue
  27. 33 414
      src/pages/pool/pool.vue
  28. 86 48
      src/pages/rank/rank.vue
  29. 83 504
      src/pages/strong/strong.vue

+ 51 - 0
dist/dev/mp-weixin/components/HistorySearchCard.js

@@ -0,0 +1,51 @@
+"use strict";
+const common_vendor = require("../common/vendor.js");
+const _sfc_main = {
+  __name: "HistorySearchCard",
+  props: {
+    defaultStartMonth: { type: String, default: "2025-01" },
+    defaultEndMonth: { type: String, default: "2025-11" }
+  },
+  emits: ["search"],
+  setup(__props, { emit }) {
+    const props = __props;
+    const startMonth = common_vendor.ref(props.defaultStartMonth);
+    const endMonth = common_vendor.ref(props.defaultEndMonth);
+    const formatMonth = (monthStr) => {
+      if (!monthStr)
+        return "请选择";
+      const [year, month] = monthStr.split("-");
+      return `${year}年${month}月`;
+    };
+    const onStartMonthChange = (e) => {
+      startMonth.value = e.detail.value;
+    };
+    const onEndMonthChange = (e) => {
+      endMonth.value = e.detail.value;
+    };
+    const onSearch = () => {
+      if (!startMonth.value || !endMonth.value) {
+        common_vendor.index.showToast({ title: "请选择开始和结束月份", icon: "none" });
+        return;
+      }
+      if (startMonth.value > endMonth.value) {
+        common_vendor.index.showToast({ title: "开始月份不能晚于结束月份", icon: "none" });
+        return;
+      }
+      emit("search", { startMonth: startMonth.value, endMonth: endMonth.value });
+    };
+    return (_ctx, _cache) => {
+      return {
+        a: common_vendor.t(formatMonth(startMonth.value)),
+        b: startMonth.value,
+        c: common_vendor.o(onStartMonthChange),
+        d: common_vendor.t(formatMonth(endMonth.value)),
+        e: endMonth.value,
+        f: common_vendor.o(onEndMonthChange),
+        g: common_vendor.o(onSearch)
+      };
+    };
+  }
+};
+const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-df43cc4c"], ["__file", "D:/program/gupiao-wx/src/components/HistorySearchCard.vue"]]);
+wx.createComponent(Component);

+ 4 - 0
dist/dev/mp-weixin/components/HistorySearchCard.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 1 - 0
dist/dev/mp-weixin/components/HistorySearchCard.wxml

@@ -0,0 +1 @@
+<view class="card history-card data-v-df43cc4c"><view class="history-header data-v-df43cc4c"><text class="history-title data-v-df43cc4c">历史股票池回顾</text></view><view class="date-range-row data-v-df43cc4c"><picker mode="date" fields="month" value="{{b}}" bindchange="{{c}}" class="date-picker-half data-v-df43cc4c"><view class="date-input data-v-df43cc4c"><text class="date-text data-v-df43cc4c">{{a}}</text></view></picker><text class="date-separator data-v-df43cc4c">至</text><picker mode="date" fields="month" value="{{e}}" bindchange="{{f}}" class="date-picker-half data-v-df43cc4c"><view class="date-input data-v-df43cc4c"><text class="date-text data-v-df43cc4c">{{d}}</text></view></picker></view><view class="history-search-button-full data-v-df43cc4c" bindtap="{{g}}"><text class="search-button-text data-v-df43cc4c">🔍 查询历史数据</text></view><text class="history-tip data-v-df43cc4c">选择时间区间,查询该期间的入池股票及表现。</text></view>

+ 67 - 0
dist/dev/mp-weixin/components/HistorySearchCard.wxss

@@ -0,0 +1,67 @@
+
+.card.data-v-df43cc4c {
+  background: #ffffff;
+  border-radius: 24rpx;
+  box-shadow: 0 16rpx 40rpx rgba(37, 52, 94, 0.08);
+  margin-bottom: 32rpx;
+}
+.history-card.data-v-df43cc4c {
+  padding: 32rpx;
+}
+.history-header.data-v-df43cc4c {
+  display: flex;
+  align-items: center;
+  margin-bottom: 24rpx;
+}
+.history-title.data-v-df43cc4c {
+  font-size: 30rpx;
+  font-weight: 600;
+  color: #222222;
+}
+.date-range-row.data-v-df43cc4c {
+  display: flex;
+  align-items: center;
+  gap: 16rpx;
+  margin-bottom: 24rpx;
+}
+.date-picker-half.data-v-df43cc4c {
+  flex: 1;
+}
+.date-separator.data-v-df43cc4c {
+  font-size: 26rpx;
+  color: #666a7f;
+  padding: 0 8rpx;
+}
+.date-input.data-v-df43cc4c {
+  background: #f7f8fc;
+  border-radius: 12rpx;
+  padding: 24rpx;
+  font-size: 26rpx;
+  color: #222222;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+.date-text.data-v-df43cc4c {
+  flex: 1;
+}
+.history-search-button-full.data-v-df43cc4c {
+  width: 100%;
+  background: linear-gradient(135deg, #5d55e8, #7568ff);
+  border-radius: 16rpx;
+  padding: 28rpx 0;
+  text-align: center;
+  margin-top: 12rpx;
+  margin-bottom: 24rpx;
+  box-shadow: 0 8rpx 20rpx rgba(93, 85, 232, 0.3);
+}
+.search-button-text.data-v-df43cc4c {
+  font-size: 28rpx;
+  font-weight: 600;
+  color: #ffffff;
+}
+.history-tip.data-v-df43cc4c {
+  font-size: 24rpx;
+  color: #9ca2b5;
+  line-height: 1.6;
+}

+ 21 - 0
dist/dev/mp-weixin/components/PerformanceCard.js

@@ -0,0 +1,21 @@
+"use strict";
+const common_vendor = require("../common/vendor.js");
+const _sfc_main = {
+  __name: "PerformanceCard",
+  props: {
+    successRate: { type: String, default: "0%" },
+    profitRate: { type: String, default: "+0%" },
+    totalTrades: { type: [Number, String], default: 0 }
+  },
+  setup(__props) {
+    return (_ctx, _cache) => {
+      return {
+        a: common_vendor.t(__props.successRate),
+        b: common_vendor.t(__props.profitRate),
+        c: common_vendor.t(__props.totalTrades)
+      };
+    };
+  }
+};
+const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-7eda9556"], ["__file", "D:/program/gupiao-wx/src/components/PerformanceCard.vue"]]);
+wx.createComponent(Component);

+ 4 - 0
dist/dev/mp-weixin/components/PerformanceCard.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 1 - 0
dist/dev/mp-weixin/components/PerformanceCard.wxml

@@ -0,0 +1 @@
+<view class="card performance-card data-v-7eda9556"><view class="performance-item data-v-7eda9556"><text class="performance-label data-v-7eda9556">历史成功率</text><text class="performance-value success data-v-7eda9556">{{a}}</text></view><view class="performance-item data-v-7eda9556"><text class="performance-label data-v-7eda9556">平均收益率</text><text class="performance-value profit data-v-7eda9556">{{b}}</text></view><view class="performance-item data-v-7eda9556"><text class="performance-label data-v-7eda9556">总交易次数</text><text class="performance-value data-v-7eda9556">{{c}}</text></view></view>

+ 35 - 0
dist/dev/mp-weixin/components/PerformanceCard.wxss

@@ -0,0 +1,35 @@
+
+.card.data-v-7eda9556 {
+  background: #ffffff;
+  border-radius: 24rpx;
+  box-shadow: 0 16rpx 40rpx rgba(37, 52, 94, 0.08);
+  margin-bottom: 32rpx;
+}
+.performance-card.data-v-7eda9556 {
+  display: flex;
+  justify-content: space-around;
+  align-items: center;
+  background: #f7f8fc;
+  padding: 32rpx 24rpx;
+}
+.performance-item.data-v-7eda9556 {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+.performance-label.data-v-7eda9556 {
+  font-size: 24rpx;
+  color: #666a7f;
+  margin-bottom: 12rpx;
+}
+.performance-value.data-v-7eda9556 {
+  font-size: 32rpx;
+  font-weight: 700;
+  color: #222222;
+}
+.performance-value.success.data-v-7eda9556 {
+  color: #3abf81;
+}
+.performance-value.profit.data-v-7eda9556 {
+  color: #f16565;
+}

+ 36 - 0
dist/dev/mp-weixin/components/PurchaseModal.js

@@ -0,0 +1,36 @@
+"use strict";
+const common_vendor = require("../common/vendor.js");
+const _sfc_main = {
+  __name: "PurchaseModal",
+  props: {
+    visible: { type: Boolean, default: false },
+    icon: { type: String, default: "💰" },
+    title: { type: String, default: "打赏解锁" },
+    description: { type: String, default: "" },
+    amountLabel: { type: String, default: "打赏金额:" },
+    amount: { type: [Number, String], default: 1 }
+  },
+  emits: ["close", "confirm"],
+  setup(__props, { emit }) {
+    const onClose = () => emit("close");
+    const onConfirm = () => emit("confirm");
+    return (_ctx, _cache) => {
+      return common_vendor.e({
+        a: __props.visible
+      }, __props.visible ? {
+        b: common_vendor.o(onClose),
+        c: common_vendor.t(__props.icon),
+        d: common_vendor.t(__props.title),
+        e: common_vendor.t(__props.description),
+        f: common_vendor.t(__props.amountLabel),
+        g: common_vendor.t(__props.amount),
+        h: common_vendor.o(onConfirm),
+        i: common_vendor.o(() => {
+        }),
+        j: common_vendor.o(onClose)
+      } : {});
+    };
+  }
+};
+const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-1af578f4"], ["__file", "D:/program/gupiao-wx/src/components/PurchaseModal.vue"]]);
+wx.createComponent(Component);

+ 4 - 0
dist/dev/mp-weixin/components/PurchaseModal.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 1 - 0
dist/dev/mp-weixin/components/PurchaseModal.wxml

@@ -0,0 +1 @@
+<view wx:if="{{a}}" class="modal-overlay data-v-1af578f4" bindtap="{{j}}"><view class="modal-content data-v-1af578f4" catchtap="{{i}}"><view class="modal-close-btn data-v-1af578f4" bindtap="{{b}}"><text class="close-icon data-v-1af578f4">✕</text></view><view class="reward-header data-v-1af578f4"><text class="reward-icon data-v-1af578f4">{{c}}</text><text class="reward-title data-v-1af578f4">{{d}}</text></view><view class="reward-info data-v-1af578f4"><text class="reward-desc data-v-1af578f4">{{e}}</text><view class="reward-amount-simple data-v-1af578f4"><text class="amount-label data-v-1af578f4">{{f}}</text><text class="amount-value data-v-1af578f4">¥{{g}}</text></view></view><view class="modal-footer data-v-1af578f4"><view class="pay-button data-v-1af578f4" bindtap="{{h}}"><text class="pay-button-text data-v-1af578f4">确认支付</text></view><text class="agreement-text data-v-1af578f4">点击即表示同意《用户订阅协议》</text></view></view></view>

+ 102 - 0
dist/dev/mp-weixin/components/PurchaseModal.wxss

@@ -0,0 +1,102 @@
+
+.modal-overlay.data-v-1af578f4 {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 1000;
+}
+.modal-content.data-v-1af578f4 {
+  width: 640rpx;
+  background: #ffffff;
+  border-radius: 24rpx;
+  padding: 48rpx 40rpx 40rpx;
+  box-sizing: border-box;
+  position: relative;
+}
+.modal-close-btn.data-v-1af578f4 {
+  position: absolute;
+  top: 24rpx;
+  right: 24rpx;
+  width: 48rpx;
+  height: 48rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 10;
+}
+.close-icon.data-v-1af578f4 {
+  font-size: 36rpx;
+  color: #9ca2b5;
+  font-weight: 300;
+  line-height: 1;
+}
+.reward-header.data-v-1af578f4 {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  margin-bottom: 40rpx;
+}
+.reward-icon.data-v-1af578f4 {
+  font-size: 64rpx;
+  margin-bottom: 16rpx;
+}
+.reward-title.data-v-1af578f4 {
+  font-size: 32rpx;
+  font-weight: 600;
+  color: #222222;
+}
+.reward-info.data-v-1af578f4 {
+  margin-bottom: 40rpx;
+}
+.reward-desc.data-v-1af578f4 {
+  display: block;
+  font-size: 26rpx;
+  color: #666a7f;
+  text-align: center;
+  margin-bottom: 24rpx;
+  line-height: 1.6;
+}
+.reward-amount-simple.data-v-1af578f4 {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  gap: 8rpx;
+}
+.amount-label.data-v-1af578f4 {
+  font-size: 28rpx;
+  color: #666a7f;
+}
+.amount-value.data-v-1af578f4 {
+  font-size: 36rpx;
+  font-weight: 700;
+  color: #f16565;
+}
+.modal-footer.data-v-1af578f4 {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+.pay-button.data-v-1af578f4 {
+  width: 100%;
+  background: linear-gradient(135deg, #5d55e8, #7568ff);
+  border-radius: 16rpx;
+  padding: 28rpx 0;
+  text-align: center;
+  margin-bottom: 24rpx;
+  box-shadow: 0 8rpx 20rpx rgba(93, 85, 232, 0.3);
+}
+.pay-button-text.data-v-1af578f4 {
+  font-size: 30rpx;
+  font-weight: 600;
+  color: #ffffff;
+}
+.agreement-text.data-v-1af578f4 {
+  font-size: 22rpx;
+  color: #9ca2b5;
+}

+ 39 - 65
dist/dev/mp-weixin/pages/pool/pool.js

@@ -2,20 +2,18 @@
 const common_vendor = require("../../common/vendor.js");
 const utils_auth = require("../../utils/auth.js");
 require("../../utils/api.js");
+if (!Math) {
+  (PerformanceCard + HistorySearchCard + PurchaseModal)();
+}
+const PurchaseModal = () => "../../components/PurchaseModal.js";
+const PerformanceCard = () => "../../components/PerformanceCard.js";
+const HistorySearchCard = () => "../../components/HistorySearchCard.js";
 const _sfc_main = {
   __name: "pool",
   setup(__props) {
     const isPurchased = common_vendor.ref(false);
     const showModal = common_vendor.ref(false);
-    const startMonth = common_vendor.ref("2025-01");
-    const endMonth = common_vendor.ref("2025-11");
     const isLoggedIn = common_vendor.ref(false);
-    const formatMonth = (monthStr) => {
-      if (!monthStr)
-        return "请选择";
-      const [year, month] = monthStr.split("-");
-      return `${year}年${month}月`;
-    };
     const checkLogin = () => {
       isLoggedIn.value = utils_auth.isLoggedIn();
       return isLoggedIn.value;
@@ -29,8 +27,7 @@ const _sfc_main = {
         const purchaseInfo = common_vendor.index.getStorageSync("pool_purchase");
         if (purchaseInfo) {
           const now = Date.now();
-          const expireTime = purchaseInfo.expireTime;
-          if (now < expireTime) {
+          if (now < purchaseInfo.expireTime) {
             isPurchased.value = true;
           } else {
             common_vendor.index.removeStorageSync("pool_purchase");
@@ -53,9 +50,7 @@ const _sfc_main = {
           cancelText: "取消",
           success: (res) => {
             if (res.confirm) {
-              common_vendor.index.navigateTo({
-                url: "/pages/login/login"
-              });
+              common_vendor.index.navigateTo({ url: "/pages/login/login" });
             }
           }
         });
@@ -70,79 +65,58 @@ const _sfc_main = {
       const now = Date.now();
       const today = /* @__PURE__ */ new Date();
       today.setHours(23, 59, 59, 999);
-      const expireTime = today.getTime();
-      const purchaseInfo = {
+      common_vendor.index.setStorageSync("pool_purchase", {
         plan: "reward",
         purchaseTime: now,
-        expireTime
-      };
-      common_vendor.index.setStorageSync("pool_purchase", purchaseInfo);
+        expireTime: today.getTime()
+      });
       isPurchased.value = true;
       closePurchaseModal();
-      common_vendor.index.showToast({
-        title: "解锁成功",
-        icon: "success"
-      });
+      common_vendor.index.showToast({ title: "解锁成功", icon: "success" });
     };
-    const onStartMonthChange = (e) => {
-      startMonth.value = e.detail.value;
-    };
-    const onEndMonthChange = (e) => {
-      endMonth.value = e.detail.value;
-    };
-    const onHistorySearch = () => {
-      if (!startMonth.value || !endMonth.value) {
-        common_vendor.index.showToast({
-          title: "请选择开始和结束月份",
-          icon: "none"
-        });
-        return;
-      }
-      if (startMonth.value > endMonth.value) {
-        common_vendor.index.showToast({
-          title: "开始月份不能晚于结束月份",
-          icon: "none"
-        });
-        return;
-      }
+    const onHistorySearch = ({ startMonth, endMonth }) => {
+      const formatMonth = (monthStr) => {
+        const [year, month] = monthStr.split("-");
+        return `${year}年${month}月`;
+      };
       common_vendor.index.showToast({
-        title: `查询${formatMonth(startMonth.value)}至${formatMonth(endMonth.value)}`,
+        title: `查询${formatMonth(startMonth)}至${formatMonth(endMonth)}`,
         icon: "none",
         duration: 2e3
       });
     };
     common_vendor.onLoad(() => {
-      const loginStatus = checkLogin();
-      console.log("[超短池] 登录状态:", loginStatus);
+      console.log("[超短池] 登录状态:", checkLogin());
       checkPurchaseStatus();
     });
     common_vendor.onShow(() => {
-      const loginStatus = checkLogin();
-      console.log("[超短池] 登录状态:", loginStatus);
+      console.log("[超短池] 登录状态:", checkLogin());
       checkPurchaseStatus();
       common_vendor.index.setNavigationBarTitle({ title: "量化交易大师" });
     });
     return (_ctx, _cache) => {
       return common_vendor.e({
-        a: !isPurchased.value
+        a: common_vendor.p({
+          successRate: "75%",
+          profitRate: "+3.2%",
+          totalTrades: 120
+        }),
+        b: !isPurchased.value
       }, !isPurchased.value ? {
-        b: common_vendor.o(showPurchaseModal)
+        c: common_vendor.o(showPurchaseModal)
       } : {}, {
-        c: common_vendor.t(formatMonth(startMonth.value)),
-        d: startMonth.value,
-        e: common_vendor.o(onStartMonthChange),
-        f: common_vendor.t(formatMonth(endMonth.value)),
-        g: endMonth.value,
-        h: common_vendor.o(onEndMonthChange),
-        i: common_vendor.o(onHistorySearch),
-        j: showModal.value
-      }, showModal.value ? {
-        k: common_vendor.o(closePurchaseModal),
-        l: common_vendor.o(handlePurchase),
-        m: common_vendor.o(() => {
-        }),
-        n: common_vendor.o(closePurchaseModal)
-      } : {});
+        d: common_vendor.o(onHistorySearch),
+        e: common_vendor.o(closePurchaseModal),
+        f: common_vendor.o(handlePurchase),
+        g: common_vendor.p({
+          visible: showModal.value,
+          icon: "💰",
+          title: "打赏解锁",
+          description: "支持作者,解锁今日超短池内容",
+          amountLabel: "打赏金额:",
+          amount: 1
+        })
+      });
     };
   }
 };

+ 5 - 1
dist/dev/mp-weixin/pages/pool/pool.json

@@ -1,4 +1,8 @@
 {
   "navigationBarTitleText": "量化交易大师",
-  "usingComponents": {}
+  "usingComponents": {
+    "purchase-modal": "../../components/PurchaseModal",
+    "performance-card": "../../components/PerformanceCard",
+    "history-search-card": "../../components/HistorySearchCard"
+  }
 }

Plik diff jest za duży
+ 0 - 0
dist/dev/mp-weixin/pages/pool/pool.wxml


+ 0 - 229
dist/dev/mp-weixin/pages/pool/pool.wxss

@@ -21,8 +21,6 @@
   box-shadow: 0 16rpx 40rpx rgba(37, 52, 94, 0.08);
   margin-bottom: 32rpx;
 }
-
-/* 超短精选池标题区域 */
 .pool-header-section {
   margin-bottom: 24rpx;
 }
@@ -44,43 +42,9 @@
   font-size: 26rpx;
   color: #666a7f;
 }
-
-/* 性能指标卡片 */
-.performance-card {
-  display: flex;
-  justify-content: space-around;
-  align-items: center;
-  background: #f7f8fc;
-  padding: 32rpx 24rpx;
-}
-.performance-item {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-}
-.performance-label {
-  font-size: 24rpx;
-  color: #666a7f;
-  margin-bottom: 12rpx;
-}
-.performance-value {
-  font-size: 32rpx;
-  font-weight: 700;
-  color: #222222;
-}
-.performance-value.success {
-  color: #3abf81;
-}
-.performance-value.profit {
-  color: #f16565;
-}
-
-/* 超短精选池卡片 */
 .pool-card {
   padding: 32rpx;
 }
-
-/* 锁定内容 */
 .locked-content {
   display: flex;
   flex-direction: column;
@@ -119,8 +83,6 @@
   font-weight: 600;
   color: #ffffff;
 }
-
-/* 已解锁内容 */
 .unlocked-content {
   margin-top: 32rpx;
 }
@@ -140,197 +102,6 @@
   font-size: 26rpx;
   color: #9ca2b5;
 }
-
-/* 历史股票池回顾 */
-.history-card {
-  padding: 32rpx;
-}
-.history-header {
-  display: flex;
-  align-items: center;
-  margin-bottom: 24rpx;
-}
-.history-icon {
-  font-size: 28rpx;
-  margin-right: 12rpx;
-}
-.history-title {
-  font-size: 30rpx;
-  font-weight: 600;
-  color: #222222;
-}
-.history-search-row {
-  display: flex;
-  align-items: center;
-}
-.date-range-row {
-  display: flex;
-  align-items: center;
-  gap: 16rpx;
-  margin-bottom: 24rpx;
-}
-.date-picker-half {
-  flex: 1;
-}
-.date-separator {
-  font-size: 26rpx;
-  color: #666a7f;
-  padding: 0 8rpx;
-}
-.date-input {
-  background: #f7f8fc;
-  border-radius: 12rpx;
-  padding: 24rpx;
-  font-size: 26rpx;
-  color: #222222;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-.date-text {
-  flex: 1;
-}
-.date-icon {
-  font-size: 28rpx;
-  margin-left: 12rpx;
-}
-.history-search-button-full {
-  width: 100%;
-  background: linear-gradient(135deg, #5d55e8, #7568ff);
-  border-radius: 16rpx;
-  padding: 28rpx 0;
-  text-align: center;
-  margin-top: 12rpx;
-  margin-bottom: 24rpx;
-  box-shadow: 0 8rpx 20rpx rgba(93, 85, 232, 0.3);
-}
-.search-button-text {
-  font-size: 28rpx;
-  font-weight: 600;
-  color: #ffffff;
-}
-.history-search-button {
-  width: 80rpx;
-  height: 80rpx;
-  background: #5d55e8;
-  border-radius: 12rpx;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  margin-left: 16rpx;
-}
-.search-icon {
-  font-size: 32rpx;
-  color: #ffffff;
-}
-.history-tip {
-  font-size: 24rpx;
-  color: #9ca2b5;
-  line-height: 1.6;
-}
-
-/* 购买弹窗 */
-.modal-overlay {
-  position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: rgba(0, 0, 0, 0.5);
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  z-index: 1000;
-}
-.modal-content {
-  width: 640rpx;
-  background: #ffffff;
-  border-radius: 24rpx;
-  padding: 48rpx 40rpx 40rpx;
-  box-sizing: border-box;
-  position: relative;
-}
-.modal-close-btn {
-  position: absolute;
-  top: 24rpx;
-  right: 24rpx;
-  width: 48rpx;
-  height: 48rpx;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  z-index: 10;
-}
-.close-icon {
-  font-size: 36rpx;
-  color: #9ca2b5;
-  font-weight: 300;
-  line-height: 1;
-}
-.reward-header {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  margin-bottom: 40rpx;
-}
-.reward-icon {
-  font-size: 64rpx;
-  margin-bottom: 16rpx;
-}
-.reward-title {
-  font-size: 32rpx;
-  font-weight: 600;
-  color: #222222;
-}
-.reward-info {
-  margin-bottom: 40rpx;
-}
-.reward-desc {
-  display: block;
-  font-size: 26rpx;
-  color: #666a7f;
-  text-align: center;
-  margin-bottom: 24rpx;
-  line-height: 1.6;
-}
-.reward-amount-simple {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  gap: 8rpx;
-}
-.amount-label {
-  font-size: 28rpx;
-  color: #666a7f;
-}
-.amount-value {
-  font-size: 36rpx;
-  font-weight: 700;
-  color: #f16565;
-}
-.modal-footer {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-}
-.pay-button {
-  width: 100%;
-  background: linear-gradient(135deg, #5d55e8, #7568ff);
-  border-radius: 16rpx;
-  padding: 28rpx 0;
-  text-align: center;
-  margin-bottom: 24rpx;
-  box-shadow: 0 8rpx 20rpx rgba(93, 85, 232, 0.3);
-}
-.pay-button-text {
-  font-size: 30rpx;
-  font-weight: 600;
-  color: #ffffff;
-}
-.agreement-text {
-  font-size: 22rpx;
-  color: #9ca2b5;
-}
 .bottom-safe-area {
   height: 80rpx;
 }

+ 21 - 12
dist/dev/mp-weixin/pages/rank/rank.js

@@ -12,11 +12,18 @@ const _sfc_main = {
     const isLoggedIn = common_vendor.ref(false);
     const myStocks = common_vendor.ref([]);
     const viewMode = common_vendor.ref("list");
+    const swiperIndex = common_vendor.ref(0);
     const isLoading = common_vendor.ref(false);
     const lastLoadTime = common_vendor.ref(0);
     const CACHE_DURATION = 5e3;
     const setViewMode = (mode) => {
       viewMode.value = mode;
+      swiperIndex.value = mode === "list" ? 0 : 1;
+    };
+    const onSwiperChange = (e) => {
+      const index = e.detail.current;
+      swiperIndex.value = index;
+      viewMode.value = index === 0 ? "list" : "table";
     };
     const indexData = common_vendor.ref({
       stockCode: "000001",
@@ -292,7 +299,9 @@ const _sfc_main = {
         j: common_vendor.o(($event) => setViewMode("list")),
         k: viewMode.value === "table" ? 1 : "",
         l: common_vendor.o(($event) => setViewMode("table")),
-        m: common_vendor.f(myStocks.value, (stock, index, i0) => {
+        m: myStocks.value.length > 0
+      }, myStocks.value.length > 0 ? {
+        n: common_vendor.f(myStocks.value, (stock, index, i0) => {
           return {
             a: stock.code,
             b: common_vendor.o(($event) => removeStock(index), stock.code),
@@ -303,9 +312,10 @@ const _sfc_main = {
               ["show-delete"]: true
             })
           };
-        }),
-        n: viewMode.value === "list",
-        o: myStocks.value.length === 0 ? 1 : "",
+        })
+      } : {}, {
+        o: myStocks.value.length > 0
+      }, myStocks.value.length > 0 ? {
         p: common_vendor.f(myStocks.value, (stock, index, i0) => {
           return {
             a: common_vendor.t(stock.name),
@@ -319,15 +329,14 @@ const _sfc_main = {
             i: stock.code,
             j: common_vendor.o(($event) => handleStockClick(stock, index), stock.code)
           };
-        }),
-        q: viewMode.value === "table",
-        r: myStocks.value.length === 0 ? 1 : "",
-        s: myStocks.value.length === 0
-      }, myStocks.value.length === 0 ? {} : {}, {
-        t: !isLoggedIn.value ? 1 : "",
-        v: !isLoggedIn.value
+        })
+      } : {}, {
+        q: swiperIndex.value,
+        r: common_vendor.o(onSwiperChange),
+        s: !isLoggedIn.value ? 1 : "",
+        t: !isLoggedIn.value
       }, !isLoggedIn.value ? {
-        w: common_vendor.o(goToLogin)
+        v: common_vendor.o(goToLogin)
       } : {});
     };
   }

Plik diff jest za duży
+ 0 - 0
dist/dev/mp-weixin/pages/rank/rank.wxml


+ 9 - 0
dist/dev/mp-weixin/pages/rank/rank.wxss

@@ -116,6 +116,15 @@
   color: #E53935;
 }
 
+/* 滑动切换容器 */
+.view-swiper {
+  height: calc(100vh - 380rpx);
+  width: 100%;
+}
+.swiper-scroll {
+  height: 100%;
+}
+
 /* 隐藏空列表 */
 .hidden-list {
   display: none !important;

+ 46 - 93
dist/dev/mp-weixin/pages/strong/strong.js

@@ -2,29 +2,21 @@
 const common_vendor = require("../../common/vendor.js");
 const utils_auth = require("../../utils/auth.js");
 const utils_api = require("../../utils/api.js");
+if (!Math) {
+  (PerformanceCard + HistorySearchCard + PurchaseModal)();
+}
+const PurchaseModal = () => "../../components/PurchaseModal.js";
+const PerformanceCard = () => "../../components/PerformanceCard.js";
+const HistorySearchCard = () => "../../components/HistorySearchCard.js";
 const _sfc_main = {
   __name: "strong",
   setup(__props) {
     const isPurchased = common_vendor.ref(false);
     const showModal = common_vendor.ref(false);
     const stockList = common_vendor.ref([
-      {
-        name: "信维通信",
-        code: "300136"
-      },
-      {
-        name: "中国卫星",
-        code: "600118"
-      }
+      { name: "信维通信", code: "300136" },
+      { name: "中国卫星", code: "600118" }
     ]);
-    const startMonth = common_vendor.ref("2025-01");
-    const endMonth = common_vendor.ref("2025-11");
-    const formatMonth = (monthStr) => {
-      if (!monthStr)
-        return "请选择";
-      const [year, month] = monthStr.split("-");
-      return `${year}年${month}月`;
-    };
     const checkPurchaseStatus = () => {
       if (!utils_auth.isLoggedIn()) {
         isPurchased.value = false;
@@ -34,8 +26,7 @@ const _sfc_main = {
         const purchaseInfo = common_vendor.index.getStorageSync("strong_pool_purchase");
         if (purchaseInfo) {
           const now = Date.now();
-          const expireTime = purchaseInfo.expireTime;
-          if (now < expireTime) {
+          if (now < purchaseInfo.expireTime) {
             isPurchased.value = true;
           } else {
             common_vendor.index.removeStorageSync("strong_pool_purchase");
@@ -58,9 +49,7 @@ const _sfc_main = {
           cancelText: "取消",
           success: (res) => {
             if (res.confirm) {
-              common_vendor.index.navigateTo({
-                url: "/pages/login/login"
-              });
+              common_vendor.index.navigateTo({ url: "/pages/login/login" });
             }
           }
         });
@@ -74,42 +63,22 @@ const _sfc_main = {
     const handlePurchase = () => {
       const now = Date.now();
       const expireTime = now + 365 * 24 * 60 * 60 * 1e3;
-      const purchaseInfo = {
+      common_vendor.index.setStorageSync("strong_pool_purchase", {
         plan: "yearly",
         purchaseTime: now,
         expireTime
-      };
-      common_vendor.index.setStorageSync("strong_pool_purchase", purchaseInfo);
+      });
       isPurchased.value = true;
       closePurchaseModal();
-      common_vendor.index.showToast({
-        title: "解锁成功",
-        icon: "success"
-      });
-    };
-    const onStartMonthChange = (e) => {
-      startMonth.value = e.detail.value;
-    };
-    const onEndMonthChange = (e) => {
-      endMonth.value = e.detail.value;
+      common_vendor.index.showToast({ title: "解锁成功", icon: "success" });
     };
-    const onHistorySearch = () => {
-      if (!startMonth.value || !endMonth.value) {
-        common_vendor.index.showToast({
-          title: "请选择开始和结束月份",
-          icon: "none"
-        });
-        return;
-      }
-      if (startMonth.value > endMonth.value) {
-        common_vendor.index.showToast({
-          title: "开始月份不能晚于结束月份",
-          icon: "none"
-        });
-        return;
-      }
+    const onHistorySearch = ({ startMonth, endMonth }) => {
+      const formatMonth = (monthStr) => {
+        const [year, month] = monthStr.split("-");
+        return `${year}年${month}月`;
+      };
       common_vendor.index.showToast({
-        title: `查询${formatMonth(startMonth.value)}至${formatMonth(endMonth.value)}`,
+        title: `查询${formatMonth(startMonth)}至${formatMonth(endMonth)}`,
         icon: "none",
         duration: 2e3
       });
@@ -134,65 +103,52 @@ const _sfc_main = {
         let currentPrice = null;
         try {
           const quoteRes = await utils_api.getStockQuotes(stock.code);
-          console.log("[添加股票] 行情数据:", JSON.stringify(quoteRes));
           if (quoteRes.code === 200 && quoteRes.data && quoteRes.data.length > 0) {
-            const quoteData = quoteRes.data[0];
-            currentPrice = quoteData.currentPrice;
+            currentPrice = quoteRes.data[0].currentPrice;
           }
         } catch (e) {
           console.error("获取行情数据失败:", e);
         }
-        console.log("[添加股票] 请求参数:", { stockCode: stock.code, stockName: stock.name, currentPrice });
         const addRes = await utils_api.addUserStock({
           stockCode: stock.code,
           stockName: stock.name,
           currentPrice
         });
-        console.log("[添加股票] 服务器返回:", JSON.stringify(addRes));
         common_vendor.index.hideLoading();
         if (addRes.code === 200 && addRes.data === true) {
-          common_vendor.index.showToast({
-            title: "添加成功",
-            icon: "success"
-          });
+          common_vendor.index.showToast({ title: "添加成功", icon: "success" });
         } else if (addRes.code === 200 && addRes.data === false) {
-          common_vendor.index.showToast({
-            title: "股票已存在",
-            icon: "none"
-          });
+          common_vendor.index.showToast({ title: "股票已存在", icon: "none" });
         } else {
-          common_vendor.index.showToast({
-            title: addRes.message || "添加失败",
-            icon: "none"
-          });
+          common_vendor.index.showToast({ title: addRes.message || "添加失败", icon: "none" });
         }
       } catch (e) {
         common_vendor.index.hideLoading();
         console.error("添加股票失败:", e);
-        common_vendor.index.showToast({
-          title: "添加失败",
-          icon: "none"
-        });
+        common_vendor.index.showToast({ title: "添加失败", icon: "none" });
       }
     };
     common_vendor.onLoad(() => {
-      const loginStatus = utils_auth.isLoggedIn();
-      console.log("[强势池] 登录状态:", loginStatus);
+      console.log("[强势池] 登录状态:", utils_auth.isLoggedIn());
       checkPurchaseStatus();
     });
     common_vendor.onShow(() => {
-      const loginStatus = utils_auth.isLoggedIn();
-      console.log("[强势池] 登录状态:", loginStatus);
+      console.log("[强势池] 登录状态:", utils_auth.isLoggedIn());
       checkPurchaseStatus();
       common_vendor.index.setNavigationBarTitle({ title: "量化交易大师" });
     });
     return (_ctx, _cache) => {
       return common_vendor.e({
-        a: !isPurchased.value
+        a: common_vendor.p({
+          successRate: "88%",
+          profitRate: "+12.5%",
+          totalTrades: 45
+        }),
+        b: !isPurchased.value
       }, !isPurchased.value ? {
-        b: common_vendor.o(showPurchaseModal)
+        c: common_vendor.o(showPurchaseModal)
       } : {
-        c: common_vendor.f(stockList.value, (stock, index, i0) => {
+        d: common_vendor.f(stockList.value, (stock, index, i0) => {
           return {
             a: common_vendor.t(stock.name),
             b: common_vendor.t(stock.code),
@@ -201,21 +157,18 @@ const _sfc_main = {
           };
         })
       }, {
-        d: common_vendor.t(formatMonth(startMonth.value)),
-        e: startMonth.value,
-        f: common_vendor.o(onStartMonthChange),
-        g: common_vendor.t(formatMonth(endMonth.value)),
-        h: endMonth.value,
-        i: common_vendor.o(onEndMonthChange),
-        j: common_vendor.o(onHistorySearch),
-        k: showModal.value
-      }, showModal.value ? {
-        l: common_vendor.o(closePurchaseModal),
-        m: common_vendor.o(handlePurchase),
-        n: common_vendor.o(() => {
-        }),
-        o: common_vendor.o(closePurchaseModal)
-      } : {});
+        e: common_vendor.o(onHistorySearch),
+        f: common_vendor.o(closePurchaseModal),
+        g: common_vendor.o(handlePurchase),
+        h: common_vendor.p({
+          visible: showModal.value,
+          icon: "📅",
+          title: "年订阅解锁",
+          description: "订阅全年,解锁强势趋势池内容",
+          amountLabel: "订阅金额:",
+          amount: 98
+        })
+      });
     };
   }
 };

+ 5 - 1
dist/dev/mp-weixin/pages/strong/strong.json

@@ -1,4 +1,8 @@
 {
   "navigationBarTitleText": "量化交易大师",
-  "usingComponents": {}
+  "usingComponents": {
+    "purchase-modal": "../../components/PurchaseModal",
+    "performance-card": "../../components/PerformanceCard",
+    "history-search-card": "../../components/HistorySearchCard"
+  }
 }

Plik diff jest za duży
+ 0 - 0
dist/dev/mp-weixin/pages/strong/strong.wxml


+ 39 - 277
dist/dev/mp-weixin/pages/strong/strong.wxss

@@ -21,8 +21,6 @@
   box-shadow: 0 16rpx 40rpx rgba(37, 52, 94, 0.08);
   margin-bottom: 32rpx;
 }
-
-/* 强势趋势池标题区域 */
 .pool-header-section {
   margin-bottom: 24rpx;
 }
@@ -44,40 +42,55 @@
   font-size: 26rpx;
   color: #666a7f;
 }
-
-/* 性能指标卡片 */
-.performance-card {
-  display: flex;
-  justify-content: space-around;
-  align-items: center;
-  background: #f7f8fc;
-  padding: 32rpx 24rpx;
+.pool-card {
+  padding: 32rpx;
 }
-.performance-item {
+.locked-content {
   display: flex;
   flex-direction: column;
   align-items: center;
+  padding: 60rpx 0 40rpx;
 }
-.performance-label {
-  font-size: 24rpx;
-  color: #666a7f;
-  margin-bottom: 12rpx;
+.lock-icon-wrapper {
+  margin-bottom: 32rpx;
 }
-.performance-value {
-  font-size: 32rpx;
-  font-weight: 700;
+.lock-icon {
+  font-size: 80rpx;
+}
+.lock-text {
+  font-size: 28rpx;
   color: #222222;
+  margin-bottom: 16rpx;
+  text-align: center;
 }
-.performance-value.success {
-  color: #3abf81;
+.lock-desc {
+  font-size: 24rpx;
+  color: #9ca2b5;
+  margin-bottom: 48rpx;
+  text-align: center;
+  line-height: 1.6;
 }
-.performance-value.profit {
-  color: #f16565;
+.unlock-button {
+  width: 100%;
+  background: linear-gradient(135deg, #5d55e8, #7568ff);
+  border-radius: 16rpx;
+  padding: 28rpx 0;
+  text-align: center;
+  box-shadow: 0 12rpx 24rpx rgba(93, 85, 232, 0.4);
 }
-
-/* 股票池卡片 */
-.pool-card {
-  padding: 32rpx;
+.unlock-button-text {
+  font-size: 30rpx;
+  font-weight: 600;
+  color: #ffffff;
+}
+.unlocked-content {
+  margin-top: 32rpx;
+}
+.unlocked-tip {
+  font-size: 26rpx;
+  color: #3abf81;
+  margin-bottom: 24rpx;
+  display: block;
 }
 .stock-item {
   display: flex;
@@ -95,7 +108,6 @@
 .stock-name-row {
   display: flex;
   align-items: center;
-  margin-bottom: 12rpx;
 }
 .stock-name {
   font-size: 28rpx;
@@ -110,11 +122,6 @@
 .stock-right {
   display: flex;
   align-items: center;
-  gap: 16rpx;
-}
-.stock-actions {
-  display: flex;
-  gap: 12rpx;
 }
 .action-btn {
   width: 56rpx;
@@ -133,251 +140,6 @@
   font-weight: 700;
   color: #ffffff;
 }
-
-/* 历史股票池回顾 */
-.history-card {
-  padding: 32rpx;
-}
-.history-header {
-  display: flex;
-  align-items: center;
-  margin-bottom: 24rpx;
-}
-.history-icon {
-  font-size: 28rpx;
-  margin-right: 12rpx;
-}
-.history-title {
-  font-size: 30rpx;
-  font-weight: 600;
-  color: #222222;
-}
-.history-search-row {
-  display: flex;
-  align-items: center;
-}
-.date-range-row {
-  display: flex;
-  align-items: center;
-  gap: 16rpx;
-  margin-bottom: 24rpx;
-}
-.date-picker-half {
-  flex: 1;
-}
-.date-separator {
-  font-size: 26rpx;
-  color: #666a7f;
-  padding: 0 8rpx;
-}
-.date-input {
-  background: #f7f8fc;
-  border-radius: 12rpx;
-  padding: 24rpx;
-  font-size: 26rpx;
-  color: #222222;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-.date-text {
-  flex: 1;
-}
-.date-icon {
-  font-size: 28rpx;
-  margin-left: 12rpx;
-}
-.history-search-button-full {
-  width: 100%;
-  background: linear-gradient(135deg, #5d55e8, #7568ff);
-  border-radius: 16rpx;
-  padding: 28rpx 0;
-  text-align: center;
-  margin-top: 12rpx;
-  margin-bottom: 24rpx;
-  box-shadow: 0 8rpx 20rpx rgba(93, 85, 232, 0.3);
-}
-.search-button-text {
-  font-size: 28rpx;
-  font-weight: 600;
-  color: #ffffff;
-}
-.history-tip {
-  font-size: 24rpx;
-  color: #9ca2b5;
-  line-height: 1.6;
-}
-.history-search-button {
-  width: 80rpx;
-  height: 80rpx;
-  background: #5d55e8;
-  border-radius: 12rpx;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  margin-left: 16rpx;
-}
-.search-icon {
-  font-size: 32rpx;
-  color: #ffffff;
-}
-
-/* 弹窗样式 */
-.modal-overlay {
-  position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: rgba(0, 0, 0, 0.5);
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  z-index: 1000;
-}
-.modal-content {
-  width: 640rpx;
-  background: #ffffff;
-  border-radius: 24rpx;
-  padding: 48rpx 40rpx 40rpx;
-  box-sizing: border-box;
-  position: relative;
-}
-.modal-close-btn {
-  position: absolute;
-  top: 24rpx;
-  right: 24rpx;
-  width: 48rpx;
-  height: 48rpx;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  z-index: 10;
-}
-.close-icon {
-  font-size: 36rpx;
-  color: #9ca2b5;
-  font-weight: 300;
-  line-height: 1;
-}
-.reward-header {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  margin-bottom: 40rpx;
-}
-.reward-icon {
-  font-size: 64rpx;
-  margin-bottom: 16rpx;
-}
-.reward-title {
-  font-size: 32rpx;
-  font-weight: 600;
-  color: #222222;
-}
-.reward-info {
-  margin-bottom: 40rpx;
-}
-.reward-desc {
-  display: block;
-  font-size: 26rpx;
-  color: #666a7f;
-  text-align: center;
-  margin-bottom: 24rpx;
-  line-height: 1.6;
-}
-.reward-amount-simple {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  gap: 8rpx;
-}
-.amount-label {
-  font-size: 28rpx;
-  color: #666a7f;
-}
-.amount-value {
-  font-size: 36rpx;
-  font-weight: 700;
-  color: #f16565;
-}
-.modal-footer {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-}
-.pay-button {
-  width: 100%;
-  background: linear-gradient(135deg, #5d55e8, #7568ff);
-  border-radius: 16rpx;
-  padding: 28rpx 0;
-  text-align: center;
-  margin-bottom: 24rpx;
-  box-shadow: 0 8rpx 20rpx rgba(93, 85, 232, 0.3);
-}
-.pay-button-text {
-  font-size: 30rpx;
-  font-weight: 600;
-  color: #ffffff;
-}
-.agreement-text {
-  font-size: 22rpx;
-  color: #9ca2b5;
-}
-.bottom-safe-area {
-  height: 80rpx;
-}
-
-/* 锁定内容样式 */
-.locked-content {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  padding: 60rpx 0 40rpx;
-}
-.lock-icon-wrapper {
-  margin-bottom: 32rpx;
-}
-.locked-content .lock-icon {
-  font-size: 80rpx;
-}
-.lock-text {
-  font-size: 28rpx;
-  color: #222222;
-  margin-bottom: 16rpx;
-  text-align: center;
-}
-.lock-desc {
-  font-size: 24rpx;
-  color: #9ca2b5;
-  margin-bottom: 48rpx;
-  text-align: center;
-  line-height: 1.6;
-}
-.locked-content .unlock-button {
-  width: 100%;
-  background: linear-gradient(135deg, #5d55e8, #7568ff);
-  border-radius: 16rpx;
-  padding: 28rpx 0;
-  text-align: center;
-  box-shadow: 0 12rpx 24rpx rgba(93, 85, 232, 0.4);
-}
-.locked-content .unlock-button-text {
-  font-size: 30rpx;
-  font-weight: 600;
-  color: #ffffff;
-}
-
-/* 已解锁内容样式 */
-.unlocked-content {
-  margin-top: 32rpx;
-}
-.unlocked-tip {
-  font-size: 26rpx;
-  color: #3abf81;
-  margin-bottom: 24rpx;
-  display: block;
-}
 .bottom-safe-area {
   height: 80rpx;
 }

+ 166 - 0
src/components/HistorySearchCard.vue

@@ -0,0 +1,166 @@
+<template>
+  <view class="card history-card">
+    <view class="history-header">
+      <text class="history-title">历史股票池回顾</text>
+    </view>
+    
+    <!-- 月份区间选择 -->
+    <view class="date-range-row">
+      <picker 
+        mode="date"
+        fields="month"
+        :value="startMonth"
+        @change="onStartMonthChange"
+        class="date-picker-half"
+      >
+        <view class="date-input">
+          <text class="date-text">{{ formatMonth(startMonth) }}</text>
+        </view>
+      </picker>
+      
+      <text class="date-separator">至</text>
+      
+      <picker 
+        mode="date"
+        fields="month"
+        :value="endMonth"
+        @change="onEndMonthChange"
+        class="date-picker-half"
+      >
+        <view class="date-input">
+          <text class="date-text">{{ formatMonth(endMonth) }}</text>
+        </view>
+      </picker>
+    </view>
+    
+    <!-- 查询按钮 -->
+    <view class="history-search-button-full" @click="onSearch">
+      <text class="search-button-text">🔍 查询历史数据</text>
+    </view>
+    
+    <text class="history-tip">选择时间区间,查询该期间的入池股票及表现。</text>
+  </view>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+
+const props = defineProps({
+  defaultStartMonth: { type: String, default: '2025-01' },
+  defaultEndMonth: { type: String, default: '2025-11' }
+})
+
+const emit = defineEmits(['search'])
+
+const startMonth = ref(props.defaultStartMonth)
+const endMonth = ref(props.defaultEndMonth)
+
+// 格式化月份显示
+const formatMonth = (monthStr) => {
+  if (!monthStr) return '请选择'
+  const [year, month] = monthStr.split('-')
+  return `${year}年${month}月`
+}
+
+const onStartMonthChange = (e) => {
+  startMonth.value = e.detail.value
+}
+
+const onEndMonthChange = (e) => {
+  endMonth.value = e.detail.value
+}
+
+const onSearch = () => {
+  if (!startMonth.value || !endMonth.value) {
+    uni.showToast({ title: '请选择开始和结束月份', icon: 'none' })
+    return
+  }
+  
+  if (startMonth.value > endMonth.value) {
+    uni.showToast({ title: '开始月份不能晚于结束月份', icon: 'none' })
+    return
+  }
+  
+  emit('search', { startMonth: startMonth.value, endMonth: endMonth.value })
+}
+</script>
+
+<style scoped>
+.card {
+  background: #ffffff;
+  border-radius: 24rpx;
+  box-shadow: 0 16rpx 40rpx rgba(37, 52, 94, 0.08);
+  margin-bottom: 32rpx;
+}
+
+.history-card {
+  padding: 32rpx;
+}
+
+.history-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 24rpx;
+}
+
+.history-title {
+  font-size: 30rpx;
+  font-weight: 600;
+  color: #222222;
+}
+
+.date-range-row {
+  display: flex;
+  align-items: center;
+  gap: 16rpx;
+  margin-bottom: 24rpx;
+}
+
+.date-picker-half {
+  flex: 1;
+}
+
+.date-separator {
+  font-size: 26rpx;
+  color: #666a7f;
+  padding: 0 8rpx;
+}
+
+.date-input {
+  background: #f7f8fc;
+  border-radius: 12rpx;
+  padding: 24rpx;
+  font-size: 26rpx;
+  color: #222222;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.date-text {
+  flex: 1;
+}
+
+.history-search-button-full {
+  width: 100%;
+  background: linear-gradient(135deg, #5d55e8, #7568ff);
+  border-radius: 16rpx;
+  padding: 28rpx 0;
+  text-align: center;
+  margin-top: 12rpx;
+  margin-bottom: 24rpx;
+  box-shadow: 0 8rpx 20rpx rgba(93, 85, 232, 0.3);
+}
+
+.search-button-text {
+  font-size: 28rpx;
+  font-weight: 600;
+  color: #ffffff;
+}
+
+.history-tip {
+  font-size: 24rpx;
+  color: #9ca2b5;
+  line-height: 1.6;
+}
+</style>

+ 67 - 0
src/components/PerformanceCard.vue

@@ -0,0 +1,67 @@
+<template>
+  <view class="card performance-card">
+    <view class="performance-item">
+      <text class="performance-label">历史成功率</text>
+      <text class="performance-value success">{{ successRate }}</text>
+    </view>
+    <view class="performance-item">
+      <text class="performance-label">平均收益率</text>
+      <text class="performance-value profit">{{ profitRate }}</text>
+    </view>
+    <view class="performance-item">
+      <text class="performance-label">总交易次数</text>
+      <text class="performance-value">{{ totalTrades }}</text>
+    </view>
+  </view>
+</template>
+
+<script setup>
+defineProps({
+  successRate: { type: String, default: '0%' },
+  profitRate: { type: String, default: '+0%' },
+  totalTrades: { type: [Number, String], default: 0 }
+})
+</script>
+
+<style scoped>
+.card {
+  background: #ffffff;
+  border-radius: 24rpx;
+  box-shadow: 0 16rpx 40rpx rgba(37, 52, 94, 0.08);
+  margin-bottom: 32rpx;
+}
+
+.performance-card {
+  display: flex;
+  justify-content: space-around;
+  align-items: center;
+  background: #f7f8fc;
+  padding: 32rpx 24rpx;
+}
+
+.performance-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+.performance-label {
+  font-size: 24rpx;
+  color: #666a7f;
+  margin-bottom: 12rpx;
+}
+
+.performance-value {
+  font-size: 32rpx;
+  font-weight: 700;
+  color: #222222;
+}
+
+.performance-value.success {
+  color: #3abf81;
+}
+
+.performance-value.profit {
+  color: #f16565;
+}
+</style>

+ 164 - 0
src/components/PurchaseModal.vue

@@ -0,0 +1,164 @@
+<template>
+  <view v-if="visible" class="modal-overlay" @click="onClose">
+    <view class="modal-content" @click.stop>
+      <view class="modal-close-btn" @click="onClose">
+        <text class="close-icon">✕</text>
+      </view>
+      
+      <view class="reward-header">
+        <text class="reward-icon">{{ icon }}</text>
+        <text class="reward-title">{{ title }}</text>
+      </view>
+      
+      <view class="reward-info">
+        <text class="reward-desc">{{ description }}</text>
+        <view class="reward-amount-simple">
+          <text class="amount-label">{{ amountLabel }}</text>
+          <text class="amount-value">¥{{ amount }}</text>
+        </view>
+      </view>
+
+      <view class="modal-footer">
+        <view class="pay-button" @click="onConfirm">
+          <text class="pay-button-text">确认支付</text>
+        </view>
+        <text class="agreement-text">点击即表示同意《用户订阅协议》</text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script setup>
+defineProps({
+  visible: { type: Boolean, default: false },
+  icon: { type: String, default: '💰' },
+  title: { type: String, default: '打赏解锁' },
+  description: { type: String, default: '' },
+  amountLabel: { type: String, default: '打赏金额:' },
+  amount: { type: [Number, String], default: 1 }
+})
+
+const emit = defineEmits(['close', 'confirm'])
+
+const onClose = () => emit('close')
+const onConfirm = () => emit('confirm')
+</script>
+
+<style scoped>
+.modal-overlay {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 1000;
+}
+
+.modal-content {
+  width: 640rpx;
+  background: #ffffff;
+  border-radius: 24rpx;
+  padding: 48rpx 40rpx 40rpx;
+  box-sizing: border-box;
+  position: relative;
+}
+
+.modal-close-btn {
+  position: absolute;
+  top: 24rpx;
+  right: 24rpx;
+  width: 48rpx;
+  height: 48rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 10;
+}
+
+.close-icon {
+  font-size: 36rpx;
+  color: #9ca2b5;
+  font-weight: 300;
+  line-height: 1;
+}
+
+.reward-header {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  margin-bottom: 40rpx;
+}
+
+.reward-icon {
+  font-size: 64rpx;
+  margin-bottom: 16rpx;
+}
+
+.reward-title {
+  font-size: 32rpx;
+  font-weight: 600;
+  color: #222222;
+}
+
+.reward-info {
+  margin-bottom: 40rpx;
+}
+
+.reward-desc {
+  display: block;
+  font-size: 26rpx;
+  color: #666a7f;
+  text-align: center;
+  margin-bottom: 24rpx;
+  line-height: 1.6;
+}
+
+.reward-amount-simple {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  gap: 8rpx;
+}
+
+.amount-label {
+  font-size: 28rpx;
+  color: #666a7f;
+}
+
+.amount-value {
+  font-size: 36rpx;
+  font-weight: 700;
+  color: #f16565;
+}
+
+.modal-footer {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+.pay-button {
+  width: 100%;
+  background: linear-gradient(135deg, #5d55e8, #7568ff);
+  border-radius: 16rpx;
+  padding: 28rpx 0;
+  text-align: center;
+  margin-bottom: 24rpx;
+  box-shadow: 0 8rpx 20rpx rgba(93, 85, 232, 0.3);
+}
+
+.pay-button-text {
+  font-size: 30rpx;
+  font-weight: 600;
+  color: #ffffff;
+}
+
+.agreement-text {
+  font-size: 22rpx;
+  color: #9ca2b5;
+}
+</style>

+ 33 - 414
src/pages/pool/pool.vue

@@ -12,20 +12,11 @@
         </view>
 
         <!-- 性能指标卡片 -->
-        <view class="card performance-card">
-          <view class="performance-item">
-            <text class="performance-label">历史成功率</text>
-            <text class="performance-value success">75%</text>
-          </view>
-          <view class="performance-item">
-            <text class="performance-label">平均收益率</text>
-            <text class="performance-value profit">+3.2%</text>
-          </view>
-          <view class="performance-item">
-            <text class="performance-label">总交易次数</text>
-            <text class="performance-value">120</text>
-          </view>
-        </view>
+        <PerformanceCard 
+          successRate="75%" 
+          profitRate="+3.2%" 
+          :totalTrades="120" 
+        />
 
         <!-- 超短精选池区域 -->
         <view class="card pool-card">
@@ -44,7 +35,6 @@
           <!-- 已购买时显示内容 -->
           <view v-else class="unlocked-content">
             <text class="unlocked-tip">您已解锁,可以查看超短精选池内容</text>
-            <!-- 这里可以显示实际的股票池内容 -->
             <view class="stock-list-placeholder">
               <text class="placeholder-text">股票池内容将在此显示</text>
             </view>
@@ -52,47 +42,7 @@
         </view>
 
         <!-- 历史股票池回顾 -->
-        <view class="card history-card">
-          <view class="history-header">
-            <text class="history-title">历史股票池回顾</text>
-          </view>
-          
-          <!-- 月份区间选择 -->
-          <view class="date-range-row">
-            <picker 
-              mode="date"
-              fields="month"
-              :value="startMonth"
-              @change="onStartMonthChange"
-              class="date-picker-half"
-            >
-              <view class="date-input">
-                <text class="date-text">{{ formatMonth(startMonth) }}</text>
-              </view>
-            </picker>
-            
-            <text class="date-separator">至</text>
-            
-            <picker 
-              mode="date"
-              fields="month"
-              :value="endMonth"
-              @change="onEndMonthChange"
-              class="date-picker-half"
-            >
-              <view class="date-input">
-                <text class="date-text">{{ formatMonth(endMonth) }}</text>
-              </view>
-            </picker>
-          </view>
-          
-          <!-- 查询按钮 -->
-          <view class="history-search-button-full" @click="onHistorySearch">
-            <text class="search-button-text">🔍 查询历史数据</text>
-          </view>
-          
-          <text class="history-tip">选择时间区间,查询该期间的入池股票及表现。</text>
-        </view>
+        <HistorySearchCard @search="onHistorySearch" />
 
         <!-- 预留底部空间 -->
         <view class="bottom-safe-area"></view>
@@ -100,33 +50,16 @@
     </scroll-view>
 
     <!-- 购买弹窗 -->
-    <view v-if="showModal" class="modal-overlay" @click="closePurchaseModal">
-      <view class="modal-content" @click.stop>
-        <view class="modal-close-btn" @click="closePurchaseModal">
-          <text class="close-icon">✕</text>
-        </view>
-        
-        <view class="reward-header">
-          <text class="reward-icon">💰</text>
-          <text class="reward-title">打赏解锁</text>
-        </view>
-        
-        <view class="reward-info">
-          <text class="reward-desc">支持作者,解锁今日超短池内容</text>
-          <view class="reward-amount-simple">
-            <text class="amount-label">打赏金额:</text>
-            <text class="amount-value">¥1</text>
-          </view>
-        </view>
-
-        <view class="modal-footer">
-          <view class="pay-button" @click="handlePurchase">
-            <text class="pay-button-text">确认支付</text>
-          </view>
-          <text class="agreement-text">点击即表示同意《用户订阅协议》</text>
-        </view>
-      </view>
-    </view>
+    <PurchaseModal
+      :visible="showModal"
+      icon="💰"
+      title="打赏解锁"
+      description="支持作者,解锁今日超短池内容"
+      amountLabel="打赏金额:"
+      :amount="1"
+      @close="closePurchaseModal"
+      @confirm="handlePurchase"
+    />
   </view>
 </template>
 
@@ -134,20 +67,14 @@
 import { ref } from 'vue'
 import { onLoad, onShow } from '@dcloudio/uni-app'
 import { isLoggedIn as checkLoginStatus } from '../../utils/auth.js'
+import PurchaseModal from '../../components/PurchaseModal.vue'
+import PerformanceCard from '../../components/PerformanceCard.vue'
+import HistorySearchCard from '../../components/HistorySearchCard.vue'
 
 const isPurchased = ref(false)
 const showModal = ref(false)
-const startMonth = ref('2025-01')  // 开始月份
-const endMonth = ref('2025-11')    // 结束月份
 const isLoggedIn = ref(false)
 
-// 格式化月份显示
-const formatMonth = (monthStr) => {
-  if (!monthStr) return '请选择'
-  const [year, month] = monthStr.split('-')
-  return `${year}年${month}月`
-}
-
 // 检查登录状态
 const checkLogin = () => {
   isLoggedIn.value = checkLoginStatus()
@@ -156,7 +83,6 @@ const checkLogin = () => {
 
 // 检查购买状态
 const checkPurchaseStatus = () => {
-  // 先检查登录状态
   if (!checkLogin()) {
     isPurchased.value = false
     return
@@ -166,11 +92,9 @@ const checkPurchaseStatus = () => {
     const purchaseInfo = uni.getStorageSync('pool_purchase')
     if (purchaseInfo) {
       const now = Date.now()
-      const expireTime = purchaseInfo.expireTime
-      if (now < expireTime) {
+      if (now < purchaseInfo.expireTime) {
         isPurchased.value = true
       } else {
-        // 已过期,清除购买信息
         uni.removeStorageSync('pool_purchase')
         isPurchased.value = false
       }
@@ -185,7 +109,6 @@ const checkPurchaseStatus = () => {
 
 // 显示购买弹窗(需要登录)
 const showPurchaseModal = () => {
-  // 检查登录状态
   if (!checkLogin()) {
     uni.showModal({
       title: '登录提示',
@@ -194,101 +117,57 @@ const showPurchaseModal = () => {
       cancelText: '取消',
       success: (res) => {
         if (res.confirm) {
-          uni.navigateTo({
-            url: '/pages/login/login'
-          })
+          uni.navigateTo({ url: '/pages/login/login' })
         }
       }
     })
     return
   }
-  
   showModal.value = true
 }
 
-// 关闭购买弹窗
 const closePurchaseModal = () => {
   showModal.value = false
 }
 
 // 处理购买
 const handlePurchase = () => {
-  // 计算过期时间 - 当天23:59:59过期
   const now = Date.now()
   const today = new Date()
   today.setHours(23, 59, 59, 999)
-  const expireTime = today.getTime()
 
-  // 保存购买信息
-  const purchaseInfo = {
+  uni.setStorageSync('pool_purchase', {
     plan: 'reward',
     purchaseTime: now,
-    expireTime: expireTime
-  }
-  uni.setStorageSync('pool_purchase', purchaseInfo)
+    expireTime: today.getTime()
+  })
 
-  // 更新购买状态
   isPurchased.value = true
-
-  // 关闭弹窗
   closePurchaseModal()
-
-  // 显示成功提示
-  uni.showToast({
-    title: '解锁成功',
-    icon: 'success'
-  })
-}
-
-// 开始月份选择变化
-const onStartMonthChange = (e) => {
-  startMonth.value = e.detail.value
-}
-
-// 结束月份选择变化
-const onEndMonthChange = (e) => {
-  endMonth.value = e.detail.value
+  uni.showToast({ title: '解锁成功', icon: 'success' })
 }
 
 // 历史查询
-const onHistorySearch = () => {
-  if (!startMonth.value || !endMonth.value) {
-    uni.showToast({
-      title: '请选择开始和结束月份',
-      icon: 'none'
-    })
-    return
+const onHistorySearch = ({ startMonth, endMonth }) => {
+  const formatMonth = (monthStr) => {
+    const [year, month] = monthStr.split('-')
+    return `${year}年${month}月`
   }
-  
-  // 验证时间区间
-  if (startMonth.value > endMonth.value) {
-    uni.showToast({
-      title: '开始月份不能晚于结束月份',
-      icon: 'none'
-    })
-    return
-  }
-  
   uni.showToast({
-    title: `查询${formatMonth(startMonth.value)}至${formatMonth(endMonth.value)}`,
+    title: `查询${formatMonth(startMonth)}至${formatMonth(endMonth)}`,
     icon: 'none',
     duration: 2000
   })
 }
 
-// 使用uni-app生命周期钩子
 onLoad(() => {
-  const loginStatus = checkLogin()
-  console.log('[超短池] 登录状态:', loginStatus)
+  console.log('[超短池] 登录状态:', checkLogin())
   checkPurchaseStatus()
 })
 
 onShow(() => {
-  // 每次页面显示时都检查登录状态和购买状态
-  const loginStatus = checkLogin()
-  console.log('[超短池] 登录状态:', loginStatus)
+  console.log('[超短池] 登录状态:', checkLogin())
   checkPurchaseStatus()
-  // 设置导航栏标题
   uni.setNavigationBarTitle({ title: '量化交易大师' })
 })
 </script>
@@ -320,7 +199,6 @@ onShow(() => {
   margin-bottom: 32rpx;
 }
 
-/* 超短精选池标题区域 */
 .pool-header-section {
   margin-bottom: 24rpx;
 }
@@ -347,47 +225,10 @@ onShow(() => {
   color: #666a7f;
 }
 
-/* 性能指标卡片 */
-.performance-card {
-  display: flex;
-  justify-content: space-around;
-  align-items: center;
-  background: #f7f8fc;
-  padding: 32rpx 24rpx;
-}
-
-.performance-item {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-}
-
-.performance-label {
-  font-size: 24rpx;
-  color: #666a7f;
-  margin-bottom: 12rpx;
-}
-
-.performance-value {
-  font-size: 32rpx;
-  font-weight: 700;
-  color: #222222;
-}
-
-.performance-value.success {
-  color: #3abf81;
-}
-
-.performance-value.profit {
-  color: #f16565;
-}
-
-/* 超短精选池卡片 */
 .pool-card {
   padding: 32rpx;
 }
 
-/* 锁定内容 */
 .locked-content {
   display: flex;
   flex-direction: column;
@@ -433,7 +274,6 @@ onShow(() => {
   color: #ffffff;
 }
 
-/* 已解锁内容 */
 .unlocked-content {
   margin-top: 32rpx;
 }
@@ -457,228 +297,7 @@ onShow(() => {
   color: #9ca2b5;
 }
 
-/* 历史股票池回顾 */
-.history-card {
-  padding: 32rpx;
-}
-
-.history-header {
-  display: flex;
-  align-items: center;
-  margin-bottom: 24rpx;
-}
-
-.history-icon {
-  font-size: 28rpx;
-  margin-right: 12rpx;
-}
-
-.history-title {
-  font-size: 30rpx;
-  font-weight: 600;
-  color: #222222;
-}
-
-.history-search-row {
-  display: flex;
-  align-items: center;
-}
-
-.date-range-row {
-  display: flex;
-  align-items: center;
-  gap: 16rpx;
-  margin-bottom: 24rpx;
-}
-
-.date-picker-half {
-  flex: 1;
-}
-
-.date-separator {
-  font-size: 26rpx;
-  color: #666a7f;
-  padding: 0 8rpx;
-}
-
-.date-input {
-  background: #f7f8fc;
-  border-radius: 12rpx;
-  padding: 24rpx;
-  font-size: 26rpx;
-  color: #222222;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-
-.date-text {
-  flex: 1;
-}
-
-.date-icon {
-  font-size: 28rpx;
-  margin-left: 12rpx;
-}
-
-.history-search-button-full {
-  width: 100%;
-  background: linear-gradient(135deg, #5d55e8, #7568ff);
-  border-radius: 16rpx;
-  padding: 28rpx 0;
-  text-align: center;
-  margin-top: 12rpx;
-  margin-bottom: 24rpx;
-  box-shadow: 0 8rpx 20rpx rgba(93, 85, 232, 0.3);
-}
-
-.search-button-text {
-  font-size: 28rpx;
-  font-weight: 600;
-  color: #ffffff;
-}
-
-.history-search-button {
-  width: 80rpx;
-  height: 80rpx;
-  background: #5d55e8;
-  border-radius: 12rpx;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  margin-left: 16rpx;
-}
-
-.search-icon {
-  font-size: 32rpx;
-  color: #ffffff;
-}
-
-.history-tip {
-  font-size: 24rpx;
-  color: #9ca2b5;
-  line-height: 1.6;
-}
-
-/* 购买弹窗 */
-.modal-overlay {
-  position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: rgba(0, 0, 0, 0.5);
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  z-index: 1000;
-}
-
-.modal-content {
-  width: 640rpx;
-  background: #ffffff;
-  border-radius: 24rpx;
-  padding: 48rpx 40rpx 40rpx;
-  box-sizing: border-box;
-  position: relative;
-}
-
-.modal-close-btn {
-  position: absolute;
-  top: 24rpx;
-  right: 24rpx;
-  width: 48rpx;
-  height: 48rpx;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  z-index: 10;
-}
-
-.close-icon {
-  font-size: 36rpx;
-  color: #9ca2b5;
-  font-weight: 300;
-  line-height: 1;
-}
-
-.reward-header {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  margin-bottom: 40rpx;
-}
-
-.reward-icon {
-  font-size: 64rpx;
-  margin-bottom: 16rpx;
-}
-
-.reward-title {
-  font-size: 32rpx;
-  font-weight: 600;
-  color: #222222;
-}
-
-.reward-info {
-  margin-bottom: 40rpx;
-}
-
-.reward-desc {
-  display: block;
-  font-size: 26rpx;
-  color: #666a7f;
-  text-align: center;
-  margin-bottom: 24rpx;
-  line-height: 1.6;
-}
-
-.reward-amount-simple {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  gap: 8rpx;
-}
-
-.amount-label {
-  font-size: 28rpx;
-  color: #666a7f;
-}
-
-.amount-value {
-  font-size: 36rpx;
-  font-weight: 700;
-  color: #f16565;
-}
-
-.modal-footer {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-}
-
-.pay-button {
-  width: 100%;
-  background: linear-gradient(135deg, #5d55e8, #7568ff);
-  border-radius: 16rpx;
-  padding: 28rpx 0;
-  text-align: center;
-  margin-bottom: 24rpx;
-  box-shadow: 0 8rpx 20rpx rgba(93, 85, 232, 0.3);
-}
-
-.pay-button-text {
-  font-size: 30rpx;
-  font-weight: 600;
-  color: #ffffff;
-}
-
-.agreement-text {
-  font-size: 22rpx;
-  color: #9ca2b5;
-}
-
 .bottom-safe-area {
   height: 80rpx;
 }
-</style>
+</style>

+ 86 - 48
src/pages/rank/rank.vue

@@ -41,55 +41,74 @@
           </view>
         </view>
 
-        <!-- 列表视图 -->
-        <view v-show="viewMode === 'list'" class="stock-list" :class="{ 'hidden-list': myStocks.length === 0 }">
-          <stock-list-item 
-            v-for="(stock, index) in myStocks" 
-            :key="stock.code"
-            :stock="stock"
-            :show-delete="true"
-            @delete="removeStock(index)"
-            @click="handleStockClick(stock, index)"
-          />
-        </view>
-
-        <!-- 表格视图 -->
-        <view v-show="viewMode === 'table'" class="stock-table" :class="{ 'hidden-list': myStocks.length === 0 }">
-          <!-- 表头 -->
-          <view class="table-header">
-            <text class="th-name">股票</text>
-            <text class="th-date">自选日</text>
-            <text class="th-price">自选价</text>
-            <text class="th-profit">自选收益</text>
-          </view>
-          <!-- 表格内容 -->
-          <view 
-            v-for="(stock, index) in myStocks" 
-            :key="stock.code"
-            class="table-row"
-            @click="handleStockClick(stock, index)"
-          >
-            <view class="td-name">
-              <text class="stock-name">{{ stock.name }}</text>
-              <view class="stock-code-row">
-                <text :class="['stock-tag', getMarketClass(stock.code)]">{{ getMarketTag(stock.code) }}</text>
-                <text class="stock-code">{{ stock.code }}</text>
+        <!-- 滑动切换容器 -->
+        <swiper 
+          class="view-swiper"
+          :current="swiperIndex"
+          @change="onSwiperChange"
+          :duration="200"
+        >
+          <!-- 热力图视图 -->
+          <swiper-item>
+            <scroll-view scroll-y class="swiper-scroll">
+              <view v-if="myStocks.length > 0" class="stock-list">
+                <stock-list-item 
+                  v-for="(stock, index) in myStocks" 
+                  :key="stock.code"
+                  :stock="stock"
+                  :show-delete="true"
+                  @delete="removeStock(index)"
+                  @click="handleStockClick(stock, index)"
+                />
               </view>
-            </view>
-            <text class="td-date">{{ stock.addDate || '--' }}</text>
-            <text class="td-price">{{ formatPrice(stock.addPrice) }}</text>
-            <text :class="['td-profit', getProfitClass(stock.profitPercent)]">
-              {{ stock.profitPercent || '--' }}
-            </text>
-          </view>
-        </view>
-
-        <!-- 空状态 -->
-        <view v-if="myStocks.length === 0" class="empty-content">
-          <view class="empty-icon">📊</view>
-          <text class="empty-text">暂无收藏股票</text>
-          <text class="empty-desc">在强势池中点击"+"按钮添加股票</text>
-        </view>
+              <view v-else class="empty-content">
+                <view class="empty-icon">📊</view>
+                <text class="empty-text">暂无收藏股票</text>
+                <text class="empty-desc">在强势池中点击"+"按钮添加股票</text>
+              </view>
+            </scroll-view>
+          </swiper-item>
+          
+          <!-- 详情表格视图 -->
+          <swiper-item>
+            <scroll-view scroll-y class="swiper-scroll">
+              <view v-if="myStocks.length > 0" class="stock-table">
+                <!-- 表头 -->
+                <view class="table-header">
+                  <text class="th-name">股票</text>
+                  <text class="th-date">自选日</text>
+                  <text class="th-price">自选价</text>
+                  <text class="th-profit">自选收益</text>
+                </view>
+                <!-- 表格内容 -->
+                <view 
+                  v-for="(stock, index) in myStocks" 
+                  :key="stock.code"
+                  class="table-row"
+                  @click="handleStockClick(stock, index)"
+                >
+                  <view class="td-name">
+                    <text class="stock-name">{{ stock.name }}</text>
+                    <view class="stock-code-row">
+                      <text :class="['stock-tag', getMarketClass(stock.code)]">{{ getMarketTag(stock.code) }}</text>
+                      <text class="stock-code">{{ stock.code }}</text>
+                    </view>
+                  </view>
+                  <text class="td-date">{{ stock.addDate || '--' }}</text>
+                  <text class="td-price">{{ formatPrice(stock.addPrice) }}</text>
+                  <text :class="['td-profit', getProfitClass(stock.profitPercent)]">
+                    {{ stock.profitPercent || '--' }}
+                  </text>
+                </view>
+              </view>
+              <view v-else class="empty-content">
+                <view class="empty-icon">📊</view>
+                <text class="empty-text">暂无收藏股票</text>
+                <text class="empty-desc">在强势池中点击"+"按钮添加股票</text>
+              </view>
+            </scroll-view>
+          </swiper-item>
+        </swiper>
 
         <!-- 底部安全区域 -->
         <view class="bottom-safe-area"></view>
@@ -120,6 +139,7 @@ import StockListItem from '../../components/StockListItem.vue'
 const isLoggedIn = ref(false)
 const myStocks = ref([])
 const viewMode = ref('list') // 'list' 或 'table'
+const swiperIndex = ref(0) // swiper当前索引
 const isLoading = ref(false) // 加载状态
 const lastLoadTime = ref(0) // 上次加载时间
 const CACHE_DURATION = 5000 // 缓存有效期5秒
@@ -127,6 +147,14 @@ const CACHE_DURATION = 5000 // 缓存有效期5秒
 // 设置视图模式
 const setViewMode = (mode) => {
   viewMode.value = mode
+  swiperIndex.value = mode === 'list' ? 0 : 1
+}
+
+// swiper滑动切换
+const onSwiperChange = (e) => {
+  const index = e.detail.current
+  swiperIndex.value = index
+  viewMode.value = index === 0 ? 'list' : 'table'
 }
 
 const indexData = ref({
@@ -578,6 +606,16 @@ onUnload(() => {
   color: #E53935;
 }
 
+/* 滑动切换容器 */
+.view-swiper {
+  height: calc(100vh - 380rpx);
+  width: 100%;
+}
+
+.swiper-scroll {
+  height: 100%;
+}
+
 /* 隐藏空列表 */
 .hidden-list {
   display: none !important;

+ 83 - 504
src/pages/strong/strong.vue

@@ -12,20 +12,11 @@
         </view>
 
         <!-- 性能指标卡片 -->
-        <view class="card performance-card">
-          <view class="performance-item">
-            <text class="performance-label">历史成功率</text>
-            <text class="performance-value success">88%</text>
-          </view>
-          <view class="performance-item">
-            <text class="performance-label">平均收益率</text>
-            <text class="performance-value profit">+12.5%</text>
-          </view>
-          <view class="performance-item">
-            <text class="performance-label">总交易次数</text>
-            <text class="performance-value">45</text>
-          </view>
-        </view>
+        <PerformanceCard 
+          successRate="88%" 
+          profitRate="+12.5%" 
+          :totalTrades="45" 
+        />
 
         <!-- 强势趋势池区域 -->
         <view class="card pool-card">
@@ -52,10 +43,8 @@
                 </view>
               </view>
               <view class="stock-right">
-                <view class="stock-actions">
-                  <view class="action-btn buy-btn" @click="addToMyStocks(stock)">
-                    <text class="action-icon">+</text>
-                  </view>
+                <view class="action-btn buy-btn" @click="addToMyStocks(stock)">
+                  <text class="action-icon">+</text>
                 </view>
               </view>
             </view>
@@ -63,47 +52,7 @@
         </view>
 
         <!-- 历史股票池回顾 -->
-        <view class="card history-card">
-          <view class="history-header">
-            <text class="history-title">历史股票池回顾</text>
-          </view>
-          
-          <!-- 月份区间选择 -->
-          <view class="date-range-row">
-            <picker 
-              mode="date"
-              fields="month"
-              :value="startMonth"
-              @change="onStartMonthChange"
-              class="date-picker-half"
-            >
-              <view class="date-input">
-                <text class="date-text">{{ formatMonth(startMonth) }}</text>
-              </view>
-            </picker>
-            
-            <text class="date-separator">至</text>
-            
-            <picker 
-              mode="date"
-              fields="month"
-              :value="endMonth"
-              @change="onEndMonthChange"
-              class="date-picker-half"
-            >
-              <view class="date-input">
-                <text class="date-text">{{ formatMonth(endMonth) }}</text>
-              </view>
-            </picker>
-          </view>
-          
-          <!-- 查询按钮 -->
-          <view class="history-search-button-full" @click="onHistorySearch">
-            <text class="search-button-text">🔍 查询历史数据</text>
-          </view>
-          
-          <text class="history-tip">选择时间区间,查询该期间的入池股票及表现。</text>
-        </view>
+        <HistorySearchCard @search="onHistorySearch" />
 
         <!-- 预留底部空间 -->
         <view class="bottom-safe-area"></view>
@@ -111,33 +60,16 @@
     </scroll-view>
 
     <!-- 购买弹窗 -->
-    <view v-if="showModal" class="modal-overlay" @click="closePurchaseModal">
-      <view class="modal-content" @click.stop>
-        <view class="modal-close-btn" @click="closePurchaseModal">
-          <text class="close-icon">✕</text>
-        </view>
-        
-        <view class="reward-header">
-          <text class="reward-icon">📅</text>
-          <text class="reward-title">年订阅解锁</text>
-        </view>
-        
-        <view class="reward-info">
-          <text class="reward-desc">订阅全年,解锁强势趋势池内容</text>
-          <view class="reward-amount-simple">
-            <text class="amount-label">订阅金额:</text>
-            <text class="amount-value">¥98</text>
-          </view>
-        </view>
-
-        <view class="modal-footer">
-          <view class="pay-button" @click="handlePurchase">
-            <text class="pay-button-text">确认支付</text>
-          </view>
-          <text class="agreement-text">点击即表示同意《用户订阅协议》</text>
-        </view>
-      </view>
-    </view>
+    <PurchaseModal
+      :visible="showModal"
+      icon="📅"
+      title="年订阅解锁"
+      description="订阅全年,解锁强势趋势池内容"
+      amountLabel="订阅金额:"
+      :amount="98"
+      @close="closePurchaseModal"
+      @confirm="handlePurchase"
+    />
   </view>
 </template>
 
@@ -146,36 +78,20 @@ import { ref } from 'vue'
 import { onLoad, onShow } from '@dcloudio/uni-app'
 import { isLoggedIn as checkLoginStatus } from '../../utils/auth.js'
 import { getStockQuotes, addUserStock } from '../../utils/api.js'
+import PurchaseModal from '../../components/PurchaseModal.vue'
+import PerformanceCard from '../../components/PerformanceCard.vue'
+import HistorySearchCard from '../../components/HistorySearchCard.vue'
 
-// 购买状态
 const isPurchased = ref(false)
 const showModal = ref(false)
 
-// 股票列表数据
 const stockList = ref([
-  {
-    name: '信维通信',
-    code: '300136',
-  },
-  {
-    name: '中国卫星',
-    code: '600118',
-  }
+  { name: '信维通信', code: '300136' },
+  { name: '中国卫星', code: '600118' }
 ])
 
-const startMonth = ref('2025-01')  // 开始月份
-const endMonth = ref('2025-11')    // 结束月份
-
-// 格式化月份显示
-const formatMonth = (monthStr) => {
-  if (!monthStr) return '请选择'
-  const [year, month] = monthStr.split('-')
-  return `${year}年${month}月`
-}
-
 // 检查购买状态
 const checkPurchaseStatus = () => {
-  // 先检查登录状态
   if (!checkLoginStatus()) {
     isPurchased.value = false
     return
@@ -185,11 +101,9 @@ const checkPurchaseStatus = () => {
     const purchaseInfo = uni.getStorageSync('strong_pool_purchase')
     if (purchaseInfo) {
       const now = Date.now()
-      const expireTime = purchaseInfo.expireTime
-      if (now < expireTime) {
+      if (now < purchaseInfo.expireTime) {
         isPurchased.value = true
       } else {
-        // 已过期,清除购买信息
         uni.removeStorageSync('strong_pool_purchase')
         isPurchased.value = false
       }
@@ -204,7 +118,6 @@ const checkPurchaseStatus = () => {
 
 // 显示购买弹窗(需要登录)
 const showPurchaseModal = () => {
-  // 检查登录状态
   if (!checkLoginStatus()) {
     uni.showModal({
       title: '登录提示',
@@ -213,81 +126,43 @@ const showPurchaseModal = () => {
       cancelText: '取消',
       success: (res) => {
         if (res.confirm) {
-          uni.navigateTo({
-            url: '/pages/login/login'
-          })
+          uni.navigateTo({ url: '/pages/login/login' })
         }
       }
     })
     return
   }
-  
   showModal.value = true
 }
 
-// 关闭购买弹窗
 const closePurchaseModal = () => {
   showModal.value = false
 }
 
 // 处理购买
 const handlePurchase = () => {
-  // 计算过期时间 - 年订阅365天后过期
   const now = Date.now()
   const expireTime = now + 365 * 24 * 60 * 60 * 1000
 
-  // 保存购买信息
-  const purchaseInfo = {
+  uni.setStorageSync('strong_pool_purchase', {
     plan: 'yearly',
     purchaseTime: now,
     expireTime: expireTime
-  }
-  uni.setStorageSync('strong_pool_purchase', purchaseInfo)
+  })
 
-  // 更新购买状态
   isPurchased.value = true
-
-  // 关闭弹窗
   closePurchaseModal()
-
-  // 显示成功提示
-  uni.showToast({
-    title: '解锁成功',
-    icon: 'success'
-  })
-}
-
-// 开始月份选择变化
-const onStartMonthChange = (e) => {
-  startMonth.value = e.detail.value
-}
-
-// 结束月份选择变化
-const onEndMonthChange = (e) => {
-  endMonth.value = e.detail.value
+  uni.showToast({ title: '解锁成功', icon: 'success' })
 }
 
 // 历史查询
-const onHistorySearch = () => {
-  if (!startMonth.value || !endMonth.value) {
-    uni.showToast({
-      title: '请选择开始和结束月份',
-      icon: 'none'
-    })
-    return
-  }
-  
-  // 验证时间区间
-  if (startMonth.value > endMonth.value) {
-    uni.showToast({
-      title: '开始月份不能晚于结束月份',
-      icon: 'none'
-    })
-    return
+const onHistorySearch = ({ startMonth, endMonth }) => {
+  const formatMonth = (monthStr) => {
+    const [year, month] = monthStr.split('-')
+    return `${year}年${month}月`
   }
-  
   uni.showToast({
-    title: `查询${formatMonth(startMonth.value)}至${formatMonth(endMonth.value)}`,
+    title: `查询${formatMonth(startMonth)}至${formatMonth(endMonth)}`,
     icon: 'none',
     duration: 2000
   })
@@ -295,7 +170,6 @@ const onHistorySearch = () => {
 
 // 添加到我的股票
 const addToMyStocks = async (stock) => {
-  // 检查登录状态
   if (!checkLoginStatus()) {
     uni.showModal({
       title: '登录提示',
@@ -310,74 +184,50 @@ const addToMyStocks = async (stock) => {
     })
     return
   }
-  
+
   try {
-    // 显示加载提示
     uni.showLoading({ title: '添加中...' })
     
-    // 获取股票实时行情数据
     let currentPrice = null
     try {
       const quoteRes = await getStockQuotes(stock.code)
-      console.log('[添加股票] 行情数据:', JSON.stringify(quoteRes))
       if (quoteRes.code === 200 && quoteRes.data && quoteRes.data.length > 0) {
-        const quoteData = quoteRes.data[0]
-        currentPrice = quoteData.currentPrice
+        currentPrice = quoteRes.data[0].currentPrice
       }
     } catch (e) {
       console.error('获取行情数据失败:', e)
     }
     
-    // 调用后端接口保存到数据库
-    console.log('[添加股票] 请求参数:', { stockCode: stock.code, stockName: stock.name, currentPrice })
     const addRes = await addUserStock({
       stockCode: stock.code,
       stockName: stock.name,
       currentPrice: currentPrice
     })
-    console.log('[添加股票] 服务器返回:', JSON.stringify(addRes))
     
     uni.hideLoading()
     
     if (addRes.code === 200 && addRes.data === true) {
-      uni.showToast({
-        title: '添加成功',
-        icon: 'success'
-      })
+      uni.showToast({ title: '添加成功', icon: 'success' })
     } else if (addRes.code === 200 && addRes.data === false) {
-      uni.showToast({
-        title: '股票已存在',
-        icon: 'none'
-      })
+      uni.showToast({ title: '股票已存在', icon: 'none' })
     } else {
-      uni.showToast({
-        title: addRes.message || '添加失败',
-        icon: 'none'
-      })
+      uni.showToast({ title: addRes.message || '添加失败', icon: 'none' })
     }
   } catch (e) {
     uni.hideLoading()
     console.error('添加股票失败:', e)
-    uni.showToast({
-      title: '添加失败',
-      icon: 'none'
-    })
+    uni.showToast({ title: '添加失败', icon: 'none' })
   }
 }
 
 onLoad(() => {
-  // 页面加载时检查登录状态和购买状态
-  const loginStatus = checkLoginStatus()
-  console.log('[强势池] 登录状态:', loginStatus)
+  console.log('[强势池] 登录状态:', checkLoginStatus())
   checkPurchaseStatus()
 })
 
 onShow(() => {
-  // 页面显示时检查登录状态和购买状态(从登录页返回时会触发)
-  const loginStatus = checkLoginStatus()
-  console.log('[强势池] 登录状态:', loginStatus)
+  console.log('[强势池] 登录状态:', checkLoginStatus())
   checkPurchaseStatus()
-  // 设置导航栏标题
   uni.setNavigationBarTitle({ title: '量化交易大师' })
 })
 </script>
@@ -409,7 +259,6 @@ onShow(() => {
   margin-bottom: 32rpx;
 }
 
-/* 强势趋势池标题区域 */
 .pool-header-section {
   margin-bottom: 24rpx;
 }
@@ -436,44 +285,64 @@ onShow(() => {
   color: #666a7f;
 }
 
-/* 性能指标卡片 */
-.performance-card {
-  display: flex;
-  justify-content: space-around;
-  align-items: center;
-  background: #f7f8fc;
-  padding: 32rpx 24rpx;
+.pool-card {
+  padding: 32rpx;
 }
 
-.performance-item {
+.locked-content {
   display: flex;
   flex-direction: column;
   align-items: center;
+  padding: 60rpx 0 40rpx;
 }
 
-.performance-label {
-  font-size: 24rpx;
-  color: #666a7f;
-  margin-bottom: 12rpx;
+.lock-icon-wrapper {
+  margin-bottom: 32rpx;
 }
 
-.performance-value {
-  font-size: 32rpx;
-  font-weight: 700;
+.lock-icon {
+  font-size: 80rpx;
+}
+
+.lock-text {
+  font-size: 28rpx;
   color: #222222;
+  margin-bottom: 16rpx;
+  text-align: center;
 }
 
-.performance-value.success {
-  color: #3abf81;
+.lock-desc {
+  font-size: 24rpx;
+  color: #9ca2b5;
+  margin-bottom: 48rpx;
+  text-align: center;
+  line-height: 1.6;
 }
 
-.performance-value.profit {
-  color: #f16565;
+.unlock-button {
+  width: 100%;
+  background: linear-gradient(135deg, #5d55e8, #7568ff);
+  border-radius: 16rpx;
+  padding: 28rpx 0;
+  text-align: center;
+  box-shadow: 0 12rpx 24rpx rgba(93, 85, 232, 0.4);
 }
 
-/* 股票池卡片 */
-.pool-card {
-  padding: 32rpx;
+.unlock-button-text {
+  font-size: 30rpx;
+  font-weight: 600;
+  color: #ffffff;
+}
+
+.unlocked-content {
+  margin-top: 32rpx;
+}
+
+.unlocked-tip {
+  font-size: 26rpx;
+  color: #3abf81;
+  margin-bottom: 24rpx;
+  display: block;
 }
 
 .stock-item {
@@ -495,7 +364,6 @@ onShow(() => {
 .stock-name-row {
   display: flex;
   align-items: center;
-  margin-bottom: 12rpx;
 }
 
 .stock-name {
@@ -513,12 +381,6 @@ onShow(() => {
 .stock-right {
   display: flex;
   align-items: center;
-  gap: 16rpx;
-}
-
-.stock-actions {
-  display: flex;
-  gap: 12rpx;
 }
 
 .action-btn {
@@ -541,289 +403,6 @@ onShow(() => {
   color: #ffffff;
 }
 
-/* 历史股票池回顾 */
-.history-card {
-  padding: 32rpx;
-}
-
-.history-header {
-  display: flex;
-  align-items: center;
-  margin-bottom: 24rpx;
-}
-
-.history-icon {
-  font-size: 28rpx;
-  margin-right: 12rpx;
-}
-
-.history-title {
-  font-size: 30rpx;
-  font-weight: 600;
-  color: #222222;
-}
-
-.history-search-row {
-  display: flex;
-  align-items: center;
-}
-
-.date-range-row {
-  display: flex;
-  align-items: center;
-  gap: 16rpx;
-  margin-bottom: 24rpx;
-}
-
-.date-picker-half {
-  flex: 1;
-}
-
-.date-separator {
-  font-size: 26rpx;
-  color: #666a7f;
-  padding: 0 8rpx;
-}
-
-.date-input {
-  background: #f7f8fc;
-  border-radius: 12rpx;
-  padding: 24rpx;
-  font-size: 26rpx;
-  color: #222222;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-
-.date-text {
-  flex: 1;
-}
-
-.date-icon {
-  font-size: 28rpx;
-  margin-left: 12rpx;
-}
-
-.history-search-button-full {
-  width: 100%;
-  background: linear-gradient(135deg, #5d55e8, #7568ff);
-  border-radius: 16rpx;
-  padding: 28rpx 0;
-  text-align: center;
-  margin-top: 12rpx;
-  margin-bottom: 24rpx;
-  box-shadow: 0 8rpx 20rpx rgba(93, 85, 232, 0.3);
-}
-
-.search-button-text {
-  font-size: 28rpx;
-  font-weight: 600;
-  color: #ffffff;
-}
-
-.history-tip {
-  font-size: 24rpx;
-  color: #9ca2b5;
-  line-height: 1.6;
-}
-
-.history-search-button {
-  width: 80rpx;
-  height: 80rpx;
-  background: #5d55e8;
-  border-radius: 12rpx;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  margin-left: 16rpx;
-}
-
-.search-icon {
-  font-size: 32rpx;
-  color: #ffffff;
-}
-
-/* 弹窗样式 */
-.modal-overlay {
-  position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: rgba(0, 0, 0, 0.5);
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  z-index: 1000;
-}
-
-.modal-content {
-  width: 640rpx;
-  background: #ffffff;
-  border-radius: 24rpx;
-  padding: 48rpx 40rpx 40rpx;
-  box-sizing: border-box;
-  position: relative;
-}
-
-.modal-close-btn {
-  position: absolute;
-  top: 24rpx;
-  right: 24rpx;
-  width: 48rpx;
-  height: 48rpx;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  z-index: 10;
-}
-
-.close-icon {
-  font-size: 36rpx;
-  color: #9ca2b5;
-  font-weight: 300;
-  line-height: 1;
-}
-
-.reward-header {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  margin-bottom: 40rpx;
-}
-
-.reward-icon {
-  font-size: 64rpx;
-  margin-bottom: 16rpx;
-}
-
-.reward-title {
-  font-size: 32rpx;
-  font-weight: 600;
-  color: #222222;
-}
-
-.reward-info {
-  margin-bottom: 40rpx;
-}
-
-.reward-desc {
-  display: block;
-  font-size: 26rpx;
-  color: #666a7f;
-  text-align: center;
-  margin-bottom: 24rpx;
-  line-height: 1.6;
-}
-
-.reward-amount-simple {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  gap: 8rpx;
-}
-
-.amount-label {
-  font-size: 28rpx;
-  color: #666a7f;
-}
-
-.amount-value {
-  font-size: 36rpx;
-  font-weight: 700;
-  color: #f16565;
-}
-
-.modal-footer {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-}
-
-.pay-button {
-  width: 100%;
-  background: linear-gradient(135deg, #5d55e8, #7568ff);
-  border-radius: 16rpx;
-  padding: 28rpx 0;
-  text-align: center;
-  margin-bottom: 24rpx;
-  box-shadow: 0 8rpx 20rpx rgba(93, 85, 232, 0.3);
-}
-
-.pay-button-text {
-  font-size: 30rpx;
-  font-weight: 600;
-  color: #ffffff;
-}
-
-.agreement-text {
-  font-size: 22rpx;
-  color: #9ca2b5;
-}
-
-.bottom-safe-area {
-  height: 80rpx;
-}
-
-/* 锁定内容样式 */
-.locked-content {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  padding: 60rpx 0 40rpx;
-}
-
-.lock-icon-wrapper {
-  margin-bottom: 32rpx;
-}
-
-.locked-content .lock-icon {
-  font-size: 80rpx;
-}
-
-.lock-text {
-  font-size: 28rpx;
-  color: #222222;
-  margin-bottom: 16rpx;
-  text-align: center;
-}
-
-.lock-desc {
-  font-size: 24rpx;
-  color: #9ca2b5;
-  margin-bottom: 48rpx;
-  text-align: center;
-  line-height: 1.6;
-}
-
-.locked-content .unlock-button {
-  width: 100%;
-  background: linear-gradient(135deg, #5d55e8, #7568ff);
-  border-radius: 16rpx;
-  padding: 28rpx 0;
-  text-align: center;
-  box-shadow: 0 12rpx 24rpx rgba(93, 85, 232, 0.4);
-}
-
-.locked-content .unlock-button-text {
-  font-size: 30rpx;
-  font-weight: 600;
-  color: #ffffff;
-}
-
-/* 已解锁内容样式 */
-.unlocked-content {
-  margin-top: 32rpx;
-}
-
-.unlocked-tip {
-  font-size: 26rpx;
-  color: #3abf81;
-  margin-bottom: 24rpx;
-  display: block;
-}
-
 .bottom-safe-area {
   height: 80rpx;
 }

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików