优化样式

This commit is contained in:
speakeloudest 2025-12-31 06:47:39 -08:00
parent 2b0741fdb9
commit 4d153b4149
5 changed files with 102 additions and 40 deletions

View File

@ -39,10 +39,12 @@
</div>
<div class="px-6 pt-[85px] pb-[23px]">
<Button
:disabled="isPaying"
@click="$emit('pay', selectedValue)"
class="h-[50px] w-full rounded-[32px] border-none bg-black text-[16px] font-black text-white transition-all hover:bg-black/90 active:scale-[0.98]"
class="h-[50px] w-full rounded-[32px] border-none bg-black text-[16px] font-black text-white transition-all hover:bg-black/90 active:scale-[0.98] disabled:opacity-50"
>
立即支付
<Loader2 v-if="isPaying" class="mr-2 h-4 w-4 animate-spin" />
{{ isPaying ? '正在支付...' : '立即支付' }}
</Button>
</div>
</div>
@ -51,6 +53,7 @@
<script setup lang="ts">
import { ref, computed } from 'vue'
import { Button } from '@/components/ui/button'
import { Loader2 } from 'lucide-vue-next'
interface PaymentOption {
label: string
@ -60,6 +63,7 @@ interface PaymentOption {
const props = defineProps<{
methods: any[]
selectedPlan: any
isPaying?: boolean
}>()
const list = computed(() =>

View File

@ -52,6 +52,7 @@
<PaymentMethod
:methods="payments"
:selectedPlan="selectedPlan"
:is-paying="isPaying"
@pay="(id: number | string) => $emit('pay', id)"
/>
</div>
@ -76,6 +77,7 @@ const props = defineProps<{
userInfo: { email: string }
selectedPlanId: string
selectedPlan: any
isPaying: boolean
}>()
const emit = defineEmits(['select-plan', 'pay', 'refresh'])

View File

@ -22,6 +22,7 @@
<PaymentMethod
:methods="payments"
:selectedPlan="selectedPlan"
:is-paying="isPaying"
@pay="(id: number | string) => $emit('pay', id)"
/>
</div>
@ -63,6 +64,7 @@ const props = defineProps<{
userInfo: { email: string }
selectedPlanId: string
selectedPlan: any
isPaying: boolean
}>()
const emit = defineEmits(['select-plan', 'pay', 'refresh'])

View File

@ -32,6 +32,7 @@
:user-info="userSubInfo"
:selected-plan-id="selectedPlanId"
:selected-plan="activePlan"
:is-paying="isPaying"
@select-plan="handlePlanSelect"
@pay="handlePay"
@refresh="init"
@ -46,6 +47,7 @@
:user-info="userSubInfo"
:selected-plan-id="selectedPlanId"
:selected-plan="activePlan"
:is-paying="isPaying"
@select-plan="handlePlanSelect"
@pay="handlePay"
@refresh="init"
@ -70,6 +72,7 @@ const route = useRoute()
const router = useRouter()
// --- State ---
const selectedPlanId = ref('p2')
const isPaying = ref(false)
const orderStatusDialogRef = ref<InstanceType<typeof OrderStatusDialog> | null>(null)
const selectedPayment = ref('alipay')
@ -132,6 +135,7 @@ const handlePlanSelect = (id: string) => {
}
const handlePay = (methodId: number | string) => {
if (isPaying.value) return
const plan = plans.value.find((p) => p.id === selectedPlanId.value)
if (!plan) return
@ -147,7 +151,7 @@ const handlePay = (methodId: number | string) => {
if (isRenewal) {
params.user_subscribe_id = already.id
}
console.log(params)
isPaying.value = true
request.post(api, params).then((res: any) => {
request
.post('/api/v1/public/portal/order/checkout', {
@ -163,6 +167,11 @@ const handlePay = (methodId: number | string) => {
})
}
})
.finally(() => {
isPaying.value = false
})
}).catch(() => {
isPaying.value = false
})
}

View File

@ -52,6 +52,68 @@ interface ResponseType extends AxiosResponse {
config: RequestConfig
}
const ERROR_MESSAGES: Record<number | string, string> = {
'200': '成功',
'500': '内部服务器错误',
'10001': '数据库查询错误',
'10002': '数据库更新错误',
'10003': '数据库插入错误',
'10004': '数据库删除错误',
'20001': '用户已存在',
'20002': '用户不存在',
'20003': '用户密码错误',
'20004': '用户已禁用',
'20005': '余额不足',
'20006': '停止注册',
'20007': '未绑定Telegram',
'20008': '用户未绑定OAuth方式',
'20009': '邀请码错误',
'30001': '节点已存在',
'30002': '节点不存在',
'30003': '节点组已存在',
'30004': '节点组不存在',
'30005': '节点组不为空',
'400': '参数错误',
'40002': '用户令牌为空',
'40003': '用户令牌无效',
'40004': '用户令牌已过期',
'40005': '您还没有登录',
'401': '请求过多',
'50001': '优惠券不存在',
'50002': '优惠券已被使用',
'50003': '优惠券不匹配',
'60001': '订阅已过期',
'60002': '订阅不可用',
'60003': '用户已有订阅',
'60004': '订阅已被使用',
'60005': '单一订阅模式超出限制',
'60006': '订阅配额限制',
'70001': '验证码错误',
'80001': '队列入队错误',
'90001': '调试模式已启用',
'90002': '发送短信错误',
'90003': '短信功能未启用',
'90004': '电子邮件功能未启用',
'90005': '不支持的登录方式',
'90006': '身份验证器不支持此方式',
'90007': '电话区号为空',
'90008': '密码为空',
'90009': '区号为空',
'90010': '需要密码或验证码',
'90011': '电子邮件已存在',
'90012': '电话号码已存在',
'90013': '设备已存在',
'90014': '电话号码错误',
'90015': '此账户今日已达到发送次数限制',
'90017': '设备不存在',
'90018': '用户 ID 不匹配',
'61001': '订单不存在',
'61002': '支付方式未找到',
'61003': '订单状态错误',
'61004': '重置周期不足',
'61005': '存在没用完的流量',
}
export default class Request {
public axiosInstance: AxiosInstance
@ -93,34 +155,26 @@ export default class Request {
if (config.data && !(config.data instanceof FormData)) {
const plainText = JSON.stringify(config.data)
// 加密后config.data 会变成 { data: '...', time: '...' }
config.data = HiAesUtil.encryptData(plainText, encryptionKey)
}
if (config.method?.toLowerCase() === 'get' || config.params) {
const paramsToEncrypt = config.params || {} // 为空则加密 "{}"
const paramsToEncrypt = config.params || {}
const plainParamsText = JSON.stringify(paramsToEncrypt)
const encryptedParams = HiAesUtil.encryptData(plainParamsText, encryptionKey)
// 将原参数替换为加密后的 data 和 time 字段
config.params = {
data: encryptedParams.data,
time: encryptedParams.time,
}
}
if (config.data?.time) {
console.log(
'解密',
HiAesUtil.decryptData(config.data.data, config.data.time, encryptionKey),
)
}
config.headers = mergeExtraConfig.formatHeader({
...this.config.headers,
...config.headers,
lang: 'zh_CN',
'login-type': 'device',
'user-agent': 'android',
...(mergeExtraConfig.withToken && {
[mergeExtraConfig.tokenKey]: mergeExtraConfig.getToken(),
}),
@ -142,7 +196,6 @@ export default class Request {
const { data, config } = response
let responseData = response.data.data
// 假设后端返回格式为 { data: "base64...", time: "..." }
if (responseData && responseData.data && responseData.time) {
try {
const decryptedStr = HiAesUtil.decryptData(
@ -150,7 +203,6 @@ export default class Request {
responseData.time,
encryptionKey,
)
// 解密后转化为 JSON 对象供后续业务使用
responseData = JSON.parse(decryptedStr)
} catch (e) {
console.error('解密失败:', e)
@ -158,39 +210,32 @@ export default class Request {
}
}
axiosCanceler.removePending(config)
if (data.code == 40004) {
toast.error('登录状态已失效, 请重新登录')
redirectLogin()
return
}
if (data.code == 70001) {
toast.error('验证码错误')
redirectLogin()
return
}
const resData = config.extraConfig?.originResponseData ? response : responseData
if (config.extraConfig?.handleResponse) {
if (data.code === 200) {
return resData
if (data.code !== 200) {
const msg = ERROR_MESSAGES[data.code] || response.data?.msg || data?.error || '未知错误'
if (data.code == 40004 || data.code == 40003 || data.code == 40005) {
toast.error(msg)
redirectLogin()
return
}
if (config.extraConfig?.handleResponse) {
this.errorReport(config.extraConfig.errorLevel ?? 2, msg)
return Promise.reject({
...data,
message: msg,
})
}
this.errorReport(
config.extraConfig.errorLevel ?? 2,
response.data?.msg ?? data?.error ?? '未知错误',
)
return Promise.reject({
...data,
message: response.data?.msg ?? data?.error ?? '未知错误',
})
} else {
return resData
}
return config.extraConfig?.originResponseData ? response : responseData
},
(error) => {
const status = error?.response?.status
const code = error?.code
let message = error?.message
if (status === 401) {
// message = '未登录或登录状态失效'
redirectLogin()
return
}