refactor: move project under backend
这个提交包含在:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,3 +1,2 @@
|
||||
app/node_modules/
|
||||
app/data/
|
||||
*.log
|
||||
# Local artifacts created before moving into backend/
|
||||
app/
|
||||
|
||||
3
backend/.gitignore
vendored
普通文件
3
backend/.gitignore
vendored
普通文件
@@ -0,0 +1,3 @@
|
||||
app/node_modules/
|
||||
app/data/
|
||||
*.log
|
||||
@@ -24,6 +24,7 @@ npm run dev
|
||||
```
|
||||
|
||||
服务默认监听 `:3001`(可在 `app/.env` 修改)。
|
||||
通过域名访问时统一前缀为:`https://capay.hao.work/backend`。
|
||||
|
||||
### 免费套餐低频监控
|
||||
在 `app/.env` 中已设置:
|
||||
@@ -35,6 +36,7 @@ npm run dev
|
||||
支持多个 Alchemy 免费 key:使用 `ALCHEMY_API_KEYS=key1,key2`,系统会按轮询周期进行轮转调用,降低单 key 的频率。
|
||||
|
||||
## API 说明(简化版)
|
||||
域名访问时请在路径前加 `/backend` 前缀(例如:`/backend/payments/orders`)。
|
||||
### 1) 开通商户
|
||||
`POST /merchants`
|
||||
```json
|
||||
@@ -1,5 +1,5 @@
|
||||
APP_PORT=3001
|
||||
APP_HOST=https://capay.hao.work
|
||||
APP_HOST=https://capay.hao.work/backend
|
||||
PLAN=free
|
||||
ADMIN_API_KEY=whoami139
|
||||
|
||||
@@ -21,7 +21,9 @@ const curlTrackTx = document.getElementById('curl-track-tx');
|
||||
const webhookTip = document.getElementById('webhook-tip');
|
||||
|
||||
const STORAGE_KEY = 'capay_admin_key';
|
||||
const baseUrl = window.location.origin;
|
||||
const basePath = window.location.pathname.replace(/\/[^/]*$/, '/').replace(/\/+$/, '');
|
||||
const apiBase = basePath || '';
|
||||
const baseUrl = `${window.location.origin}${apiBase}`;
|
||||
|
||||
function setStatus(text, ok) {
|
||||
statusText.textContent = text;
|
||||
@@ -43,13 +45,18 @@ function setAdminKey(value) {
|
||||
localStorage.setItem(STORAGE_KEY, value);
|
||||
}
|
||||
|
||||
function withBase(path) {
|
||||
if (!apiBase) return path;
|
||||
return `${apiBase}${path}`;
|
||||
}
|
||||
|
||||
async function request(path, options = {}) {
|
||||
const headers = options.headers ? { ...options.headers } : {};
|
||||
const adminKey = getAdminKey();
|
||||
if (adminKey) {
|
||||
headers['x-admin-key'] = adminKey;
|
||||
}
|
||||
const res = await fetch(path, { ...options, headers });
|
||||
const res = await fetch(withBase(path), { ...options, headers });
|
||||
if (!res.ok) {
|
||||
const text = await res.text();
|
||||
let message = text;
|
||||
@@ -5,7 +5,7 @@
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>Capay API Docs</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" />
|
||||
<link rel="stylesheet" href="/styles.css" />
|
||||
<link rel="stylesheet" href="../styles.css" />
|
||||
<style>
|
||||
.docs-header {
|
||||
max-width: 1180px;
|
||||
@@ -41,7 +41,7 @@
|
||||
<h2>Capay API Docs</h2>
|
||||
<p class="muted">Swagger-style documentation with live requests.</p>
|
||||
</div>
|
||||
<a class="pill link" href="/">Back to Admin</a>
|
||||
<a class="pill link" href="../">Back to Admin</a>
|
||||
</div>
|
||||
|
||||
<div id="swagger-ui"></div>
|
||||
@@ -50,7 +50,7 @@
|
||||
<script>
|
||||
window.onload = function () {
|
||||
window.ui = SwaggerUIBundle({
|
||||
url: "/openapi.json",
|
||||
url: "../openapi.json",
|
||||
dom_id: "#swagger-ui",
|
||||
deepLinking: true,
|
||||
presets: [SwaggerUIBundle.presets.apis],
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>Capay 管理后台</title>
|
||||
<link rel="stylesheet" href="/styles.css" />
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
@@ -16,7 +16,7 @@
|
||||
<div class="hero-meta">
|
||||
<span class="pill">API Admin</span>
|
||||
<span class="pill" id="status-pill">未连接</span>
|
||||
<a class="pill link" href="/docs/">API Docs</a>
|
||||
<a class="pill link" href="docs/">API Docs</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -131,6 +131,6 @@
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script src="/app.js"></script>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -7,7 +7,7 @@
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"url": "/"
|
||||
"url": "/backend"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"HOST": "https://capay.hao.work",
|
||||
"HOST": "https://capay.hao.work/backend",
|
||||
"PORT": 8081,
|
||||
"MONGO_CONNECTION_STRING": "mongodb://localhost:27017",
|
||||
"MONGO_KEAGATE_DB": "keagate",
|
||||
@@ -13,8 +13,16 @@ server {
|
||||
# include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||
# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3001;
|
||||
location = / {
|
||||
return 302 /backend/;
|
||||
}
|
||||
|
||||
location = /backend {
|
||||
return 301 /backend/;
|
||||
}
|
||||
|
||||
location /backend/ {
|
||||
proxy_pass http://127.0.0.1:3001/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
在新工单中引用
屏蔽一个用户