zhb 2 ay önce
ebeveyn
işleme
3c2a9b68c5

+ 2 - 51
pages.json

@@ -35,27 +35,6 @@
         "navigationStyle": "custom"
       }
     },
-    {
-      "path": "pages/mine/index",
-      "style": {
-        "navigationBarTitleText": "",
-        "navigationStyle": "custom"
-      }
-    },
-    {
-      "path": "pages/mine/language",
-      "style": {
-        "navigationBarTitleText": "",
-        "navigationStyle": "custom"
-      }
-    },
-    {
-      "path": "pages/mine/improve",
-      "style": {
-        "navigationBarTitleText": "",
-        "navigationStyle": "custom"
-      }
-    },
     {
       "path": "pages/mine/info",
       "style": {
@@ -63,27 +42,6 @@
         "navigationStyle": "custom"
       }
     },
-    {
-      "path": "pages/mine/permission",
-      "style": {
-        "navigationBarTitleText": "",
-        "navigationStyle": "custom"
-      }
-    },
-    {
-      "path": "pages/mine/privacy",
-      "style": {
-        "navigationBarTitleText": "",
-        "navigationStyle": "custom"
-      }
-    },
-    {
-      "path": "pages/mine/pay-password",
-      "style": {
-        "navigationBarTitleText": "",
-        "navigationStyle": "custom"
-      }
-    },
     {
       "path": "pages/mine/kyc",
       "style": {
@@ -282,14 +240,7 @@
       }
     },
     {
-      "path": "pages/mine/notice",
-      "style": {
-        "navigationBarTitleText": "",
-        "navigationStyle": "custom"
-      }
-    },
-    {
-      "path": "pages/mine/new",
+      "path": "pages/common/chat",
       "style": {
         "navigationBarTitleText": "",
         "navigationStyle": "custom"
@@ -312,4 +263,4 @@
     "animationDuration": 300
   },
   "uniIdRouter": {}
-}
+}

+ 0 - 928
pages/mine/improve.vue

@@ -1,928 +0,0 @@
-<template>
-  <cwg-page-wrapper>
-    <view class="page page-shadow">
-      <u-form ref="formRef" :rules="rules" :model="formData" class="payment-form">
-        <!-- 第一步:基本信息 -->
-        <view v-show="currentStep === 1" class="form-section">
-          <h3 class="section-title">{{ t("card.Info.s1") }}</h3>
-          <cwg-input v-model:value="formData.lastName" fkey="lastName" :required="true" :label="t('card.Form.f4')"
-            rulesKey="lastName" :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-          <cwg-input v-model:value="formData.firstName" fkey="firstName" :required="true" :label="t('card.Form.f5')"
-            rulesKey="firstName" :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-          <cwg-input v-model:value="formData.email" fkey="email" :label="t('card.Form.f3')" :required="true"
-            rulesKey="email" :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-          <view class="f" v-if="phoneCodes.length > 0">
-            <cwg-input v-model:value="formData.areaCode" class="l" fkey="areaCode" :required="true" type="select"
-              :show-search="true" :columns="phoneCodes" :label="t('card.Form.f2')" rulesKey="areaCode"
-              :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-            <cwg-input v-model:value="formData.mobile" class="r" fkey="mobile" label=" " rulesKey="mobile"
-              :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-          </view>
-          <cwg-input v-model:value="formData.gender" fkey="gender" type="select" :required="true" rulesKey="gender"
-            :columns="sexOptions" :label="t('card.Form.f8')" :readonly="isReadonly" :disabled="isReadonly"
-            @change="handleChange" />
-          <cwg-input v-model:value="formData.birthday" :required="true" type="date" fkey="birthday" rulesKey="birthday"
-            :label="t('card.Form.f6')" :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-        </view>
-        <!-- 第二步:国籍信息 -->
-        <view v-show="currentStep === 2" class="form-section">
-          <h3 class="section-title">{{ t("ImproveImmediately.Title.AddressInformation") }}</h3>
-          <cwg-input v-if="countryOptions.length > 0" v-model:value="formData.nationality" fkey="nationality"
-            type="select" :required="true" :show-search="true" rulesKey="nationality" :columns="countryOptions"
-            :label="t('card.Form.f7')" :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-          <cwg-input v-if="cityOptions.length > 0" v-model:value="formData.town" fkey="town" :required="true"
-            :show-search="true" rulesKey="town" type="select" :columns="cityOptions" :label="t('card.Form.f9')"
-            :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-          <cwg-input v-model:value="formData.address" fkey="address" :label="t('card.Form.f10')" :required="true"
-            rulesKey="address" :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-          <cwg-input v-model:value="formData.postCode" :required="true" fkey="postCode" rulesKey="postCode"
-            :label="t('card.Form.f11')" :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-        </view>
-        <!-- 第三步:职业信息 -->
-        <view v-show="currentStep === 3" class="form-section">
-          <h3 class="section-title">{{ t("card.Info.s0") }}</h3>
-          <cwg-input v-if="occupationList.length > 0" v-model:value="formData.occupation" fkey="occupation"
-            type="select" :columns="occupationList" :label="t('card.Form.f12')" :readonly="isReadonly"
-            :disabled="isReadonly" @change="handleChange" />
-          <cwg-input v-model:value="formData.annualSalary" fkey="annualSalary" :label="t('card.Form.f13')"
-            :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-          <cwg-input v-model:value="formData.accountPurpose" fkey="accountPurpose" :label="t('card.Form.f14')"
-            :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-          <cwg-input v-model:value="formData.expectedMonthlyVolume" fkey="expectedMonthlyVolume"
-            :label="t('card.Form.f15')" :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-        </view>
-        <!-- 第四步:证件信息 -->
-        <view v-show="currentStep === 4" class="form-section">
-          <h3 class="section-title">{{ t("card.Info.s2") }}</h3>
-          <cwg-input v-if="availableIdTypeOptions.length" v-model:value="formData.idType" rulesKey="idType"
-            fkey="idType" :required="true" type="select" :columns="availableIdTypeOptions" :label="t('card.Form.f16')"
-            :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-          <cwg-input v-model:value="formData.idNumber" :required="true" rulesKey="idNumber" fkey="idNumber"
-            :label="t('card.Form.f17')" :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-          <cwg-input v-if="formData.nationality == 'US'" v-model:value="formData.ssn" fkey="ssn" rulesKey="ssn"
-            :label="t('card.Form.f18')" :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
-          <cwg-input v-model:value="formData.issueDate" :required="true" type="date" fkey="issueDate"
-            rulesKey="issueDate" :label="t('card.Form.f19')" :readonly="isReadonly" :disabled="isReadonly"
-            @change="handleChange" />
-          <cwg-input v-model:value="formData.idNoExpiryDate" :required="true" type="date" fkey="idNoExpiryDate"
-            rulesKey="idNoExpiryDate" :label="t('card.Form.f20')" :readonly="isReadonly" :disabled="isReadonly"
-            @change="handleChange" />
-          <template v-if="formData.photoStatus == '1'">
-            <cwg-input v-model:value="formData.idFrontUrl" :required="true" type="upload" fkey="idFrontUrl"
-              rulesKey="idFrontUrl" :label="t('card.Form.f21')" :is-upload-d="true"
-              accept="image/png, image/jpeg, image/jpg" :readonly="isReadonly" :disabled="isReadonly"
-              @change="handleChange">
-              <view class="cwg-upload">
-                <cwg-icon name="back-top" />
-                <view class="name">
-                  {{ t("card.Form.f23_2") }}{{ t("card.Form.f23") }}
-                </view>
-                <view class="back">{{ t("card.Form.f23_3") }}</view>
-              </view>
-            </cwg-input>
-            <cwg-input v-model:value="formData.idBackUrl" type="upload" :required="true" fkey="idBackUrl"
-              rulesKey="idBackUrl" :label="t('card.Form.f22')" :is-upload-d="true"
-              accept="image/png, image/jpeg, image/jpg" :readonly="isReadonly" :disabled="isReadonly"
-              @change="handleChange">
-              <view class="cwg-upload">
-                <cwg-icon name="back-top" />
-                <view class="name">
-                  {{ t("card.Form.f23_2") }}{{ t("card.Form.f23") }}
-                </view>
-                <view class="back">{{ t("card.Form.f23_3") }}</view>
-              </view>
-            </cwg-input>
-            <cwg-input v-model:value="formData.idHoldUrl" type="upload" fkey="idHoldUrl" :required="true"
-              rulesKey="idHoldUrl" :label="t('card.Form.f23')" :is-upload-d="true"
-              accept="image/png, image/jpeg, image/jpg" :readonly="isReadonly" :disabled="isReadonly"
-              @change="handleChange">
-              <view class="cwg-upload">
-                <cwg-icon name="back-top" />
-                <view class="name">
-                  {{ t("card.Form.f23_2") }}{{ t("card.Form.f23") }}
-                </view>
-                <view class="back">{{ t("card.Form.f23_3") }}</view>
-              </view>
-            </cwg-input>
-          </template>
-        </view>
-        <!-- 步骤控制按钮 -->
-        <view class="form-actions">
-          <template v-if="currentStep === 3">
-            <view class="fixed-btn">
-              <view class="cwg-button two-btn">
-                <u-button plain block class="prev-btn" @click="goStep(2)">
-                  {{ t("card.Btn.Previous") }}
-                </u-button>
-                <u-button type="primary" block :loading="loadingStates.validateStep3" @click="validateStep3">
-                  {{ t("card.Btn.Next") }}
-                </u-button>
-              </view>
-            </view>
-          </template>
-          <template v-else-if="currentStep === 2">
-            <view class="fixed-btn">
-              <view class="cwg-button two-btn">
-                <u-button plain block class="prev-btn" @click="goStep(1)">
-                  {{ t("card.Btn.Previous") }}
-                </u-button>
-                <u-button type="warning" block :loading="loadingStates.validateStep2" @click="validateStep2">
-                  {{ t("card.Btn.Next") }}
-                </u-button>
-              </view>
-            </view>
-          </template>
-          <template v-else-if="currentStep === 1">
-            <view class="fixed-btn">
-              <view class="cwg-button two-btn">
-                <u-button type="warning" block :loading="loadingStates.validateStep1" @click="validateStep1">
-                  {{ t("card.Btn.Next") }}
-                </u-button>
-              </view>
-            </view>
-          </template>
-          <template v-else-if="currentStep === 4">
-            <view class="fixed-btn">
-              <view class="cwg-button two-btn">
-                <u-button plain block class="prev-btn" @click="goStep(3)">
-                  {{ t("card.Btn.Previous") }}
-                </u-button>
-                <u-button v-if="!isUpdate" type="warning" block :loading="loadingStates.validateStep4"
-                  @click="validateStep4(1)">
-                  {{ t("card.Btn.Submit") }}
-                </u-button>
-                <u-button v-if="isUpdate && !isAuthInfo" type="warning" block :loading="loadingStates.validateStep4"
-                  @click="validateStep4(2)">
-                  {{ t("card.Btn.Update") }}
-                </u-button>
-                <u-button v-if="
-                  isUpdate &&
-                  formData.kycStatus != '2' &&
-                  formData.photoStatus != '1'
-                " type="warning" block :loading="loadingStates.validateStep4" @click="validateStep4(3)">
-                  {{ t("card.Btn.Auth") }}
-                </u-button>
-              </view>
-            </view>
-          </template>
-        </view>
-      </u-form>
-    </view>
-    <view class="form-tab"></view>
-  </cwg-page-wrapper>
-  <card-websdk-link ref="cardWebsdkLinkRef" />
-</template>
-
-<script setup lang="ts">
-import { ref, onMounted, watch, computed } from "vue";
-import { pinyin } from "pinyin-pro";
-import { useI18n } from "vue-i18n";
-import { onLoad } from '@dcloudio/uni-app'
-import { userToken } from "@/composables/config";
-import { ucardApi } from "@/api/ucard";
-import { userApi } from "@/api/user";
-import useUserStore from "@/stores/use-user-store";
-import useIdTypeOptions from "@/composables/useIdTypeOptions";
-import { Patterns, Validators } from "@/utils/validators";
-import CardWebsdkLink from "@/components/card-websdkLink.vue";
-import useRouter from "@/hooks/useRouter";
-const router = useRouter();
-
-const { availableIdTypeOptions, loadIdTypesConfig } = useIdTypeOptions()
-console.log(availableIdTypeOptions, 1212121, 'storeIdTypeOptionsstoreIdTypeOptions');
-
-const { t } = useI18n();
-const currentStep = ref<number>(1);
-const cardWebsdkLinkRef = ref<InstanceType<typeof CardWebsdkLink> | null>(null);
-
-onLoad((options) => {
-  currentStep.value = parseInt(options?.currentStep || '1', 10);
-});
-
-const formRef = ref();
-
-function goStep(step: number) {
-  currentStep.value = step;
-}
-
-const sexOptions = ref([
-  { text: t("card.Form.v1"), value: "M" },
-  { text: t("card.Form.v2"), value: "F" },
-]);
-
-function validateName(a: any, b?: any, c?: any) {
-  const reg = /^[A-Z\s]+$/i;
-  // Element 风格: (rule, value, callback)
-  if (typeof c === "function") {
-    const value = b;
-    const callback = c;
-    const val = String(value ?? "").trim();
-    if (!val) return callback(new Error(t("card.vaildate.v4")));
-    if (!reg.test(val)) return callback(new Error(t("card.vaildate.v38")));
-    if (val.length < 2 || val.length > 23)
-      return callback(new Error(t("card.vaildate.v39")));
-    const firstName = String(formData.value?.firstName ?? "").trim();
-    const lastName = String(formData.value?.lastName ?? "").trim();
-    if (`${firstName} ${lastName}`.length > 23)
-      return callback(new Error(t("card.vaildate.v40")));
-    return callback();
-  }
-  // Vant 风格: (value) => boolean | string | Promise
-  const val = String(a ?? "").trim();
-  if (!val) return t("card.vaildate.v4");
-  if (!reg.test(val)) return t("card.vaildate.v38");
-  if (val.length < 2 || val.length > 23) return t("card.vaildate.v39");
-  const firstName = String(formData.value?.firstName ?? "").trim();
-  const lastName = String(formData.value?.lastName ?? "").trim();
-  if (`${firstName} ${lastName}`.length > 23) return t("card.vaildate.v40");
-  return true;
-}
-
-// 生日校验:18 岁以上
-function validateBirthday(a: any, b?: any, c?: any) {
-  // Element 风格: (rule, value, callback)
-  if (typeof c === "function") {
-    const value = b;
-    const callback = c;
-    const val = value;
-    if (!val) return callback(new Error(t("card.vaildate.v5")));
-
-    const today = new Date();
-    const birthDate = new Date(val);
-    let age = today.getFullYear() - birthDate.getFullYear();
-    const month = today.getMonth() - birthDate.getMonth();
-    if (month < 0 || (month === 0 && today.getDate() < birthDate.getDate()))
-      age--;
-
-    if (age < 18) return callback(new Error(t("card.New.n3")));
-    return callback();
-  }
-
-  // uview-plus / Vant 风格: (value) => boolean | string
-  const val = a;
-  if (!val) return t("card.vaildate.v5");
-
-  const today = new Date();
-  const birthDate = new Date(val);
-  let age = today.getFullYear() - birthDate.getFullYear();
-  const month = today.getMonth() - birthDate.getMonth();
-  if (month < 0 || (month === 0 && today.getDate() < birthDate.getDate()))
-    age--;
-
-  return age < 18 ? t("card.New.n3") : true;
-}
-
-function validateAddress(a: any, b?: any, c?: any) {
-  // 地址只需要校验长度和基础字符合法性,允许数字、字母、空格等
-  // Element 风格: (rule, value, callback)
-  if (typeof c === "function") {
-    const value = b;
-    const callback = c;
-    const val = String(value ?? "").trim();
-
-    if (!val) return callback(new Error(t("card.vaildate.v27")));
-    if (val.length < 2 || val.length > 40)
-      return callback(new Error(t("card.New.n1")));
-    if (!Patterns.address.test(val))
-      return callback(new Error(t("card.New.n1")));
-
-    return callback();
-  }
-
-  // Vant 风格: (value) => boolean | string | Promise
-  const val = String(a ?? "").trim();
-  if (!val) return t("card.vaildate.v27");
-  if (val.length < 2 || val.length > 40) return t("card.New.n1");
-  return Patterns.address.test(val) ? true : t("card.New.n1");
-}
-
-// 表单验证规则
-const rules = {
-  areaCode: [Validators.required(t("card.vaildate.v1"))],
-  mobile: [
-    Validators.required(t("card.vaildate.v2")),
-    Validators.pattern(Patterns.mobile, t("card.vaildate.v44")),
-  ],
-  email: [
-    Validators.required(t("card.vaildate.v28")),
-    Validators.pattern(Patterns.email, t("card.vaildate.v28")),
-  ],
-  firstName: [
-    Validators.required(t("card.vaildate.v3")),
-    Validators.custom(validateName),
-  ],
-  lastName: [
-    Validators.required(t("card.vaildate.v4")),
-    Validators.custom(validateName),
-  ],
-  birthday: [
-    Validators.required(t("card.vaildate.v5"), "change"),
-    Validators.custom(validateBirthday, "change"),
-  ],
-  nationality: [Validators.required(t("card.vaildate.v6"), "change")],
-  town: [Validators.required(t("card.vaildate.v7"), "change")],
-  address: [
-    Validators.required(t("card.vaildate.v27")),
-    Validators.custom(validateAddress),
-  ],
-  gender: [Validators.required(t("card.vaildate.v9"), "change")],
-  occupation: [Validators.required(t("card.vaildate.v10"), "change")],
-  annualSalary: [Validators.required(t("card.vaildate.v11"))],
-  accountPurpose: [Validators.required(t("card.vaildate.v12"))],
-  expectedMonthlyVolume: [Validators.required(t("card.vaildate.v13"))],
-  idType: [Validators.required(t("card.vaildate.v14"), "change")],
-  idNumber: [
-    Validators.required(t("card.vaildate.v15")),
-    Validators.pattern(Patterns.idNumber, t("card.vaildate.v45")),
-  ],
-  ssn: [Validators.required(t("card.vaildate.v16"))],
-  issueDate: [Validators.required(t("card.vaildate.v17"), "change")],
-  idNoExpiryDate: [Validators.required(t("card.vaildate.v18"), "change")],
-  idFrontUrl: [Validators.required(t("card.vaildate.v19"), "change")],
-  idBackUrl: [Validators.required(t("card.vaildate.v20"), "change")],
-  idHoldUrl: [Validators.required(t("card.vaildate.v21"), "change")],
-  postCode: [
-    Validators.required(t("card.vaildate.v8")),
-    Validators.pattern(Patterns.postcode, t("card.New.n2")),
-  ],
-};
-
-const formData = ref({
-  merchantOrderNo: undefined,
-  cardTypeId: undefined,
-  areaCode: undefined,
-  mobile: undefined,
-  email: undefined,
-  firstName: undefined,
-  lastName: undefined,
-  birthday: undefined,
-  nationality: undefined,
-  country: undefined,
-  town: undefined,
-  address: undefined,
-  postCode: undefined,
-  gender: undefined,
-  occupation: undefined,
-  annualSalary: undefined,
-  accountPurpose: undefined,
-  expectedMonthlyVolume: undefined,
-  idType: undefined,
-  idNumber: undefined,
-  ssn: undefined,
-  issueDate: undefined,
-  idNoExpiryDate: undefined,
-  idFrontUrl: undefined,
-  idBackUrl: undefined,
-  idHoldUrl: undefined,
-  ipAddress: undefined,
-  cId: undefined,
-  customId: undefined,
-  photoStatus: '1',
-  kycStatus: '1'
-});
-
-const isUpdate = ref(false);
-const isAuthInfo = ref(false);
-
-// 国家选项
-const countryOptions = ref<Array<{ text: string; value: string }>>([]);
-const cityOptions = ref<Array<{ text: string; value: string }>>([]);
-const phoneCodes = ref<Array<{ text: string; value: string }>>([]);
-const occupationList = ref<Array<{ text: string; value: string }>>([]);
-
-// 获取国家列表
-async function getCountryListForSelect() {
-  try {
-    const res = await ucardApi.ucardCountryCity({});
-    if (res.code === 200 || res.code === 0) {
-      countryOptions.value = res.data.map((item: any) => ({
-        text: item.enName,
-        value: item.code,
-      }));
-      phoneCodes.value = res.data.map((item: any) => ({
-        text: `${item.areaCode} ${item.enName}`,
-        value: item.areaCode,
-      }));
-    }
-  } catch (error) {
-    console.error('Error loading country list:', error);
-    countryOptions.value = [];
-  }
-}
-
-
-// 获取城市列表
-async function getCityListForSelect(countryCode: string) {
-  try {
-    const res = await ucardApi.ucardCountryCity({ code: countryCode });
-    if (res.code === 200 || res.code === 0) {
-      const cityList = res.data.map((item: any) => ({
-        text: item.enName,
-        value: item.code,
-      }));
-      cityOptions.value = cityList;
-    }
-  } catch (error) {
-    console.error('Error loading city list:', error);
-    cityOptions.value = [];
-  }
-}
-
-// 获取职业
-async function getOccupationList() {
-  try {
-    const res = await ucardApi.getOccupationList();
-    if (res.code === 200 || res.code === 0) {
-      const list = res.data.map((item: any) => ({
-        text: item.description,
-        value: item.occupationCode,
-      }));
-      occupationList.value = list;
-    }
-  } catch (error) {
-    console.error('Error loading occupation list:', error);
-    occupationList.value = [];
-  }
-}
-
-function handleChange(value: any) {
-  formData.value = { ...formData.value, [value.key]: value.value };
-
-  if (value.key === "nationality") {
-    formData.value = { ...formData.value, country: value.value };
-    getCityListForSelect(value.value);
-    loadIdTypesConfig(value.value);
-    formData.value.town = "";
-  }
-}
-
-const containsChinese = (str: string) => /[\u4E00-\u9FA5]/.test(str);
-
-const convertToPinyin = (value: string) =>
-  containsChinese(value)
-    ? pinyin(value, { toneType: "none", type: "capitalize" })
-    : value;
-
-// 初始化表单数据 - 使用现有用户信息进行回显
-function initFormDataWithUserInfo() {
-  if (!userInfo.value) return;
-
-  const customInfo = userInfo.value.customInfo || userInfo.value;
-
-  // 基本信息
-  formData.value.email = customInfo.email || formData.value.email;
-  formData.value.areaCode = customInfo.areaCode || formData.value.areaCode;
-  formData.value.mobile = customInfo.mobile || formData.value.mobile;
-  formData.value.birthday = customInfo.birthday || formData.value.birthday;
-  formData.value.gender = customInfo.gender || formData.value.gender;
-
-  // 姓名处理
-  if (customInfo.lastName) {
-    formData.value.lastName = convertToPinyin(customInfo.lastName);
-  }
-  if (customInfo.firstName) {
-    formData.value.firstName = convertToPinyin(customInfo.firstName);
-  }
-
-  // 地址信息
-  formData.value.nationality = customInfo.nationality || formData.value.nationality;
-  formData.value.town = customInfo.town || formData.value.town;
-  formData.value.address = customInfo.address || formData.value.address;
-  formData.value.postCode = customInfo.postCode || formData.value.postCode;
-
-  // 职业信息
-  formData.value.occupation = customInfo.occupation || formData.value.occupation;
-  formData.value.annualSalary = customInfo.annualSalary || formData.value.annualSalary;
-  formData.value.accountPurpose = customInfo.accountPurpose || formData.value.accountPurpose;
-  formData.value.expectedMonthlyVolume = customInfo.expectedMonthlyVolume || formData.value.expectedMonthlyVolume;
-
-  // 证件信息
-  formData.value.idType = customInfo.idType || formData.value.idType;
-  formData.value.idNumber = customInfo.idNumber || formData.value.idNumber;
-  formData.value.ssn = customInfo.ssn || formData.value.ssn;
-  formData.value.issueDate = customInfo.issueDate || formData.value.issueDate;
-  formData.value.idNoExpiryDate = customInfo.idNoExpiryDate || formData.value.idNoExpiryDate;
-  formData.value.idFrontUrl = customInfo.idFrontUrl || formData.value.idFrontUrl;
-  formData.value.idBackUrl = customInfo.idBackUrl || formData.value.idBackUrl;
-  formData.value.idHoldUrl = customInfo.idHoldUrl || formData.value.idHoldUrl;
-
-  // 状态信息
-  formData.value.photoStatus = customInfo.photoStatus || '1';
-  formData.value.kycStatus = customInfo.kycStatus || '1';
-
-  // 对于下拉选择字段,需要确保它们在选项列表中存在
-  setTimeout(() => {
-    // 确保 areaCode 在选项中
-    if (formData.value.areaCode && phoneCodes.value.length > 0) {
-      const areaCodeExists = phoneCodes.value.some(item => item.value === formData.value.areaCode);
-      if (!areaCodeExists) {
-        // 如果不存在,添加该项到选项中
-        phoneCodes.value.push({
-          text: formData.value.areaCode,
-          value: formData.value.areaCode
-        });
-      }
-    }
-
-    // 确保 nationality 在选项中
-    if (formData.value.nationality && countryOptions.value.length > 0) {
-      const nationalityExists = countryOptions.value.some(item => item.value === formData.value.nationality);
-      if (!nationalityExists) {
-        countryOptions.value.push({
-          text: formData.value.nationality,
-          value: formData.value.nationality
-        });
-      }
-    }
-
-    // 确保 occupation 在选项中
-    if (formData.value.occupation && occupationList.value.length > 0) {
-      const occupationExists = occupationList.value.some(item => item.value === formData.value.occupation);
-      if (!occupationExists) {
-        occupationList.value.push({
-          text: formData.value.occupation,
-          value: formData.value.occupation
-        });
-      }
-    }
-
-    // 确保 gender 在选项中
-    if (formData.value.gender) {
-      const genderExists = sexOptions.value.some(item => item.value === formData.value.gender);
-      if (!genderExists) {
-        sexOptions.value.push({
-          text: formData.value.gender === 'M' ? t("card.Form.v1") : t("card.Form.v2"),
-          value: formData.value.gender
-        });
-      }
-    }
-  }, 100);
-}
-
-async function getUserSingle() {
-  if (!userToken.value) {
-    uni.showToast({ title: t("common.loginFirst"), icon: 'none' });
-    return;
-  }
-
-  try {
-    const res = await userApi.getUserSingle();
-    if (res.code === 200 && res.data) {
-      // 更新表单数据
-      formData.value = { ...formData.value, ...res.data };
-      userStore.saveUserInfo(res.data);
-
-      // 设置状态
-      if (res.data) {
-        isUpdate.value = true;
-      }
-
-      if (res.data.approveStatus == 2 || res.data.kycStatus == 2) {
-        isAuthInfo.value = true;
-      }
-
-      if (res.data.approveStatus == 3) {
-        isAuthInfo.value = false;
-      }
-
-      // 如果有国籍信息,加载对应的城市列表
-      if (res.data.nationality) {
-        await getCityListForSelect(res.data.nationality);
-        await loadIdTypesConfig(res.data.nationality);
-      }
-    }
-  } catch (error: any) {
-    console.error('Error in getUserSingle:', error);
-    uni.showToast({ title: error.message || t("common.error"), icon: 'none' });
-  }
-}
-
-// 加载状态
-const loadingStates = ref({
-  validateStep1: false,
-  validateStep2: false,
-  validateStep3: false,
-  validateStep4: false,
-});
-
-// 第一步校验 - 基本信息完整性
-async function validateStep1() {
-  loadingStates.value.validateStep1 = true;
-  try {
-    const requiredFields = [
-      "email",
-      "lastName",
-      "firstName",
-      "mobile",
-      "areaCode",
-      "birthday",
-      "gender",
-    ] as const;
-    await formRef.value?.validateField(requiredFields, (errorsRes: any) => {
-      const hasError = Array.isArray(errorsRes) && errorsRes.length > 0;
-      if (hasError) {
-        uni.showToast({ title: errorsRes[0].message, icon: 'none' });
-      } else {
-        goStep(2);
-      }
-    });
-  } catch (error: any) {
-    if (Array.isArray(error) && error.length > 0) {
-      uni.showToast({ title: error[0].message, icon: 'none' });
-    } else {
-
-    }
-  } finally {
-    loadingStates.value.validateStep1 = false;
-  }
-}
-
-// 第二步校验 - 国籍信息
-async function validateStep2() {
-  loadingStates.value.validateStep2 = true;
-  try {
-    const requiredFields = [
-      "nationality",
-      "town",
-      "postCode",
-      "address",
-    ] as const;
-    await formRef.value?.validateField(requiredFields, (errorsRes: any) => {
-      const hasError = Array.isArray(errorsRes) && errorsRes.length > 0;
-      if (hasError) {
-        uni.showToast({ title: errorsRes[0].message, icon: 'none' });
-      } else {
-        goStep(3);
-      }
-    });
-  } catch (error: any) {
-    if (Array.isArray(error) && error.length > 0) {
-      uni.showToast({ title: error[0].message, icon: 'none' });
-    } else {
-
-    }
-  } finally {
-    loadingStates.value.validateStep2 = false;
-  }
-}
-
-// 第三步校验 - 职业信息
-async function validateStep3() {
-  loadingStates.value.validateStep3 = true;
-  try {
-    const requiredFields = [
-      "occupation",
-      "annualSalary",
-      "accountPurpose",
-      "expectedMonthlyVolume",
-    ] as const;
-    await formRef.value?.validateField(requiredFields, (errorsRes: any) => {
-      const hasError = Array.isArray(errorsRes) && errorsRes.length > 0;
-      if (hasError) {
-        uni.showToast({ title: errorsRes[0].message, icon: 'none' });
-      } else {
-        goStep(4);
-      }
-    });
-  } catch (error: any) {
-    if (Array.isArray(error) && error.length > 0) {
-      uni.showToast({ title: error[0].message, icon: 'none' });
-    } else {
-
-    }
-  } finally {
-    loadingStates.value.validateStep3 = false;
-  }
-}
-
-// 第四步校验 校验所有信息
-async function validateStep4(type: number) {
-  loadingStates.value.validateStep4 = true;
-  try {
-    const requiredFields: Array<keyof typeof formData.value> = [
-      "email",
-      "lastName",
-      "firstName",
-      "mobile",
-      "areaCode",
-      "nationality",
-      "town",
-      "postCode",
-      "address",
-      "birthday",
-      "gender",
-      "idType",
-      "idNumber",
-      "issueDate",
-      "idNoExpiryDate",
-      "occupation",
-      "annualSalary",
-      "accountPurpose",
-      "expectedMonthlyVolume",
-    ];
-
-    // 只有在需要上传照片时才验证照片字段
-    if (formData.value.photoStatus === '1') {
-      requiredFields.push("idFrontUrl", "idBackUrl", "idHoldUrl");
-    }
-
-    await formRef.value?.validateField(requiredFields, (errorsRes: any) => {
-      const hasError = Array.isArray(errorsRes) && errorsRes.length > 0;
-      console.log(hasError, 121212);
-
-      if (hasError) {
-        uni.showToast({ title: errorsRes[0].message, icon: 'none' });
-      } else {
-        // 最终校验所有信息
-        switch (type) {
-          case 1:
-            infoSubmit();
-            break;
-          case 2:
-            infoUpdate();
-            break;
-          case 3:
-            infoAuth();
-            break;
-          default:
-            break;
-        }
-      }
-    });
-  } catch (error: any) {
-    if (Array.isArray(error) && error.length > 0) {
-      uni.showToast({ title: error[0].message, icon: 'none' });
-    } else {
-
-    }
-  } finally {
-    loadingStates.value.validateStep4 = false;
-  }
-}
-
-async function infoSubmit() {
-  try {
-    const res = await ucardApi.merchantRegister(formData.value);
-    if (res.code === 200) {
-      uni.showToast({ title: t("common.success"), icon: 'success' });
-      // 提交成功后打开 WebSDK 弹窗
-      router.push({
-        path: "/pages/mine/kyc",
-        query: { cardId: (formData.value as any).id },
-      });
-      // cardWebsdkLinkRef.value?.getWebsdkLink(
-      //   (formData.value as any).id
-      // );
-    } else {
-      uni.showToast({ title: res.msg, icon: 'none' });
-    }
-  } catch (error: any) {
-    uni.showToast({ title: error.message || t("common.error"), icon: 'none' });
-  }
-}
-
-async function infoUpdate() {
-  try {
-    const res = await ucardApi.merchantUpdate(formData.value);
-    if (res.code === 200) {
-      uni.showToast({ title: t("common.success"), icon: 'success' });
-      // 更新成功后打开 WebSDK 弹窗
-      // router.push({
-      //   path: "/pages/mine/kyc",
-      //   query: { cardId: (formData.value as any).id },
-      // });
-    } else {
-      uni.showToast({ title: res.msg, icon: 'none' });
-    }
-  } catch (error: any) {
-    if (Array.isArray(error) && error.length > 0) {
-      uni.showToast({ title: error[0].message, icon: 'none' });
-    } else {
-      uni.showToast({ title: t("card.New.errer"), icon: 'none' });
-    }
-  }
-}
-
-async function infoAuth() {
-  try {
-    // 认证操作后也打开 WebSDK 弹窗(无需等待额外接口)
-    router.push({
-      path: "/pages/mine/kyc",
-      query: { cardId: (formData.value as any).id },
-    });
-  } catch (error: any) {
-    if (Array.isArray(error) && error.length > 0) {
-      uni.showToast({ title: error[0].message, icon: 'none' });
-    } else {
-      uni.showToast({ title: t("card.New.errer"), icon: 'none' });
-    }
-  }
-}
-
-const isReadonly = computed(() => isAuthInfo.value);
-
-onMounted(async () => {
-  // 用现有用户信息回显
-  initFormDataWithUserInfo();
-  // 先加载选项数据
-  await Promise.all([
-    getOccupationList(),
-    getCountryListForSelect()
-  ]);
-
-
-
-  // 延迟加载用户详细信息
-  setTimeout(async () => {
-    await getUserSingle();
-  }, 100);
-});
-</script>
-
-<style scoped lang="scss">
-@import "@/uni.scss";
-
-.form-tab {
-  height: px2rpx(100);
-}
-
-.form-section {
-  margin: px2rpx(8) 0;
-}
-
-.section-title {
-  color: #1a1a1a;
-  font-family: Roboto;
-  font-size: px2rpx(22);
-  font-style: normal;
-  font-weight: 600;
-  line-height: px2rpx(22);
-  margin-bottom: px2rpx(16);
-}
-
-.two-btn {
-  display: flex;
-  align-items: center;
-  gap: px2rpx(31);
-
-  .prev-btn {
-    border: 1px solid var(--main-yellow) !important;
-    color: #fff !important;
-    background: transparent;
-  }
-}
-
-.f {
-  display: flex;
-  align-items: flex-end;
-  gap: px2rpx(12);
-
-  .l {
-    flex: 1;
-  }
-
-  .r {
-    width: px2rpx(203);
-  }
-}
-
-:deep(.u-uploader) {
-  width: 100%;
-
-  .u-uploader__wrapper {
-    width: 100%;
-    display: block;
-  }
-
-  .u-uploader__preview {
-    width: 100% !important;
-    height: px2rpx(160) !important;
-    border-radius: px2rpx(24);
-    overflow: hidden;
-
-    .u-uploader__preview-image {
-      width: 100%;
-      height: 100%;
-
-      .u-image__img {
-        object-fit: contain;
-      }
-    }
-
-    .u-uploader__preview-delete {
-      position: absolute;
-      top: 0;
-      right: 0;
-      width: px2rpx(30);
-      height: px2rpx(30);
-      border-radius: 0 px2rpx(24) 0 0;
-
-      i {
-        text-align: center;
-        line-height: px2rpx(30);
-        font-size: px2rpx(30);
-      }
-    }
-  }
-}
-</style>

+ 0 - 232
pages/mine/index.vue

@@ -1,232 +0,0 @@
-<template>
-	<cwg-page-wrapper :isHeaderFixed="true">
-		<view class="page">
-			<cwg-header :title="t('pages.mine.index')">
-				<div class="language-switch" @click="router.push('/pages/customer/index')">
-					<cwg-icon color="#000" icon="cog-outline" />
-				</div>
-			</cwg-header>
-			<view class="user-card">
-				<view class="avatar"></view>
-				<view class="user-info">
-					<view class="phone">{{ userInfo?.email }}</view>
-				</view>
-			</view>
-			<view class="group">
-				<view class="group-item" @click="openProfile()">
-					<cwg-icon color="#000" icon="shield-lock-open-outline" />
-					<text class="item-text">{{ t("language.i3") }}</text>
-					<text class="item-text version" v-if="!isPersonalInfoCompleted">{{ t("language.i0") }}</text>
-					<text class="item-text version" v-if="isPersonalInfoCompleted">{{ t("State.ToCertified") }}</text>
-					<cwg-icon color="#000" icon="chevron-right" />
-				</view>
-				<view class="group-item" @click="router.push('/pages/apply-record/list')">
-					<cwg-icon color="#000" icon="kksq" />
-					<text class="item-text">{{ t("card.tab15") }}</text>
-					<text class="version item-text"></text>
-					<cwg-icon color="#000" icon="chevron-right" />
-				</view>
-				<view class="group-item" @click="router.push('/pages/wallet/balance')">
-					<cwg-icon color="#000" icon="qbye" />
-					<text class="item-text">{{ t("card.tab17") }}</text>
-					<text class="version item-text"></text>
-					<cwg-icon color="#000" icon="chevron-right" />
-				</view>
-				<view class="group-item" @click="router.push('/pages/wallet/vaultody-list')">
-					<cwg-icon color="#000" icon="qbye" />
-					<text class="item-text">{{ t("pages.wallet.vaultody-list") }}</text>
-					<text class="version item-text"></text>
-					<cwg-icon color="#000" icon="chevron-right" />
-				</view>
-				<view class="group-item" @click="router.push('/pages/wallet/withdraw-list')">
-					<cwg-icon color="#000" icon="qbye" />
-					<text class="item-text">{{ t("pages.wallet.withdraw-list") }}</text>
-					<text class="version item-text"></text>
-					<cwg-icon color="#000" icon="chevron-right" />
-				</view>
-				<view class="group-item" @click="router.push('/pages/mine/help')">
-					<cwg-icon color="#000" icon="cjwt" />
-					<text class="item-text">{{ t('pages.mine.help') }}</text>
-					<text class="version item-text"></text>
-					<cwg-icon color="#000" icon="chevron-right" />
-				</view>
-				<view class="group-item" @click="router.push('/pages/mine/cog')">
-					<cwg-icon color="#000" icon="sz" />
-					<text class="item-text">{{ t('pages.mine.cog') }}</text>
-					<text class="version item-text"></text>
-					<cwg-icon color="#000" icon="chevron-right" />
-				</view>
-			</view>
-		</view>
-	</cwg-page-wrapper>
-
-</template>
-
-<script setup lang="ts">
-import { ref, computed, onMounted } from "vue";
-import { useI18n } from "vue-i18n";
-import useRouter from "@/hooks/useRouter";
-import useUserStore from "@/stores/use-user-store";
-import { ucardApi } from "@/api/ucard";
-const { t } = useI18n();
-const userStore = useUserStore();
-const router = useRouter();
-const userInfo = computed(() => userStore.userInfo);
-// 判断是否已完成个人信息认证
-const isPersonalInfoCompleted = computed(() => {
-	if (userInfo?.approveStatus == 2) {
-		return true;
-	} else {
-		return false;
-	}
-});
-
-function openProfile() {
-	if (!isPersonalInfoCompleted.value) {
-		router.push('/pages/mine/info');
-	} else {
-		router.push('/pages/mine/improve');
-	}
-}
-async function getUserInfo() {
-	try {
-		const res = await ucardApi.getSingle();
-		userStore.saveUserInfo(res.data);
-	} catch (error) {
-		console.log(error, 111);
-	}
-}
-onMounted(() => {
-	if (!userInfo.value?.id) {
-		getUserInfo();
-	}
-});
-</script>
-
-<style scoped lang="scss">
-@import "@/uni.scss";
-
-:deep(.u-modal__content) {
-	padding: px2rpx(24) px2rpx(40);
-
-	.p1 {
-		color: #363130;
-		font-family: "League Spartan";
-		font-size: px2rpx(17);
-		font-style: normal;
-		font-weight: 400;
-		line-height: normal;
-		margin-bottom: px2rpx(32);
-	}
-
-	.modal-class {
-		width: px2rpx(300);
-
-	}
-
-	.title {
-		color: #1a1a1a;
-		text-align: center;
-		font-family: Roboto;
-		font-size: px2rpx(22);
-		font-style: normal;
-		font-weight: 600;
-		line-height: px2rpx(22);
-	}
-
-	.no-button {
-		width: 100%;
-		margin: px2rpx(12) 0;
-
-		.u-button {
-			background-color: #ffbdc8 !important;
-		}
-	}
-
-	.ok-button {
-		margin: px2rpx(4) 0;
-		/* background-color: #EA002A; */
-	}
-}
-
-.user-card {
-	width: 100%;
-	display: inline-flex;
-	flex-direction: column;
-	justify-content: center;
-	align-items: center;
-	gap: px2rpx(24);
-	padding-bottom: px2rpx(48);
-
-	.avatar {
-		width: px2rpx(64);
-		height: px2rpx(64);
-		border-radius: 50%;
-		background: #d8d8d8 url("/static/images/avatars.png") center/cover no-repeat;
-		border: 4rpx solid #fff;
-	}
-
-	.phone {
-		// 1a1a1a
-		color: var(--primary-color);
-		font-family: Roboto;
-		font-size: px2rpx(22);
-		font-style: normal;
-		font-weight: 600;
-		line-height: px2rpx(4);
-	}
-}
-
-.user-info .group {
-	background: var(--action-bg);
-	border-radius: px2rpx(16);
-	margin-top: px2rpx(24);
-	overflow: hidden;
-}
-
-.group-item {
-	display: flex;
-	align-items: center;
-	padding: px2rpx(16) 0;
-	color: #000;
-	font-size: px2rpx(16);
-	/* border-bottom: 2rpx solid var(--action-bg); */
-	position: relative;
-}
-
-.group-item:last-child {
-	border-bottom: none;
-}
-
-svg {
-	width: px2rpx(24);
-	height: px2rpx(24);
-	color: #000;
-	font-size: px2rpx(24);
-}
-
-.group-item .version {
-	margin-left: auto;
-	color: #000;
-	font-size: px2rpx(16);
-}
-
-.item-text {
-	margin-left: px2rpx(12);
-}
-
-.code-dialog {
-	display: flex;
-	justify-content: center;
-	gap: px2rpx(12);
-	padding: px2rpx(16);
-
-	:deep(.u-popup__content) {
-		width: 90% !important;
-	}
-
-	:deep(.u-modal) {
-		width: 100% !important;
-	}
-}
-</style>

+ 0 - 72
pages/mine/language.vue

@@ -1,72 +0,0 @@
-<template>
-  <cwg-page-wrapper>
-    <view class="page page-shadow">
-      <view v-for="item in localesList" :key="item" class="lang-item" :class="{ active: currentLang === item }"
-        @click="changeLang(item)">
-        {{ t(`language.${item}`) }}
-        <view v-if="currentLang === item" class="check">
-          <cwg-icon name="icon_select" />
-        </view>
-      </view>
-    </view>
-  </cwg-page-wrapper>
-</template>
-
-<script setup lang="ts">
-import { ref } from "vue";
-import { useI18n } from "vue-i18n";
-import { lang } from "@/composables/config";
-import { localesList, LANG_MAP } from "@/locale/index";
-
-const { locale, t } = useI18n();
-const currentLang = ref(lang.value || locale.value);
-function changeLang(langValue: string) {
-  locale.value = langValue;
-  lang.value = langValue;
-  const localeValue = LANG_MAP[langValue] || 'zh-Hans';
-
-  uni.setLocale(localeValue);
-  currentLang.value = langValue;
-}
-</script>
-
-<style scoped lang="scss">
-@import "@/uni.scss";
-
-.title {
-  font-size: px2rpx(22);
-  color: #000;
-  font-weight: bold;
-  margin-bottom: px2rpx(44);
-}
-
-.lang-item {
-  background: var(--main-bg);
-  border-radius: px2rpx(14);
-  padding: px2rpx(18);
-  font-size: px2rpx(20);
-  margin-bottom: px2rpx(44);
-  color: #000;
-  display: flex;
-  align-items: center;
-  cursor: pointer;
-  transition: background 0.2s;
-}
-
-.lang-item.active {
-  border-radius: px2rpx(10);
-  background: rgba(255, 209, 216, 0.85);
-}
-
-.check {
-  margin-left: auto;
-
-  svg {
-    width: px2rpx(44);
-    height: px2rpx(44);
-    font-size: px2rpx(44);
-    margin-right: px2rpx(12);
-    color: #4caf50;
-  }
-}
-</style>

+ 0 - 444
pages/mine/new.vue

@@ -1,444 +0,0 @@
-<template>
-    <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
-        <view class="info-card">
-            <!-- 标题栏 -->
-            <view class="content-title">
-                <view>{{ titleMap[title] }}</view>
-                <view v-if="title == 7" class="btn crm-cursor" @click="backIndex">
-                    <uni-icons type="arrowleft" size="20" color="#666"></uni-icons>
-                    <text>{{ t('Custom.Settings.Title') }}</text>
-                </view>
-            </view>
-            <!-- 内容区域 - 图文类型 -->
-            <view v-if="[1, 2, 3, 5].includes(title)" class="content crm-border-radius">
-                <view v-if="imgContentIf" class="img">
-                    <image :src="imgContent" mode="widthFix" class="content-image" @click="previewImage" />
-                </view>
-                <rich-text :nodes="Content" class="rich-text"></rich-text>
-            </view>
-            <!-- 内容区域 - 视频类型4 -->
-            <view v-if="title == 4" class="content crm-border-radius" style="overflow: auto;">
-                <text class="con-title">{{ info.title }}</text>
-                <view class="con-time" style="display: flex; justify-content: space-between;">
-                    <text>{{ info.createTime }}</text>
-                    <image src="/static/images/img/acc_logo.png" mode="aspectFit" style="height: 40px; width: auto;" />
-                </view>
-                <view class="my_video" style="width: 100%;">
-                    <!-- 使用 video 组件 -->
-                    <video :src="info.url" controls style="width: 100%;" :show-fullscreen-btn="true"
-                        :enable-play-gesture="true"></video>
-                </view>
-                <text class="con-des">{{ info.description }}</text>
-            </view>
-            <!-- 内容区域 - 视频类型6 -->
-            <view v-if="title == 6" class="content crm-border-radius" style="overflow: auto;">
-                <text class="con-title">{{ info.title }}</text>
-                <text class="con-time">{{ info.subTitle }}</text>
-                <view class="my_video" style="width: 100%;">
-                    <video :src="imgContent" controls style="width: 100%;" :show-fullscreen-btn="true"
-                        :enable-play-gesture="true"></video>
-                </view>
-                <rich-text :nodes="info.content" class="con-des"></rich-text>
-            </view>
-            <!-- 内容区域 - 公告类型7 -->
-            <view v-if="title == 7" class="content crm-border-radius" style="overflow: auto;">
-                <text class="con-title">{{ info.subject }}</text>
-                <rich-text :nodes="info.content" class="con-des"></rich-text>
-            </view>
-            <!-- 内容区域 - 交易观点8 / 财经日历9 -->
-            <view v-if="title == 8 || title == 9" class="content crm-border-radius">
-                <view style="width: 100%; min-height: 800px;">
-                    <!-- #ifdef H5 -->
-                    <iframe width="100%" height="100%" style="min-height: 800px; border: none;" :src="imgContent" />
-                    <!-- #endif -->
-                    <!-- #ifndef H5 -->
-                    <web-view :src="imgContent"></web-view>
-                    <!-- #endif -->
-                </view>
-            </view>
-
-            <!-- 内容区域 - 电子书10 -->
-            <view v-if="title == 10" class="content crm-border-radius" style="overflow: auto;">
-                <view class="ebookBox">
-                    <image :src="imgUrl + info.coverImage" mode="aspectFill" />
-                    <view>
-                        <text class="news-title">{{ info.title }}</text>
-                        <rich-text :nodes="info.content" class="con-des"></rich-text>
-                        <view class="news-status">
-                            <!-- #ifdef H5 -->
-                            <a :href="imgUrl + info.bookUrl" target="_blank">{{ t('blockchain.item12') }}</a>
-                            <!-- #endif -->
-                            <!-- #ifndef H5 -->
-                            <button @click="downloadEbook" class="download-btn">{{ t('blockchain.item12') }}</button>
-                            <!-- #endif -->
-                        </view>
-                    </view>
-                </view>
-            </view>
-
-            <!-- 内容区域 - 视频类型11 -->
-            <view v-if="title == 11" class="content crm-border-radius">
-                <view style="display: flex; justify-content: flex-end; margin-bottom: 15px;">
-                    <image src="/static/images/img/acc_logo.png" mode="aspectFit" style="height: 40px; width: auto;" />
-                </view>
-                <view style="width: 80%; min-height: 800px; margin: auto;">
-                    <view style="position: relative; overflow: hidden; padding-bottom: 56.25%;">
-                        <!-- #ifdef H5 -->
-                        <iframe :src="videoSrc" width="100%" height="100%" frameborder="0" scrolling="auto"
-                            style="position: absolute;" allowfullscreen></iframe>
-                        <!-- #endif -->
-                        <!-- #ifndef H5 -->
-                        <web-view :src="videoSrc"></web-view>
-                        <!-- #endif -->
-                    </view>
-                </view>
-            </view>
-        </view>
-    </cwg-page-wrapper>
-</template>
-
-<script setup>
-import { ref, computed, onMounted, watch } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import { useI18n } from 'vue-i18n'
-import { newsApi } from '@/service/news';
-import Config from '@/config/index'
-
-const { t } = useI18n()
-const { Code, Host80 } = Config
-const titleMap = computed(() => ({
-    1: t('News.ViewAnalysis'),
-    2: t('News.NewsInformation'),
-    3: t('News.Announcement'),
-    4: t('News.VideoCommentary'),
-    5: t('News.NewsInformation'),
-    6: t('News.VideoCommentary'),
-    7: t('News.Notice'),
-    8: t('News.TradeIdeas'),
-    9: t('News.FinancialCalendar'),
-    10: t('News.Ebook'),
-    11: t('News.VideoCommentary')
-}));
-// 路由参数
-const title = ref(null)
-const Id = ref(null)
-
-// 数据
-const Content = ref('')
-const imgContent = ref('')
-const imgContentIf = ref(false)
-const info = ref({})
-const imgUrl = Host80
-
-// 视频源计算属性
-const videoSrc = computed(() => {
-    const lang = uni.getStorageSync('lang') || 'en'
-    const isChinese = ['cn', 'zhHant'].includes(lang)
-    return isChinese
-        ? 'https://videos.tradingcentral.cn/players/H5quTuut-iodula4l.html'
-        : 'https://videos.tradingcentral.cn/players/SHILp3nA-iodula4l.html'
-})
-
-// 预览图片
-const previewImage = () => {
-    if (imgContent.value) {
-        uni.previewImage({
-            urls: [imgContent.value],
-            current: 0
-        })
-    }
-}
-
-// 下载电子书
-const downloadEbook = () => {
-    const url = imgUrl + info.value.bookUrl
-    // #ifdef APP-PLUS
-    plus.runtime.openURL(url)
-    // #endif
-    // #ifdef MP-WEIXIN
-    uni.downloadFile({
-        url: url,
-        success: (res) => {
-            if (res.statusCode === 200) {
-                uni.openDocument({
-                    filePath: res.tempFilePath,
-                    success: () => {
-                        uni.showToast({
-                            title: t('common.success'),
-                            icon: 'success'
-                        })
-                    }
-                })
-            }
-        }
-    })
-    // #endif
-}
-
-// 获取新闻详情
-const getNewsSingle = async () => {
-    uni.showLoading({ title: t('common.loading') })
-
-    try {
-        if (title.value == 1) {
-            const res = await newsApi.newsAnalysisSingle({ id: Id.value })
-            if (res.code == 200) {
-                if (res.data) {
-                    imgContent.value = res.data.media
-                    Content.value = res.data.content
-                    imgContentIf.value = !!res.data.media
-                }
-            } else {
-                uni.showToast({ title: res.msg, icon: 'none' })
-            }
-        } else if (title.value == 3) {
-            const res = await newsApi.newsInformationSingle({ id: Id.value })
-            if (res.code == 200) {
-                if (res.data) {
-                    imgContent.value = Host80 + res.data.coverImage
-                    Content.value = res.data.content
-                    imgContentIf.value = !!res.data.coverImage
-                }
-            } else {
-                uni.showToast({ title: res.msg, icon: 'none' })
-            }
-        } else if (title.value == 7) {
-            const res = await newsApi.newsNoticeSingle({ id: Id.value })
-            if (res.code == 200) {
-                if (res.data) {
-                    info.value = res.data
-                }
-            } else {
-                uni.showToast({ title: res.msg, icon: 'none' })
-            }
-        } else if (title.value == 4) {
-            const res = await newsApi.newsWebTvSearchSingle({ id: Id.value })
-            if (res.code == 200) {
-                if (res.data) {
-                    info.value = res.data
-                }
-            } else {
-                uni.showToast({ title: res.msg, icon: 'none' })
-            }
-        } else if (title.value == 5) {
-            const res = await newsApi.newsInformationNewsletterSingle({ id: Id.value })
-            if (res.code == 200) {
-                if (res.data) {
-                    imgContent.value = Host80 + res.data.coverImage
-                    Content.value = res.data.content
-                    imgContentIf.value = !!res.data.coverImage
-                }
-            } else {
-                uni.showToast({ title: res.msg, icon: 'none' })
-            }
-        } else if (title.value == 6) {
-            const res = await newsApi.newsVideoSingle({ id: Id.value })
-            if (res.code == 200) {
-                if (res.data) {
-                    info.value = res.data
-                    imgContent.value = res.data.videoUrl.indexOf('http') > -1
-                        ? res.data.videoUrl
-                        : (Host80 + res.data.videoUrl)
-                }
-            } else {
-                uni.showToast({ title: res.msg, icon: 'none' })
-            }
-        } else if (title.value == 8) {
-            const res = await newsApi.handShakeGet({})
-            if (res.code == 200) {
-                imgContent.value = res.msg
-            } else {
-                uni.showToast({ title: res.msg, icon: 'none' })
-            }
-        } else if (title.value == 9) {
-            const res = await newsApi.handFinancialCalendar({})
-            if (res.code == 200) {
-                imgContent.value = res.msg
-            } else {
-                uni.showToast({ title: res.msg, icon: 'none' })
-            }
-        } else if (title.value == 10) {
-            const res = await newsApi.newsEbookSingle({ id: Id.value })
-            if (res.code == 200) {
-                info.value = res.data
-            } else {
-                uni.showToast({ title: res.msg, icon: 'none' })
-            }
-        }
-    } catch (error) {
-        console.error('加载失败:', error)
-        uni.showToast({ title: t('common.error'), icon: 'none' })
-    } finally {
-        uni.hideLoading()
-    }
-}
-
-// 返回
-const backIndex = () => {
-    uni.navigateTo({
-        url: '/pages/mine/notice'
-    })
-}
-
-// 监听路由参数
-onLoad((query) => {
-    title.value = Number(query.title)
-    Id.value = Number(query.id)
-    getNewsSingle()
-})
-
-// 监听路由变化
-watch([() => title.value, () => Id.value], () => {
-    getNewsSingle()
-})
-</script>
-
-<style scoped lang="scss">
-.content {
-    flex: 1;
-    width: 100%;
-    background-color: var(--color-white);
-    overflow: hidden;
-    overflow-y: auto;
-    text-align: left;
-    padding: 30rpx;
-    box-sizing: border-box;
-    line-height: 1.8;
-
-    .img {
-        margin-bottom: 30rpx;
-
-        .content-image {
-            width: 100%;
-            max-height: 400rpx;
-            object-fit: contain;
-        }
-    }
-
-    .con-title {
-        font-size: 36rpx;
-        font-weight: bold;
-        margin: 20rpx 0;
-        color: #333;
-    }
-
-    .con-time {
-        margin-bottom: 30rpx;
-        font-size: 28rpx;
-        color: #999;
-    }
-
-    .con-des {
-        margin: 30rpx 0;
-        font-size: 28rpx;
-        color: #666;
-    }
-}
-
-.ebookBox {
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-
-    @media (min-width: 768px) {
-        flex-direction: row;
-        align-items: flex-start;
-    }
-
-    image {
-        width: 360rpx;
-        height: 525rpx;
-        margin-right: 50rpx;
-        border-radius: 16rpx;
-        object-fit: cover;
-    }
-
-    .news-title {
-        color: #EB3F57;
-        font-size: 36rpx;
-        font-weight: bold;
-        margin-bottom: 20rpx;
-    }
-
-    .news-status {
-        margin-top: 30rpx;
-
-        a,
-        .download-btn {
-            display: inline-block;
-            color: var(--color-white);
-            height: 60rpx;
-            line-height: 60rpx;
-            background-color: #EB3F57;
-            padding: 0 30rpx;
-            font-weight: bold;
-            border-radius: 8rpx;
-            font-size: 28rpx;
-        }
-    }
-}
-
-// 富文本样式
-:deep(.rich-text) {
-    font-size: 28rpx;
-    color: #666;
-
-    table {
-        border-collapse: collapse;
-        width: 100%;
-        margin: 20rpx 0;
-    }
-
-    th,
-    td {
-        border: 1rpx solid #dcdfe6;
-        padding: 16rpx;
-        text-align: left;
-    }
-
-    th {
-        background-color: #f5f7fa;
-    }
-
-    img {
-        max-width: 100%;
-        height: auto;
-    }
-}
-
-.content-title {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    font-size: px2rpx(20);
-    font-weight: 500;
-
-    .content-title-btns {
-        margin: px2rpx(8) 0;
-
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        gap: px2rpx(12);
-
-        .btn-primary {
-            min-width: px2rpx(120);
-            background-color: var(--color-error);
-            color: white;
-            padding: 0 px2rpx(12);
-            border: none;
-            font-size: px2rpx(14);
-            text-align: center;
-            cursor: pointer;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            gap: px2rpx(8);
-        }
-
-        .btn-primary:active {
-            background-color: var(--color-navy-700);
-        }
-    }
-}
-</style>

+ 0 - 150
pages/mine/notice.vue

@@ -1,150 +0,0 @@
-<template>
-    <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
-        <view class="info-card">
-            <view class="content-title">
-                <view v-t="'News.Notice'"></view>
-            </view>
-            <view class="search-bar">
-                <cwg-combox v-model:value="search.read" :options="typeMap" :placeholder="t('placeholder.choose')" />
-            </view>
-            <cwg-tabel ref="tableRef" :columns="columns" :queryParams="search" :api="listApi" :show-operation="false"
-                :showPagination="false">
-                <template #subject="{ row }">
-                    <view class="subject underline" @click="toView(row, 7)">
-                        {{ row.subject }}
-                    </view>
-                </template>
-            </cwg-tabel>
-        </view>
-    </cwg-page-wrapper>
-</template>
-
-<script setup lang="ts">
-import { computed, ref, onMounted } from 'vue';
-import { useI18n } from 'vue-i18n';
-const { t, locale } = useI18n();
-import useRouter from '@/hooks/useRouter'
-const router = useRouter()
-import { newsApi } from '@/service/news';
-const search = ref({})
-const typeMap = computed(() => ([
-    { value: null, text: t('State.All') },
-    { value: 0, text: t('News.Unread') },
-    { value: 1, text: t('News.Read') }
-]));
-
-const isZh = computed(() => ['cn', 'zh', 'zhHant'].includes(locale.value));
-// 表格列配置
-const columns = ref([
-    {
-        prop: 'subject',
-        label: t('News.Title'),
-        align: 'left',
-        slot: 'subject'
-    },
-    {
-        prop: 'addTime',
-        label: t('Drawer.Label.Date'),
-        type: 'date',
-        dateFormat: 'YYYY-MM-DD HH:mm',
-        align: 'left'
-    },
-    {
-        prop: 'status',
-        label: t('Custom.Recording.Status'),
-        formatter: ({ row }) => row.read ? t('News.Read') : t('News.Unread'),
-        align: 'left'
-    }
-])
-
-
-//查看详情
-const toView = (data, title) => {
-    router.push({ path: "/pages/mine/new", query: { title, id: data.id } }).catch(err => err);
-    if (title == 7) {
-        data.read = 1;
-    }
-}
-const addFileDialog = ref(null);
-const listApi = ref(null)
-listApi.value = newsApi.newsNoticeList
-</script>
-
-<style scoped lang="scss">
-@import "@/uni.scss";
-
-.avatar {
-    width: px2rpx(60);
-    height: px2rpx(60);
-    border-radius: 4px;
-}
-
-.content-title {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    font-size: px2rpx(20);
-    font-weight: 500;
-
-    .content-title-btns {
-        margin: px2rpx(8) 0;
-
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        gap: px2rpx(12);
-
-        .btn-primary {
-            min-width: px2rpx(120);
-            background-color: var(--color-error);
-            color: white;
-            padding: 0 px2rpx(12);
-            border: none;
-            font-size: px2rpx(14);
-            text-align: center;
-            cursor: pointer;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            gap: px2rpx(8);
-        }
-
-        .btn-primary:active {
-            background-color: var(--color-navy-700);
-        }
-    }
-}
-
-.operation-btn {
-    :deep(span) {
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        gap: px2rpx(4);
-        cursor: pointer;
-        background-color: var(--color-slate-150);
-        padding: px2rpx(8) 0;
-    }
-}
-
-.operation-btn.disabled {
-    cursor: not-allowed;
-    opacity: 0.5;
-}
-
-.search-bar {
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    flex-wrap: wrap;
-    gap: px2rpx(16);
-    margin: px2rpx(16) 0;
-
-    .cwg-combox,
-    .uni-easyinput,
-    .uni-date {
-        width: px2rpx(240) !important;
-        flex: none;
-    }
-}
-</style>

+ 0 - 90
pages/mine/pay-password.vue

@@ -1,90 +0,0 @@
-<template>
-  <cwg-page-wrapper>
-    <view class="page">
-      <u-form ref="resetForm">
-        <cwg-input v-model:value="loginName" type="text" :required="true" fkey="loginName" :label="t('login.p1')"
-          :clearable="true" :placeholder="t('login.msg1')" :rules="[{ required: true, message: t('login.msg1') }]"
-          @change="handleChange">
-        </cwg-input>
-        <cwg-input v-model:value="oldPassword" :type="showPassword ? 'text' : 'password'" fkey="oldPassword"
-          :required="true" :label="t('login.p3')" :clearable="true" :placeholder="t('login.msg3')"
-          :rules="[{ required: true, message: t('login.msg3') }]" @change="handleChange">
-          <template #right-icon1>
-            <!-- <u-icon name="eye-o" @click="showPassword = !showPassword" /> -->
-          </template>
-        </cwg-input>
-        <cwg-input v-model:value="newPassword" :type="showPassword1 ? 'text' : 'password'" fkey="newPassword"
-          :required="true" :label="t('login.p4')" :clearable="true" :placeholder="t('login.msg3')"
-          :rules="[{ required: true, message: t('login.msg3') }]" @change="handleChange">
-          <template #right-icon1>
-            <!-- <u-icon name="eye-o" @click="showPassword1 = !showPassword1" /> -->
-          </template>
-        </cwg-input>
-        <view class="fixed-btn">
-          <view class="cwg-button">
-            <u-button type="primary" block :loading="loading" @click="handleReset">{{ t("pages.mine.pay-password")
-            }}</u-button>
-          </view>
-        </view>
-      </u-form>
-      <SuccessPrompt v-if="isShow" :btn-click="btnClick" :btn-title="t('newSignin.item7')" />
-    </view>
-  </cwg-page-wrapper>
-</template>
-
-<script setup lang="ts">
-import { ref, onMounted, watch } from "vue";
-import { showToast } from "@/utils/toast";
-import { useI18n } from "vue-i18n";
-import useRouter from "@/hooks/useRouter";
-import { userApi } from "@/api/user";
-
-const { t } = useI18n();
-const resetForm = ref();
-const router = useRouter();
-const loading = ref(false);
-const loginName = ref("");
-const oldPassword = ref("");
-const newPassword = ref("");
-const isShow = ref(false);
-const showPassword = ref(false);
-const showPassword1 = ref(false);
-function btnClick() {
-  router.push("/pages/login/index");
-}
-async function handleReset() {
-  loading.value = true;
-  try {
-    await resetForm.value?.validate([
-      "loginName",
-      "newPassword",
-      "oldPassword",
-    ]);
-    if (newPassword.value == oldPassword.value) {
-      showToast(t("login.msg5"));
-      return;
-    }
-    const res = await userApi.updateEmailPassword({
-      newPassword: newPassword.value,
-      oldPassword: oldPassword.value,
-    });
-    if (res.code == 200) {
-      isShow.value = true;
-    } else {
-      showToast(res.msg);
-    }
-  } catch (error: any) {
-    if (Array.isArray(error) && error.length > 0) {
-      showToast(error[0].message);
-    } else {
-      showToast(t("login.msg0_2"));
-    }
-    return;
-  } finally {
-    loading.value = false;
-  }
-}
-function handleChange(value: any) { }
-</script>
-
-<style scoped lang="scss"></style>

+ 0 - 332
pages/mine/permission.vue

@@ -1,332 +0,0 @@
-<template>
-    <cwg-page-wrapper class="permission-page">
-        <view class="content">
-            <view class="permission-list">
-                <view v-for="item in permissionList" :key="item.key" class="permission-item"
-                    @click="onPermissionClick(item)">
-                    <view class="item-left">
-                        <view class="item-info">
-                            <view class="item-title">{{ item.title }}</view>
-                            <view class="item-desc">{{ item.desc }}
-                                <text class="item-description" v-if="item.description" @click.stop="goDetail(item)">《{{
-                                    item.description }}》</text>
-                            </view>
-                        </view>
-                    </view>
-
-                    <view class="item-right">
-                        <view :class="['status', item.status]">
-                            {{ item.status }}
-                        </view>
-                        <cwg-icon color="#817f7f" icon="chevron-right" />
-                    </view>
-                </view>
-            </view>
-
-            <view class="tips">
-                <text class="tips-text">
-                    {{ t('mine.p14') }}
-                </text>
-            </view>
-        </view>
-    </cwg-page-wrapper>
-</template>
-
-<script setup lang="ts">
-import { ref, onMounted } from 'vue'
-import { permission } from '@/js_sdk/wa-permission/permission.js'
-import { onLoad } from '@dcloudio/uni-app'
-import useRouter from "@/hooks/useRouter";
-import { useI18n } from "vue-i18n";
-const { t } = useI18n();
-const router = useRouter();
-// #ifdef APP-PLUS
-let isIos = false
-try {
-    isIos = (plus.os.name === "iOS")
-} catch (e) {
-    console.error('检测平台失败:', e)
-}
-// #endif
-
-/* =======================
- * 权限列表配置(核心)
- * ======================= */
-const permissionList = ref([
-    // {
-    //     key: 'location',
-    //     title: t('mine.p1'),
-    //     desc: t('mine.p2'),
-    //     icon: 'location',
-    //     iconBg: 'location',
-    //     iosPermission: 'location',
-    //     androidPermission: 'android.permission.ACCESS_FINE_LOCATION',
-    //     status: t('mine.p13'),
-    //     type: 4,
-    //     description: t('mine.p3')
-    // },
-    {
-        key: 'camera',
-        title: t('mine.p4'),
-        desc: t('mine.p5'),
-        icon: 'camera',
-        iconBg: 'camera',
-        iosPermission: 'camera',
-        androidPermission: 'android.permission.CAMERA',
-        status: t('mine.p13'),
-        type: 2,
-        description: t('mine.p6')
-    },
-    // {
-    //     key: 'microphone',
-    //     title: '麦克风',
-    //     desc: '录制音频',
-    //     icon: 'sound',
-    //     iconBg: 'microphone',
-    //     iosPermission: 'record',
-    //     androidPermission: 'android.permission.RECORD_AUDIO',
-    //     status: t('mine.p13')
-    // },
-    {
-        key: 'album',
-        title: t('mine.p7'),
-        desc: t('mine.p8'),
-        icon: 'image',
-        iconBg: 'album',
-        iosPermission: 'photoLibrary',
-        androidPermission: 'android.permission.READ_EXTERNAL_STORAGE',
-        status: t('mine.p13'),
-        type: 3,
-        description: t('mine.p9')
-    },
-    {
-        key: 'clipboard',
-        title: t('mine.p10'),
-        desc: t('mine.p11'),
-        icon: 'list',
-        iconBg: 'clipboard',
-        iosPermission: null,
-        androidPermission: null,
-        status: t('mine.p12'),
-    }
-])
-
-const goDetail = (item: any) => {
-    let type = item.type;
-    //  console.log(item, 111111);
-
-    router.push({
-        path: "/pages/mine/privacy",
-        query: {
-            type
-        },
-    });
-}
-
-/* =======================
- * 点击入口 - 检查权限并引导授权
- * ======================= */
-const onPermissionClick = async (item: any) => {
-    // 粘贴板无需授权,直接提示
-    if (!item.iosPermission && !item.androidPermission) {
-        uni.showToast({
-            title: '该权限无需授权',
-            icon: 'success'
-        })
-        return
-    }
-
-    // #ifdef APP-PLUS
-    permission.gotoAppPermissionSetting()
-    // #endif
-
-    // #ifndef APP-PLUS
-    uni.showToast({
-        title: '当前平台无需授权',
-        icon: 'success'
-    })
-    // #endif
-}
-
-/* =======================
- * 初始化检查权限 - 遍历所有权限进行检查
- * ======================= */
-const checkAllPermissions = async () => {
-    // #ifdef APP-PLUS
-    try {
-        for (const item of permissionList.value) {
-            // 粘贴板无需检查
-            if (!item.iosPermission && !item.androidPermission) {
-                item.status = t('mine.p12')
-                continue
-            }
-
-            if (isIos) {
-                // iOS 权限检查
-                const hasPermission = permission.judgeIosPermission(item.iosPermission)
-                item.status = hasPermission ? t('mine.p12') : t('mine.p13')
-                //  console.log(`${item.title} iOS 初始状态:`, item.status)
-            } else {
-                // Android 权限请求
-                const result = await permission.checkAndroidPermission(item.androidPermission)
-                //  console.log(`${item.title} Android 权限结果:`, result)
-
-                if (result === 1) {
-                    item.status = t('mine.p12')
-                } else if (result === -1) {
-                    item.status = t('mine.p13')
-                } else {
-                    item.status = t('mine.p13')
-                }
-            }
-        }
-    } catch (error) {
-        console.error('检查权限失败:', error)
-    }
-    // #endif
-
-    // #ifndef APP-PLUS
-    // 非 APP 平台全部标记为已授权
-    permissionList.value.forEach(item => {
-        item.status = t('mine.p12')
-    })
-    // #endif
-}
-onMounted(() => {
-    checkAllPermissions()
-})
-</script>
-
-<style lang="scss" scoped>
-@import "@/uni.scss";
-
-.permission-page {
-    min-height: 100vh;
-    background-color: #f5f5f5;
-    padding: px2rpx(12) !important;
-
-    .content {
-        .permission-list {
-            background-color: var(--color-white);
-            border-radius: px2rpx(16);
-            overflow: hidden;
-
-            .permission-item {
-                display: flex;
-                align-items: center;
-                justify-content: space-between;
-                padding: px2rpx(32) px2rpx(12);
-                border-bottom: 1px solid #f0f0f0;
-
-                &:last-child {
-                    border-bottom: none;
-                }
-
-                &:active {
-                    background-color: #f8f8f8;
-                }
-
-                .item-left {
-                    display: flex;
-                    align-items: center;
-                    flex: 1;
-
-                    .icon-wrapper {
-                        width: px2rpx(44);
-                        height: px2rpx(44);
-                        border-radius: px2rpx(8);
-                        display: flex;
-                        align-items: center;
-                        justify-content: center;
-                        margin-right: px2rpx(24);
-
-                        &.location {
-                            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-                        }
-
-                        &.camera {
-                            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
-                        }
-
-                        &.microphone {
-                            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
-                        }
-
-                        &.album {
-                            background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
-                        }
-
-                        &.clipboard {
-                            background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
-                        }
-                    }
-
-                    .item-info {
-                        flex: 1;
-
-                        .item-title {
-                            font-size: px2rpx(18);
-                            font-weight: 500;
-                            color: #333;
-                            display: block;
-                            margin-bottom: px2rpx(8);
-                        }
-
-                        .item-desc {
-                            font-size: px2rpx(16);
-                            color: #999;
-                            display: block;
-                        }
-
-                        .item-description {
-                            font-size: px2rpx(14);
-                            color: var(--main-yellow);
-                        }
-                    }
-                }
-
-                .item-right {
-                    display: flex;
-                    align-items: center;
-                    gap: px2rpx(4);
-
-                    .status {
-                        font-size: px2rpx(16);
-                        padding: px2rpx(8) px2rpx(12);
-                        border-radius: px2rpx(4);
-
-                        &.未授权 {
-                            color: #999;
-                            background-color: #f5f5f5;
-                        }
-
-                        &.已授权 {
-                            color: #52c41a;
-                            background-color: #f6ffed;
-                        }
-
-                        &.已拒绝 {
-                            color: #ff4d4f;
-                            background-color: #fff1f0;
-                        }
-                    }
-                }
-            }
-        }
-
-        .tips {
-            margin-top: px2rpx(24);
-            padding: px2rpx(24);
-            background-color: #fffbe6;
-            border-radius: px2rpx(16);
-            border: 1px solid #ffe58f;
-
-            .tips-text {
-                font-size: px2rpx(12);
-                color: #d48806;
-                line-height: 1.6;
-            }
-        }
-    }
-}
-</style>

+ 0 - 50
pages/mine/privacy.vue

@@ -1,50 +0,0 @@
-<template>
-    <cwg-page-wrapper class="permission-page" :isHeaderFixed="true">
-        <cwg-header :title="title" :showBack="true" />
-        <view class="content">
-            <view class="privacy" v-html="privacy"></view>
-        </view>
-    </cwg-page-wrapper>
-</template>
-
-<script setup lang="ts">
-import { ref, onMounted, computed } from 'vue'
-import { ucardApi } from '@/api/ucard'
-import { onLoad } from '@dcloudio/uni-app'
-import { useI18n } from "vue-i18n";
-const { t } = useI18n();
-const type = ref(1);
-onLoad((o) => {
-    type.value = o?.type || 1;
-    getPrivacy();
-});
-const titleMap: Record<number, string> = {
-    1: t('mine.p15'),
-    2: t('mine.p16'),
-    3: t('mine.p17'),
-    4: t('mine.p18'),
-};
-const title = computed(() => {
-    return titleMap[type.value]
-});
-const privacy = ref('');
-const getPrivacy = async () => {
-    const res = await ucardApi.getAppPrivacyPolicyPage({ page: { current: 1, row: 10 }, type: type.value });
-    if (res.code === 200) {
-        privacy.value = res.data[0].content;
-    }
-};
-
-</script>
-
-<style lang="scss" scoped>
-@import "@/uni.scss";
-
-.permission-page {
-    min-height: 100vh;
-    background-color: #f5f5f5;
-    padding: px2rpx(12) !important;
-
-    .content {}
-}
-</style>