线上配置2
Production deploy / build (push) Successful in 1m31s
Details
Production deploy / build (push) Successful in 1m31s
Details
This commit is contained in:
parent
33fdcac27f
commit
ba3422afc4
|
|
@ -17,6 +17,7 @@
|
||||||
"ali-oss": "^6.23.0",
|
"ali-oss": "^6.23.0",
|
||||||
"axios": "^1.13.2",
|
"axios": "^1.13.2",
|
||||||
"bcryptjs": "^3.0.3",
|
"bcryptjs": "^3.0.3",
|
||||||
|
"canvas": "^3.2.1",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"epub": "^1.3.0",
|
"epub": "^1.3.0",
|
||||||
|
|
@ -3065,13 +3066,13 @@
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.13.2",
|
"version": "1.13.5",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
|
||||||
"integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==",
|
"integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.6",
|
"follow-redirects": "^1.15.11",
|
||||||
"form-data": "^4.0.4",
|
"form-data": "^4.0.5",
|
||||||
"proxy-from-env": "^1.1.0"
|
"proxy-from-env": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -3674,6 +3675,20 @@
|
||||||
],
|
],
|
||||||
"license": "CC-BY-4.0"
|
"license": "CC-BY-4.0"
|
||||||
},
|
},
|
||||||
|
"node_modules/canvas": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/canvas/-/canvas-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-ej1sPFR5+0YWtaVp6S1N1FVz69TQCqmrkGeRvQxZeAB1nAIcjNTHVwrZtYtWFFBmQsF40/uDLehsW5KuYC99mg==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"node-addon-api": "^7.0.0",
|
||||||
|
"prebuild-install": "^7.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.12.0 || >= 20.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/chalk": {
|
"node_modules/chalk": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||||
|
|
@ -4277,9 +4292,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/diff": {
|
"node_modules/diff": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz",
|
||||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
"integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
@ -7666,6 +7681,12 @@
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/node-addon-api": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/node-ensure": {
|
"node_modules/node-ensure": {
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
# 课程生成功能测试指南
|
|
||||||
|
|
||||||
## 部署状态
|
|
||||||
|
|
||||||
✅ **代码已部署到服务器**
|
|
||||||
- 服务器地址: https://api.muststudy.xin
|
|
||||||
- PM2 服务: 运行中
|
|
||||||
- 修复内容: 大纲生成完成后自动开始生成课程内容
|
|
||||||
|
|
||||||
## 测试方法
|
|
||||||
|
|
||||||
### 方法1: 使用测试脚本(推荐)
|
|
||||||
|
|
||||||
1. **获取Token**
|
|
||||||
- 使用手机号登录获取Token
|
|
||||||
- 或使用现有的测试账号
|
|
||||||
|
|
||||||
2. **运行测试脚本**
|
|
||||||
```bash
|
|
||||||
export TEST_TOKEN='your_token_here'
|
|
||||||
cd backend
|
|
||||||
bash scripts/test-course-generation-direct.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方法2: 直接调用API
|
|
||||||
|
|
||||||
1. **创建课程**
|
|
||||||
```bash
|
|
||||||
curl -X POST https://api.muststudy.xin/api/ai/content/upload \
|
|
||||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-d '{
|
|
||||||
"content": "测试内容...",
|
|
||||||
"style": "essence"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **查询状态**
|
|
||||||
```bash
|
|
||||||
curl -X GET https://api.muststudy.xin/api/my-courses \
|
|
||||||
-H 'Authorization: Bearer YOUR_TOKEN'
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **查询日志**
|
|
||||||
```bash
|
|
||||||
curl -X GET "https://api.muststudy.xin/api/ai/prompts/logs?taskId=TASK_ID" \
|
|
||||||
-H 'Authorization: Bearer YOUR_TOKEN'
|
|
||||||
```
|
|
||||||
|
|
||||||
## 测试检查点
|
|
||||||
|
|
||||||
1. ✅ 创建课程后立即返回 courseId 和 taskId
|
|
||||||
2. ✅ 进度从 0% 开始,逐步增长
|
|
||||||
3. ✅ 大纲生成完成后(30%)自动继续生成内容(40%+)
|
|
||||||
4. ✅ 最终完成(100%)
|
|
||||||
5. ✅ 所有步骤都记录了日志(可通过 taskId 查询)
|
|
||||||
|
|
||||||
## 问题排查
|
|
||||||
|
|
||||||
如果进度卡在30%:
|
|
||||||
- 检查服务器日志: `pm2 logs wildgrowth-api`
|
|
||||||
- 检查任务状态: `GET /api/ai/content/tasks/:taskId`
|
|
||||||
- 检查错误信息: 查看 `error_message` 字段
|
|
||||||
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { CustomError } from '../middleware/errorHandler';
|
||||||
import { AuthRequest } from '../middleware/auth';
|
import { AuthRequest } from '../middleware/auth';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { documentParserService } from '../services/documentParserService';
|
import { documentParserService } from '../services/documentParserService';
|
||||||
|
import ossService from '../services/ossService';
|
||||||
import { logger } from '../utils/logger';
|
import { logger } from '../utils/logger';
|
||||||
|
|
||||||
// 确保 images 目录存在
|
// 确保 images 目录存在
|
||||||
|
|
@ -91,6 +92,36 @@ const documentUpload = multer({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// OSS 上传:内存存储,上传后直接传到 OSS
|
||||||
|
const ossFileFilter = (req: Request, file: Express.Multer.File, cb: multer.FileFilterCallback) => {
|
||||||
|
// 允许常见文件类型(可按需扩展)
|
||||||
|
const allowedMimes = [
|
||||||
|
'image/jpeg',
|
||||||
|
'image/jpg',
|
||||||
|
'image/png',
|
||||||
|
'image/webp',
|
||||||
|
'image/gif',
|
||||||
|
'application/pdf',
|
||||||
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||||
|
'application/epub+zip',
|
||||||
|
'text/plain',
|
||||||
|
'application/octet-stream',
|
||||||
|
];
|
||||||
|
if (allowedMimes.includes(file.mimetype) || file.mimetype.startsWith('image/')) {
|
||||||
|
cb(null, true);
|
||||||
|
} else {
|
||||||
|
cb(new CustomError('不支持的文件类型', 400));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const ossUpload = multer({
|
||||||
|
storage: multer.memoryStorage(),
|
||||||
|
fileFilter: ossFileFilter,
|
||||||
|
limits: {
|
||||||
|
fileSize: 50 * 1024 * 1024, // 50MB
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传图片
|
* 上传图片
|
||||||
* POST /api/upload/image
|
* POST /api/upload/image
|
||||||
|
|
@ -184,3 +215,95 @@ export const uploadDocument = [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件到 OSS
|
||||||
|
* POST /api/upload/oss
|
||||||
|
* body: FormData with 'file' field
|
||||||
|
* 返回 OSS 对象路径和访问 URL
|
||||||
|
*/
|
||||||
|
export const uploadToOss = [
|
||||||
|
ossUpload.single('file'),
|
||||||
|
async (req: AuthRequest, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const userId = req.userId;
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
throw new CustomError('未授权', 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!req.file) {
|
||||||
|
throw new CustomError('请选择要上传的文件', 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ext = path.extname(req.file.originalname) || '';
|
||||||
|
const objectName = `uploads/${Date.now()}-${uuidv4()}${ext}`;
|
||||||
|
|
||||||
|
await ossService.putBuffer(objectName, req.file.buffer, {
|
||||||
|
contentType: req.file.mimetype,
|
||||||
|
});
|
||||||
|
|
||||||
|
const url = ossService.getObjectUrl(objectName);
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
objectName,
|
||||||
|
url,
|
||||||
|
filename: req.file.originalname,
|
||||||
|
size: req.file.size,
|
||||||
|
contentType: req.file.mimetype,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 OSS 下载文件
|
||||||
|
* GET /api/upload/oss/download?objectName=xxx
|
||||||
|
* 通过 objectName 参数指定 OSS 对象路径,返回文件流
|
||||||
|
*/
|
||||||
|
export const downloadFromOss = async (
|
||||||
|
req: AuthRequest,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
): Promise<void> => {
|
||||||
|
try {
|
||||||
|
const userId = req.userId;
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
throw new CustomError('未授权', 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
const objectName = req.query.objectName as string;
|
||||||
|
|
||||||
|
if (!objectName || typeof objectName !== 'string') {
|
||||||
|
throw new CustomError('缺少 objectName 参数', 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 防止路径遍历
|
||||||
|
if (objectName.includes('..') || objectName.startsWith('/')) {
|
||||||
|
throw new CustomError('无效的 objectName', 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { stream, contentLength, contentType } =
|
||||||
|
await ossService.getObjectStream(objectName);
|
||||||
|
|
||||||
|
const filename = objectName.split('/').pop() || 'download';
|
||||||
|
|
||||||
|
res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(filename)}"`);
|
||||||
|
if (contentType) {
|
||||||
|
res.setHeader('Content-Type', contentType);
|
||||||
|
}
|
||||||
|
if (contentLength) {
|
||||||
|
res.setHeader('Content-Length', contentLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.pipe(res);
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
import { Router } from 'express';
|
import { Router } from 'express';
|
||||||
import { uploadImage, uploadDocument } from '../controllers/uploadController';
|
import {
|
||||||
|
uploadImage,
|
||||||
|
uploadDocument,
|
||||||
|
uploadToOss,
|
||||||
|
downloadFromOss,
|
||||||
|
} from '../controllers/uploadController';
|
||||||
import { authenticate } from '../middleware/auth';
|
import { authenticate } from '../middleware/auth';
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
@ -20,6 +25,23 @@ router.post('/image', authenticate, uploadImage);
|
||||||
*/
|
*/
|
||||||
router.post('/document', authenticate, uploadDocument);
|
router.post('/document', authenticate, uploadDocument);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @route POST /api/upload/oss
|
||||||
|
* @desc 上传文件到 OSS
|
||||||
|
* @access Private
|
||||||
|
* @body FormData with 'file' field
|
||||||
|
* @returns { success: true, data: { objectName, url, filename, size, contentType } }
|
||||||
|
*/
|
||||||
|
router.post('/oss', authenticate, uploadToOss);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @route GET /api/upload/oss/download
|
||||||
|
* @desc 从 OSS 下载文件
|
||||||
|
* @access Private
|
||||||
|
* @query objectName - OSS 对象路径(如 uploads/xxx.png)
|
||||||
|
*/
|
||||||
|
router.get('/oss/download', authenticate, downloadFromOss);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,30 @@ export class OssService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 OSS 获取文件流(用于下载)
|
||||||
|
* @param objectName - OSS对象名称
|
||||||
|
* @returns Promise<{ stream: Readable; contentLength?: number; contentType?: string }>
|
||||||
|
*/
|
||||||
|
async getObjectStream(objectName: string): Promise<{
|
||||||
|
stream: NodeJS.ReadableStream;
|
||||||
|
contentLength?: number;
|
||||||
|
contentType?: string;
|
||||||
|
}> {
|
||||||
|
try {
|
||||||
|
const result = await this.client.getStream(objectName);
|
||||||
|
const headers = (result as { res?: { headers?: Record<string, string> } }).res?.headers;
|
||||||
|
return {
|
||||||
|
stream: result.stream,
|
||||||
|
contentLength: headers?.['content-length'] ? parseInt(headers['content-length'], 10) : undefined,
|
||||||
|
contentType: headers?.['content-type'],
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
||||||
|
throw new Error(`从OSS获取文件失败: ${errorMessage}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查对象是否存在
|
* 检查对象是否存在
|
||||||
* @param objectName - OSS对象名称
|
* @param objectName - OSS对象名称
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include "Shared.xcconfig"
|
#include "Shared.xcconfig"
|
||||||
|
|
||||||
// API 域名(注入 Info.plist,运行时通过 Bundle.main 读取)
|
// API 域名(注入 Info.plist,运行时通过 Bundle.main 读取)
|
||||||
API_DOMAIN = https://api.muststudy.xin
|
API_DOMAIN = https:/$()/api.muststudy.xin
|
||||||
INFOPLIST_KEY_API_DOMAIN = $(API_DOMAIN)
|
INFOPLIST_KEY_API_DOMAIN = $(API_DOMAIN)
|
||||||
|
|
||||||
// Swift 编译条件:代码中可用 #if API_ENV_DEVELOP
|
// Swift 编译条件:代码中可用 #if API_ENV_DEVELOP
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
#include "Shared.xcconfig"
|
#include "Shared.xcconfig"
|
||||||
|
|
||||||
// API 域名(注入 Info.plist,运行时通过 Bundle.main 读取)
|
// API 域名(注入 Info.plist,运行时通过 Bundle.main 读取)
|
||||||
API_DOMAIN = http://localhost:3000
|
API_DOMAIN = http:/$()/localhost:3000
|
||||||
INFOPLIST_KEY_API_DOMAIN = $(API_DOMAIN)
|
INFOPLIST_KEY_API_DOMAIN = $(API_DOMAIN)
|
||||||
|
|
||||||
// Swift 编译条件:代码中可用 #if API_ENV_LOCAL
|
// Swift 编译条件:代码中可用 #if API_ENV_LOCAL
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include "Shared.xcconfig"
|
#include "Shared.xcconfig"
|
||||||
|
|
||||||
// API 域名(注入 Info.plist,运行时通过 Bundle.main 读取)
|
// API 域名(注入 Info.plist,运行时通过 Bundle.main 读取)
|
||||||
API_DOMAIN = https://wildgrowth.upolar.com
|
API_DOMAIN = https:/$()/wildgrowth.upolar.com
|
||||||
INFOPLIST_KEY_API_DOMAIN = $(API_DOMAIN)
|
INFOPLIST_KEY_API_DOMAIN = $(API_DOMAIN)
|
||||||
|
|
||||||
// Swift 编译条件:代码中可用 #if API_ENV_ONLINE
|
// Swift 编译条件:代码中可用 #if API_ENV_ONLINE
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,8 @@
|
||||||
// 包含 Swift 版本、编译选项等通用设置
|
// 包含 Swift 版本、编译选项等通用设置
|
||||||
|
|
||||||
SWIFT_VERSION = 5.0
|
SWIFT_VERSION = 5.0
|
||||||
|
|
||||||
|
// 启用 Info.plist 中的 $(变量) 展开,否则 Info-API.plist 的 $(API_DOMAIN) 无法注入
|
||||||
|
INFOPLIST_EXPAND_BUILD_SETTINGS = YES
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES
|
SWIFT_EMIT_LOC_STRINGS = YES
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES
|
||||||
|
|
|
||||||
|
|
@ -376,6 +376,7 @@
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = "Config/Info-API.plist";
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "电子成长";
|
INFOPLIST_KEY_CFBundleDisplayName = "电子成长";
|
||||||
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
|
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.books";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.books";
|
||||||
|
|
@ -507,6 +508,7 @@
|
||||||
baseConfigurationReference = A3CF00022EE29B130004B865 /* Online.xcconfig */;
|
baseConfigurationReference = A3CF00022EE29B130004B865 /* Online.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
API_DOMAIN = "https://wildgrowth.upolar.com";
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
|
@ -569,6 +571,7 @@
|
||||||
baseConfigurationReference = A3CF00022EE29B130004B865 /* Online.xcconfig */;
|
baseConfigurationReference = A3CF00022EE29B130004B865 /* Online.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
API_DOMAIN = "https://wildgrowth.upolar.com";
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
|
@ -623,6 +626,7 @@
|
||||||
baseConfigurationReference = A3CF00032EE29B130004B865 /* Develop.xcconfig */;
|
baseConfigurationReference = A3CF00032EE29B130004B865 /* Develop.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
API_DOMAIN = "https://api.muststudy.xin";
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
|
@ -685,6 +689,7 @@
|
||||||
baseConfigurationReference = A3CF00032EE29B130004B865 /* Develop.xcconfig */;
|
baseConfigurationReference = A3CF00032EE29B130004B865 /* Develop.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
API_DOMAIN = "https://api.muststudy.xin";
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
|
@ -739,6 +744,7 @@
|
||||||
baseConfigurationReference = A3CF00042EE29B130004B865 /* Local.xcconfig */;
|
baseConfigurationReference = A3CF00042EE29B130004B865 /* Local.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
API_DOMAIN = "http://localhost:3000";
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
|
@ -801,6 +807,7 @@
|
||||||
baseConfigurationReference = A3CF00042EE29B130004B865 /* Local.xcconfig */;
|
baseConfigurationReference = A3CF00042EE29B130004B865 /* Local.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
API_DOMAIN = "http://localhost:3000";
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
|
@ -954,7 +961,6 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = A3CF00042EE29B130004B865 /* Local.xcconfig */;
|
baseConfigurationReference = A3CF00042EE29B130004B865 /* Local.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
API_DOMAIN = "";
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||||
|
|
@ -1005,7 +1011,6 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = A3CF00042EE29B130004B865 /* Local.xcconfig */;
|
baseConfigurationReference = A3CF00042EE29B130004B865 /* Local.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
API_DOMAIN = "";
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue