Explorar o código

feat: 挑战流程全部

huangziyang hai 1 día
pai
achega
99e9bde9bd

+ 38 - 2
App.vue

@@ -1,7 +1,6 @@
 <script>
 export default {
   onLaunch: function () {
-
     console.log("App Launch");
   },
   onShow: function () {
@@ -57,4 +56,41 @@ button {
   background: $uni-primary-light;
   color: $primary;
 }
-</style>
+
+.checkbox {
+  .wx-checkbox-input {
+    width: 34rpx;
+    height: 34rpx;
+    border-radius: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  /*checkbox选中后样式  */
+  .wx-checkbox-input.wx-checkbox-input-checked {
+    background: $primary;
+    border-color: $primary;
+  }
+  /*checkbox选中后图标样式  */
+  .wx-checkbox-input.wx-checkbox-input-checked::before {
+    width: 20rpx;
+    height: 20rpx;
+    line-height: 20rpx;
+    text-align: center;
+    font-size: 22rpx;
+    color: #fff;
+    background: transparent;
+    transform: translate(-50%, -50%) scale(1);
+    -webkit-transform: translate(-50%, -50%) scale(1);
+  }
+}
+
+.required {
+  &::before {
+    content: "*";
+    color: $error;
+    font-size: 32rpx;
+    margin-right: 10rpx;
+  }
+}
+</style>

+ 1 - 0
components/Container/Container.vue

@@ -290,6 +290,7 @@ scroll-view ::-webkit-scrollbar {
   padding: 24rpx;
   position: absolute;
   bottom: 0;
+  box-sizing: border-box;
 }
 
 .topic-scroll {

+ 104 - 0
components/RadioBlock/RadioBlock.vue

@@ -0,0 +1,104 @@
+<script setup name="RadioBlock">
+import { ref, onMounted } from "vue";
+const props = defineProps({
+  col: Number,
+  columns: {
+    type: Array,
+    default: () => [],
+  },
+  modelValue: {
+    type: [String, Number],
+    default: "",
+  },
+  name: {
+    type: String,
+    default: "",
+  },
+});
+
+const selectIndex = ref(null);
+
+const emit = defineEmits(["change", "update:modelValue"]);
+
+onMounted(() => {
+  if (props.modelValue) {
+    selectIndex.value = props.modelValue;
+  }
+});
+
+const onChange = (e) => {
+  let value = +e.detail.value;
+  if (Object.is(NaN, value)) {
+    value = e.detail.value;
+  }
+  selectIndex.value = value;
+  emit("update:modelValue", value);
+  emit(
+    "change",
+    value,
+    props.columns.find((item) => item.value === value)
+  );
+};
+</script>
+
+<template>
+  <radio-group :name="name" @change="onChange">
+    <view
+      class="grid"
+      :style="{
+        gridTemplateColumns: `repeat(${col || columns.length}, 1fr)`,
+      }"
+    >
+      <label
+        class="radio"
+        :class="{
+          active: selectIndex === item.value,
+        }"
+        v-for="item in columns"
+        :key="item.value"
+      >
+        <radio
+          class="uni-radio"
+          :value="item.value"
+          :checked="selectIndex === item.value"
+        />
+        <view @click="selectIndex = item.value">
+          {{ item.label }}
+        </view>
+      </label>
+    </view>
+  </radio-group>
+</template>
+
+<style scoped lang="scss">
+@import "@/uni.scss";
+.grid {
+  display: grid;
+  gap: 22rpx;
+
+  .radio {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border: 1px solid #ccc;
+    padding: 0 auto;
+    font-weight: 500;
+    font-size: 28rpx;
+    color: #333333;
+    border-radius: 8rpx;
+    height: 60rpx;
+
+    .uni-radio {
+      width: 0;
+      height: 0;
+      opacity: 0;
+    }
+  }
+
+  .radio.active {
+    background-color: $primary;
+    border-color: $primary;
+    color: #fff;
+  }
+}
+</style>

+ 2 - 2
mixin/shareMixin.js

@@ -2,9 +2,9 @@ export default {
   data() {
     return {
       share: {
-        title: "开邻做题家",
+        title: "执业药师要上岸,免费题库来相伴!",
         path: "/pages/index/index",
-        imageUrl: "分享显示的图片链接",
+        imageUrl: "https://kailin-mp.oss-cn-shenzhen.aliyuncs.com/static/index/doctor_share.png",
         desc: "简介",
       },
     };

+ 14 - 0
pages.json

@@ -28,6 +28,20 @@
         "navigationBarTitleText": "规则"
       }
     },
+    {
+      "path": "pages/richpage/index",
+      "style": {
+        "navigationStyle": "custom",
+        "navigationBarTitleText": "权益阅读页面"
+      }
+    },
+    {
+      "path": "pages/challenge/registration",
+      "style": {
+        "navigationStyle": "custom",
+        "navigationBarTitleText": "报名"
+      }
+    },
     {
       "path": "pages/challenge/addContant",
       "style": {

+ 63 - 6
pages/challenge/addContant.vue

@@ -6,19 +6,49 @@
     }"
   >
     <view class="bg">
+      <div class="bg-0"></div>
       <view class="bg-1">
-        <image
-          src="https://openwork-oss.oss-cn-shenzhen.aliyuncs.com/uploads/question/2025/06/lW8ekxb2fdipLnTFDC4njYTMqz4ZsoDV6iQy6JRu.jpg"
-          show-menu-by-longpress
-          class="qrcode"
-        ></image>
+        <image :src="qrcode" show-menu-by-longpress class="qrcode"></image>
       </view>
+      <div class="bg-2">
+        <div>报名信息</div>
+        <div class="text-14">
+          {{ info.contact_name }}{{ info.contact_information
+          }}{{ info.pharmacist_type === 1 ? "中药" : "西药" }}
+        </div>
+        <div class="text-t9 text-12">如需修改报名信息,请联系客服修改</div>
+      </div>
     </view>
   </Container>
 </template>
 
 <script setup>
 import Container from "@/components/Container/Container.vue";
+import { request } from "../../utils/request";
+import { ref } from "vue";
+import { onShow } from "@dcloudio/uni-app";
+import { getRoute } from "../../utils/router";
+
+const qrcode = ref("");
+const info = ref({});
+
+onShow(() => {
+  request("api/question_bank/question_reception/common_config/detail", {
+    content_code: "challenge_activities",
+  }).then((res) => {
+    const { type } = getRoute().params;
+    const key =
+      type === 1 ? "chinese_medicine_qrcode" : "western_medicine_qrcode";
+    qrcode.value = res.data.content_detail[key];
+  });
+  request(
+    "api/question_bank/question_reception/challenge_registration_log/detail"
+  ).then((res) => {
+    if (res.data) {
+      info.value = res.data;
+    }
+  });
+});
 </script>
 
 <style scoped lang="scss">
@@ -28,11 +58,24 @@ import Container from "@/components/Container/Container.vue";
   background: url("https://openwork-oss.oss-cn-shenzhen.aliyuncs.com/uploads/question/2025/05/yz2eTeqIRv60IEe6kOQBOYlHr75wiFIpeFqrJmgZ.png");
   background-size: 100% 100%;
   padding: 216rpx 10rpx;
+  box-sizing: border-box;
+  position: relative;
+
+  .bg-0 {
+    width: 128rpx;
+    height: 128rpx;
+    top: 70rpx;
+    left: 50%;
+    transform: translateX(-50%);
+    background: url("https://openwork-oss.oss-cn-shenzhen.aliyuncs.com/uploads/question/2025/06/IGf12z7pkPWDXrRxt9Yk9xVz9Mt1Cs8OZXGkyT1R.png");
+    background-size: 100% 100%;
+    position: absolute;
+  }
 
   .bg-1 {
     width: 730.71rpx;
     height: 841rpx;
-    background: url("https://openwork-oss.oss-cn-shenzhen.aliyuncs.com/uploads/question/2025/05/cOeqNuCTmz0r5LeZnW6qnKIFZJQCC1r4FarsZS55.png");
+    background: url("https://openwork-oss.oss-cn-shenzhen.aliyuncs.com/uploads/question/2025/06/U29HhzEGO1qyFSKkngSFM3uosicKhY8Gc4EsifY8.png");
     background-size: 100% 100%;
     position: relative;
 
@@ -45,5 +88,19 @@ import Container from "@/components/Container/Container.vue";
       background-size: 100% 100%;
     }
   }
+
+  .bg-2 {
+    width: 680rpx;
+    height: 310rpx;
+    margin: 0 20rpx;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    box-sizing: border-box;
+    justify-content: center;
+    gap: 51rpx;
+    background: url("https://openwork-oss.oss-cn-shenzhen.aliyuncs.com/uploads/question/2025/06/CyJTtM0Jtx2JY4aMthrAwjl0caJxApRcypbKsU20.png");
+    background-size: 100% 100%;
+  }
 }
 </style>

+ 10 - 46
pages/challenge/index.vue

@@ -22,9 +22,7 @@ import Container from "../../components/Container/Container.vue";
 import { request } from "../../utils/request";
 import { router } from "../../utils/router";
 import { onShow } from "@dcloudio/uni-app";
-import { ref, getCurrentInstance } from "vue";
-import ext from "../../ext.json";
-const instance = getCurrentInstance();
+import { ref } from "vue";
 const isPay = ref(true);
 
 const p = ref(0);
@@ -48,55 +46,21 @@ onShow(async () => {
 const toRule = () => {
   router.push({
     url: "/pages/challenge/rule",
+    params: {
+      id: p.value,
+    },
   });
 };
 
 const toAdd = async () => {
-  if (isPay.value) {
-    router.push({
-      url: "/pages/challenge/addContant",
-    });
-    return;
-  }
-  uni.login({
-    provider: instance.proxy.$mpPlatform.substring(3),
-    success: async ({ code }) => {
-      const package_id = p.value;
-      // 先调用新增订单再支付
-      const order = await request(
-        "api/question_bank/question_reception/orders/add",
-        {
-          package_id,
-        }
-      );
-      const e = await request(
-        "api/question_bank/question_reception/orders/wechat_pay",
-        {
-          code,
-          order_id: order.data.order_id,
-          app_id: ext.extAppid,
-        }
-      );
-
-      uni.requestPayment({
-        provider: "wxpay",
-        timeStamp: e.data.timeStamp, //时间戳
-        nonceStr: e.data.nonceStr, //随机字符串
-        package: e.data.package, //prepay_id
-        signType: e.data.signType, //签名算法MD5
-        paySign: e.data.paySign, //签名,
-        success(res) {
-          console.log(res);
-          router.push({
-            url: "/pages/challenge/addContant",
-          });
-        },
-        fail(err) {
-          console.log(err);
-        },
-      });
+  router.push({
+    url: "/pages/challenge/registration",
+    params: {
+      id: p.value,
+      isPay: isPay.value,
     },
   });
+  
 };
 </script>
 

+ 350 - 0
pages/challenge/registration.vue

@@ -0,0 +1,350 @@
+<script setup name="registration">
+import Container from "../../components/Container/Container.vue";
+import CustomerService from "../../components/CustomerService/CustomerService.vue";
+import RadioBlock from "../../components/RadioBlock/RadioBlock.vue";
+import Modal from "../../components/Modal/Modal.vue";
+import { onShow } from "@dcloudio/uni-app";
+import { request } from "../../utils/request";
+import { getRoute, router } from "../../utils/router";
+import { ref, getCurrentInstance } from "vue";
+import ext from "../../ext.json";
+
+const instance = getCurrentInstance();
+const context = ref("");
+const permissions = ref(false);
+const formData = ref({
+  contact_name: "",
+  contact_information: "",
+  pharmacist_type: 0,
+});
+const loading = ref(false);
+const show = ref(false);
+const rules = {
+  contact_name: [
+    {
+      required: true,
+      message: "请输入姓名",
+    },
+  ],
+  contact_information: [
+    {
+      required: true,
+      message: "请输入联系方式",
+      type: "phone",
+    },
+  ],
+  pharmacist_type: [
+    {
+      required: true,
+      message: "请选择报考药师类型",
+    },
+  ],
+};
+onShow(() => {
+  const { id } = getRoute().params;
+  request("api/question_bank/question_reception/recharge_package/detail", {
+    id,
+  }).then((res) => {
+    context.value = res.data.instructions || "";
+  });
+});
+
+const validate = ({ value, message, type = "text" }) =>
+  new Promise((resolve, reject) => {
+    if (!value) {
+      uni.showToast({
+        title: message,
+        icon: "none",
+      });
+      loading.value = false;
+      return reject(message);
+    }
+    if (type === "phone") {
+      const phoneReg =
+        /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[1589]))\d{8}$/;
+      if (!phoneReg.test(value)) {
+        uni.showToast({
+          title: "请输入正确的手机号码",
+          icon: "none",
+        });
+        loading.value = false;
+        return reject("请输入正确的手机号码");
+      }
+    }
+
+    resolve();
+  });
+
+const onSubmit = async () => {
+  loading.value = true;
+  for (const key in formData.value) {
+    await validate({
+      value: formData.value[key],
+      message: rules[key][0].message,
+      type: rules[key][0].type,
+    });
+  }
+
+  if (!permissions.value) {
+    show.value = true;
+    return;
+  }
+  const { id } = getRoute().params;
+  uni.login({
+    provider: instance.proxy.$mpPlatform.substring(3),
+    success: async ({ code }) => {
+      const order = await request(
+        "api/question_bank/question_reception/challenge_registration_log/add",
+        {
+          package_id: id,
+          ...formData.value,
+        }
+      );
+      const e = await request(
+        "api/question_bank/question_reception/orders/wechat_pay",
+        {
+          code,
+          order_id: order.data.order_id,
+          app_id: ext.extAppid,
+        }
+      );
+
+      uni.requestPayment({
+        provider: "wxpay",
+        timeStamp: e.data.timeStamp, //时间戳
+        nonceStr: e.data.nonceStr, //随机字符串
+        package: e.data.package, //prepay_id
+        signType: e.data.signType, //签名算法MD5
+        paySign: e.data.paySign, //签名,
+        success() {
+          router.redirectTo({
+            url: "/pages/challenge/addContant",
+            params: {
+              type: formData.value.pharmacist_type,
+            },
+          });
+        },
+        fail(err) {
+          console.log(err);
+        },
+        complete() {
+          loading.value = false;
+        },
+      });
+    },
+  });
+};
+</script>
+<template>
+  <Container
+    title="报名"
+    :scrollStyle="{
+      padding: 0,
+    }"
+    bgColor="#a8e0fd"
+    bottomBgColor="#fff"
+    headerColor="#fff"
+    v-if="!show"
+  >
+    <view class="bg">
+      <view class="bg-1">
+        <form>
+          <view class="uni-form-item">
+            <view class="title required">姓名</view>
+            <input
+              class="uni-input"
+              name="contact_name"
+              placeholder="请输入真实姓名"
+              v-model="formData.contact_name"
+            />
+          </view>
+          <view class="uni-form-item">
+            <view class="title required">联系方式</view>
+            <input
+              class="uni-input"
+              name="contact_information"
+              placeholder="请输入电话号码"
+              v-model="formData.contact_information"
+            />
+          </view>
+          <view class="uni-form-item">
+            <view class="title required">报考药师类型(请选择)</view>
+            <RadioBlock
+              v-model="formData.pharmacist_type"
+              name="pharmacist_type"
+              :columns="[
+                {
+                  label: '西药',
+                  value: 2,
+                },
+                {
+                  label: '中药',
+                  value: 1,
+                },
+              ]"
+            />
+          </view>
+        </form>
+      </view>
+    </view>
+    <div class="permissions">
+      <label>
+        <checkbox class="checkbox" :value="permissions" />
+        阅读并确认
+      </label>
+      <span
+        class="text-primary"
+        @click="
+          () => {
+            router.push({
+              url: '/pages/richpage/index',
+              params: {
+                title: '会员服务权益',
+                content_code: 'service_rights',
+              },
+            });
+          }
+        "
+        >《会员服务权益》</span
+      >
+      <span
+        class="text-primary"
+        @click="
+          () => {
+            router.push({
+              url: '/pages/challenge/rule',
+              params: {
+                id: getRoute().params.id,
+              },
+            });
+          }
+        "
+        >《活动规则》</span
+      >
+    </div>
+    <view class="service">
+      <CustomerService>联系客服</CustomerService>
+    </view>
+    <template #footer>
+      <button
+        :loading="loading"
+        :disabled="loading"
+        class="btn"
+        @click="onSubmit"
+      >
+        ¥999 立即开通
+      </button>
+    </template>
+  </Container>
+  <Modal
+    v-model:open="show"
+    title="温馨提示"
+    :submitter="{
+      closeText: '不同意',
+      text: '同意并支付',
+    }"
+    :onClose="() => (show = false)"
+    :onSubmit="
+      () => {
+        permissions = true;
+        show = false;
+        onSubmit();
+      }
+    "
+  >
+    <div class="text">
+      <span> 阅读并确认 </span>
+      <span
+        class="text-primary"
+        @click="
+          () => {
+            router.push({
+              url: '/pages/richpage/index',
+              params: {
+                title: '会员服务权益',
+                content_code: 'service_rights',
+              },
+            });
+          }
+        "
+        >《会员服务权益》</span
+      >
+      <span
+        class="text-primary"
+        @click="
+          () => {
+            router.push({
+              url: '/pages/challenge/rule',
+              params: {
+                id: getRoute().params.id,
+              },
+            });
+          }
+        "
+        >《活动规则》</span
+      >
+    </div>
+  </Modal>
+</template>
+<style scoped lang="scss">
+.bg {
+  width: 100%;
+  background: url("https://openwork-oss.oss-cn-shenzhen.aliyuncs.com/uploads/question/2025/05/yz2eTeqIRv60IEe6kOQBOYlHr75wiFIpeFqrJmgZ.png")
+    no-repeat;
+  background-size: 100%;
+  padding: 216rpx 10rpx 0;
+  box-sizing: border-box;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+
+  .bg-1 {
+    width: 730.71rpx;
+    height: 841rpx;
+    background: url("https://openwork-oss.oss-cn-shenzhen.aliyuncs.com/uploads/question/2025/06/3P7CBvlUNmunkIM1PA5voYhrGpIIgeqgy30pLb1z.png")
+      no-repeat;
+    background-size: 100% 100%;
+    position: relative;
+    box-sizing: border-box;
+    padding: 170rpx 50rpx;
+    .uni-form-item .title {
+      padding: 20rpx 0;
+    }
+
+    .uni-input {
+      border-radius: 8rpx 8rpx 8rpx 8rpx;
+      border: 1rpx solid #dddddd;
+      padding: 14rpx 9rpx;
+    }
+  }
+}
+.text {
+  font-size: 30rpx;
+  margin: 20rpx 0;
+}
+.service {
+  position: absolute;
+  bottom: 20%;
+  right: 5%;
+  color: $uni-primary;
+  font-size: 28rpx;
+  margin-bottom: 40rpx;
+  text-align: right;
+}
+.permissions {
+  position: absolute;
+  bottom: 15%;
+  left: 32rpx;
+  display: flex;
+  align-items: center;
+  font-weight: 500;
+  font-size: 28rpx;
+  color: #333333;
+}
+.btn {
+  margin: 32rpx 0;
+  font-weight: 400;
+  font-size: 32rpx;
+  color: #ffffff;
+}
+</style>

+ 37 - 2
pages/challenge/rule.vue

@@ -1,7 +1,42 @@
 <script setup>
 import Container from "../../components/Container/Container.vue";
+import { onShow } from "@dcloudio/uni-app";
+import { request } from "../../utils/request";
+import { getRoute } from "../../utils/router";
+import uvParse from "../../uni_modules/uv-parse/components/uv-parse/uv-parse.vue";
+import { ref } from "vue";
+
+const replaceImageDimensions = (str) =>
+  str
+    .replace(
+      /<img([^>]*?)style="([^"]*?)width:\s*[^;]+;\s*height:\s*[^;]+;([^"]*?)"([^>]*?)\/?>/g,
+      '<img$1style="$2width:100%;height:100%;$3"$4/>'
+    )
+    .replace(
+      /<img([^>]*?)width="[^"]*"([^>]*?)height="[^"]*"([^>]*?)\/?>/g,
+      '<img$1width="100%"$2height="100%"$3/>'
+    );
+const context = ref("");
+const titles = ref("活动");
+onShow(() => {
+  const { id, title } = getRoute().params;
+  if (title) {
+    titles.value = title;
+  }
+  request("api/question_bank/question_reception/recharge_package/detail", {
+    id,
+  }).then((res) => {
+    context.value = res.data.instructions || "";
+  });
+});
 </script>
 <template>
-  <Container title="规则"> </Container>
+  <Container :title="titles">
+    <uvParse class="text" :content="replaceImageDimensions(context)"></uvParse>
+  </Container>
 </template>
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.text {
+  line-height: 2;
+}
+</style>

+ 52 - 22
pages/learn/index.vue

@@ -14,11 +14,11 @@
         @click="currentIndex = 0"
       >
         <span>
-          <span class="primary">{{ 10 }}</span
-          >/{{ 20 }}
+          <span class="primary">{{ info.answer_total }}</span
+          >/{{ info.topic_total }}
         </span>
         <span
-          >正确率<span class="primary">{{ 50 }}%</span></span
+          >正确率<span class="primary">{{ info.accuracy }}</span></span
         >
       </div>
       <div
@@ -26,7 +26,7 @@
         :class="currentIndex === 1 && 'select'"
         @click="currentIndex = 1"
       >
-        考试记录(<span class="primary">{{ 1 }}</span
+        考试记录(<span class="primary">{{ info.real_paper_total }}</span
         >)
       </div>
       <div
@@ -34,7 +34,7 @@
         :class="currentIndex === 2 && 'select'"
         @click="currentIndex = 2"
       >
-        考试记录(<span class="primary">{{ 2 }}</span
+        题目收藏(<span class="primary">{{ info.favorite_total }}</span
         >)
       </div>
     </div>
@@ -42,28 +42,28 @@
       <scroll-view class="scroll" scroll-x>
         <div class="box">
           <div
-            v-for="item in 7"
+            v-for="(item, index) in info.chapter_infos"
             class="item"
             :class="{
-              select: item === currentTab,
+              select: item.id === currentTab,
             }"
-            :key="item"
-            @click="currentTab = item"
+            :key="item.id"
+            @click="
+              () => {
+                currentTab = item.id;
+              }
+            "
           >
-            法规{{ item }}
+            {{ item.name }}
           </div>
         </div>
       </scroll-view>
       <div class="select-line" v-if="currentIndex === 0">
-        <div class="item" :class="{ select: isRight }" @click="isRight = true">
-          答案正确({{ 2301 }})
+        <div class="item" :class="{ select: isRight }" @click="isRight = 1">
+          答案正确({{ rightTotal }})
         </div>
-        <div
-          class="item"
-          :class="{ select: !isRight }"
-          @click="isRight = false"
-        >
-          答案错误({{ 2301 }})
+        <div class="item" :class="{ select: !isRight }" @click="isRight = 0">
+          答案错误({{ errorTotal }})
         </div>
       </div>
     </div>
@@ -137,11 +137,41 @@
 
 <script setup>
 import Container from "@/components/Container/Container.vue";
-import { ref } from "vue";
+import { ref, watch } from "vue";
+import { onShow } from "@dcloudio/uni-app";
+import { request } from "../../utils/request";
+
+const currentIndex = ref(0);
+const currentTab = ref(0);
+const isRight = ref(1);
+const info = ref({});
+const rightTotal = ref(0);
+const errorTotal = ref(0);
+
+watch([currentTab, isRight], () => {
+  request(
+    "api/question_bank/question_reception/study_book/get_answer_topic_record",
+    {
+      chapter_id: currentTab.value,
+      is_correct: isRight.value,
+    }
+  ).then((res) => {
+    if (isRight.value) {
+      rightTotal.value = res.data.total;
+    } else {
+      errorTotal.value = res.data.total;
+    }
+  });
+});
 
-const currentIndex = ref(2);
-const currentTab = ref(1);
-const isRight = ref(true);
+onShow(() => {
+  request(
+    "api/question_bank/question_reception/study_book/get_study_record_title"
+  ).then((res) => {
+    info.value = res.data;
+    currentTab.value = res.data.chapter_infos[0].id;
+  });
+});
 // 示例数据
 </script>
 

+ 28 - 2
pages/recharge/index.vue

@@ -56,8 +56,34 @@
               }"
               >{{ item.text }}</text
             >
-            <text>《会员服务权益》</text>
-            <text>(自动续费协议)</text>
+            <text
+              @click="
+                () => {
+                  router.push({
+                    url: '/pages/richpage/index',
+                    params: {
+                      title: '会员服务权益',
+                      content_code: 'service_rights',
+                    },
+                  });
+                }
+              "
+              >《会员服务权益》</text
+            >
+            <text
+              @click="
+                () => {
+                  router.push({
+                    url: '/pages/richpage/index',
+                    params: {
+                      title: '自动续费协议',
+                      content_code: 'automatic_renewal_agreement',
+                    },
+                  });
+                }
+              "
+              >(自动续费协议)</text
+            >
           </template>
         </uni-data-checkbox>
       </view>

+ 48 - 0
pages/richpage/index.vue

@@ -0,0 +1,48 @@
+<script setup>
+import Container from "../../components/Container/Container.vue";
+import { onShow } from "@dcloudio/uni-app";
+import { request } from "../../utils/request";
+import { getRoute } from "../../utils/router";
+import uvParse from "../../uni_modules/uv-parse/components/uv-parse/uv-parse.vue";
+import { ref } from "vue";
+
+const replaceImageDimensions = (str) =>
+  str
+    .replace(
+      /<img([^>]*?)style="([^"]*?)width:\s*[^;]+;\s*height:\s*[^;]+;([^"]*?)"([^>]*?)\/?>/g,
+      '<img$1style="$2width:100%;height:100%;$3"$4/>'
+    )
+    .replace(
+      /<img([^>]*?)width="[^"]*"([^>]*?)height="[^"]*"([^>]*?)\/?>/g,
+      '<img$1width="100%"$2height="100%"$3/>'
+    );
+const context = ref("");
+const titles = ref("");
+onShow(() => {
+  /**
+   * service_rights=会员服务权益,
+   * automatic_renewal_agreement=自动续费协议
+   * examination_countdown=倒计时,
+   * challenge_activities=奖学金挑战信息
+   */
+  const { title, content_code } = getRoute().params;
+  if (title) {
+    titles.value = title;
+  }
+  request("api/question_bank/question_reception/common_config/detail", {
+    content_code,
+  }).then((res) => {
+    context.value = res.data.content_detail || "";
+  });
+});
+</script>
+<template>
+  <Container :title="titles">
+    <uvParse class="text" :content="replaceImageDimensions(context)"></uvParse>
+  </Container>
+</template>
+<style scoped lang="scss">
+.text {
+  line-height: 2;
+}
+</style>

+ 79 - 6
uni.scss

@@ -1,12 +1,85 @@
-@import '@/uni_modules/uni-scss/variables.scss';
+@import "@/uni_modules/uni-scss/variables.scss";
 
-$uni-primary: #3F75FF;
-$uni-primary-disable:#94bcff;
-$uni-primary-light: #F3F6FF;
+$uni-primary: #3f75ff;
+$uni-primary-disable: #94bcff;
+$uni-primary-light: #f3f6ff;
 
-$primary: #3F75FF;
+$primary: #3f75ff;
 
 $success: #00be00;
 $error: #f00;
 $default: #e7e7e7;
-$warning: #ff9900;
+$warning: #ff9900;
+$t9: #999999;
+
+$colorMap: (
+  (
+    color: $primary,
+    name: primary,
+  ),
+  (
+    color: $success,
+    name: success,
+  ),
+  (
+    color: $error,
+    name: error,
+  ),
+  (
+    color: $default,
+    name: default,
+  ),
+  (
+    color: $warning,
+    name: warning,
+  ),
+  (
+    color: $t9,
+    name: t9,
+  )
+);
+
+@each $item in $colorMap {
+  $name: map-get($item, name);
+  $color: map-get($item, color);
+
+  .text-#{$name} {
+    color: $color;
+  }
+
+  .bg-#{$name} {
+    background-color: $color;
+  }
+
+  .border-#{$name} {
+    border-color: $color;
+  }
+}
+
+$sizeMap: (
+  (
+    size: 10,
+    name: 10,
+  ),
+  (
+    size: 12,
+    name: 12,
+  ),
+  (
+    size: 14,
+    name: 14,
+  ),
+  (
+    size: 16,
+    name: 16,
+  )
+);
+
+@each $item in $sizeMap {
+  $name: map-get($item, name);
+  $size: map-get($item, size);
+
+  .text-#{$name} {
+    font-size: #{$size * 2}rpx;
+  }
+}