parent
43001a12c7
commit
0b4e1fa13b
@ -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';
|
||||
|
||||
@ -100,6 +101,7 @@ import { Logger } from './logger';
|
||||
MessageModule,
|
||||
FileModule,
|
||||
WorkspaceModule,
|
||||
UpgradeModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [
|
||||
|
@ -20,6 +20,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, // 上传文件错误
|
||||
}
|
||||
|
@ -1,9 +1,14 @@
|
||||
// 状态类型
|
||||
export enum RECORD_STATUS {
|
||||
NEW = 'new', // 新建
|
||||
NEW = 'new', // 新建 | 未发布
|
||||
PUBLISHED = 'published', // 发布
|
||||
CLOSE = 'close', // 关闭
|
||||
}
|
||||
|
||||
export const enum RECORD_SUB_STATUS {
|
||||
DEFAULT = '', // 默认
|
||||
EDITING = 'editing', // 编辑
|
||||
PAUSING = 'pausing', // 暂停
|
||||
PUBLISHED = 'published', // 发布
|
||||
REMOVED = 'removed', // 删除
|
||||
FORCE_REMOVED = 'forceRemoved', // 从回收站删除
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Column, ObjectIdColumn, BeforeInsert, BeforeUpdate } from 'typeorm';
|
||||
import { ObjectId } from 'mongodb';
|
||||
import { RECORD_STATUS } from '../enums';
|
||||
import { RECORD_STATUS, RECORD_SUB_STATUS } from '../enums';
|
||||
|
||||
export class BaseEntity {
|
||||
@ObjectIdColumn()
|
||||
@ -12,9 +12,15 @@ export class BaseEntity {
|
||||
date: number;
|
||||
};
|
||||
|
||||
@Column()
|
||||
subStatus: {
|
||||
status: RECORD_SUB_STATUS;
|
||||
date: number;
|
||||
};
|
||||
|
||||
@Column()
|
||||
statusList: Array<{
|
||||
status: RECORD_STATUS;
|
||||
status: RECORD_STATUS | RECORD_SUB_STATUS;
|
||||
date: number;
|
||||
}>;
|
||||
|
||||
@ -32,6 +38,10 @@ export class BaseEntity {
|
||||
this.curStatus = curStatus;
|
||||
this.statusList = [curStatus];
|
||||
}
|
||||
if (!this.subStatus) {
|
||||
const subStatus = { status: RECORD_SUB_STATUS.DEFAULT, date: now };
|
||||
this.subStatus = subStatus;
|
||||
}
|
||||
this.createDate = now;
|
||||
this.updateDate = now;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { UserService } from '../services/user.service';
|
||||
import { User } from 'src/models/user.entity';
|
||||
import { HttpException } from 'src/exceptions/httpException';
|
||||
import { hash256 } from 'src/utils/hash256';
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_SUB_STATUS } from 'src/enums';
|
||||
import { ObjectId } from 'mongodb';
|
||||
|
||||
describe('UserService', () => {
|
||||
@ -145,7 +145,7 @@ describe('UserService', () => {
|
||||
expect(userRepository.findOne).toHaveBeenCalledWith({
|
||||
where: {
|
||||
username: username,
|
||||
'curStatus.status': { $ne: RECORD_STATUS.REMOVED },
|
||||
'subStatus.status': { $ne: RECORD_SUB_STATUS.REMOVED },
|
||||
},
|
||||
});
|
||||
expect(user).toEqual(userInfo);
|
||||
@ -163,7 +163,7 @@ describe('UserService', () => {
|
||||
expect(findOneSpy).toHaveBeenCalledWith({
|
||||
where: {
|
||||
username: username,
|
||||
'curStatus.status': { $ne: RECORD_STATUS.REMOVED },
|
||||
'subStatus.status': { $ne: RECORD_SUB_STATUS.REMOVED },
|
||||
},
|
||||
});
|
||||
expect(user).toBe(null);
|
||||
@ -184,7 +184,7 @@ describe('UserService', () => {
|
||||
expect(userRepository.findOne).toHaveBeenCalledWith({
|
||||
where: {
|
||||
_id: new ObjectId(id),
|
||||
'curStatus.status': { $ne: RECORD_STATUS.REMOVED },
|
||||
'subStatus.status': { $ne: RECORD_SUB_STATUS.REMOVED },
|
||||
},
|
||||
});
|
||||
expect(user).toEqual(userInfo);
|
||||
@ -202,7 +202,7 @@ describe('UserService', () => {
|
||||
expect(findOneSpy).toHaveBeenCalledWith({
|
||||
where: {
|
||||
_id: new ObjectId(id),
|
||||
'curStatus.status': { $ne: RECORD_STATUS.REMOVED },
|
||||
'subStatus.status': { $ne: RECORD_SUB_STATUS.REMOVED },
|
||||
},
|
||||
});
|
||||
expect(user).toBe(null);
|
||||
@ -228,7 +228,7 @@ describe('UserService', () => {
|
||||
expect(userRepository.find).toHaveBeenCalledWith({
|
||||
where: {
|
||||
username: new RegExp(username),
|
||||
'curStatus.status': { $ne: RECORD_STATUS.REMOVED },
|
||||
'subStatus.status': { $ne: RECORD_SUB_STATUS.REMOVED },
|
||||
},
|
||||
skip: 0,
|
||||
take: 10,
|
||||
@ -263,7 +263,7 @@ describe('UserService', () => {
|
||||
_id: {
|
||||
$in: idList.map((id) => new ObjectId(id)),
|
||||
},
|
||||
'curStatus.status': { $ne: RECORD_STATUS.REMOVED },
|
||||
'subStatus.status': { $ne: RECORD_SUB_STATUS.REMOVED },
|
||||
},
|
||||
select: ['_id', 'username', 'createDate'],
|
||||
});
|
||||
|
@ -5,7 +5,7 @@ import { User } from 'src/models/user.entity';
|
||||
import { HttpException } from 'src/exceptions/httpException';
|
||||
import { EXCEPTION_CODE } from 'src/enums/exceptionCode';
|
||||
import { hash256 } from 'src/utils/hash256';
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_SUB_STATUS } from 'src/enums';
|
||||
import { ObjectId } from 'mongodb';
|
||||
|
||||
@Injectable()
|
||||
@ -53,8 +53,8 @@ export class UserService {
|
||||
const user = await this.userRepository.findOne({
|
||||
where: {
|
||||
username: username,
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -66,8 +66,8 @@ export class UserService {
|
||||
const user = await this.userRepository.findOne({
|
||||
where: {
|
||||
_id: new ObjectId(id),
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -79,8 +79,8 @@ export class UserService {
|
||||
const list = await this.userRepository.find({
|
||||
where: {
|
||||
username: new RegExp(username),
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
},
|
||||
skip,
|
||||
@ -96,8 +96,8 @@ export class UserService {
|
||||
_id: {
|
||||
$in: idList.map((item) => new ObjectId(item)),
|
||||
},
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
},
|
||||
select: ['_id', 'username', 'createDate'],
|
||||
|
@ -10,7 +10,7 @@ import { MessagePushingLogService } from '../services/messagePushingLog.service'
|
||||
import { CreateMessagePushingTaskDto } from '../dto/createMessagePushingTask.dto';
|
||||
import { UpdateMessagePushingTaskDto } from '../dto/updateMessagePushingTask.dto';
|
||||
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_SUB_STATUS } from 'src/enums';
|
||||
import { MESSAGE_PUSHING_TYPE } from 'src/enums/messagePushing';
|
||||
import { MESSAGE_PUSHING_HOOK } from 'src/enums/messagePushing';
|
||||
import { MessagePushingTask } from 'src/models/messagePushingTask.entity';
|
||||
@ -121,7 +121,7 @@ describe('MessagePushingTaskService', () => {
|
||||
ownerId: mockOwnerId,
|
||||
surveys: { $all: [surveyId] },
|
||||
triggerHook: hook,
|
||||
'curStatus.status': { $ne: RECORD_STATUS.REMOVED },
|
||||
'subStatus.status': { $ne: RECORD_SUB_STATUS.REMOVED },
|
||||
},
|
||||
});
|
||||
});
|
||||
@ -146,7 +146,7 @@ describe('MessagePushingTaskService', () => {
|
||||
where: {
|
||||
ownerId: mockOwnerId,
|
||||
_id: new ObjectId(taskId),
|
||||
'curStatus.status': { $ne: RECORD_STATUS.REMOVED },
|
||||
'subStatus.status': { $ne: RECORD_SUB_STATUS.REMOVED },
|
||||
},
|
||||
});
|
||||
});
|
||||
@ -161,8 +161,8 @@ describe('MessagePushingTaskService', () => {
|
||||
pushAddress: 'http://update.example.com',
|
||||
triggerHook: MESSAGE_PUSHING_HOOK.RESPONSE_INSERTED,
|
||||
surveys: ['new survey id'],
|
||||
curStatus: {
|
||||
status: RECORD_STATUS.EDITING,
|
||||
subStatus: {
|
||||
status: RECORD_SUB_STATUS.EDITING,
|
||||
date: Date.now(),
|
||||
},
|
||||
};
|
||||
@ -211,18 +211,18 @@ describe('MessagePushingTaskService', () => {
|
||||
{
|
||||
ownerId: mockOwnerId,
|
||||
_id: new ObjectId(taskId),
|
||||
'curStatus.status': { $ne: RECORD_STATUS.REMOVED },
|
||||
'subStatus.status': { $ne: RECORD_SUB_STATUS.REMOVED },
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
curStatus: {
|
||||
status: RECORD_STATUS.REMOVED,
|
||||
subStatus: {
|
||||
status: RECORD_SUB_STATUS.REMOVED,
|
||||
date: expect.any(Number),
|
||||
},
|
||||
},
|
||||
$push: {
|
||||
statusList: {
|
||||
status: RECORD_STATUS.REMOVED,
|
||||
status: RECORD_SUB_STATUS.REMOVED,
|
||||
date: expect.any(Number),
|
||||
},
|
||||
},
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_STATUS, RECORD_SUB_STATUS } from 'src/enums';
|
||||
import {
|
||||
MESSAGE_PUSHING_TYPE,
|
||||
MESSAGE_PUSHING_HOOK,
|
||||
@ -26,4 +26,9 @@ export class UpdateMessagePushingTaskDto {
|
||||
status: RECORD_STATUS;
|
||||
date: number;
|
||||
};
|
||||
@ApiProperty({ description: '任务子状态', required: false })
|
||||
subStatus?: {
|
||||
status: RECORD_SUB_STATUS;
|
||||
date: number;
|
||||
};
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import { MESSAGE_PUSHING_HOOK } from 'src/enums/messagePushing';
|
||||
import { CreateMessagePushingTaskDto } from '../dto/createMessagePushingTask.dto';
|
||||
import { UpdateMessagePushingTaskDto } from '../dto/updateMessagePushingTask.dto';
|
||||
import { ObjectId } from 'mongodb';
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_SUB_STATUS } from 'src/enums';
|
||||
import { MESSAGE_PUSHING_TYPE } from 'src/enums/messagePushing';
|
||||
import { MessagePushingLogService } from './messagePushingLog.service';
|
||||
import { httpPost } from 'src/utils/request';
|
||||
@ -44,8 +44,8 @@ export class MessagePushingTaskService {
|
||||
ownerId?: string;
|
||||
}): Promise<MessagePushingTask[]> {
|
||||
const where: Record<string, any> = {
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
};
|
||||
if (surveyId) {
|
||||
@ -75,8 +75,8 @@ export class MessagePushingTaskService {
|
||||
where: {
|
||||
ownerId,
|
||||
_id: new ObjectId(id),
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -103,26 +103,25 @@ export class MessagePushingTaskService {
|
||||
const updatedTask = Object.assign(existingTask, updateData);
|
||||
return await this.messagePushingTaskRepository.save(updatedTask);
|
||||
}
|
||||
|
||||
async remove({ id, ownerId }: { id: string; ownerId: string }) {
|
||||
const curStatus = {
|
||||
status: RECORD_STATUS.REMOVED,
|
||||
const subStatus = {
|
||||
status: RECORD_SUB_STATUS.REMOVED,
|
||||
date: Date.now(),
|
||||
};
|
||||
return this.messagePushingTaskRepository.updateOne(
|
||||
{
|
||||
ownerId,
|
||||
_id: new ObjectId(id),
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
curStatus,
|
||||
subStatus,
|
||||
},
|
||||
$push: {
|
||||
statusList: curStatus as never,
|
||||
statusList: subStatus as never,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
@ -116,6 +116,9 @@ describe('SurveyMetaController', () => {
|
||||
curStatus: {
|
||||
date: date,
|
||||
},
|
||||
subStatus: {
|
||||
date: date,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -132,10 +135,12 @@ describe('SurveyMetaController', () => {
|
||||
createDate: expect.stringMatching(
|
||||
/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/,
|
||||
),
|
||||
updateDate: expect.stringMatching(
|
||||
curStatus: expect.objectContaining({
|
||||
date: expect.stringMatching(
|
||||
/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/,
|
||||
),
|
||||
curStatus: expect.objectContaining({
|
||||
}),
|
||||
subStatus: expect.objectContaining({
|
||||
date: expect.stringMatching(
|
||||
/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/,
|
||||
),
|
||||
|
@ -4,7 +4,7 @@ import { MongoRepository } from 'typeorm';
|
||||
import { SurveyMeta } from 'src/models/surveyMeta.entity';
|
||||
import { PluginManagerProvider } from 'src/securityPlugin/pluginManager.provider';
|
||||
import { XiaojuSurveyPluginManager } from 'src/securityPlugin/pluginManager';
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_STATUS, RECORD_SUB_STATUS } from 'src/enums';
|
||||
import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
import { HttpException } from 'src/exceptions/httpException';
|
||||
import { SurveyUtilPlugin } from 'src/securityPlugin/surveyUtilPlugin';
|
||||
@ -100,14 +100,18 @@ describe('SurveyMetaService', () => {
|
||||
it('should edit a survey meta and return it if in NEW or EDITING status', async () => {
|
||||
const survey = new SurveyMeta();
|
||||
survey.curStatus = { status: RECORD_STATUS.PUBLISHED, date: Date.now() };
|
||||
survey.subStatus = {
|
||||
status: RECORD_SUB_STATUS.DEFAULT,
|
||||
date: Date.now(),
|
||||
};
|
||||
survey.statusList = [];
|
||||
jest.spyOn(surveyRepository, 'save').mockResolvedValue(survey);
|
||||
|
||||
const result = await service.editSurveyMeta(survey);
|
||||
|
||||
expect(survey.curStatus.status).toEqual(RECORD_STATUS.EDITING);
|
||||
expect(survey.subStatus.status).toEqual(RECORD_SUB_STATUS.EDITING);
|
||||
expect(survey.statusList.length).toBe(1);
|
||||
expect(survey.statusList[0].status).toEqual(RECORD_STATUS.EDITING);
|
||||
expect(survey.statusList[0].status).toEqual(RECORD_SUB_STATUS.EDITING);
|
||||
expect(surveyRepository.save).toHaveBeenCalledWith(survey);
|
||||
expect(result).toEqual(survey);
|
||||
});
|
||||
@ -118,6 +122,10 @@ describe('SurveyMetaService', () => {
|
||||
// 准备假的SurveyMeta对象
|
||||
const survey = new SurveyMeta();
|
||||
survey.curStatus = { status: RECORD_STATUS.NEW, date: Date.now() };
|
||||
survey.subStatus = {
|
||||
status: RECORD_SUB_STATUS.DEFAULT,
|
||||
date: Date.now(),
|
||||
};
|
||||
survey.statusList = [];
|
||||
|
||||
// 模拟save方法
|
||||
@ -128,9 +136,9 @@ describe('SurveyMetaService', () => {
|
||||
|
||||
// 验证结果
|
||||
expect(result).toBe(survey);
|
||||
expect(survey.curStatus.status).toBe(RECORD_STATUS.REMOVED);
|
||||
expect(survey.subStatus.status).toBe(RECORD_SUB_STATUS.REMOVED);
|
||||
expect(survey.statusList.length).toBe(1);
|
||||
expect(survey.statusList[0].status).toBe(RECORD_STATUS.REMOVED);
|
||||
expect(survey.statusList[0].status).toBe(RECORD_SUB_STATUS.REMOVED);
|
||||
expect(surveyRepository.save).toHaveBeenCalledTimes(1);
|
||||
expect(surveyRepository.save).toHaveBeenCalledWith(survey);
|
||||
});
|
||||
@ -138,7 +146,10 @@ describe('SurveyMetaService', () => {
|
||||
it('should throw exception when survey is already removed', async () => {
|
||||
// 准备假的SurveyMeta对象,其状态已设置为REMOVED
|
||||
const survey = new SurveyMeta();
|
||||
survey.curStatus = { status: RECORD_STATUS.REMOVED, date: Date.now() };
|
||||
survey.subStatus = {
|
||||
status: RECORD_SUB_STATUS.REMOVED,
|
||||
date: Date.now(),
|
||||
};
|
||||
|
||||
// 调用要测试的方法并期待异常
|
||||
await expect(service.deleteSurveyMeta(survey)).rejects.toThrow(
|
||||
@ -195,6 +206,10 @@ describe('SurveyMetaService', () => {
|
||||
status: RECORD_STATUS.PUBLISHED,
|
||||
date: expect.any(Number),
|
||||
},
|
||||
subStatus: {
|
||||
status: RECORD_SUB_STATUS.DEFAULT,
|
||||
date: expect.any(Number),
|
||||
},
|
||||
} as unknown as SurveyMeta;
|
||||
|
||||
jest.spyOn(surveyRepository, 'save').mockResolvedValue(savedSurveyMeta);
|
||||
|
@ -175,6 +175,25 @@ export class SurveyController {
|
||||
};
|
||||
}
|
||||
|
||||
@HttpCode(200)
|
||||
@Post('/pausingSurvey')
|
||||
@UseGuards(SurveyGuard)
|
||||
@SetMetadata('surveyId', 'body.surveyId')
|
||||
@SetMetadata('surveyPermission', [SURVEY_PERMISSION.SURVEY_CONF_MANAGE])
|
||||
@UseGuards(Authentication)
|
||||
async pausingSurvey(@Request() req) {
|
||||
const surveyMeta = req.surveyMeta;
|
||||
|
||||
await this.surveyMetaService.pausingSurveyMeta(surveyMeta);
|
||||
await this.responseSchemaService.pausingResponseSchema({
|
||||
surveyPath: surveyMeta.surveyPath,
|
||||
});
|
||||
|
||||
return {
|
||||
code: 200,
|
||||
};
|
||||
}
|
||||
|
||||
@Get('/getSurvey')
|
||||
@HttpCode(200)
|
||||
@UseGuards(SurveyGuard)
|
||||
|
@ -130,8 +130,8 @@ export class SurveyMetaController {
|
||||
item.surveyType = item.questionType || 'normal';
|
||||
}
|
||||
item.createDate = moment(item.createDate).format(fmt);
|
||||
item.updateDate = moment(item.updateDate).format(fmt);
|
||||
item.curStatus.date = moment(item.curStatus.date).format(fmt);
|
||||
item.subStatus.date = moment(item.subStatus.date).format(fmt);
|
||||
const surveyId = item._id.toString();
|
||||
if (cooperSurveyIdMap[surveyId]) {
|
||||
item.isCollaborated = true;
|
||||
|
@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { MongoRepository } from 'typeorm';
|
||||
import { SurveyResponse } from 'src/models/surveyResponse.entity';
|
||||
import { RECORD_SUB_STATUS } from 'src/enums';
|
||||
|
||||
import moment from 'moment';
|
||||
import { keyBy } from 'lodash';
|
||||
@ -34,8 +35,8 @@ export class DataStatisticService {
|
||||
const dataListMap = keyBy(dataList, 'field');
|
||||
const where = {
|
||||
pageId: surveyId,
|
||||
'curStatus.status': {
|
||||
$ne: 'removed',
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
};
|
||||
const [surveyResponseList, total] =
|
||||
@ -124,8 +125,8 @@ export class DataStatisticService {
|
||||
{
|
||||
$match: {
|
||||
pageId: surveyId,
|
||||
'curStatus.status': {
|
||||
$ne: 'removed',
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { MongoRepository, FindOptionsOrder } from 'typeorm';
|
||||
import { SurveyMeta } from 'src/models/surveyMeta.entity';
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_STATUS, RECORD_SUB_STATUS } from 'src/enums';
|
||||
import { ObjectId } from 'mongodb';
|
||||
import { HttpException } from 'src/exceptions/httpException';
|
||||
import { EXCEPTION_CODE } from 'src/enums/exceptionCode';
|
||||
@ -75,33 +75,58 @@ export class SurveyMetaService {
|
||||
return await this.surveyRepository.save(newSurvey);
|
||||
}
|
||||
|
||||
async pausingSurveyMeta(survey: SurveyMeta) {
|
||||
if (
|
||||
survey.curStatus.status !== RECORD_STATUS.PUBLISHED ||
|
||||
(survey?.subStatus?.status &&
|
||||
survey?.subStatus?.status != RECORD_SUB_STATUS.EDITING)
|
||||
) {
|
||||
throw new HttpException(
|
||||
'问卷不能暂停',
|
||||
EXCEPTION_CODE.SURVEY_STATUS_TRANSFORM_ERROR,
|
||||
);
|
||||
}
|
||||
const subCurStatus = {
|
||||
status: RECORD_SUB_STATUS.PAUSING,
|
||||
date: Date.now(),
|
||||
};
|
||||
survey.subStatus = subCurStatus;
|
||||
survey.curStatus.status = RECORD_STATUS.PUBLISHED;
|
||||
if (Array.isArray(survey.statusList)) {
|
||||
survey.statusList.push(subCurStatus);
|
||||
} else {
|
||||
survey.statusList = [subCurStatus];
|
||||
}
|
||||
return this.surveyRepository.save(survey);
|
||||
}
|
||||
|
||||
async editSurveyMeta(survey: SurveyMeta) {
|
||||
if (
|
||||
survey.curStatus.status !== RECORD_STATUS.NEW &&
|
||||
survey.curStatus.status !== RECORD_STATUS.EDITING
|
||||
survey.subStatus.status !== RECORD_SUB_STATUS.EDITING
|
||||
) {
|
||||
const newStatus = {
|
||||
status: RECORD_STATUS.EDITING,
|
||||
status: RECORD_SUB_STATUS.EDITING,
|
||||
date: Date.now(),
|
||||
};
|
||||
survey.curStatus = newStatus;
|
||||
survey.subStatus = newStatus;
|
||||
survey.statusList.push(newStatus);
|
||||
}
|
||||
return this.surveyRepository.save(survey);
|
||||
}
|
||||
|
||||
async deleteSurveyMeta(survey: SurveyMeta) {
|
||||
if (survey.curStatus.status === RECORD_STATUS.REMOVED) {
|
||||
if (survey.subStatus.status === RECORD_SUB_STATUS.REMOVED) {
|
||||
throw new HttpException(
|
||||
'问卷已删除,不能重复删除',
|
||||
EXCEPTION_CODE.SURVEY_STATUS_TRANSFORM_ERROR,
|
||||
);
|
||||
}
|
||||
const newStatusInfo = {
|
||||
status: RECORD_STATUS.REMOVED,
|
||||
status: RECORD_SUB_STATUS.REMOVED,
|
||||
date: Date.now(),
|
||||
};
|
||||
survey.curStatus = newStatusInfo;
|
||||
survey.subStatus = newStatusInfo;
|
||||
if (Array.isArray(survey.statusList)) {
|
||||
survey.statusList.push(newStatusInfo);
|
||||
} else {
|
||||
@ -127,12 +152,15 @@ export class SurveyMetaService {
|
||||
const query: Record<string, any> = Object.assign(
|
||||
{},
|
||||
{
|
||||
'curStatus.status': {
|
||||
$ne: 'removed',
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
},
|
||||
condition.filter,
|
||||
);
|
||||
if (condition.filter['curStatus.status']) {
|
||||
query['subStatus.status'] = RECORD_SUB_STATUS.DEFAULT;
|
||||
}
|
||||
if (workspaceId) {
|
||||
query.workspaceId = workspaceId;
|
||||
} else {
|
||||
@ -162,12 +190,23 @@ export class SurveyMetaService {
|
||||
: ({
|
||||
createDate: -1,
|
||||
} as FindOptionsOrder<SurveyMeta>);
|
||||
|
||||
const [data, count] = await this.surveyRepository.findAndCount({
|
||||
where: query,
|
||||
skip,
|
||||
take: pageSize,
|
||||
order,
|
||||
select: [
|
||||
'_id',
|
||||
'title',
|
||||
'remark',
|
||||
'surveyType',
|
||||
'curStatus',
|
||||
'subStatus',
|
||||
'createDate',
|
||||
'owner',
|
||||
'ownerId',
|
||||
'workspaceId',
|
||||
],
|
||||
});
|
||||
return { data, count };
|
||||
} catch (error) {
|
||||
@ -181,6 +220,10 @@ export class SurveyMetaService {
|
||||
date: Date.now(),
|
||||
};
|
||||
surveyMeta.curStatus = curStatus;
|
||||
surveyMeta.subStatus = {
|
||||
status: RECORD_SUB_STATUS.DEFAULT,
|
||||
date: Date.now(),
|
||||
};
|
||||
if (Array.isArray(surveyMeta.statusList)) {
|
||||
surveyMeta.statusList.push(curStatus);
|
||||
} else {
|
||||
@ -192,8 +235,8 @@ export class SurveyMetaService {
|
||||
async countSurveyMetaByWorkspaceId({ workspaceId }) {
|
||||
const total = await this.surveyRepository.count({
|
||||
workspaceId,
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
});
|
||||
return total;
|
||||
|
@ -3,7 +3,7 @@ import { MongoRepository } from 'typeorm';
|
||||
import { ClientEncryptService } from '../services/clientEncrypt.service';
|
||||
import { ClientEncrypt } from 'src/models/clientEncrypt.entity';
|
||||
import { ENCRYPT_TYPE } from 'src/enums/encrypt';
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_SUB_STATUS } from 'src/enums';
|
||||
import { ObjectId } from 'mongodb';
|
||||
import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
|
||||
@ -88,8 +88,8 @@ describe('ClientEncryptService', () => {
|
||||
expect(repository.findOne).toHaveBeenCalledWith({
|
||||
where: {
|
||||
_id: new ObjectId(id),
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { ResponseSchema } from 'src/models/responseSchema.entity';
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_STATUS, RECORD_SUB_STATUS } from 'src/enums';
|
||||
import { ObjectId } from 'mongodb';
|
||||
|
||||
export const mockResponseSchema: ResponseSchema = {
|
||||
@ -8,6 +8,10 @@ export const mockResponseSchema: ResponseSchema = {
|
||||
status: RECORD_STATUS.PUBLISHED,
|
||||
date: 1710399368439,
|
||||
},
|
||||
subStatus: {
|
||||
status: RECORD_SUB_STATUS.DEFAULT,
|
||||
date: 1710399368439,
|
||||
},
|
||||
statusList: [
|
||||
{
|
||||
status: RECORD_STATUS.PUBLISHED,
|
||||
|
@ -3,7 +3,7 @@ import { ResponseSchemaController } from '../controllers/responseSchema.controll
|
||||
import { ResponseSchemaService } from '../services/responseScheme.service';
|
||||
import { HttpException } from 'src/exceptions/httpException';
|
||||
import { EXCEPTION_CODE } from 'src/enums/exceptionCode';
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_STATUS, RECORD_SUB_STATUS } from 'src/enums';
|
||||
|
||||
import { ResponseSchema } from 'src/models/responseSchema.entity';
|
||||
import { Logger } from 'src/logger';
|
||||
@ -69,6 +69,7 @@ describe('ResponseSchemaController', () => {
|
||||
const mockResponseSchema = {
|
||||
surveyPath: 'testSurveyPath',
|
||||
curStatus: { status: RECORD_STATUS.PUBLISHED, date: Date.now() },
|
||||
subStatus: { status: RECORD_SUB_STATUS.DEFAULT, date: Date.now() },
|
||||
} as ResponseSchema;
|
||||
|
||||
jest
|
||||
@ -97,7 +98,7 @@ describe('ResponseSchemaController', () => {
|
||||
jest
|
||||
.spyOn(responseSchemaService, 'getResponseSchemaByPath')
|
||||
.mockResolvedValue({
|
||||
curStatus: { status: RECORD_STATUS.REMOVED },
|
||||
subStatus: { status: RECORD_SUB_STATUS.REMOVED },
|
||||
} as ResponseSchema);
|
||||
|
||||
await expect(controller.getSchema(mockQueryInfo)).rejects.toThrow(
|
||||
@ -125,6 +126,9 @@ describe('ResponseSchemaController', () => {
|
||||
curStatus: {
|
||||
status: 'published',
|
||||
},
|
||||
subStatus: {
|
||||
status: '',
|
||||
},
|
||||
code: {
|
||||
baseConf: {
|
||||
passwordSwitch: true,
|
||||
@ -149,6 +153,9 @@ describe('ResponseSchemaController', () => {
|
||||
curStatus: {
|
||||
status: 'published',
|
||||
},
|
||||
subStatus: {
|
||||
status: '',
|
||||
},
|
||||
code: {
|
||||
baseConf: {
|
||||
passwordSwitch: true,
|
||||
@ -172,6 +179,9 @@ describe('ResponseSchemaController', () => {
|
||||
curStatus: {
|
||||
status: 'published',
|
||||
},
|
||||
subStatus: {
|
||||
status: '',
|
||||
},
|
||||
code: {
|
||||
baseConf: {
|
||||
passwordSwitch: true,
|
||||
@ -200,6 +210,9 @@ describe('ResponseSchemaController', () => {
|
||||
curStatus: {
|
||||
status: 'published',
|
||||
},
|
||||
subStatus: {
|
||||
status: '',
|
||||
},
|
||||
code: {
|
||||
baseConf: {
|
||||
passwordSwitch: true,
|
||||
@ -228,6 +241,9 @@ describe('ResponseSchemaController', () => {
|
||||
curStatus: {
|
||||
status: 'published',
|
||||
},
|
||||
subStatus: {
|
||||
status: '',
|
||||
},
|
||||
code: {
|
||||
baseConf: {
|
||||
passwordSwitch: true,
|
||||
|
@ -18,7 +18,7 @@ import { HttpException } from 'src/exceptions/httpException';
|
||||
import { SurveyNotFoundException } from 'src/exceptions/surveyNotFoundException';
|
||||
import { ResponseSecurityPlugin } from 'src/securityPlugin/responseSecurityPlugin';
|
||||
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_STATUS, RECORD_SUB_STATUS } from 'src/enums';
|
||||
import { SurveyResponse } from 'src/models/surveyResponse.entity';
|
||||
import { Logger } from 'src/logger';
|
||||
import { ResponseSchema } from 'src/models/responseSchema.entity';
|
||||
@ -335,6 +335,9 @@ describe('SurveyResponseController', () => {
|
||||
curStatus: {
|
||||
status: RECORD_STATUS.PUBLISHED,
|
||||
},
|
||||
subStatus: {
|
||||
status: RECORD_SUB_STATUS.DEFAULT,
|
||||
},
|
||||
code: {
|
||||
baseConf: {
|
||||
passwordSwitch: true,
|
||||
|
@ -77,7 +77,7 @@ describe('SurveyResponseService', () => {
|
||||
expect(surveyResponseRepository.count).toHaveBeenCalledWith({
|
||||
where: {
|
||||
surveyPath,
|
||||
'curStatus.status': { $ne: 'removed' },
|
||||
'subStatus.status': { $ne: 'removed' },
|
||||
},
|
||||
});
|
||||
});
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
import { ResponseSchemaService } from '../services/responseScheme.service';
|
||||
import { HttpException } from 'src/exceptions/httpException';
|
||||
import { EXCEPTION_CODE } from 'src/enums/exceptionCode';
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_SUB_STATUS } from 'src/enums';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import Joi from 'joi';
|
||||
import { Logger } from 'src/logger';
|
||||
@ -46,7 +46,7 @@ export class ResponseSchemaController {
|
||||
);
|
||||
if (
|
||||
!responseSchema ||
|
||||
responseSchema.curStatus.status === RECORD_STATUS.REMOVED
|
||||
responseSchema.subStatus.status === RECORD_SUB_STATUS.REMOVED
|
||||
) {
|
||||
throw new HttpException(
|
||||
'问卷已删除',
|
||||
@ -82,7 +82,7 @@ export class ResponseSchemaController {
|
||||
// 问卷信息
|
||||
const schema =
|
||||
await this.responseSchemaService.getResponseSchemaByPath(surveyPath);
|
||||
if (!schema || schema.curStatus.status === 'removed') {
|
||||
if (!schema || schema.subStatus.status === RECORD_SUB_STATUS.REMOVED) {
|
||||
throw new SurveyNotFoundException('该问卷不存在,无法提交');
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import { checkSign } from 'src/utils/checkSign';
|
||||
import { ENCRYPT_TYPE } from 'src/enums/encrypt';
|
||||
import { EXCEPTION_CODE } from 'src/enums/exceptionCode';
|
||||
import { getPushingData } from 'src/utils/messagePushing';
|
||||
import { RECORD_SUB_STATUS } from 'src/enums';
|
||||
|
||||
import { ResponseSchemaService } from '../services/responseScheme.service';
|
||||
import { CounterService } from '../services/counter.service';
|
||||
@ -73,9 +74,18 @@ export class SurveyResponseController {
|
||||
// 查询schema
|
||||
const responseSchema =
|
||||
await this.responseSchemaService.getResponseSchemaByPath(surveyPath);
|
||||
if (!responseSchema || responseSchema.curStatus.status === 'removed') {
|
||||
if (
|
||||
!responseSchema ||
|
||||
responseSchema.subStatus.status === RECORD_SUB_STATUS.REMOVED
|
||||
) {
|
||||
throw new SurveyNotFoundException('该问卷不存在,无法提交');
|
||||
}
|
||||
if (responseSchema?.subStatus?.status === RECORD_SUB_STATUS.PAUSING) {
|
||||
throw new HttpException(
|
||||
'该问卷已暂停,无法提交',
|
||||
EXCEPTION_CODE.RESPONSE_PAUSING,
|
||||
);
|
||||
}
|
||||
|
||||
// 白名单的verifyId校验
|
||||
const baseConf = responseSchema.code.baseConf;
|
||||
|
@ -4,7 +4,7 @@ import { MongoRepository } from 'typeorm';
|
||||
import { ClientEncrypt } from 'src/models/clientEncrypt.entity';
|
||||
import { ENCRYPT_TYPE } from 'src/enums/encrypt';
|
||||
import { ObjectId } from 'mongodb';
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_SUB_STATUS } from 'src/enums';
|
||||
|
||||
@Injectable()
|
||||
export class ClientEncryptService {
|
||||
@ -38,8 +38,8 @@ export class ClientEncryptService {
|
||||
return this.clientEncryptRepository.findOne({
|
||||
where: {
|
||||
_id: new ObjectId(id),
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -52,8 +52,8 @@ export class ClientEncryptService {
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
curStatus: {
|
||||
status: RECORD_STATUS.REMOVED,
|
||||
subStatus: {
|
||||
status: RECORD_SUB_STATUS.REMOVED,
|
||||
date: Date.now(),
|
||||
},
|
||||
},
|
||||
|
@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { MongoRepository } from 'typeorm';
|
||||
import { ResponseSchema } from 'src/models/responseSchema.entity';
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_STATUS, RECORD_SUB_STATUS } from 'src/enums';
|
||||
|
||||
@Injectable()
|
||||
export class ResponseSchemaService {
|
||||
@ -23,12 +23,20 @@ export class ResponseSchemaService {
|
||||
status: RECORD_STATUS.PUBLISHED,
|
||||
date: Date.now(),
|
||||
};
|
||||
clientSurvey.subStatus = {
|
||||
status: RECORD_SUB_STATUS.DEFAULT,
|
||||
date: Date.now(),
|
||||
};
|
||||
return this.responseSchemaRepository.save(clientSurvey);
|
||||
} else {
|
||||
const curStatus = {
|
||||
status: RECORD_STATUS.PUBLISHED,
|
||||
date: Date.now(),
|
||||
};
|
||||
const subStatus = {
|
||||
status: RECORD_SUB_STATUS.DEFAULT,
|
||||
date: Date.now(),
|
||||
};
|
||||
const newClientSurvey = this.responseSchemaRepository.create({
|
||||
title,
|
||||
surveyPath,
|
||||
@ -36,6 +44,7 @@ export class ResponseSchemaService {
|
||||
pageId,
|
||||
curStatus,
|
||||
statusList: [curStatus],
|
||||
subStatus,
|
||||
});
|
||||
return this.responseSchemaRepository.save(newClientSurvey);
|
||||
}
|
||||
@ -53,6 +62,26 @@ export class ResponseSchemaService {
|
||||
});
|
||||
}
|
||||
|
||||
async pausingResponseSchema({ surveyPath }) {
|
||||
const responseSchema = await this.responseSchemaRepository.findOne({
|
||||
where: { surveyPath },
|
||||
});
|
||||
if (responseSchema) {
|
||||
const subStatus = {
|
||||
status: RECORD_SUB_STATUS.PAUSING,
|
||||
date: Date.now(),
|
||||
};
|
||||
responseSchema.subStatus = subStatus;
|
||||
responseSchema.curStatus.status = RECORD_STATUS.PUBLISHED;
|
||||
if (Array.isArray(responseSchema.statusList)) {
|
||||
responseSchema.statusList.push(subStatus);
|
||||
} else {
|
||||
responseSchema.statusList = [subStatus];
|
||||
}
|
||||
return this.responseSchemaRepository.save(responseSchema);
|
||||
}
|
||||
}
|
||||
|
||||
async deleteResponseSchema({ surveyPath }) {
|
||||
const responseSchema = await this.responseSchemaRepository.findOne({
|
||||
where: { surveyPath },
|
||||
|
@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { MongoRepository } from 'typeorm';
|
||||
import { SurveyResponse } from 'src/models/surveyResponse.entity';
|
||||
import { RECORD_SUB_STATUS } from 'src/enums';
|
||||
@Injectable()
|
||||
export class SurveyResponseService {
|
||||
constructor(
|
||||
@ -38,8 +39,8 @@ export class SurveyResponseService {
|
||||
const count = await this.surveyResponseRepository.count({
|
||||
where: {
|
||||
surveyPath,
|
||||
'curStatus.status': {
|
||||
$ne: 'removed',
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
18
server/src/modules/upgrade/controllers/upgrade.controller.ts
Normal file
18
server/src/modules/upgrade/controllers/upgrade.controller.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { Controller, Get, HttpCode } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { UpgradeService } from '../services/upgrade.service';
|
||||
|
||||
@ApiTags('survey')
|
||||
@Controller('/api/upgrade')
|
||||
export class UpgradeController {
|
||||
constructor(private readonly upgradeService: UpgradeService) {}
|
||||
|
||||
@Get('/subStatus')
|
||||
@HttpCode(200)
|
||||
async upgradeSubStatus() {
|
||||
await this.upgradeService.upgradeSubStatus();
|
||||
return {
|
||||
code: 200,
|
||||
};
|
||||
}
|
||||
}
|
74
server/src/modules/upgrade/services/upgrade.service.ts
Normal file
74
server/src/modules/upgrade/services/upgrade.service.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { MongoRepository } from 'typeorm';
|
||||
import { SurveyMeta } from 'src/models/surveyMeta.entity';
|
||||
import { ResponseSchema } from 'src/models/ResponseSchema.entity';
|
||||
import { RECORD_STATUS, RECORD_SUB_STATUS } from 'src/enums';
|
||||
|
||||
@Injectable()
|
||||
export class UpgradeService {
|
||||
constructor(
|
||||
@InjectRepository(SurveyMeta)
|
||||
private readonly SurveyMeta: MongoRepository<SurveyMeta>,
|
||||
@InjectRepository(ResponseSchema)
|
||||
private readonly ResponseSchema: MongoRepository<ResponseSchema>,
|
||||
) {}
|
||||
|
||||
async upgradeSubStatus() {
|
||||
const surveyMetaList = await this.SurveyMeta.find();
|
||||
const responseSchemaList = await this.ResponseSchema.find();
|
||||
|
||||
const callBack = (v: SurveyMeta | ResponseSchema) => {
|
||||
// 将主状态的REMOVED,EDITING刷到子状态
|
||||
// 主状态查一下历史数据删除前最近的状态是“新建”or“已发布
|
||||
if (
|
||||
v.curStatus.status == (RECORD_SUB_STATUS.REMOVED as any) ||
|
||||
v.curStatus.status == (RECORD_SUB_STATUS.EDITING as any)
|
||||
) {
|
||||
const subStatus = {
|
||||
status: v.curStatus.status,
|
||||
date: v.curStatus.date,
|
||||
};
|
||||
v.subStatus = subStatus as any;
|
||||
console.log('subStatus', subStatus);
|
||||
if (v.curStatus.status == (RECORD_SUB_STATUS.EDITING as any)) {
|
||||
v.curStatus.status = RECORD_STATUS.PUBLISHED;
|
||||
}
|
||||
if (v.curStatus.status == (RECORD_SUB_STATUS.REMOVED as any)) {
|
||||
for (let index = v.statusList.length; index > 0; index--) {
|
||||
const item = v.statusList[index];
|
||||
if (
|
||||
item?.status == RECORD_STATUS.PUBLISHED ||
|
||||
item?.status == RECORD_STATUS.NEW
|
||||
) {
|
||||
v.curStatus.status = item.status;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
if (
|
||||
v.curStatus.status == RECORD_STATUS.PUBLISHED ||
|
||||
v.curStatus.status == RECORD_STATUS.NEW
|
||||
) {
|
||||
const subStatus = {
|
||||
status: RECORD_SUB_STATUS.DEFAULT,
|
||||
date: v.statusList[0].date,
|
||||
};
|
||||
v.subStatus = subStatus;
|
||||
}
|
||||
return v;
|
||||
};
|
||||
|
||||
surveyMetaList.map(async (v) => {
|
||||
const item = callBack(v);
|
||||
await this.SurveyMeta.save(item);
|
||||
});
|
||||
|
||||
responseSchemaList.map(async (v) => {
|
||||
const item = callBack(v);
|
||||
await this.ResponseSchema.save(item);
|
||||
});
|
||||
}
|
||||
}
|
39
server/src/modules/upgrade/upgrade.module.ts
Normal file
39
server/src/modules/upgrade/upgrade.module.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
|
||||
import { MessageModule } from '../message/message.module';
|
||||
|
||||
import { UpgradeService } from './services/upgrade.service';
|
||||
|
||||
import { ResponseSchema } from 'src/models/responseSchema.entity';
|
||||
import { Counter } from 'src/models/counter.entity';
|
||||
import { SurveyResponse } from 'src/models/surveyResponse.entity';
|
||||
import { ClientEncrypt } from 'src/models/clientEncrypt.entity';
|
||||
import { Logger } from 'src/logger';
|
||||
import { SurveyMeta } from 'src/models/surveyMeta.entity';
|
||||
|
||||
import { UpgradeController } from './controllers/upgrade.controller';
|
||||
|
||||
import { AuthModule } from '../auth/auth.module';
|
||||
import { WorkspaceModule } from '../workspace/workspace.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([
|
||||
ResponseSchema,
|
||||
Counter,
|
||||
SurveyResponse,
|
||||
ClientEncrypt,
|
||||
SurveyMeta,
|
||||
]),
|
||||
ConfigModule,
|
||||
MessageModule,
|
||||
AuthModule,
|
||||
WorkspaceModule,
|
||||
],
|
||||
controllers: [UpgradeController],
|
||||
providers: [UpgradeService, Logger],
|
||||
exports: [UpgradeService],
|
||||
})
|
||||
export class UpgradeModule {}
|
@ -242,11 +242,15 @@ describe('WorkspaceController', () => {
|
||||
|
||||
describe('getWorkspaceAndMember', () => {
|
||||
it('should return a list of workspaces and members for the user', async () => {
|
||||
const req = { user: { _id: new ObjectId() } };
|
||||
|
||||
const workspaceId = new ObjectId();
|
||||
const userId = new ObjectId();
|
||||
const memberList = [{ workspaceId, userId: userId }];
|
||||
jest.spyOn(userService, 'getUserListByIds').mockResolvedValue([
|
||||
{
|
||||
_id: userId,
|
||||
},
|
||||
] as Array<User>);
|
||||
const req = { user: { _id: userId } };
|
||||
const workspaceId = new ObjectId();
|
||||
const memberList = [{ workspaceId, userId }];
|
||||
const workspaces = [{ _id: workspaceId, name: 'Test Workspace' }];
|
||||
const userList = [{ _id: userId, username: 'Test User' }];
|
||||
|
||||
|
@ -6,7 +6,7 @@ import { Workspace } from 'src/models/workspace.entity';
|
||||
import { SurveyMeta } from 'src/models/surveyMeta.entity';
|
||||
|
||||
import { ObjectId } from 'mongodb';
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_SUB_STATUS } from 'src/enums';
|
||||
|
||||
interface FindAllByIdWithPaginationParams {
|
||||
workspaceIdList: string[];
|
||||
@ -56,8 +56,8 @@ export class WorkspaceService {
|
||||
_id: {
|
||||
$in: workspaceIdList.map((item) => new ObjectId(item)),
|
||||
},
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
};
|
||||
|
||||
@ -91,8 +91,8 @@ export class WorkspaceService {
|
||||
_id: {
|
||||
$in: workspaceIdList.map((m) => new ObjectId(m)),
|
||||
},
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
};
|
||||
if (name) {
|
||||
@ -115,7 +115,7 @@ export class WorkspaceService {
|
||||
|
||||
async delete(id: string) {
|
||||
const newStatus = {
|
||||
status: RECORD_STATUS.REMOVED,
|
||||
status: RECORD_SUB_STATUS.REMOVED,
|
||||
date: Date.now(),
|
||||
};
|
||||
const workspaceRes = await this.workspaceRepository.updateOne(
|
||||
@ -124,7 +124,7 @@ export class WorkspaceService {
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
curStatus: newStatus,
|
||||
subStatus: newStatus,
|
||||
},
|
||||
$push: {
|
||||
statusList: newStatus as never,
|
||||
@ -137,7 +137,7 @@ export class WorkspaceService {
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
curStatus: newStatus,
|
||||
subStatus: newStatus,
|
||||
},
|
||||
$push: {
|
||||
statusList: newStatus as never,
|
||||
@ -155,8 +155,8 @@ export class WorkspaceService {
|
||||
return await this.workspaceRepository.find({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
},
|
||||
order: {
|
||||
|
@ -3,7 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { MongoRepository } from 'typeorm';
|
||||
import { WorkspaceMember } from 'src/models/workspaceMember.entity';
|
||||
import { ObjectId } from 'mongodb';
|
||||
import { RECORD_STATUS } from 'src/enums';
|
||||
import { RECORD_SUB_STATUS } from 'src/enums';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMemberService {
|
||||
@ -94,8 +94,8 @@ export class WorkspaceMemberService {
|
||||
return this.workspaceMemberRepository.find({
|
||||
where: {
|
||||
workspaceId,
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
},
|
||||
select: ['_id', 'createDate', 'curStatus', 'role', 'userId'],
|
||||
@ -135,8 +135,8 @@ export class WorkspaceMemberService {
|
||||
async countByWorkspaceId({ workspaceId }) {
|
||||
return this.workspaceMemberRepository.count({
|
||||
workspaceId,
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
'subStatus.status': {
|
||||
$ne: RECORD_SUB_STATUS.REMOVED,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ export function getFilter(filterList: Array<FilterItem>) {
|
||||
'remark',
|
||||
'surveyType',
|
||||
'curStatus.status',
|
||||
'subStatus.status',
|
||||
];
|
||||
return filterList.reduce(
|
||||
(preItem, curItem) => {
|
||||
|
@ -52,3 +52,13 @@ export const deleteSurvey = (surveyId) => {
|
||||
export const updateSurvey = (data) => {
|
||||
return axios.post('/survey/updateMeta', data)
|
||||
}
|
||||
|
||||
export const pausingSurvey= (surveyId) => {
|
||||
return axios.post('/survey/pausingSurvey', {
|
||||
surveyId
|
||||
})
|
||||
}
|
||||
|
||||
export const upgradeSubStatus = () => {
|
||||
return axios.get('/upgrade/subStatus')
|
||||
}
|
@ -66,7 +66,7 @@ export const fieldConfig = {
|
||||
},
|
||||
updateDate: {
|
||||
title: '更新时间',
|
||||
key: 'curStatus.date',
|
||||
key: 'subStatus.date',
|
||||
minWidth: 200
|
||||
},
|
||||
createDate: {
|
||||
@ -98,13 +98,36 @@ export const noSearchDataConfig = {
|
||||
img: '/imgs/icons/list-empty.webp'
|
||||
}
|
||||
|
||||
export const statusMaps = {
|
||||
new: '未发布',
|
||||
editing: '修改中',
|
||||
published: '已发布',
|
||||
removed: '',
|
||||
pausing: ''
|
||||
export const curStatus = {
|
||||
new: {
|
||||
value: 'new',
|
||||
label: '未发布'
|
||||
},
|
||||
published: {
|
||||
value: 'published',
|
||||
label: '已发布'
|
||||
}
|
||||
}
|
||||
|
||||
// 子状态
|
||||
export const subStatus = {
|
||||
editing: {
|
||||
label: '修改中',
|
||||
value: 'editing'
|
||||
},
|
||||
pausing: {
|
||||
label: '暂停中',
|
||||
value: 'pausing'
|
||||
}
|
||||
}
|
||||
|
||||
export const statusMaps = {
|
||||
...Object.fromEntries(Object.keys(curStatus).map(key => ([key, curStatus[key].label]))),
|
||||
...Object.fromEntries(Object.keys(subStatus).map(key => ([key, subStatus[key].label])))
|
||||
}
|
||||
|
||||
export const curStatusKey = 'curStatus.status';
|
||||
export const subStatusKey = 'subStatus.status';
|
||||
|
||||
// 问卷类型
|
||||
export const surveyTypeSelect = {
|
||||
@ -146,29 +169,21 @@ export const curStatusSelect = {
|
||||
value: '',
|
||||
label: '全部状态'
|
||||
},
|
||||
{
|
||||
value: 'new',
|
||||
label: '未发布'
|
||||
},
|
||||
{
|
||||
value: 'published',
|
||||
label: '已发布'
|
||||
},
|
||||
{
|
||||
value: 'editing',
|
||||
label: '修改中'
|
||||
}
|
||||
curStatus.new,
|
||||
curStatus.published,
|
||||
subStatus.editing,
|
||||
subStatus.pausing
|
||||
],
|
||||
default: ''
|
||||
}
|
||||
|
||||
export const selectOptionsDict = Object.freeze({
|
||||
surveyType: surveyTypeSelect,
|
||||
'curStatus.status': curStatusSelect
|
||||
status: curStatusSelect,
|
||||
})
|
||||
|
||||
export const buttonOptionsDict = Object.freeze({
|
||||
'curStatus.date': {
|
||||
'subStatus.date': {
|
||||
label: '更新时间',
|
||||
icons: [
|
||||
{
|
||||
|
@ -42,6 +42,7 @@
|
||||
@row-click="onRowClick"
|
||||
>
|
||||
<el-table-column column-key="space" width="20" />
|
||||
|
||||
<el-table-column
|
||||
v-for="field in fieldList"
|
||||
:key="field.key"
|
||||
@ -123,7 +124,7 @@ import EmptyIndex from '@/management/components/EmptyIndex.vue'
|
||||
import CooperModify from '@/management/components/CooperModify/ModifyDialog.vue'
|
||||
import { CODE_MAP } from '@/management/api/base'
|
||||
import { QOP_MAP } from '@/management/utils/constant.ts'
|
||||
import { deleteSurvey } from '@/management/api/survey'
|
||||
import { deleteSurvey,pausingSurvey } from '@/management/api/survey'
|
||||
import { useWorkSpaceStore } from '@/management/stores/workSpace'
|
||||
import { useSurveyListStore } from '@/management/stores/surveyList'
|
||||
import ModifyDialog from './ModifyDialog.vue'
|
||||
@ -140,7 +141,9 @@ import {
|
||||
noListDataConfig,
|
||||
noSearchDataConfig,
|
||||
selectOptionsDict,
|
||||
buttonOptionsDict
|
||||
buttonOptionsDict,
|
||||
curStatus,
|
||||
subStatus
|
||||
} from '@/management/config/listConfig'
|
||||
|
||||
const surveyListStore = useSurveyListStore()
|
||||
@ -197,42 +200,12 @@ const dataList = computed(() => {
|
||||
return data.value.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
'curStatus.date': item.curStatus.date
|
||||
'curStatus.date': item.curStatus.date,
|
||||
'subStatus.date': item.subStatus.date
|
||||
}
|
||||
})
|
||||
})
|
||||
const filter = computed(() => {
|
||||
return [
|
||||
{
|
||||
comparator: '',
|
||||
condition: [
|
||||
{
|
||||
field: 'title',
|
||||
value: searchVal.value,
|
||||
comparator: '$regex'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
comparator: '',
|
||||
condition: [
|
||||
{
|
||||
field: 'curStatus.status',
|
||||
value: selectValueMap.value['curStatus.status']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
comparator: '',
|
||||
condition: [
|
||||
{
|
||||
field: 'surveyType',
|
||||
value: selectValueMap.value.surveyType
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
const order = computed(() => {
|
||||
const formatOrder = Object.entries(buttonValueMap.value)
|
||||
.filter(([, effectValue]) => effectValue)
|
||||
@ -245,14 +218,8 @@ const order = computed(() => {
|
||||
})
|
||||
|
||||
const onRefresh = async () => {
|
||||
const filterString = JSON.stringify(
|
||||
filter.value.filter((item) => {
|
||||
return item.condition[0].value
|
||||
})
|
||||
)
|
||||
let params = {
|
||||
curPage: currentPage.value,
|
||||
filter: filterString,
|
||||
order: order.value
|
||||
}
|
||||
if (workSpaceId.value) {
|
||||
@ -286,6 +253,10 @@ const getToolConfig = (row) => {
|
||||
key: 'release',
|
||||
label: '投放'
|
||||
},
|
||||
{
|
||||
key: subStatus.pausing.value,
|
||||
label: '暂停'
|
||||
},
|
||||
{
|
||||
key: 'cooper',
|
||||
label: '协作'
|
||||
@ -306,6 +277,10 @@ const getToolConfig = (row) => {
|
||||
if (row.currentPermissions.includes(SurveyPermissions.SurveyManage)) {
|
||||
// 协作人判断权限显示投放按钮
|
||||
funcList.push(
|
||||
{
|
||||
key: subStatus.pausing.value,
|
||||
label: '暂停'
|
||||
},
|
||||
{
|
||||
key: QOP_MAP.EDIT,
|
||||
label: '修改'
|
||||
@ -339,7 +314,12 @@ const getToolConfig = (row) => {
|
||||
permissionsBtn.splice(-1)
|
||||
funcList = permissionsBtn
|
||||
}
|
||||
const order = ['edit', 'analysis', 'release', 'delete', 'copy', 'cooper']
|
||||
const order = ['edit', 'analysis', 'release', 'pausing', 'delete', 'copy', 'cooper']
|
||||
if((row.curStatus.status !== curStatus.published.value && row.curStatus.status !== subStatus.editing.value) || (row.subStatus.status &&
|
||||
row.subStatus.status != subStatus.editing.value)){
|
||||
order.splice(3, 1)
|
||||
funcList = funcList.filter(item => item.key !== subStatus.pausing.value)
|
||||
}
|
||||
const result = funcList.sort((a, b) => order.indexOf(a.key) - order.indexOf(b.key))
|
||||
|
||||
return result
|
||||
@ -374,6 +354,9 @@ const handleClick = (key, data) => {
|
||||
case 'cooper':
|
||||
onCooper(data)
|
||||
return
|
||||
case 'pausing':
|
||||
onPausing(data)
|
||||
return
|
||||
default:
|
||||
return
|
||||
}
|
||||
@ -398,6 +381,26 @@ const onDelete = async (row) => {
|
||||
ElMessage.error(res.errmsg || '删除失败')
|
||||
}
|
||||
}
|
||||
|
||||
const onPausing = async (row) => {
|
||||
try {
|
||||
await ElMessageBox.confirm('“暂停回收”后问卷将不能填写,是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
} catch (error) {
|
||||
console.log('取消暂停')
|
||||
return
|
||||
}
|
||||
const res = await pausingSurvey(row._id)
|
||||
if (res.code === CODE_MAP.SUCCESS) {
|
||||
ElMessage.success('暂停成功')
|
||||
onRefresh()
|
||||
} else {
|
||||
ElMessage.error(res.errmsg || '暂停失败')
|
||||
}
|
||||
}
|
||||
const handleCurrentChange = (current) => {
|
||||
currentPage.value = current
|
||||
onRefresh()
|
||||
|
@ -1,23 +1,23 @@
|
||||
<template>
|
||||
<div :class="['list-state', 'list-state-' + value.curStatus?.status]">
|
||||
<div :class="['list-state', 'list-state-' + status]">
|
||||
<span class="list-state-badge" />
|
||||
<span>{{ statusMaps[value.curStatus?.status] }}</span>
|
||||
<span>{{ statusMaps[status] }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { statusMaps } from '@/management/config/listConfig'
|
||||
export default {
|
||||
name: 'StateModule',
|
||||
props: {
|
||||
value: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
statusMaps
|
||||
}
|
||||
}
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const status = computed(() => {
|
||||
const {curStatus,subStatus } = props.value;
|
||||
return subStatus?.status || curStatus?.status;
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -30,6 +30,12 @@ export default {
|
||||
background: $normal-color;
|
||||
}
|
||||
}
|
||||
&-pausing{
|
||||
color: #EB505C;
|
||||
.list-state-badge {
|
||||
background: #EB505C;
|
||||
}
|
||||
}
|
||||
&-published {
|
||||
color: #0dbd93;
|
||||
.list-state-badge {
|
||||
|
@ -9,15 +9,28 @@ import { getSurveyList as getSurveyListReq } from '@/management/api/survey'
|
||||
|
||||
import { useWorkSpaceStore } from './workSpace'
|
||||
|
||||
import {
|
||||
curStatus,
|
||||
subStatus,
|
||||
curStatusKey,
|
||||
subStatusKey
|
||||
} from '@/management/config/listConfig'
|
||||
|
||||
const verdictStatus = (status:never) => {
|
||||
if(curStatus[status]) return curStatusKey
|
||||
if (subStatus[status]) return subStatusKey
|
||||
return curStatusKey
|
||||
}
|
||||
|
||||
function useSearchSurvey() {
|
||||
const searchVal = ref('')
|
||||
const selectValueMap = ref<Record<string, any>>({
|
||||
surveyType: '',
|
||||
'curStatus.status': ''
|
||||
'status': '',
|
||||
})
|
||||
|
||||
const buttonValueMap = ref<Record<string, any>>({
|
||||
'curStatus.date': '',
|
||||
'subStatus.date': '',
|
||||
createDate: -1
|
||||
})
|
||||
|
||||
@ -37,8 +50,8 @@ function useSearchSurvey() {
|
||||
comparator: '',
|
||||
condition: [
|
||||
{
|
||||
field: 'curStatus.status',
|
||||
value: selectValueMap.value['curStatus.status']
|
||||
field: verdictStatus( selectValueMap.value['status'] as never),
|
||||
value: selectValueMap.value['status']
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -67,13 +80,13 @@ function useSearchSurvey() {
|
||||
function resetSelectValueMap() {
|
||||
selectValueMap.value = {
|
||||
surveyType: '',
|
||||
'curStatus.status': ''
|
||||
'status': ''
|
||||
}
|
||||
}
|
||||
|
||||
function resetButtonValueMap() {
|
||||
buttonValueMap.value = {
|
||||
'curStatus.date': '',
|
||||
'subStatus.date': '',
|
||||
createDate: -1
|
||||
}
|
||||
}
|
||||
|
@ -39,3 +39,4 @@ export const validate = ({ surveyPath, password, whitelist }) => {
|
||||
whitelist
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,13 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
const checkStatus = (data: any) => {
|
||||
const alert = useCommandComponent(AlertDialog)
|
||||
if (data?.subStatus?.status == 'pausing') {
|
||||
alert({ title:'问卷已暂停回收' })
|
||||
}
|
||||
}
|
||||
|
||||
const getDetail = async (surveyPath: string) => {
|
||||
const alert = useCommandComponent(AlertDialog)
|
||||
|
||||
@ -73,6 +80,7 @@ const getDetail = async (surveyPath: string) => {
|
||||
loadData(res, surveyPath)
|
||||
} else {
|
||||
const res: any = await getPublishedSurveyInfo({ surveyPath })
|
||||
checkStatus(res.data)
|
||||
loadData(res, surveyPath)
|
||||
surveyStore.getEncryptInfo()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user