Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] 新增暂停功能以及多表字段升级 #434

Merged
merged 5 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions DATA_COLLECTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Important Disclosure re:XIAOJUSURVEY Data Collection

XIAOJUSURVEY is open-source software developed and maintained by XIAOJUSURVEY Team and available at https://github.com/didi/xiaoju-survey.
We hereby state the purpose and reason for collecting data.

## Purpose of data collection

Data collected is used to help improve XIAOJUSURVEY for all users. It is important that our team understands the usage patterns as soon as possible, so we can best decide how to design future features and prioritize current work.

## Types of data collected

XIAOJUSURVEY just collects data about version's information. The data collected is subsequently reported to the XIAOJUSURVEY's backend services.

All data collected will be used exclusively by the XIAOJUSURVEY team for analytical purposes only. The data will be neither accessible nor sold to any third party.

## Sensitive data

XIAOJUSURVEY will never collect and/or report sensitive information, such as private keys, API keys, or passwords.

## How do I opt-in to or opt-out of data sharing?

See [docs](https://xiaojusurvey.didi.cn/docs/next/community/%E6%95%B0%E6%8D%AE%E4%B8%8A%E6%8A%A5%E5%A3%B0%E6%98%8E) for information on configuring this functionality.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,4 @@ _任何问题和合作可以联系小助手。_

## CHANGELOG

关注重大项目变更:[MAJOR CHANGELOG](https://github.com/didi/xiaoju-survey/issues/48)。
关注重大项目变更:[MAJOR CHANGELOG](https://github.com/didi/xiaoju-survey/issues/48)。
2 changes: 1 addition & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ services:
- xiaoju-survey

xiaoju-survey:
image: "xiaojusurvey/xiaoju-survey:1.1.6-slim" # 最新版本:https://hub.docker.com/r/xiaojusurvey/xiaoju-survey/tags
image: "xiaojusurvey/xiaoju-survey:1.2.0-slim" # 最新版本:https://hub.docker.com/r/xiaojusurvey/xiaoju-survey/tags
container_name: xiaoju-survey
restart: always
ports:
Expand Down
2 changes: 1 addition & 1 deletion server/.env
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
XIAOJU_SURVEY_MONGO_DB_NAME=xiaojuSurvey
XIAOJU_SURVEY_MONGO_URL=mongodb://127.0.0.1:27017
XIAOJU_SURVEY_MONGO_URL=
XIAOJU_SURVEY_MONGO_AUTH_SOURCE=admin

XIAOJU_SURVEY_REDIS_HOST=
Expand Down
20 changes: 20 additions & 0 deletions server/.env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
XIAOJU_SURVEY_MONGO_DB_NAME=xiaojuSurvey
XIAOJU_SURVEY_MONGO_URL=mongodb://127.0.0.1:27017
XIAOJU_SURVEY_MONGO_AUTH_SOURCE=admin

XIAOJU_SURVEY_REDIS_HOST=
XIAOJU_SURVEY_REDIS_PORT=
XIAOJU_SURVEY_REDIS_USERNAME=
XIAOJU_SURVEY_REDIS_PASSWORD=
XIAOJU_SURVEY_REDIS_DB=


XIAOJU_SURVEY_RESPONSE_AES_ENCRYPT_SECRET_KEY=dataAesEncryptSecretKey
XIAOJU_SURVEY_HTTP_DATA_ENCRYPT_TYPE=rsa

XIAOJU_SURVEY_JWT_SECRET=xiaojuSurveyJwtSecret
XIAOJU_SURVEY_JWT_EXPIRES_IN=8h

XIAOJU_SURVEY_LOGGER_FILENAME=./logs/app.log

XIAOJU_SURVEY_REPORT=true
9 changes: 5 additions & 4 deletions server/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "server",
"version": "0.0.1",
"description": "",
"name": "xiaoju-survey-server",
"version": "1.3.0",
"description": "XIAOJUSURVEY的server端",
"author": "",
"scripts": {
"build": "nest build",
Expand All @@ -22,6 +22,7 @@
"@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.1.1",
"@nestjs/core": "^10.0.0",
"@nestjs/microservices": "^10.4.4",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/serve-static": "^4.0.0",
"@nestjs/swagger": "^7.3.0",
Expand Down Expand Up @@ -75,7 +76,7 @@
"prettier": "^3.0.0",
"redis-memory-server": "^0.11.0",
"source-map-support": "^0.5.21",
"supertest": "^6.3.3",
"supertest": "^7.0.0",
"ts-jest": "^29.1.0",
"ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
Expand Down
62 changes: 62 additions & 0 deletions server/scripts/run-report.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import fs, { promises as fsa } from 'fs-extra';
import path from 'path';
import fetch from 'node-fetch';

interface PackageJson {
type?: string;
name?: string;
version?: string;
description?: string;
id?: string;
msg?: string;
}

const getId = () => {
const id = new Date().getTime().toString();
process.env.XIAOJU_SURVEY_REPORT_ID = id;

return id;
};

const readData = async (directory: string): Promise<PackageJson | null> => {
const packageJsonPath = path.join(directory, 'package.json');
const id = process.env.XIAOJU_SURVEY_REPORT_ID || getId();
try {
if (!fs.existsSync(directory)) {
return {
type: 'server',
name: '',
version: '',
description: '',
id,
msg: '文件不存在',
};
}
const data = await fsa.readFile(packageJsonPath, 'utf8').catch((e) => e);
const { name, version, description } = JSON.parse(data) as PackageJson;
return { type: 'server', name, version, description, id };
} catch (error) {
return error;
}
};

(async (): Promise<void> => {
if (
process.env.NODE_ENV === 'development' &&
!process.env.XIAOJU_SURVEY_REPORT
) {
return;
}

const res = await readData(path.join(process.cwd()));

// 上报
fetch('https://xiaojusurveysrc.didi.cn/reportSourceData', {
method: 'POST',
headers: {
Accept: 'application/json, */*',
'Content-Type': 'application/json',
},
body: JSON.stringify(res),
}).catch(() => {});
})();
11 changes: 8 additions & 3 deletions server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { AuthModule } from './modules/auth/auth.module';
import { MessageModule } from './modules/message/message.module';
import { FileModule } from './modules/file/file.module';
import { WorkspaceModule } from './modules/workspace/workspace.module';
import { UpgradeModule } from './modules/upgrade/upgrade.module';

import { join } from 'path';

Expand All @@ -35,18 +36,21 @@ import { MessagePushingLog } from './models/messagePushingLog.entity';
import { WorkspaceMember } from './models/workspaceMember.entity';
import { Workspace } from './models/workspace.entity';
import { Collaborator } from './models/collaborator.entity';
import { DownloadTask } from './models/downloadTask.entity';
import { Session } from './models/session.entity';

import { LoggerProvider } from './logger/logger.provider';
import { PluginManagerProvider } from './securityPlugin/pluginManager.provider';
import { LogRequestMiddleware } from './middlewares/logRequest.middleware';
import { PluginManager } from './securityPlugin/pluginManager';
import { Logger } from './logger';
import { DownloadTask } from './models/downloadTask.entity';
import { Session } from './models/session.entity';

@Module({
imports: [
ConfigModule.forRoot({}),
ConfigModule.forRoot({
envFilePath: `.env.${process.env.NODE_ENV}`, // 根据 NODE_ENV 动态加载对应的 .env 文件
isGlobal: true, // 使配置模块在应用的任何地方可用
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
Expand Down Expand Up @@ -104,6 +108,7 @@ import { Session } from './models/session.entity';
MessageModule,
FileModule,
WorkspaceModule,
UpgradeModule,
],
controllers: [AppController],
providers: [
Expand Down
6 changes: 6 additions & 0 deletions server/src/enums/downloadTaskStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export enum DOWNLOAD_TASK_STATUS {
WAITING = 'waiting', // 排队中
COMPUTING = 'computing', // 计算中
SUCCEED = 'succeed', // 导出成功
FAILED = 'failed', // 导出失败
}
1 change: 1 addition & 0 deletions server/src/enums/exceptionCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export enum EXCEPTION_CODE {
RESPONSE_OVER_LIMIT = 9003, // 超出限制
RESPONSE_SCHEMA_REMOVED = 9004, // 问卷已删除
RESPONSE_DATA_DECRYPT_ERROR = 9005, // 问卷已删除
RESPONSE_PAUSING = 9006, // 问卷已暂停

UPLOAD_FILE_ERROR = 5001, // 上传文件错误
}
15 changes: 8 additions & 7 deletions server/src/enums/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// 状态类型
export enum RECORD_STATUS {
NEW = 'new', // 新建
NEW = 'new', // 新建 | 未发布
PUBLISHED = 'published', // 发布
EDITING = 'editing', // 编辑
FINISHED = 'finished', // 已结束
REMOVED = 'removed',
}

export const enum RECORD_SUB_STATUS {
DEFAULT = '', // 默认
PAUSING = 'pausing', // 暂停
PUBLISHED = 'published', // 发布
REMOVED = 'removed', // 删除
FORCE_REMOVED = 'forceRemoved', // 从回收站删除
COMPUTING = 'computing', // 计算中
FINISHED = 'finished', // 已完成
ERROR = 'error', // 错误
}

// 历史类型
Expand Down
4 changes: 4 additions & 0 deletions server/src/enums/surveySessionStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum SESSION_STATUS {
ACTIVATED = 'activated',
DEACTIVATED = 'deactivated',
}
1 change: 1 addition & 0 deletions server/src/guards/session.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export class SessionGuard implements CanActivate {
}
const sessionInfo = await this.sessionService.findOne(sessionId);
request.sessionInfo = sessionInfo;
request.surveyId = sessionInfo.surveyId;
return true;
}
}
2 changes: 1 addition & 1 deletion server/src/interfaces/survey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export enum MemberType {
}

export interface BaseConf {
begTime: string;
beginTime: string;
endTime: string;
answerBegTime: string;
answerEndTime: string;
Expand Down
15 changes: 8 additions & 7 deletions server/src/logger/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import * as log4js from 'log4js';
import moment from 'moment';
import { Injectable, Scope } from '@nestjs/common';
import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT, RequestContext } from '@nestjs/microservices';

const log4jsLogger = log4js.getLogger();

@Injectable({ scope: Scope.REQUEST })
export class Logger {
private static inited = false;
private traceId: string;

constructor(@Inject(CONTEXT) private readonly ctx: RequestContext) {}

static init(config: { filename: string }) {
if (Logger.inited) {
Expand Down Expand Up @@ -37,16 +40,14 @@ export class Logger {
const datetime = moment().format('YYYY-MM-DD HH:mm:ss.SSS');
const level = options?.level;
const dltag = options?.dltag ? `${options.dltag}||` : '';
const traceIdStr = this.traceId ? `traceid=${this.traceId}||` : '';
const traceIdStr = this.ctx?.['traceId']
? `traceid=${this.ctx?.['traceId']}||`
: '';
return log4jsLogger[level](
`[${datetime}][${level.toUpperCase()}]${dltag}${traceIdStr}${message}`,
);
}

setTraceId(traceId: string) {
this.traceId = traceId;
}

info(message, options?: { dltag?: string }) {
return this._log(message, { ...options, level: 'info' });
}
Expand Down
4 changes: 3 additions & 1 deletion server/src/logger/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ export const genTraceId = ({ ip }) => {
} else {
ipArr = ip
.split('.')
.map((item) => parseInt(item).toString(16).padStart(2, '0'));
.map((item) =>
item ? parseInt(item).toString(16).padStart(2, '0') : '',
);
}

return `${ipArr.join('')}${Date.now().toString()}${getCountStr()}${process.pid.toString().slice(-5)}`;
Expand Down
1 change: 1 addition & 0 deletions server/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import 'scripts/run-report';

async function bootstrap() {
const PORT = process.env.PORT || 3000;
Expand Down
2 changes: 1 addition & 1 deletion server/src/middlewares/logRequest.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class LogRequestMiddleware implements NestMiddleware {
const userAgent = req.get('user-agent') || '';
const startTime = Date.now();
const traceId = genTraceId({ ip });
this.logger.setTraceId(traceId);
req['traceId'] = traceId;
const query = JSON.stringify(req.query);
const body = JSON.stringify(req.body);
this.logger.info(
Expand Down
40 changes: 5 additions & 35 deletions server/src/models/base.entity.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,13 @@
import { Column, ObjectIdColumn, BeforeInsert, BeforeUpdate } from 'typeorm';
import { ObjectIdColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';
import { ObjectId } from 'mongodb';
import { RECORD_STATUS } from '../enums';

export class BaseEntity {
@ObjectIdColumn()
_id: ObjectId;

@Column()
curStatus: {
status: RECORD_STATUS;
date: number;
};
@CreateDateColumn({ type: 'timestamp', precision: 3 })
createdAt: Date;

@Column()
statusList: Array<{
status: RECORD_STATUS;
date: number;
}>;

@Column()
createDate: number;

@Column()
updateDate: number;

@BeforeInsert()
initDefaultInfo() {
const now = Date.now();
if (!this.curStatus) {
const curStatus = { status: RECORD_STATUS.NEW, date: now };
this.curStatus = curStatus;
this.statusList = [curStatus];
}
this.createDate = now;
this.updateDate = now;
}

@BeforeUpdate()
onUpdate() {
this.updateDate = Date.now();
}
@UpdateDateColumn({ type: 'timestamp', precision: 3 })
updatedAt: Date;
}
12 changes: 12 additions & 0 deletions server/src/models/collaborator.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,16 @@ export class Collaborator extends BaseEntity {

@Column('jsonb')
permissions: Array<string>;

@Column()
creator: string;

@Column()
creatorId: string;

@Column()
operator: string;

@Column()
operatorId: string;
}
Loading
Loading