diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..e754ebc
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/config/index.js b/src/config/index.js
new file mode 100644
index 0000000..1770408
--- /dev/null
+++ b/src/config/index.js
@@ -0,0 +1,24 @@
+/**
+ * 配置文件
+ */
+
+export default {
+ // API基础URL
+ apiBaseUrl: import.meta.env.VITE_API_BASE_URL || '/api',
+
+ // PingPong SDK模式
+ pingpongMode: import.meta.env.VITE_PINGPONG_MODE || 'sandbox',
+
+ // PingPong SDK URL
+ pingpongSdkUrl: 'https://pay-cdn.pingpongx.com/production/static/sdk/1.2.0/ppPay.min.js',
+
+ // 请求超时时间(毫秒)
+ requestTimeout: 30000,
+
+ // 分页配置
+ pagination: {
+ pageSize: 10,
+ pageSizes: [10, 20, 50, 100]
+ }
+}
+
diff --git a/src/router/index.js b/src/router/index.js
new file mode 100644
index 0000000..d5264c4
--- /dev/null
+++ b/src/router/index.js
@@ -0,0 +1,36 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import CreateOrder from '../views/CreateOrder.vue'
+import Checkout from '../views/Checkout.vue'
+import PaymentResult from '../views/PaymentResult.vue'
+import OrderQuery from '../views/OrderQuery.vue'
+
+const routes = [
+ {
+ path: '/',
+ name: 'CreateOrder',
+ component: CreateOrder
+ },
+ {
+ path: '/checkout',
+ name: 'Checkout',
+ component: Checkout
+ },
+ {
+ path: '/result',
+ name: 'PaymentResult',
+ component: PaymentResult
+ },
+ {
+ path: '/query',
+ name: 'OrderQuery',
+ component: OrderQuery
+ }
+]
+
+const router = createRouter({
+ history: createWebHistory(),
+ routes
+})
+
+export default router
+
diff --git a/src/store/index.js b/src/store/index.js
new file mode 100644
index 0000000..07fd1ec
--- /dev/null
+++ b/src/store/index.js
@@ -0,0 +1,42 @@
+import { reactive } from 'vue'
+
+/**
+ * 简单的状态管理
+ * 如果需要更复杂的状态管理,可以使用 Pinia
+ */
+
+const state = reactive({
+ // 用户信息
+ user: null,
+ // 当前订单
+ currentOrder: null,
+ // 加载状态
+ loading: false
+})
+
+export default {
+ state,
+
+ // 设置用户信息
+ setUser(user) {
+ state.user = user
+ },
+
+ // 设置当前订单
+ setCurrentOrder(order) {
+ state.currentOrder = order
+ },
+
+ // 设置加载状态
+ setLoading(loading) {
+ state.loading = loading
+ },
+
+ // 清除状态
+ clear() {
+ state.user = null
+ state.currentOrder = null
+ state.loading = false
+ }
+}
+
diff --git a/src/utils/constants.js b/src/utils/constants.js
new file mode 100644
index 0000000..d877a9b
--- /dev/null
+++ b/src/utils/constants.js
@@ -0,0 +1,75 @@
+/**
+ * 常量定义
+ */
+
+// 订单状态
+export const ORDER_STATUS = {
+ PENDING: 'PENDING',
+ SUCCESS: 'SUCCESS',
+ FAILED: 'FAILED',
+ REVIEW: 'REVIEW',
+ CANCELLED: 'CANCELLED'
+}
+
+// 订单状态文本
+export const ORDER_STATUS_TEXT = {
+ [ORDER_STATUS.PENDING]: '待支付',
+ [ORDER_STATUS.SUCCESS]: '支付成功',
+ [ORDER_STATUS.FAILED]: '支付失败',
+ [ORDER_STATUS.REVIEW]: '审核中',
+ [ORDER_STATUS.CANCELLED]: '已取消'
+}
+
+// 支付类型
+export const PAYMENT_TYPE = {
+ SALE: 'SALE',
+ AUTH: 'AUTH'
+}
+
+// 支付类型文本
+export const PAYMENT_TYPE_TEXT = {
+ [PAYMENT_TYPE.SALE]: '直接付款',
+ [PAYMENT_TYPE.AUTH]: '预授权'
+}
+
+// 币种
+export const CURRENCY = {
+ USD: 'USD',
+ EUR: 'EUR',
+ GBP: 'GBP',
+ CNY: 'CNY',
+ JPY: 'JPY'
+}
+
+// 币种文本
+export const CURRENCY_TEXT = {
+ [CURRENCY.USD]: '美元',
+ [CURRENCY.EUR]: '欧元',
+ [CURRENCY.GBP]: '英镑',
+ [CURRENCY.CNY]: '人民币',
+ [CURRENCY.JPY]: '日元'
+}
+
+// 响应码
+export const RESPONSE_CODE = {
+ SUCCESS: '0000',
+ FAIL: '9999',
+ PARAM_ERROR: '4000',
+ VALIDATION_ERROR: '4001',
+ ORDER_NOT_FOUND: '1001',
+ ORDER_EXISTS: '1002'
+}
+
+// API基础路径
+export const API_BASE_URL = '/api'
+
+// PingPong SDK URL
+export const PINGPONG_SDK_URL = 'https://pay-cdn.pingpongx.com/production/static/sdk/1.2.0/ppPay.min.js'
+
+// PingPong SDK模式
+export const PINGPONG_MODE = {
+ SANDBOX: 'sandbox',
+ TEST: 'test',
+ BUILD: 'build'
+}
+
diff --git a/src/utils/helpers.js b/src/utils/helpers.js
new file mode 100644
index 0000000..6d0c49d
--- /dev/null
+++ b/src/utils/helpers.js
@@ -0,0 +1,123 @@
+/**
+ * 工具函数
+ */
+
+/**
+ * 格式化金额
+ */
+export function formatAmount(amount, currency = 'USD') {
+ if (!amount) return '0.00'
+ return parseFloat(amount).toFixed(2)
+}
+
+/**
+ * 格式化日期时间
+ */
+export function formatDateTime(dateTime, format = 'YYYY-MM-DD HH:mm:ss') {
+ if (!dateTime) return ''
+
+ const date = new Date(dateTime)
+ const year = date.getFullYear()
+ const month = String(date.getMonth() + 1).padStart(2, '0')
+ const day = String(date.getDate()).padStart(2, '0')
+ const hours = String(date.getHours()).padStart(2, '0')
+ const minutes = String(date.getMinutes()).padStart(2, '0')
+ const seconds = String(date.getSeconds()).padStart(2, '0')
+
+ return format
+ .replace('YYYY', year)
+ .replace('MM', month)
+ .replace('DD', day)
+ .replace('HH', hours)
+ .replace('mm', minutes)
+ .replace('ss', seconds)
+}
+
+/**
+ * 生成订单号
+ */
+export function generateOrderId() {
+ const timestamp = Date.now()
+ const random = Math.floor(Math.random() * 10000)
+ return `MTN${timestamp}${random.toString().padStart(4, '0')}`
+}
+
+/**
+ * 获取订单状态标签类型
+ */
+export function getStatusTagType(status) {
+ if (!status) return 'info'
+ const statusUpper = status.toUpperCase()
+ if (statusUpper === 'SUCCESS' || statusUpper === 'SUCCESSFUL') {
+ return 'success'
+ } else if (statusUpper === 'FAILED' || statusUpper === 'FAILURE') {
+ return 'danger'
+ } else if (statusUpper === 'REVIEW') {
+ return 'warning'
+ }
+ return 'info'
+}
+
+/**
+ * 获取订单状态文本
+ */
+export function getStatusText(status) {
+ if (!status) return '未知'
+ const statusMap = {
+ 'PENDING': '待支付',
+ 'SUCCESS': '支付成功',
+ 'SUCCESSFUL': '支付成功',
+ 'FAILED': '支付失败',
+ 'FAILURE': '支付失败',
+ 'REVIEW': '审核中',
+ 'CANCELLED': '已取消',
+ 'CANCEL': '已取消'
+ }
+ return statusMap[status.toUpperCase()] || status
+}
+
+/**
+ * 验证邮箱
+ */
+export function validateEmail(email) {
+ const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
+ return re.test(email)
+}
+
+/**
+ * 验证手机号(简单验证)
+ */
+export function validatePhone(phone) {
+ const re = /^1[3-9]\d{9}$/
+ return re.test(phone)
+}
+
+/**
+ * 防抖函数
+ */
+export function debounce(func, wait) {
+ let timeout
+ return function executedFunction(...args) {
+ const later = () => {
+ clearTimeout(timeout)
+ func(...args)
+ }
+ clearTimeout(timeout)
+ timeout = setTimeout(later, wait)
+ }
+}
+
+/**
+ * 节流函数
+ */
+export function throttle(func, limit) {
+ let inThrottle
+ return function(...args) {
+ if (!inThrottle) {
+ func.apply(this, args)
+ inThrottle = true
+ setTimeout(() => inThrottle = false, limit)
+ }
+ }
+}
+
diff --git a/src/views/Checkout.vue b/src/views/Checkout.vue
new file mode 100644
index 0000000..babf46c
--- /dev/null
+++ b/src/views/Checkout.vue
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+