From 90243e718060cadf80a385604f98712ec86ef8c9 Mon Sep 17 00:00:00 2001 From: Ghost <106998207@qq.com> Date: Tue, 17 Mar 2026 11:52:39 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AE=A1=E7=90=86=E7=AB=AF=E5=89=8D=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 8 + admin/src/App.vue | 12 + admin/src/assets/main.scss | 107 + admin/src/layouts/AdminLayout.vue | 357 ++++ admin/src/layouts/SuperAdminLayout.vue | 330 ++++ admin/src/main.ts | 27 + admin/src/router/index.ts | 203 ++ admin/src/stores/auth.ts | 148 ++ admin/src/utils/format.ts | 67 + admin/src/utils/request.ts | 118 ++ admin/src/views/admin/Dashboard.vue | 392 ++++ admin/src/views/admin/Distribution.vue | 1231 ++++++++++++ admin/src/views/admin/Finance.vue | 379 ++++ admin/src/views/admin/Login.vue | 254 +++ admin/src/views/admin/Orders.vue | 611 ++++++ admin/src/views/admin/PosterEditor.vue | 981 ++++++++++ admin/src/views/admin/Pricing.vue | 363 ++++ admin/src/views/admin/Questions.vue | 1059 ++++++++++ admin/src/views/admin/Settings.vue | 543 +++++ admin/src/views/admin/Users.vue | 1530 +++++++++++++++ admin/src/views/superadmin/AIConfig.vue | 1596 +++++++++++++++ admin/src/views/superadmin/Database.vue | 483 +++++ admin/src/views/superadmin/Distribution.vue | 694 +++++++ admin/src/views/superadmin/Enterprises.vue | 1215 ++++++++++++ admin/src/views/superadmin/Finance.vue | 933 +++++++++ admin/src/views/superadmin/Login.vue | 254 +++ admin/src/views/superadmin/Overview.vue | 824 ++++++++ admin/src/views/superadmin/PosterEditor.vue | 985 ++++++++++ admin/src/views/superadmin/Pricing.vue | 1072 ++++++++++ admin/src/views/superadmin/Questions.vue | 1116 +++++++++++ admin/src/views/superadmin/Settings.vue | 871 ++++++++ admin/src/views/superadmin/Users.vue | 1961 +++++++++++++++++++ admin/src/vite-env.d.ts | 1 + 33 files changed, 20725 insertions(+) create mode 100644 .gitignore create mode 100644 admin/src/App.vue create mode 100644 admin/src/assets/main.scss create mode 100644 admin/src/layouts/AdminLayout.vue create mode 100644 admin/src/layouts/SuperAdminLayout.vue create mode 100644 admin/src/main.ts create mode 100644 admin/src/router/index.ts create mode 100644 admin/src/stores/auth.ts create mode 100644 admin/src/utils/format.ts create mode 100644 admin/src/utils/request.ts create mode 100644 admin/src/views/admin/Dashboard.vue create mode 100644 admin/src/views/admin/Distribution.vue create mode 100644 admin/src/views/admin/Finance.vue create mode 100644 admin/src/views/admin/Login.vue create mode 100644 admin/src/views/admin/Orders.vue create mode 100644 admin/src/views/admin/PosterEditor.vue create mode 100644 admin/src/views/admin/Pricing.vue create mode 100644 admin/src/views/admin/Questions.vue create mode 100644 admin/src/views/admin/Settings.vue create mode 100644 admin/src/views/admin/Users.vue create mode 100644 admin/src/views/superadmin/AIConfig.vue create mode 100644 admin/src/views/superadmin/Database.vue create mode 100644 admin/src/views/superadmin/Distribution.vue create mode 100644 admin/src/views/superadmin/Enterprises.vue create mode 100644 admin/src/views/superadmin/Finance.vue create mode 100644 admin/src/views/superadmin/Login.vue create mode 100644 admin/src/views/superadmin/Overview.vue create mode 100644 admin/src/views/superadmin/PosterEditor.vue create mode 100644 admin/src/views/superadmin/Pricing.vue create mode 100644 admin/src/views/superadmin/Questions.vue create mode 100644 admin/src/views/superadmin/Settings.vue create mode 100644 admin/src/views/superadmin/Users.vue create mode 100644 admin/src/vite-env.d.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5099da1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.cursor/ +api/runtime/ +api/vendor/ +*.code-workspace +*.env +api/database/ +*.zip +.git222/ diff --git a/admin/src/App.vue b/admin/src/App.vue new file mode 100644 index 0000000..6d33e84 --- /dev/null +++ b/admin/src/App.vue @@ -0,0 +1,12 @@ + + + + + + diff --git a/admin/src/assets/main.scss b/admin/src/assets/main.scss new file mode 100644 index 0000000..43f5d3f --- /dev/null +++ b/admin/src/assets/main.scss @@ -0,0 +1,107 @@ +/* 全局样式 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html, +body, +#app { + height: 100%; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, + 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', + 'Noto Color Emoji'; +} + +/* 自定义滚动条 */ +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: #f1f1f1; +} + +::-webkit-scrollbar-thumb { + background: #c1c1c1; + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: #a8a8a8; +} + +/* Element Plus 自定义样式 */ +.el-card { + border-radius: 8px; +} + +.el-button { + border-radius: 6px; +} + +/* 页面容器 */ +.page-container { + padding: 20px; +} + +.page-header { + margin-bottom: 20px; + + h2 { + font-size: 24px; + font-weight: 600; + color: #303133; + } + + p { + margin-top: 8px; + font-size: 14px; + color: #909399; + } +} + +/* 统计卡片 */ +.stat-card { + padding: 24px; + border-radius: 12px; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + + &.blue { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + } + + &.green { + background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); + } + + &.orange { + background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); + } + + &.purple { + background: linear-gradient(135deg, #30cfd0 0%, #330867 100%); + } + + .stat-value { + font-size: 32px; + font-weight: bold; + margin: 12px 0; + } + + .stat-label { + font-size: 14px; + opacity: 0.9; + } +} + +/* 响应式 */ +@media (max-width: 768px) { + .page-container { + padding: 16px; + } +} + diff --git a/admin/src/layouts/AdminLayout.vue b/admin/src/layouts/AdminLayout.vue new file mode 100644 index 0000000..07eddec --- /dev/null +++ b/admin/src/layouts/AdminLayout.vue @@ -0,0 +1,357 @@ + + + + + + diff --git a/admin/src/layouts/SuperAdminLayout.vue b/admin/src/layouts/SuperAdminLayout.vue new file mode 100644 index 0000000..056ab3c --- /dev/null +++ b/admin/src/layouts/SuperAdminLayout.vue @@ -0,0 +1,330 @@ + + + + + + diff --git a/admin/src/main.ts b/admin/src/main.ts new file mode 100644 index 0000000..a2d90f6 --- /dev/null +++ b/admin/src/main.ts @@ -0,0 +1,27 @@ +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import ElementPlus from 'element-plus' +import 'element-plus/dist/index.css' +import 'element-plus/theme-chalk/dark/css-vars.css' +import * as ElementPlusIconsVue from '@element-plus/icons-vue' +import zhCn from 'element-plus/es/locale/lang/zh-cn' + +import App from './App.vue' +import router from './router' +import './assets/main.scss' + +const app = createApp(App) + +// 注册所有 Element Plus 图标 +for (const [key, component] of Object.entries(ElementPlusIconsVue)) { + app.component(key, component) +} + +app.use(createPinia()) +app.use(router) +app.use(ElementPlus, { + locale: zhCn, +}) + +app.mount('#app') + diff --git a/admin/src/router/index.ts b/admin/src/router/index.ts new file mode 100644 index 0000000..a7e31d5 --- /dev/null +++ b/admin/src/router/index.ts @@ -0,0 +1,203 @@ +import { createRouter, createWebHistory } from 'vue-router' +import type { RouteRecordRaw } from 'vue-router' + +const routes: RouteRecordRaw[] = [ + // 普通管理后台路由 + { + path: '/admin/login', + name: 'AdminLogin', + component: () => import('@/views/admin/Login.vue'), + meta: { title: '管理员登录' } + }, + { + path: '/admin', + component: () => import('@/layouts/AdminLayout.vue'), + redirect: '/admin/dashboard', + children: [ + { + path: 'dashboard', + name: 'AdminDashboard', + component: () => import('@/views/admin/Dashboard.vue'), + meta: { title: '数据概览' } + }, + { + path: 'users', + name: 'AdminUsers', + component: () => import('@/views/admin/Users.vue'), + meta: { title: '用户管理' } + }, + { + path: 'orders', + name: 'AdminOrders', + component: () => import('@/views/admin/Orders.vue'), + meta: { title: '订单管理' } + }, + { + path: 'distribution', + name: 'AdminDistribution', + component: () => import('@/views/admin/Distribution.vue'), + meta: { title: '分销管理' } + }, + { + path: 'questions', + name: 'AdminQuestions', + component: () => import('@/views/admin/Questions.vue'), + meta: { title: '题库管理' } + }, + { + path: 'pricing', + name: 'AdminPricing', + component: () => import('@/views/admin/Pricing.vue'), + meta: { title: '价格设置' } + }, + { + path: 'finance', + name: 'AdminFinance', + component: () => import('@/views/admin/Finance.vue'), + meta: { title: '企业余额' } + }, + { + path: 'settings', + name: 'AdminSettings', + component: () => import('@/views/admin/Settings.vue'), + meta: { title: '系统设置' } + }, + ] + }, + + // 超级管理后台路由 + { + path: '/superadmin/login', + name: 'SuperAdminLogin', + component: () => import('@/views/superadmin/Login.vue'), + meta: { title: '超级管理员登录' } + }, + { + path: '/superadmin', + component: () => import('@/layouts/SuperAdminLayout.vue'), + redirect: '/superadmin/overview', + children: [ + { + path: 'overview', + name: 'SuperAdminOverview', + component: () => import('@/views/superadmin/Overview.vue'), + meta: { title: '概览' } + }, + { + path: 'enterprises', + name: 'SuperAdminEnterprises', + component: () => import('@/views/superadmin/Enterprises.vue'), + meta: { title: '企业管理' } + }, + { + path: 'users', + name: 'SuperAdminUsers', + component: () => import('@/views/superadmin/Users.vue'), + meta: { title: '用户总览' } + }, + { + path: 'questions', + name: 'SuperAdminQuestions', + component: () => import('@/views/superadmin/Questions.vue'), + meta: { title: '题库管理' } + }, + { + path: 'ai-config', + name: 'SuperAdminAIConfig', + component: () => import('@/views/superadmin/AIConfig.vue'), + meta: { title: 'AI 服务配置' } + }, + { + path: 'pricing', + name: 'SuperAdminPricing', + component: () => import('@/views/superadmin/Pricing.vue'), + meta: { title: '全局定价' } + }, + { + path: 'distribution', + name: 'SuperAdminDistribution', + component: () => import('@/views/superadmin/Distribution.vue'), + meta: { title: '分销管理' } + }, + { + path: 'finance', + name: 'SuperAdminFinance', + component: () => import('@/views/superadmin/Finance.vue'), + meta: { title: '财务数据' } + }, + { + path: 'database', + name: 'SuperAdminDatabase', + component: () => import('@/views/superadmin/Database.vue'), + meta: { title: '数据库管理' } + }, + { + path: 'settings', + name: 'SuperAdminSettings', + component: () => import('@/views/superadmin/Settings.vue'), + meta: { title: '系统设置' } + }, + ] + }, + + // 默认重定向 + { + path: '/', + redirect: '/admin/login' + } +] + +const router = createRouter({ + history: createWebHistory(import.meta.env.BASE_URL), + routes +}) + +// 路由守卫 +router.beforeEach((to, _from, next) => { + // 设置页面标题 + document.title = to.meta.title ? `${to.meta.title} - MBTI 管理后台` : 'MBTI 管理后台' + + // 检查登录状态(使用Token) + const token = localStorage.getItem('authToken') + const userRole = localStorage.getItem('userRole') + + // 管理后台路由守卫 + if (to.path.startsWith('/admin') && to.path !== '/admin/login') { + if (!token || !userRole || !['admin', 'enterprise_admin', 'superadmin'].includes(userRole)) { + // 清除登录状态 + localStorage.removeItem('authToken') + localStorage.removeItem('userRole') + localStorage.removeItem('adminLoggedIn') + next('/admin/login') + return + } + } + + // 超级管理后台路由守卫 + if (to.path.startsWith('/superadmin') && to.path !== '/superadmin/login') { + if (!token || userRole !== 'superadmin') { + // 清除登录状态 + localStorage.removeItem('authToken') + localStorage.removeItem('userRole') + localStorage.removeItem('superAdminLoggedIn') + next('/superadmin/login') + return + } + } + + // 如果已登录,访问登录页则跳转到对应首页 + if (to.path === '/admin/login' && token && userRole && ['admin', 'enterprise_admin', 'superadmin'].includes(userRole)) { + next('/admin/dashboard') + return + } + + if (to.path === '/superadmin/login' && token && userRole === 'superadmin') { + next('/superadmin/overview') + return + } + + next() +}) + +export default router + diff --git a/admin/src/stores/auth.ts b/admin/src/stores/auth.ts new file mode 100644 index 0000000..158462e --- /dev/null +++ b/admin/src/stores/auth.ts @@ -0,0 +1,148 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' +import { request } from '@/utils/request' + +interface LoginResponse { + code: number + message: string + data: { + token: string + expires_in: number + user: { + id: number + username: string + role: string + enterprise_id?: number | null + } + } +} + +export const useAuthStore = defineStore('auth', () => { + // 管理员登录状态 + const adminLoggedIn = ref(false) + const superAdminLoggedIn = ref(false) + const currentUser = ref(null) + + // 初始化登录状态(自动执行) + function initAuth() { + if (typeof window !== 'undefined') { + const token = localStorage.getItem('authToken') + const userRole = localStorage.getItem('userRole') + + if (token && userRole) { + if (userRole === 'superadmin') { + superAdminLoggedIn.value = true + } else if (['admin', 'enterprise_admin'].includes(userRole)) { + adminLoggedIn.value = true + } + } + } + } + + // 自动初始化 + initAuth() + + // 管理员登录 + async function adminLogin(username: string, password: string): Promise { + try { + const response = await request.post('/auth/admin/login', { + username, + password + }) + + if (response.code === 200 && response.data) { + // 存储Token和用户信息 + localStorage.setItem('authToken', response.data.token) + localStorage.setItem('userRole', response.data.user.role) + localStorage.setItem('userId', String(response.data.user.id)) + localStorage.setItem('adminLoggedIn', 'true') + + currentUser.value = response.data.user + adminLoggedIn.value = true + + return true + } + return false + } catch (error: any) { + console.error('登录失败:', error) + throw error + } + } + + // 超级管理员登录 + async function superAdminLogin(username: string, password: string): Promise { + try { + const response = await request.post('/auth/superadmin/login', { + username, + password + }) + + if (response.code === 200 && response.data) { + // 存储Token和用户信息 + localStorage.setItem('authToken', response.data.token) + localStorage.setItem('userRole', response.data.user.role) + localStorage.setItem('userId', String(response.data.user.id)) + localStorage.setItem('superAdminLoggedIn', 'true') + + currentUser.value = response.data.user + superAdminLoggedIn.value = true + + return true + } + return false + } catch (error: any) { + console.error('登录失败:', error) + throw error + } + } + + // 管理员登出 + async function adminLogout() { + try { + await request.post('/auth/logout') + } catch (error) { + console.error('退出登录失败:', error) + } finally { + // 清除本地存储 + localStorage.removeItem('authToken') + localStorage.removeItem('userRole') + localStorage.removeItem('userId') + localStorage.removeItem('adminLoggedIn') + localStorage.removeItem('superAdminLoggedIn') + + adminLoggedIn.value = false + currentUser.value = null + } + } + + // 超级管理员登出 + async function superAdminLogout() { + try { + await request.post('/auth/logout') + } catch (error) { + console.error('退出登录失败:', error) + } finally { + // 清除本地存储 + localStorage.removeItem('authToken') + localStorage.removeItem('userRole') + localStorage.removeItem('userId') + localStorage.removeItem('adminLoggedIn') + localStorage.removeItem('superAdminLoggedIn') + + superAdminLoggedIn.value = false + currentUser.value = null + } + } + + return { + adminLoggedIn, + superAdminLoggedIn, + currentUser, + initAuth, + adminLogin, + superAdminLogin, + adminLogout, + superAdminLogout + } +}) + diff --git a/admin/src/utils/format.ts b/admin/src/utils/format.ts new file mode 100644 index 0000000..53588e1 --- /dev/null +++ b/admin/src/utils/format.ts @@ -0,0 +1,67 @@ +/** + * 格式化金额,自动转换为万或亿单位 + * @param amount 金额(元) + * @param decimals 保留小数位数,默认1位(仅用于万和亿单位) + * @returns 格式化后的金额字符串,如 "¥1000"、"¥1.2万" 或 "¥3.5亿" + */ +export function formatCurrency(amount: number, decimals: number = 1): string { + if (amount === null || amount === undefined || isNaN(amount)) { + return '¥0' + } + + const absAmount = Math.abs(amount) + + // 大于等于1亿,使用亿单位 + if (absAmount >= 100000000) { + return `¥${(amount / 100000000).toFixed(decimals)}亿` + } + + // 大于等于1万,使用万单位 + if (absAmount >= 10000) { + return `¥${(amount / 10000).toFixed(decimals)}万` + } + + // 小于1万,直接显示整数(不带小数) + return `¥${Math.round(amount).toLocaleString()}` +} + +/** + * 格式化金额(不带符号),自动转换为万或亿单位 + * @param amount 金额(元) + * @param decimals 保留小数位数,默认1位(仅用于万和亿单位) + * @returns 格式化后的金额字符串,如 "1000"、"1.2万" 或 "3.5亿" + */ +export function formatCurrencyWithoutSymbol(amount: number, decimals: number = 1): string { + if (amount === null || amount === undefined || isNaN(amount)) { + return '0' + } + + const absAmount = Math.abs(amount) + + // 大于等于1亿,使用亿单位 + if (absAmount >= 100000000) { + return `${(amount / 100000000).toFixed(decimals)}亿` + } + + // 大于等于1万,使用万单位 + if (absAmount >= 10000) { + return `${(amount / 10000).toFixed(decimals)}万` + } + + // 小于1万,直接显示整数(不带小数) + return `¥${Math.round(amount).toLocaleString()}` +} + +/** + * 格式化金额(元),始终保留两位小数,用于订单/财务等精确展示 + * 避免 0.23 元被 formatCurrency 四舍五入成 ¥0 + * @param amount 金额(元) + */ +export function formatMoneyYuan(amount: number): string { + if (amount === null || amount === undefined || isNaN(amount)) { + return '¥0.00' + } + const n = Number(amount) + return '¥' + (Number.isFinite(n) ? n.toFixed(2) : '0.00') +} + diff --git a/admin/src/utils/request.ts b/admin/src/utils/request.ts new file mode 100644 index 0000000..95847ed --- /dev/null +++ b/admin/src/utils/request.ts @@ -0,0 +1,118 @@ +import axios from 'axios' +import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios' +import { ElMessage } from 'element-plus' + +// 获取API基础URL +const getBaseURL = (): string => { + const envURL = import.meta.env.VITE_API_BASE_URL + if (envURL) { + // 如果环境变量是完整URL,拼接 /api/v1 + return envURL.endsWith('/') ? `${envURL}api/v1` : `${envURL}/api/v1` + } + // 默认使用相对路径 + return '/api/v1' +} + +// 创建 axios 实例 +const service: AxiosInstance = axios.create({ + baseURL: getBaseURL(), + timeout: 15000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +service.interceptors.request.use( + (config) => { + // 可以在这里添加 token + const token = localStorage.getItem('authToken') + if (token) { + config.headers.Authorization = `Bearer ${token}` + } + return config + }, + (error) => { + console.error('请求错误:', error) + return Promise.reject(error) + } +) + +// 响应拦截器 +service.interceptors.response.use( + (response: AxiosResponse) => { + const res = response.data + + // 如果返回的状态码不是 200,则认为是错误 + if (res.code && res.code !== 200) { + ElMessage.error(res.message || '请求失败') + return Promise.reject(new Error(res.message || '请求失败')) + } + + return res + }, + (error) => { + console.error('响应错误:', error) + + if (error.response) { + const { status, data } = error.response + + if (status === 401) { + ElMessage.error('未授权,请重新登录') + // 清除所有登录状态和Token + localStorage.removeItem('authToken') + localStorage.removeItem('userRole') + localStorage.removeItem('userId') + localStorage.removeItem('adminLoggedIn') + localStorage.removeItem('superAdminLoggedIn') + + // 根据当前路径跳转到对应登录页 + if (window.location.pathname.startsWith('/superadmin')) { + window.location.href = '/superadmin/login' + } else { + window.location.href = '/admin/login' + } + } else if (status === 403) { + ElMessage.error('拒绝访问') + } else if (status === 404) { + ElMessage.error('请求地址不存在') + } else if (status === 500) { + ElMessage.error('服务器错误') + } else { + ElMessage.error(data?.message || '请求失败') + } + } else if (error.request) { + ElMessage.error('网络错误,请检查网络连接') + } else { + ElMessage.error('请求配置错误') + } + + return Promise.reject(error) + } +) + +// 导出请求方法 +export const request = { + get(url: string, config?: AxiosRequestConfig): Promise { + return service.get(url, config) + }, + + post(url: string, data?: any, config?: AxiosRequestConfig): Promise { + return service.post(url, data, config) + }, + + put(url: string, data?: any, config?: AxiosRequestConfig): Promise { + return service.put(url, data, config) + }, + + delete(url: string, config?: AxiosRequestConfig): Promise { + return service.delete(url, config) + }, + + patch(url: string, data?: any, config?: AxiosRequestConfig): Promise { + return service.patch(url, data, config) + } +} + +export default service + diff --git a/admin/src/views/admin/Dashboard.vue b/admin/src/views/admin/Dashboard.vue new file mode 100644 index 0000000..cae288c --- /dev/null +++ b/admin/src/views/admin/Dashboard.vue @@ -0,0 +1,392 @@ + + + + + diff --git a/admin/src/views/admin/Distribution.vue b/admin/src/views/admin/Distribution.vue new file mode 100644 index 0000000..5d4afaa --- /dev/null +++ b/admin/src/views/admin/Distribution.vue @@ -0,0 +1,1231 @@ + + + + + diff --git a/admin/src/views/admin/Finance.vue b/admin/src/views/admin/Finance.vue new file mode 100644 index 0000000..89b2781 --- /dev/null +++ b/admin/src/views/admin/Finance.vue @@ -0,0 +1,379 @@ + + + + + diff --git a/admin/src/views/admin/Login.vue b/admin/src/views/admin/Login.vue new file mode 100644 index 0000000..d30d714 --- /dev/null +++ b/admin/src/views/admin/Login.vue @@ -0,0 +1,254 @@ + + + + + diff --git a/admin/src/views/admin/Orders.vue b/admin/src/views/admin/Orders.vue new file mode 100644 index 0000000..0eeba7d --- /dev/null +++ b/admin/src/views/admin/Orders.vue @@ -0,0 +1,611 @@ + + + + + diff --git a/admin/src/views/admin/PosterEditor.vue b/admin/src/views/admin/PosterEditor.vue new file mode 100644 index 0000000..9718beb --- /dev/null +++ b/admin/src/views/admin/PosterEditor.vue @@ -0,0 +1,981 @@ + + + + + diff --git a/admin/src/views/admin/Pricing.vue b/admin/src/views/admin/Pricing.vue new file mode 100644 index 0000000..5f133e6 --- /dev/null +++ b/admin/src/views/admin/Pricing.vue @@ -0,0 +1,363 @@ + + + + + diff --git a/admin/src/views/admin/Questions.vue b/admin/src/views/admin/Questions.vue new file mode 100644 index 0000000..1cdb5e7 --- /dev/null +++ b/admin/src/views/admin/Questions.vue @@ -0,0 +1,1059 @@ + + + + + diff --git a/admin/src/views/admin/Settings.vue b/admin/src/views/admin/Settings.vue new file mode 100644 index 0000000..3127871 --- /dev/null +++ b/admin/src/views/admin/Settings.vue @@ -0,0 +1,543 @@ + + + + + diff --git a/admin/src/views/admin/Users.vue b/admin/src/views/admin/Users.vue new file mode 100644 index 0000000..2124547 --- /dev/null +++ b/admin/src/views/admin/Users.vue @@ -0,0 +1,1530 @@ + + + + + diff --git a/admin/src/views/superadmin/AIConfig.vue b/admin/src/views/superadmin/AIConfig.vue new file mode 100644 index 0000000..d1992d5 --- /dev/null +++ b/admin/src/views/superadmin/AIConfig.vue @@ -0,0 +1,1596 @@ + + + + + diff --git a/admin/src/views/superadmin/Database.vue b/admin/src/views/superadmin/Database.vue new file mode 100644 index 0000000..2d4fc6c --- /dev/null +++ b/admin/src/views/superadmin/Database.vue @@ -0,0 +1,483 @@ + + + + + diff --git a/admin/src/views/superadmin/Distribution.vue b/admin/src/views/superadmin/Distribution.vue new file mode 100644 index 0000000..2368530 --- /dev/null +++ b/admin/src/views/superadmin/Distribution.vue @@ -0,0 +1,694 @@ + + + + + diff --git a/admin/src/views/superadmin/Enterprises.vue b/admin/src/views/superadmin/Enterprises.vue new file mode 100644 index 0000000..531a44f --- /dev/null +++ b/admin/src/views/superadmin/Enterprises.vue @@ -0,0 +1,1215 @@ + + + + + diff --git a/admin/src/views/superadmin/Finance.vue b/admin/src/views/superadmin/Finance.vue new file mode 100644 index 0000000..b8ef831 --- /dev/null +++ b/admin/src/views/superadmin/Finance.vue @@ -0,0 +1,933 @@ + + + + + diff --git a/admin/src/views/superadmin/Login.vue b/admin/src/views/superadmin/Login.vue new file mode 100644 index 0000000..6e67378 --- /dev/null +++ b/admin/src/views/superadmin/Login.vue @@ -0,0 +1,254 @@ + + + + + diff --git a/admin/src/views/superadmin/Overview.vue b/admin/src/views/superadmin/Overview.vue new file mode 100644 index 0000000..6502bfd --- /dev/null +++ b/admin/src/views/superadmin/Overview.vue @@ -0,0 +1,824 @@ + + + + + diff --git a/admin/src/views/superadmin/PosterEditor.vue b/admin/src/views/superadmin/PosterEditor.vue new file mode 100644 index 0000000..87e6517 --- /dev/null +++ b/admin/src/views/superadmin/PosterEditor.vue @@ -0,0 +1,985 @@ + + + + + diff --git a/admin/src/views/superadmin/Pricing.vue b/admin/src/views/superadmin/Pricing.vue new file mode 100644 index 0000000..82beb54 --- /dev/null +++ b/admin/src/views/superadmin/Pricing.vue @@ -0,0 +1,1072 @@ + + + + + diff --git a/admin/src/views/superadmin/Questions.vue b/admin/src/views/superadmin/Questions.vue new file mode 100644 index 0000000..3151bd6 --- /dev/null +++ b/admin/src/views/superadmin/Questions.vue @@ -0,0 +1,1116 @@ + + + + + diff --git a/admin/src/views/superadmin/Settings.vue b/admin/src/views/superadmin/Settings.vue new file mode 100644 index 0000000..360b307 --- /dev/null +++ b/admin/src/views/superadmin/Settings.vue @@ -0,0 +1,871 @@ + + + + + diff --git a/admin/src/views/superadmin/Users.vue b/admin/src/views/superadmin/Users.vue new file mode 100644 index 0000000..2d324c4 --- /dev/null +++ b/admin/src/views/superadmin/Users.vue @@ -0,0 +1,1961 @@ + + + + + diff --git a/admin/src/vite-env.d.ts b/admin/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/admin/src/vite-env.d.ts @@ -0,0 +1 @@ +///