add web and server
parent
d42944fd4e
commit
393dd32407
|
@ -1,4 +1,27 @@
|
|||
node_modules
|
||||
dist
|
||||
.zip
|
||||
web-mobile
|
||||
web-mobile
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"dev": "concurrently \"pnpm dev:frontend\" \"pnpm dev:backend\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.10.7",
|
||||
"concurrently": "^7.6.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
# 生产环境配置
|
||||
VITE_APP_ENV = 'production'
|
||||
|
||||
VITE_APP_BASE_API = '/dev-api'
|
|
@ -0,0 +1,4 @@
|
|||
# 生产环境配置
|
||||
VITE_APP_ENV = 'production'
|
||||
|
||||
VITE_APP_BASE_API = '/prod-api'
|
|
@ -0,0 +1,10 @@
|
|||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
// Generated by unplugin-auto-import
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
declare global {
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
export {}
|
||||
|
||||
/* prettier-ignore */
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
|
||||
ElCol: typeof import('element-plus/es')['ElCol']
|
||||
ElForm: typeof import('element-plus/es')['ElForm']
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
ElInput: typeof import('element-plus/es')['ElInput']
|
||||
ElRow: typeof import('element-plus/es')['ElRow']
|
||||
ElUpload: typeof import('element-plus/es')['ElUpload']
|
||||
HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
|
||||
PackageSelector: typeof import('./src/components/PackageSelector.vue')['default']
|
||||
}
|
||||
}
|
|
@ -9,12 +9,21 @@
|
|||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"ali-oss": "^6.22.0",
|
||||
"axios": "^1.7.9",
|
||||
"dayjs": "^1.11.13",
|
||||
"element-plus": "^2.9.3",
|
||||
"vue": "^3.5.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/ali-oss": "^6.16.11",
|
||||
"@unocss/preset-wind": "^65.4.3",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"@vue/tsconfig": "^0.7.0",
|
||||
"typescript": "~5.6.2",
|
||||
"unocss": "^65.4.3",
|
||||
"unplugin-auto-import": "^19.0.0",
|
||||
"unplugin-vue-components": "^28.0.0",
|
||||
"vite": "^6.0.5",
|
||||
"vue-tsc": "^2.2.0"
|
||||
}
|
||||
|
|
|
@ -1,30 +1,10 @@
|
|||
<script setup lang="ts">
|
||||
import HelloWorld from './components/HelloWorld.vue'
|
||||
import PackageSelector from "./components/PackageSelector.vue";
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<a href="https://vite.dev" target="_blank">
|
||||
<img src="/vite.svg" class="logo" alt="Vite logo" />
|
||||
</a>
|
||||
<a href="https://vuejs.org/" target="_blank">
|
||||
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
|
||||
</a>
|
||||
</div>
|
||||
<HelloWorld msg="Vite + Vue" />
|
||||
<div>
|
||||
<PackageSelector />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
transition: filter 300ms;
|
||||
}
|
||||
.logo:hover {
|
||||
filter: drop-shadow(0 0 2em #646cffaa);
|
||||
}
|
||||
.logo.vue:hover {
|
||||
filter: drop-shadow(0 0 2em #42b883aa);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import request from "@/utils/request";
|
||||
import OSS from 'ali-oss';
|
||||
|
||||
// 定义一键生成的 API 请求
|
||||
export const generatePackage = (data: any) => {
|
||||
return request.post("/generate", data);
|
||||
};
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-form :model="form" label-width="140px">
|
||||
<el-form-item label="Zip渠道包">
|
||||
<el-checkbox-group v-model="form.zipChannels">
|
||||
<el-checkbox v-for="channel in zipChannel" :key="channel" :label="channel">{{ channel }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="HTML渠道包">
|
||||
<el-checkbox-group v-model="form.htmlChannels">
|
||||
<el-checkbox v-for="channel in htmlChannel" :key="channel" :label="channel">{{ channel }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="前缀名">
|
||||
<el-input v-model="form.outputPrefix" placeholder="请输入前缀名称"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="后缀名">
|
||||
<el-input v-model="form.outputSuffix" placeholder="请输入后缀名称"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="Android商店URL">
|
||||
<el-input v-model="form.androidUrl" placeholder="请输入Android商店的URL"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="iOS商店URL">
|
||||
<el-input v-model="form.iosUrl" placeholder="请输入iOS商店的URL"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="上传Zip包">
|
||||
<el-upload action="" :before-upload="beforeUpload" :show-file-list="false" :http-request="customUpload" drag>
|
||||
<i class="el-icon-upload"></i>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<div class="el-upload__tip" slot="tip">只能上传zip文件,且不超过10MB</div>
|
||||
</el-upload>
|
||||
<el-input class="mt-2" v-model="form.ossUrl" placeholder="zip地址地址" readonly></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitForm">一键生成</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { generatePackage } from "@/api";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { Oss } from "@/utils/oss";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const zipChannel = ["facebook", "google", "tiktok", "vungle", "liftoff"];
|
||||
const htmlChannel = ["applovin", "unity", "appier", "ironsource", "mintegral", "moloco"];
|
||||
|
||||
const form = ref({
|
||||
zipChannels: [],
|
||||
htmlChannels: [],
|
||||
outputPrefix: "",
|
||||
outputSuffix: "",
|
||||
androidUrl: "",
|
||||
iosUrl: "",
|
||||
ossUrl: "",
|
||||
});
|
||||
|
||||
const beforeUpload = (file: File) => {
|
||||
const isZip = file.type === "application/zip" || file.type === "application/x-zip-compressed";
|
||||
const isLt10M = file.size / 1024 / 1024 < 10;
|
||||
|
||||
if (!isZip) {
|
||||
ElMessage.error("上传文件必须是 zip 格式!");
|
||||
return false;
|
||||
}
|
||||
if (!isLt10M) {
|
||||
ElMessage.error("上传文件大小不能超过 10MB!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
const customUpload = async (options: any) => {
|
||||
const { file, onSuccess, onError } = options;
|
||||
try {
|
||||
const formattedDate = dayjs().format("YYYYMMDDHHmm");
|
||||
const newFileName = `${formattedDate}_${encodeURIComponent(file.name)}`;
|
||||
const result = await Oss.put(newFileName, file);
|
||||
form.value.ossUrl = result.url;
|
||||
ElMessage.success("文件上传成功!");
|
||||
onSuccess(result, file);
|
||||
} catch (error) {
|
||||
ElMessage.error("上传失败,请重试!");
|
||||
onError(error);
|
||||
}
|
||||
};
|
||||
|
||||
const submitForm = async () => {
|
||||
try {
|
||||
if (form.value.zipChannels.length + form.value.htmlChannels.length === 0) {
|
||||
ElMessage.error("请先选择一个渠道!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!form.value.ossUrl) {
|
||||
ElMessage.error("请先上传cocos zip包!");
|
||||
return;
|
||||
}
|
||||
const response = await generatePackage({
|
||||
zipChannels: form.value.zipChannels,
|
||||
htmlChannels: form.value.htmlChannels,
|
||||
outputPrefix: form.value.outputPrefix,
|
||||
outputSuffix: form.value.outputSuffix,
|
||||
androidUrl: form.value.androidUrl,
|
||||
iosUrl: form.value.iosUrl,
|
||||
});
|
||||
console.log("Response:", response);
|
||||
} catch (error) {
|
||||
console.error("Error generating package:", error);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Add any custom styles here */
|
||||
</style>
|
|
@ -1,5 +1,9 @@
|
|||
import { createApp } from 'vue'
|
||||
import './style.css'
|
||||
import App from './App.vue'
|
||||
import { createApp } from "vue";
|
||||
import App from "./App.vue";
|
||||
import ElementPlus from "element-plus";
|
||||
import "element-plus/dist/index.css";
|
||||
import "virtual:uno.css";
|
||||
|
||||
createApp(App).mount('#app')
|
||||
const app = createApp(App);
|
||||
app.use(ElementPlus);
|
||||
app.mount("#app");
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import OSS from "ali-oss";
|
||||
|
||||
export const Oss = new OSS({
|
||||
region: "oss-cn-beijing",
|
||||
accessKeyId: "LTAI5tEday8PJNaMTz5mp8g4",
|
||||
accessKeySecret: "ck84eTxx4aSTjornlYrCy8RkurCHfc",
|
||||
bucket: "cocos-build-channel",
|
||||
secure: true,
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
import axios from "axios";
|
||||
|
||||
// 创建 axios 实例
|
||||
const request = axios.create({
|
||||
baseURL: import.meta.env.VITE_APP_BASE_API, // 使用环境变量
|
||||
timeout: 5000, // 请求超时时间
|
||||
});
|
||||
|
||||
// 请求拦截器
|
||||
request.interceptors.request.use(
|
||||
(config) => {
|
||||
// 可以在这里添加请求头等配置
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// 响应拦截器
|
||||
request.interceptors.response.use(
|
||||
(response) => {
|
||||
return response.data;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default request;
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
|
||||
}
|
|
@ -1,7 +1,19 @@
|
|||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "./tsconfig.app.json" },
|
||||
{ "path": "./tsconfig.node.json" }
|
||||
]
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
},
|
||||
"types": ["element-plus/global", "node", "vite/client"]
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2023"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { defineConfig, presetWind } from "unocss";
|
||||
|
||||
export default defineConfig({
|
||||
presets: [
|
||||
presetWind(),
|
||||
],
|
||||
});
|
|
@ -1,7 +1,40 @@
|
|||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import { defineConfig } from "vite";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import path from "path";
|
||||
import AutoImport from "unplugin-auto-import/vite";
|
||||
import Components from "unplugin-vue-components/vite";
|
||||
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
|
||||
import UnoCSS from "unocss/vite";
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
})
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
return {
|
||||
plugins: [
|
||||
vue(),
|
||||
AutoImport({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
Components({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
UnoCSS(),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
proxy: {
|
||||
"/dev-api": {
|
||||
target: "http://localhost:3000", // 代理到 Koa 服务器
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/dev-api/, ""), // 确保路径正确
|
||||
},
|
||||
},
|
||||
},
|
||||
define: {
|
||||
"process.env.NODE_ENV": JSON.stringify(mode),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
{
|
||||
"name": "@soyoo/server",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node src/index.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"clean-css": "^5.3.3",
|
||||
"uglify-js": "^3.19.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"archiver": "^7.0.1",
|
||||
"brotli": "^1.3.3",
|
||||
"koa": "^2.15.3"
|
||||
}
|
||||
{
|
||||
"name": "@soyoo/server",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node src/index.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"clean-css": "^5.3.3",
|
||||
"uglify-js": "^3.19.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"archiver": "^7.0.1",
|
||||
"brotli": "^1.3.3",
|
||||
"koa": "^2.15.3",
|
||||
"koa-bodyparser": "^4.4.1",
|
||||
"koa-router": "^13.0.1"
|
||||
}
|
||||
}
|
|
@ -1,12 +1,21 @@
|
|||
import Koa from "koa";
|
||||
import Router from "koa-router";
|
||||
import bodyParser from "koa-bodyparser";
|
||||
|
||||
const app = new Koa();
|
||||
const router = new Router();
|
||||
|
||||
// 中间件示例
|
||||
app.use(async (ctx) => {
|
||||
ctx.body = "Hello, Koa!";
|
||||
app.use(bodyParser());
|
||||
|
||||
router.post("/generate", async (ctx) => {
|
||||
const { zipChannels, htmlChannels, outputPrefix, outputSuffix, ossUrl, androidUrl, iosUrl } = ctx.request.body;
|
||||
|
||||
|
||||
ctx.body = { message: ossUrl };
|
||||
});
|
||||
|
||||
app.use(router.routes()).use(router.allowedMethods());
|
||||
|
||||
// 监听端口
|
||||
const PORT = 3000;
|
||||
app.listen(PORT, () => {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import { defineConfig } from '@pandacss/dev'
|
||||
|
||||
export default defineConfig({
|
||||
// 你的 Panda CSS 配置
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#1e90ff',
|
||||
secondary: '#ff6347',
|
||||
},
|
||||
},
|
||||
},
|
||||
// 其他配置选项
|
||||
})
|
1852
pnpm-lock.yaml
1852
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue